Browse Source

boost::any作为可选,用来替换std::any

进一步减少使用C++17的语法
tags/v2.9.7
tearshark 5 years ago
parent
commit
ec11d549ef
5 changed files with 101 additions and 40 deletions
  1. 1
    1
      librf/librf.h
  2. 1
    1
      librf/src/when.cpp
  3. 88
    27
      librf/src/when.h
  4. 10
    10
      tutorial/test_async_when_all.cpp
  5. 1
    1
      vs_proj/librf.vcxproj

+ 1
- 1
librf/librf.h View File

@@ -21,6 +21,6 @@
#include "src/channel.h"
#include "src/scheduler.h"
#include "src/sleep.h"
#if _HAS_CXX17
#if _HAS_CXX17 || RESUMEF_USE_BOOST_ANY
#include "src/when.h"
#endif

+ 1
- 1
librf/src/when.cpp View File

@@ -1,6 +1,6 @@
#include "_awaker.h"
#if _HAS_CXX17
#if _HAS_CXX17 || RESUMEF_USE_BOOST_ANY
#include "when.h"
#include <assert.h>

+ 88
- 27
librf/src/when.h View File

@@ -1,7 +1,21 @@
#pragma once
#include "_awaker.h"
#if RESUMEF_USE_BOOST_ANY
#include <boost/any.hpp>
namespace resumef
{
using any_t = boost::any;
using boost::any_cast;
}
#else
#include <any>
namespace resumef
{
using any_t = std::any;
using std::any_cast;
}
#endif
//纠结过when_any的返回值,是选用index + std::any,还是选用std::variant<>。最终选择了std::any。
//std::variant<>存在第一个元素不能默认构造的问题,需要使用std::monostate来占位,导致下标不是从0开始。
@@ -97,16 +111,34 @@ namespace resumef
inline future_vt operator ()() const
{
if constexpr(std::is_same_v<future_type, future_vt>)
{
co_await _f;
_val.get() = std::ignore;
}
else
{
_val.get() = co_await _f;
}
_val.get() = co_await _f;
_e->signal();
}
};
template<class _Ty>
struct when_all_functor<future_vt, _Ty>
{
using value_type = _Ty;
using future_type = future_vt;
when_impl_ptr _e;
mutable future_type _f;
mutable std::reference_wrapper<value_type> _val;
when_all_functor(const detail::when_impl_ptr & e, future_type f, value_type & v)
: _e(e)
, _f(std::move(f))
, _val(v)
{}
when_all_functor(when_all_functor &&) noexcept = default;
when_all_functor & operator = (const when_all_functor &) = default;
when_all_functor & operator = (when_all_functor &&) = default;
inline future_vt operator ()() const
{
co_await _f;
_val.get() = std::ignore;
_e->signal();
}
};
@@ -180,7 +212,7 @@ namespace resumef
return awaitable.get_future();
}
using when_any_pair = std::pair<intptr_t, std::any>;
using when_any_pair = std::pair<intptr_t, any_t>;
using when_any_result_ptr = std::shared_ptr<when_any_pair>;
template<class _Fty>
@@ -210,24 +242,53 @@ namespace resumef
{
if (_val->first < 0)
{
if constexpr(std::is_same_v<future_type, future_vt>)
auto tval = co_await _f;
if (_val->first < 0)
{
co_await _f;
if (_val->first < 0)
{
_val->first = _Idx;
_e->signal();
}
_val->first = _Idx;
_val->second = std::move(tval);
_e->signal();
}
else
}
else
{
co_await _f;
}
}
};
template<>
struct when_any_functor<future_vt>
{
using value_type = when_any_pair;
using future_type = future_vt;
when_impl_ptr _e;
mutable future_type _f;
mutable when_any_result_ptr _val;
intptr_t _Idx;
when_any_functor(const when_impl_ptr & e, future_type f, const when_any_result_ptr & v, intptr_t idx)
: _e(e)
, _f(std::move(f))
, _val(v)
, _Idx(idx)
{
assert(idx >= 0);
}
when_any_functor(when_any_functor &&) noexcept = default;
when_any_functor & operator = (const when_any_functor &) = default;
when_any_functor & operator = (when_any_functor &&) = default;
inline future_vt operator ()() const
{
if (_val->first < 0)
{
co_await _f;
if (_val->first < 0)
{
auto tval = co_await _f;
if (_val->first < 0)
{
_val->first = _Idx;
_val->second = std::move(tval);
_e->signal();
}
_val->first = _Idx;
_e->signal();
}
}
else
@@ -340,7 +401,7 @@ namespace resumef
template<class... _Fty>
auto when_any(scheduler & s, _Fty&&... f) -> future_t<detail::when_any_pair>
{
auto vals = std::make_shared<detail::when_any_pair>(-1, std::any{});
auto vals = std::make_shared<detail::when_any_pair>(-1, any_t{});
return detail::when_any_count(sizeof...(_Fty) ? 1 : 0, vals, s, std::forward<_Fty>(f)...);
}
@@ -352,7 +413,7 @@ namespace resumef
template<class _Iter, typename _Fty = decltype(*std::declval<_Iter>())>
auto when_any(scheduler & s, _Iter begin, _Iter end) -> future_t<detail::when_any_pair>
{
auto vals = std::make_shared<detail::when_any_pair>(-1, std::any{});
auto vals = std::make_shared<detail::when_any_pair>(-1, any_t{});
return detail::when_any_range((begin != end) ? 1 : 0, vals, s, begin, end);
}

+ 10
- 10
tutorial/test_async_when_all.cpp View File

@@ -8,7 +8,7 @@
#include "librf.h"
#if _HAS_CXX17
#if _HAS_CXX17 || RESUMEF_USE_BOOST_ANY
using namespace resumef;
@@ -43,7 +43,7 @@ void test_when_any()
}());
if (vals.first == 0)
std::cout << "first done! value is " << std::any_cast<int>(vals.second) << std::endl;
std::cout << "first done! value is " << resumef::any_cast<int>(vals.second) << std::endl;
else
std::cout << "any done! index is " << vals.first << std::endl;
@@ -61,7 +61,7 @@ void test_when_any()
std::vector<future_t<int> > v{ my_sleep("g"), my_sleep("h"), my_sleep("i") };
vals = co_await when_any(std::begin(v), std::end(v));
std::cout << "any range done! index is " << vals.first << ", valus is " << std::any_cast<int>(vals.second) << std::endl;
std::cout << "any range done! index is " << vals.first << ", valus is " << resumef::any_cast<int>(vals.second) << std::endl;
};
this_scheduler()->run_until_notask();
}
@@ -92,16 +92,16 @@ void test_when_all()
co_await when_all();
std::cout << "when all: zero!" << std::endl << std::endl;
auto [a, b] = co_await when_all(my_sleep("a"), my_sleep_v("b"));
(void)b; //b is std::ignore
std::cout << "when all:" << a << std::endl << std::endl;
auto ab = co_await when_all(my_sleep("a"), my_sleep_v("b"));
//ab.1 is std::ignore
std::cout << "when all:" << std::get<0>(ab) << std::endl << std::endl;
auto c = co_await my_sleep("c");
std::cout << "when all:" << c << std::endl << std::endl;
auto [d, e, f] = co_await when_all(my_sleep("d"), my_sleep_v("e"), my_sleep("f"));
(void)e; //e is std::ignore
std::cout << "when all:" << d << "," << f << std::endl << std::endl;
auto def = co_await when_all(my_sleep("d"), my_sleep_v("e"), my_sleep("f"));
//def.1 is std::ignore
std::cout << "when all:" << std::get<0>(def) << "," << std::get<2>(def) << std::endl << std::endl;
std::vector<future_t<int> > v{ my_sleep("g"), my_sleep("h"), my_sleep("i") };
auto vals = co_await when_all(std::begin(v), std::end(v));
@@ -115,7 +115,7 @@ void test_when_all()
void resumable_main_when_all()
{
#if _HAS_CXX17
#if _HAS_CXX17 || RESUMEF_USE_BOOST_ANY
srand((uint32_t)time(nullptr));
test_when_any();

+ 1
- 1
vs_proj/librf.vcxproj View File

@@ -104,7 +104,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;ASIO_STANDALONE;RESUMEF_DEBUG_COUNTER=0;RESUMEF_ENABLE_MULT_SCHEDULER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;ASIO_STANDALONE;RESUMEF_DEBUG_COUNTER=0;RESUMEF_ENABLE_MULT_SCHEDULER=1;RESUMEF_USE_BOOST_ANY=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\librf;..\..\asio-1.10.6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await</AdditionalOptions>

Loading…
Cancel
Save