Skip to content

Commit

Permalink
segmented (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoisChabot authored Jun 18, 2019
1 parent 7af85c8 commit 1c71606
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 1 deletion.
4 changes: 4 additions & 0 deletions include/var_future/future.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ auto async(QueueT& q, CbT&& callback);
template <typename Alloc, typename... Ts>
Basic_future<Alloc, Ts...> flatten(Basic_future<Alloc, std::tuple<Ts...>>& rhs);

template<typename... Ts>
auto segmented(Ts&&... args);


} // namespace aom

#include "var_future/impl/async.h"
Expand Down
12 changes: 12 additions & 0 deletions include/var_future/impl/future.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,17 @@ Basic_future<Alloc, Ts...> flatten(
return Basic_future<Alloc, Ts...>(std::move(storage));
}

/**
* @brief Permits a callback to produce a higher-order future.
*
* @tparam Ts
* @param args
* @return auto
*/
template<typename... Ts>
auto segmented(Ts&&... args) {
return detail::Segmented_callback_result<std::decay_t<Ts>...>{ std::make_tuple(std::forward<Ts>(args)...)};
}

} // namespace aom
#endif
14 changes: 14 additions & 0 deletions include/var_future/impl/storage_decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ namespace aom {

namespace detail {

template<typename... Ts>
struct Segmented_callback_result {
std::tuple<Ts...> values_;
};


template <typename... Ts>
class Future_handler_iface {
public:
Expand Down Expand Up @@ -99,6 +105,9 @@ class Future_storage : public Alloc {
template <typename Arg_alloc>
void fullfill(Basic_future<Arg_alloc, Ts...>&& f);

template <typename... Us>
void fullfill(Segmented_callback_result<Us...>&& f);

void finish(finish_type&& f);

template <typename Arg_alloc>
Expand Down Expand Up @@ -244,6 +253,11 @@ struct Storage_for_cb_result<Alloc, expected<T>> {
using type = typename Storage_for_cb_result<Alloc, T>::type;
};

template <typename Alloc, typename... Us>
struct Storage_for_cb_result<Alloc, Segmented_callback_result<Us...>> {
using type = Future_storage<Alloc, decay_future_t<Us>...>;
};

template <typename Alloc, typename T>
using Storage_for_cb_result_t = typename Storage_for_cb_result<Alloc, T>::type;

Expand Down
6 changes: 6 additions & 0 deletions include/var_future/impl/storage_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ void Future_storage<Alloc, Ts...>::fullfill(fullfill_type&& v) {
}
}

template <typename Alloc, typename... Ts>
template <typename... Us>
void Future_storage<Alloc, Ts...>::fullfill(Segmented_callback_result<Us...>&& f) {
fullfill(std::move(f.values_));
}

template <typename Alloc, typename... Ts>
template <typename Arg_alloc>
void Future_storage<Alloc, Ts...>::fullfill(
Expand Down
16 changes: 15 additions & 1 deletion tests/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ TEST(Future, variadic_get) {
static_assert(std::is_same_v<Future<int, void, int>::value_type, std::tuple<int, int>>);
}


TEST(Future, variadic_get_failure) {
Promise<void, void> p;
auto f = p.get_future();
Expand All @@ -312,3 +311,18 @@ TEST(Future, variadic_get_failure) {

EXPECT_THROW(f.get(), std::runtime_error);
}

TEST(Future, segmented_callback) {
Promise<void> p;

auto f = p.get_future().then([](){
return segmented(12, 12);
})
.then([](int a, int b) {
return a + b;
});

p.set_value();

EXPECT_EQ(24, f.get());
}

0 comments on commit 1c71606

Please sign in to comment.