Browse Source

when_all/when_any支持迭代器区间

tags/v2.9.7
tearshark 6 years ago
parent
commit
630b38ca76
4 changed files with 55 additions and 12 deletions
  1. 1
    1
      README.md
  2. 2
    2
      librf/src/future.h
  3. 40
    7
      librf/src/when.h
  4. 12
    2
      tutorial/test_async_when_all.cpp

+ 1
- 1
README.md View File

@@ -6,7 +6,7 @@ librf是一个基于C++ Coroutines提案 ‘Stackless Resumable Functions’编

目前仅支持:

Windows (使用VS2015/2017编译)
Windows (使用2017编译)(由于使用了SFINAE导致不再支持VS2015)


librf有以下特点:

+ 2
- 2
librf/src/future.h View File

@@ -121,11 +121,11 @@ namespace resumef
}
// movable, but not copyable
future_t(const future_t&) = delete;
future_t(const future_t&) = default;
future_t(future_t&& f) = default;
future_t() = default;
future_t & operator = (const future_t&) = delete;
future_t & operator = (const future_t&) = default;
future_t & operator = (future_t&& f) = default;
//------------------------------------------------------------------------------------------

+ 40
- 7
librf/src/when.h View File

@@ -45,11 +45,12 @@ namespace resumef
template<class _Fty>
struct when_one_functor
{
typedef future_t<std::remove_reference_t<_Fty> > future_type;
when_impl_ptr _e;
mutable future_t<_Fty> _f;
mutable future_type _f;
when_one_functor(const detail::when_impl_ptr & e, future_t<_Fty> f)
:_e(e)
when_one_functor(const detail::when_impl_ptr & e, future_type f)
: _e(e)
, _f(std::move(f))
{}
when_one_functor(when_one_functor &&) = default;
@@ -60,7 +61,16 @@ namespace resumef
_e->signal();
}
};
template<class _Fty>
struct when_one_functor<future_t<_Fty> > : public when_one_functor<_Fty>
{
using future_type = typename when_one_functor<_Fty>::future_type;
when_one_functor(const detail::when_impl_ptr & e, future_type f)
: when_one_functor<_Fty>(e, std::move(f))
{}
when_one_functor(when_one_functor &&) = default;
};
inline void when_one__(scheduler & s, const detail::when_impl_ptr & e)
{
@@ -73,6 +83,14 @@ namespace resumef
when_one__(s, e, std::forward<_Rest>(rest)...);
}
template<class _Iter, typename _Fty = decltype(*std::declval<_Iter>())>
inline void when_one__(scheduler & s, const detail::when_impl_ptr & e, _Iter begin, _Iter end)
{
using future_type = std::remove_reference_t<_Fty>;
for(; begin != end; ++begin)
s + when_one_functor<future_type>{e, *begin};
}
}
template<class... _Fty>
@@ -94,29 +112,44 @@ namespace resumef
return awaitable.get_future();
}
template<class... _Fty>
future_t<bool> when_all(scheduler & s, _Fty&&... f)
{
return when_count(sizeof...(_Fty), s, std::forward<_Fty>(f)...);
}
template<class... _Fty>
future_t<bool> when_all(_Fty&&... f)
{
return when_count(sizeof...(_Fty), *this_scheduler(), std::forward<_Fty>(f)...);
}
template<class _Iter, typename = decltype(*std::declval<_Iter>())>
future_t<bool> when_all(_Iter begin, _Iter end)
{
return when_count(std::distance(begin, end), *this_scheduler(), begin, end);
}
template<class... _Fty>
future_t<bool> when_any(scheduler & s, _Fty&&... f)
{
static_assert(sizeof...(_Fty) > 0);
return when_count(1, s, std::forward<_Fty>(f)...);
return when_count(sizeof...(_Fty) ? 1 : 0, s, std::forward<_Fty>(f)...);
}
template<class... _Fty>
future_t<bool> when_any(_Fty&&... f)
{
static_assert(sizeof...(_Fty) > 0);
return when_count(1, *this_scheduler(), std::forward<_Fty>(f)...);
return when_count(sizeof...(_Fty) ? 1 : 0, *this_scheduler(), std::forward<_Fty>(f)...);
}
template<class _Iter, typename = decltype(*std::declval<_Iter>())>
future_t<bool> when_any(_Iter begin, _Iter end)
{
assert(std::distance(begin, end) > 0); //???
return when_count(std::distance(begin, end) ? 1 : 0, *this_scheduler(), begin, end);
}
}

+ 12
- 2
tutorial/test_async_when_all.cpp View File

@@ -4,7 +4,7 @@
#include <string>
#include <conio.h>
#include <thread>
#include <experimental/resumable>
#include <inttypes.h>
#include "librf.h"
@@ -54,11 +54,21 @@ void test_when_all()
GO
{
co_await when_all();
std::cout << "zero!" << std::endl;
std::cout << "zero!" << std::endl << std::endl;
co_await when_all(my_sleep("a"), my_sleep("b"));
std::cout << std::endl;
co_await my_sleep("c");
std::cout << std::endl;
co_await when_all(my_sleep("d"), my_sleep("e"), my_sleep("f"));
std::cout << std::endl;
std::vector<future_vt> v{ my_sleep("g"), my_sleep("h"), my_sleep("i") };
co_await when_all(std::begin(v), std::end(v));
std::cout << std::endl;
std::cout << "all done!" << std::endl;
};
this_scheduler()->run_until_notask();

Loading…
Cancel
Save