Enable and document the new when_all

This commit is contained in:
Denis Blank 2018-03-02 02:51:53 +01:00
parent dd1b605d95
commit 9891543b1f
3 changed files with 70 additions and 14 deletions

View File

@ -43,20 +43,72 @@
#include <continuable/detail/util.hpp> #include <continuable/detail/util.hpp>
namespace cti { namespace cti {
/// Connects the given continuables with an *all* logic. /// Connects the given arguments with an all logic.
/// All continuables contained inside the given nested pack are
/// invoked at once. On completion the final handler is called
/// with the aggregated result of all continuables.
/// ///
/// \param continuables The continuable_base objects to connect. /// \param args Arbitrary arguments which are connected.
/// Requires at least 2 objects to connect. /// Every type is allowed as arguments, continuables may be
/// contained inside tuple like types (`std::tuple`)
/// or in homogeneous containers such as `std::vector`.
/// Non continuable arguments are preserved and passed
/// to the final result as shown below:
/// ```cpp
/// cti::when_all(
/// cti::make_ready_continuable(0, 1),
/// 2, //< See this plain value
/// std::vector<cti::continuable<int>>{cti::make_ready_continuable(3),
/// cti::make_ready_continuable(4)},
/// std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
/// .then([](int r0, int r1, int r2, std::vector<int> r34,
/// std::tuple<std::tuple<int>> r5) {
/// // ...
/// });
/// ```
/// ///
/// \see continuable_base::operator && for details. /// \see continuable_base::operator&& for details.
/// ///
/// \since 1.1.0 /// \since 1.1.0
template <typename... Continuables> template <typename... Args>
auto when_all(Continuables&&... continuables) { auto when_all(Args&&... args) {
static_assert(sizeof...(continuables) >= 2, return detail::composition::apply_composition(
"Requires at least 2 continuables!"); detail::composition::composition_strategy_all_tag{},
return CONTINUABLE_FOLD_EXPRESSION( std::forward<Args>(args)...);
&&, std::forward<Continuables>(continuables)...); }
/// Connects the given arguments with an all logic.
/// The content of the iterator is moved out and converted
/// to a temporary `std::vector` which is then passed to when_all.
///
/// ```cpp
/// std::vector<cti::continuable<int>> v{cti::make_ready_continuable(0),
/// cti::make_ready_continuable(1)};
///
/// cti::when_all(v.begin(), v.end())
/// .then([](std::vector<int> r01) {
/// // ...
/// });
/// ```
///
/// \param begin The begin iterator to the range which will be moved out
/// and used as the arguments to the all connection
///
/// \param end The end iterator to the range which will be moved out
/// and used as the arguments to the all connection
///
/// \see when_all for details.
///
/// \attention Prefer to invoke when_all with the whole container the
/// iterators were taken from, since this saves us
/// the creation of a temporary storage.
///
/// \since 3.0.0
template <
typename Iterator,
std::enable_if_t<detail::range::is_iterator<Iterator>::value>* = nullptr>
auto when_all(Iterator begin, Iterator end) {
return when_all(detail::range::persist_range(begin, end));
} }
/// Connects the given arguments with a sequential logic. /// Connects the given arguments with a sequential logic.

View File

@ -177,9 +177,14 @@ struct materializer<
} }
}; };
struct prepare_continuables { class prepare_continuables {
util::ownership& ownership_; util::ownership& ownership_;
public:
explicit constexpr prepare_continuables(util::ownership& ownership)
: ownership_(ownership) {
}
template <typename Continuable, template <typename Continuable,
std::enable_if_t<base::is_continuable< std::enable_if_t<base::is_continuable<
std::decay_t<Continuable>>::value>* = nullptr> std::decay_t<Continuable>>::value>* = nullptr>

View File

@ -158,8 +158,7 @@ int main(int, char**) {
// ... // ...
}); });
composition::apply_composition( cti::when_all(
composition::composition_strategy_all_tag{},
cti::make_ready_continuable(0, 1), 2, //< See this plain value cti::make_ready_continuable(0, 1), 2, //< See this plain value
std::vector<cti::continuable<int>>{cti::make_ready_continuable(3), std::vector<cti::continuable<int>>{cti::make_ready_continuable(3),
cti::make_ready_continuable(4)}, cti::make_ready_continuable(4)},