Skip to content

Commit 54059ae

Browse files
committed
added then
1 parent ca43094 commit 54059ae

File tree

2 files changed

+170
-5
lines changed

2 files changed

+170
-5
lines changed

include/beman/execution26/detail/then.hpp

+44-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_THEN
55
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_THEN
66

7+
#include <beman/execution26/detail/call_result_t.hpp>
78
#include <beman/execution26/detail/completion_signatures.hpp>
89
#include <beman/execution26/detail/completion_signatures_for.hpp>
10+
#include <beman/execution26/detail/completion_signatures_of_t.hpp>
911
#include <beman/execution26/detail/default_impls.hpp>
1012
#include <beman/execution26/detail/get_domain_early.hpp>
1113
#include <beman/execution26/detail/impls_for.hpp>
1214
#include <beman/execution26/detail/make_sender.hpp>
15+
#include <beman/execution26/detail/meta_transform.hpp>
16+
#include <beman/execution26/detail/meta_unique.hpp>
1317
#include <beman/execution26/detail/movable_value.hpp>
1418
#include <beman/execution26/detail/sender.hpp>
1519
#include <beman/execution26/detail/sender_adaptor.hpp>
@@ -102,18 +106,55 @@ namespace beman::execution26::detail
102106
};
103107
};
104108

109+
template <typename T>
110+
struct then_set_value
111+
{
112+
using type = ::beman::execution26::set_value_t(T);
113+
};
114+
template <>
115+
struct then_set_value<void>
116+
{
117+
using type = ::beman::execution26::set_value_t();
118+
};
119+
120+
template <typename, typename, typename Completion>
121+
struct then_transform
122+
{
123+
using type = Completion;
124+
};
125+
126+
template <typename Fun, typename Replace>
127+
struct then_transform_t
128+
{
129+
template <typename Completion>
130+
using transform = typename
131+
::beman::execution26::detail::then_transform<Fun, Replace, Completion>
132+
::type;
133+
};
134+
135+
template <typename Fun, typename Completion, typename... T>
136+
struct then_transform<Fun, Completion, Completion(T...)>
137+
{
138+
using type = typename ::beman::execution26::detail::then_set_value<
139+
::beman::execution26::detail::call_result_t<Fun, T...>
140+
>::type;
141+
};
105142

106-
template <typename Fun, typename Sender, typename Env>
143+
template <typename Completion, typename Fun, typename Sender, typename Env>
107144
struct completion_signatures_for_impl<
108145
::beman::execution26::detail::basic_sender<
109-
::beman::execution26::detail::then_t<::beman::execution26::set_stopped_t>,
146+
::beman::execution26::detail::then_t<Completion>,
110147
Fun,
111148
Sender
112149
>,
113150
Env
114151
>
115152
{
116-
using type = ::beman::execution26::completion_signatures<
153+
using type = ::beman::execution26::detail::meta::unique<
154+
::beman::execution26::detail::meta::transform<
155+
::beman::execution26::detail::then_transform_t<Fun, Completion>::template transform,
156+
::beman::execution26::completion_signatures_of_t<Sender, Env>
157+
>
117158
>;
118159
};
119160
}

src/beman/execution26/tests/exec-then.pass.cpp

+126-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
33

44
#include <beman/execution26/detail/then.hpp>
5-
#include <beman/execution26/detail/just.hpp>
5+
6+
#include <beman/execution26/detail/completion_signatures_of_t.hpp>
67
#include <beman/execution26/detail/connect.hpp>
8+
#include <beman/execution26/detail/just.hpp>
9+
#include <beman/execution26/detail/sender.hpp>
10+
#include <beman/execution26/detail/sender_in.hpp>
711
#include <beman/execution26/detail/start.hpp>
8-
#include <test/execution.hpp>
12+
#include <beman/execution26/detail/sync_wait.hpp>
913
#include <concepts>
14+
#include <test/execution.hpp>
1015

1116
// ----------------------------------------------------------------------------
1217

@@ -24,6 +29,13 @@ namespace
2429
auto set_value(auto&&...) && noexcept -> void {}
2530
};
2631

