Skip to content

Commit

Permalink
refactor(continue): template continuations support
Browse files Browse the repository at this point in the history
  • Loading branch information
alandefreitas committed Nov 9, 2022
1 parent e9dd133 commit 0661c48
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 59 deletions.
171 changes: 121 additions & 50 deletions include/futures/adaptor/detail/continue_invoke_tag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ namespace futures::detail {
struct no_unwrap {};
struct no_input {};
struct rvalue_unwrap {};
struct lvalue_unwrap {};
struct double_unwrap {};
struct deepest_unwrap {};
struct tuple_explode_unwrap {};
Expand Down Expand Up @@ -102,12 +101,18 @@ namespace futures::detail {
Future,
PrefixList,
Function,
std::enable_if_t<mp_apply<
std::is_invocable,
mp_append<
mp_list<Function>,
std::enable_if_t<
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
mp_list<rvalue_t<future_value_t<Future>>>>>::value>> {
Function>::valid::value
&& mp_valid<
std::is_invocable,
mp_append<
mp_list<Function>,
PrefixList,
mp_list<rvalue_t<future_value_t<Future>>>>>::value>> {
private:
template <template <class...> class F>
using invoke_expr = mp_apply<
Expand All @@ -117,7 +122,7 @@ namespace futures::detail {
PrefixList,
mp_list<rvalue_t<future_value_t<Future>>>>>;
public:
using valid = std::true_type;
using valid = invoke_expr<std::is_invocable>;
using result = invoke_expr<std::invoke_result>;
};

Expand All @@ -127,16 +132,21 @@ namespace futures::detail {
Future,
PrefixList,
Function,
std::enable_if_t<is_future_v<future_value_t<Future>>>> {
std::enable_if_t<
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_future_v<future_value_t<Future>>>> {
private:
template <template <class...> class F>
using invoke_expr = mp_apply<
F,
mp_append<
mp_list<Function>,
PrefixList,
mp_list<rvalue_t<
future_value_t<future_value_t<Future>>>>>>;
mp_list<rvalue_t<future_value_t<future_value_t<Future>>>>>>;
public:
using valid = invoke_expr<std::is_invocable>;
using result = invoke_expr<std::invoke_result>;
Expand All @@ -150,8 +160,7 @@ namespace futures::detail {

template <class T>
struct unwrap_future<T, std::enable_if_t<futures::is_future_v<T>>> {
using type = typename unwrap_future<
futures::future_value_t<T>>::type;
using type = typename unwrap_future<futures::future_value_t<T>>::type;
};

template <class F>
Expand All @@ -163,7 +172,13 @@ namespace futures::detail {
Future,
PrefixList,
Function,
std::enable_if_t<is_future_v<future_value_t<Future>>>> {
std::enable_if_t<
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_future_v<future_value_t<Future>>>> {
private:
template <template <class...> class F>
using invoke_expr = mp_apply<
Expand All @@ -183,9 +198,14 @@ namespace futures::detail {
Future,
PrefixList,
Function,
std::enable_if_t<mp_similar<
std::tuple<>,
std::decay_t<future_value_t<Future>>>::value>> {
std::enable_if_t<
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& mp_similar<std::tuple<>, std::decay_t<future_value_t<Future>>>::
value>> {
private:
template <template <class...> class F>
using invoke_expr = mp_apply<
Expand All @@ -206,8 +226,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
mp_similar<std::tuple<>, std::decay_t<future_value_t<Future>>>::
value
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& mp_similar<std::tuple<>, std::decay_t<future_value_t<Future>>>::value
&& mp_all_of<future_value_t<Future>, is_future>::value>> {
private:
template <template <class...> class F>
Expand All @@ -231,8 +255,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
mp_similar<std::tuple<>, std::decay_t<future_value_t<Future>>>::
value
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& mp_similar<std::tuple<>, std::decay_t<future_value_t<Future>>>::value
&& mp_all_of<
mp_transform<std::decay_t, future_value_t<Future>>,
is_future>::value>> {
Expand All @@ -258,7 +286,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_range_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_range_v<std::decay_t<future_value_t<Future>>>
&& is_future_v<
std::decay_t<range_value_t<future_value_t<Future>>>>>> {
private:
Expand All @@ -268,8 +301,8 @@ namespace futures::detail {
mp_append<
mp_list<Function>,
PrefixList,
mp_list<rvalue_t<detail::small_vector<future_value_t<
range_value_t<future_value_t<Future>>>>>>>>;
mp_list<rvalue_t<detail::small_vector<
future_value_t<range_value_t<future_value_t<Future>>>>>>>>;
public:
using valid = invoke_expr<std::is_invocable>;
using result = invoke_expr<std::invoke_result>;
Expand All @@ -282,7 +315,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_range_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_range_v<std::decay_t<future_value_t<Future>>>
&& is_future_v<
std::decay_t<range_value_t<future_value_t<Future>>>>>> {
private:
Expand All @@ -292,8 +330,8 @@ namespace futures::detail {
mp_append<
mp_list<Function>,
PrefixList,
mp_list<rvalue_t<detail::small_vector<unwrap_future_t<
range_value_t<future_value_t<Future>>>>>>>>;
mp_list<rvalue_t<detail::small_vector<
unwrap_future_t<range_value_t<future_value_t<Future>>>>>>>>;
public:
using valid = invoke_expr<std::is_invocable>;
using result = invoke_expr<std::invoke_result>;
Expand All @@ -306,7 +344,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>>> {
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>>> {
private:
template <template <class...> class F>
using invoke_expr = mp_apply<
Expand All @@ -316,8 +359,7 @@ namespace futures::detail {
PrefixList,
mp_list<
rvalue_t<typename future_value_t<Future>::size_type>,
rvalue_t<
typename future_value_t<Future>::sequence_type>>>>;
rvalue_t<typename future_value_t<Future>::sequence_type>>>>;
public:
using valid = invoke_expr<std::is_invocable>;
using result = invoke_expr<std::invoke_result>;
Expand All @@ -330,11 +372,15 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& mp_similar<
std::tuple<>,
std::decay_t<
typename future_value_t<Future>::sequence_type>>::value
std::decay_t<typename future_value_t<Future>::sequence_type>>::value
&& mp_all_of<
std::decay_t<typename future_value_t<Future>::sequence_type>,
is_future>::value>> {
Expand All @@ -345,8 +391,7 @@ namespace futures::detail {
mp_append<
mp_list<Function>,
PrefixList,
mp_list<
rvalue_t<typename future_value_t<Future>::size_type>>,
mp_list<rvalue_t<typename future_value_t<Future>::size_type>>,
mp_transform<
rvalue_t,
typename future_value_t<Future>::sequence_type>>>;
Expand All @@ -362,16 +407,19 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& mp_similar<
std::tuple<>,
std::decay_t<
typename future_value_t<Future>::sequence_type>>::value
std::decay_t<typename future_value_t<Future>::sequence_type>>::value
&& mp_all_of<
mp_transform<
std::decay_t,
std::decay_t<
typename future_value_t<Future>::sequence_type>>,
std::decay_t<typename future_value_t<Future>::sequence_type>>,
is_future>::value
&& mp_same<std::decay_t<
typename future_value_t<Future>::sequence_type>>::value>> {
Expand All @@ -397,7 +445,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& is_range_v<std::decay_t<
typename future_value_t<Future>::sequence_type>>>> {
private:
Expand All @@ -421,20 +474,24 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& mp_similar<
std::tuple<>,
std::decay_t<
typename future_value_t<Future>::sequence_type>>::value
std::decay_t<typename future_value_t<Future>::sequence_type>>::value
&& mp_all_of<
mp_transform<
std::decay_t,
typename future_value_t<Future>::sequence_type>,
is_future>::value
&& mp_same<mp_transform<
std::decay_t,
std::decay_t<typename future_value_t<
Future>::sequence_type>>>::value>> {
std::decay_t<typename future_value_t<Future>::sequence_type>>>::
value>> {
private:
template <template <class...> class F>
using invoke_expr = mp_apply<
Expand All @@ -457,11 +514,15 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& mp_similar<
std::tuple<>,
std::decay_t<
typename future_value_t<Future>::sequence_type>>::value
std::decay_t<typename future_value_t<Future>::sequence_type>>::value
&& mp_all_of<
mp_transform<
std::decay_t,
Expand Down Expand Up @@ -492,7 +553,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& is_range_v<std::decay_t<
typename future_value_t<Future>::sequence_type>>>> {
private:
Expand All @@ -516,7 +582,12 @@ namespace futures::detail {
PrefixList,
Function,
std::enable_if_t<
is_when_any_result_v<std::decay_t<future_value_t<Future>>>
!continue_invoke_traits<
continue_tags::no_unwrap,
Future,
PrefixList,
Function>::valid::value
&& is_when_any_result_v<std::decay_t<future_value_t<Future>>>
&& is_range_v<std::decay_t<
typename future_value_t<Future>::sequence_type>>>> {
private:
Expand Down
8 changes: 7 additions & 1 deletion include/futures/adaptor/detail/future_continue_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ namespace futures::detail {
return future_continue(std::move(before_), std::move(after_));
}

continue_invoke_result_t<Future, Function, stop_token>
mp_eval_if<
continue_is_invocable<Future, Function>,
detail::continue_tags::failure,
continue_invoke_result_t,
Future,
Function,
stop_token>
operator()(stop_token st) {
return future_continue(std::move(before_), std::move(after_), st);
}
Expand Down

0 comments on commit 0661c48

Please sign in to comment.