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



目前仅支持: 目前仅支持:


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




librf有以下特点: librf有以下特点:

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

} }
// movable, but not copyable // movable, but not copyable
future_t(const future_t&) = delete;
future_t(const future_t&) = default;
future_t(future_t&& f) = default; future_t(future_t&& f) = default;
future_t() = 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; future_t & operator = (future_t&& f) = default;
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------

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

template<class _Fty> template<class _Fty>
struct when_one_functor struct when_one_functor
{ {
typedef future_t<std::remove_reference_t<_Fty> > future_type;
when_impl_ptr _e; 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)) , _f(std::move(f))
{} {}
when_one_functor(when_one_functor &&) = default; when_one_functor(when_one_functor &&) = default;
_e->signal(); _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) inline void when_one__(scheduler & s, const detail::when_impl_ptr & e)
{ {
when_one__(s, e, std::forward<_Rest>(rest)...); 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> template<class... _Fty>
return awaitable.get_future(); return awaitable.get_future();
} }
template<class... _Fty> template<class... _Fty>
future_t<bool> when_all(scheduler & s, _Fty&&... f) future_t<bool> when_all(scheduler & s, _Fty&&... f)
{ {
return when_count(sizeof...(_Fty), s, std::forward<_Fty>(f)...); return when_count(sizeof...(_Fty), s, std::forward<_Fty>(f)...);
} }
template<class... _Fty> template<class... _Fty>
future_t<bool> when_all(_Fty&&... f) future_t<bool> when_all(_Fty&&... f)
{ {
return when_count(sizeof...(_Fty), *this_scheduler(), std::forward<_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> template<class... _Fty>
future_t<bool> when_any(scheduler & s, _Fty&&... f) future_t<bool> when_any(scheduler & s, _Fty&&... f)
{ {
static_assert(sizeof...(_Fty) > 0); 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> template<class... _Fty>
future_t<bool> when_any(_Fty&&... f) future_t<bool> when_any(_Fty&&... f)
{ {
static_assert(sizeof...(_Fty) > 0); 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

#include <string> #include <string>
#include <conio.h> #include <conio.h>
#include <thread> #include <thread>
#include <experimental/resumable>
#include <inttypes.h>
#include "librf.h" #include "librf.h"
GO GO
{ {
co_await when_all(); 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")); co_await when_all(my_sleep("a"), my_sleep("b"));
std::cout << std::endl;
co_await my_sleep("c"); co_await my_sleep("c");
std::cout << std::endl;
co_await when_all(my_sleep("d"), my_sleep("e"), my_sleep("f")); 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; std::cout << "all done!" << std::endl;
}; };
this_scheduler()->run_until_notask(); this_scheduler()->run_until_notask();

Loading…
Cancel
Save