32+
template <typename... T>
33+
struct sender
34+
{
35+
using sender_concept = test_std::sender_t;
36+
using completion_signatures = test_std::completion_signatures<T...>;
37+
};
38+
2739
template <bool Expect>
2840
auto test_has(auto cpo, auto in_sender, auto fun) -> void
2941
{
@@ -42,6 +54,114 @@ namespace
4254
test_std::start(op);
4355
}
4456
}
57+
58+
template <typename... Completions>
59+
auto test_then_type(auto sender)
60+
{
61+
static_assert(std::same_as<
62+
test_std::completion_signatures<Completions...>,
63+
test_std::completion_signatures_of_t<decltype(sender), test_std::empty_env>
64+
>);
65+
};
66+
67+
auto test_then_type() -> void
68+
{
69+
test_then_type< test_std::set_value_t()>(test_std::just() | test_std::then([]{}));
70+
test_then_type< test_std::set_value_t(int)>(test_std::just() | test_std::then([]{ return 0; }));
71+
test_then_type< test_std::set_error_t(int)>(test_std::just_error(0) | test_std::then([]{ return 0; }));
72+
test_then_type< test_std::set_stopped_t()>(test_std::just_stopped() | test_std::then([]{ return 0; }));
73+
74+
test_then_type< test_std::set_value_t()>(test_std::just() | test_std::upon_error([]{ return 0; }));
75+
test_then_type< test_std::set_value_t(int)>(test_std::just_error(error{})
76+
| test_std::upon_error([](error){ return 0; }));
77+
test_then_type< test_std::set_stopped_t()>(test_std::just_stopped() | test_std::upon_error([]{}));
78+
79+
test_then_type< test_std::set_value_t(int)>(test_std::just(0) | test_std::upon_stopped([]{}));
80+
test_then_type< test_std::set_error_t(int)>(test_std::just_error(0) | test_std::upon_stopped([]{}));
81+
test_then_type< test_std::set_value_t()>(test_std::just_stopped() | test_std::upon_stopped([]{}));
82+
}
83+
84+
auto test_then_multi_type() -> void
85+
{
86+
static_assert(test_std::sender<sender<>>);
87+
static_assert(test_std::sender_in<sender<>>);
88+
89+
test_then_type<
90+
test_std::set_value_t(),
91+
test_std::set_value_t(int, int),
92+
test_std::set_error_t(error),
93+
test_std::set_stopped_t()
94+
>(sender<
95+
test_std::set_value_t(),
96+
test_std::set_value_t(int, int),
97+
test_std::set_error_t(error),
98+
test_std::set_stopped_t()
99+
>());
100+
test_then_type<
101+
test_std::set_value_t(bool),
102+
test_std::set_error_t(error),
103+
test_std::set_stopped_t()
104+
>(sender<
105+
test_std::set_value_t(),
106+
test_std::set_value_t(int, int),
107+
test_std::set_error_t(error),
108+
test_std::set_stopped_t()
109+
>() | test_std::then([](auto&&...){ return true; }));
110+
test_then_type<
111+
test_std::set_value_t(),
112+
test_std::set_value_t(int, int),
113+
test_std::set_value_t(bool),
114+
test_std::set_stopped_t()
115+
>(sender<
116+
test_std::set_value_t(),
117+
test_std::set_value_t(int, int),
118+
test_std::set_error_t(error),
119+
test_std::set_stopped_t()
120+
>() | test_std::upon_error([](error){ return true; }));
121+
test_then_type<
122+
test_std::set_value_t(),
123+
test_std::set_value_t(int, int),
124+
test_std::set_stopped_t()
125+
>(sender<
126+
test_std::set_value_t(),
127+
test_std::set_value_t(int, int),
128+
test_std::set_error_t(error),
129+
test_std::set_stopped_t()
130+
>() | test_std::upon_error([](error){}));
131+
test_then_type<
132+
test_std::set_value_t(int),
133+
test_std::set_value_t(int, int),
134+
test_std::set_error_t(error),
135+
test_std::set_value_t()
136+
>(sender<
137+
test_std::set_value_t(int),
138+
test_std::set_value_t(int, int),
139+
test_std::set_error_t(error),
140+
test_std::set_stopped_t()
141+
>() | test_std::upon_stopped([]{}));
142+
test_then_type<
143+
test_std::set_value_t(),
144+
test_std::set_value_t(int, int),
145+
test_std::set_error_t(error)
146+
>(sender<
147+
test_std::set_value_t(),
148+
test_std::set_value_t(int, int),
149+
test_std::set_error_t(error),
150+
test_std::set_stopped_t()
151+
>() | test_std::upon_stopped([]{}));
152+
}
153+
auto test_then_value() -> void
154+
{
155+
assert(std::tuple{17} == *test_std::sync_wait(
156+
test_std::just(5, 12) | test_std::then([](int a, int b){ return a + b; })
157+
));
158+
assert(std::tuple{17} == test_std::sync_wait(
159+
test_std::just_error(17) | test_std::upon_error([](int a){ return a; })
160+
));
161+
assert(std::tuple{17} == test_std::sync_wait(
162+
test_std::just_stopped() | test_std::upon_stopped([](){ return 17; })
163+
));
164+
}
45165
}
46166

47167
auto main() -> int
@@ -54,4 +174,8 @@ auto main() -> int
54174
test_has<true>(test_std::then, test_std::just(), []{});
55175
test_has<true>(test_std::then, test_std::just_error(error{3}), []{});
56176
test_has<true>(test_std::then, test_std::just_stopped(), []{});
177+
178+
test_then_type();
179+
test_then_multi_type();
180+
test_then_value();
57181
}

0 commit comments

Comments
 (0)