Skip to content

Commit 80bc99a

Browse files
committed
added has_completions
1 parent 0b30f61 commit 80bc99a

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// include/beman/execution26/detail/has_completions.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_HAS_COMPLETIONS
5+
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_HAS_COMPLETIONS
6+
7+
#include <beman/execution26/detail/valid_completion_for.hpp>
8+
#include <beman/execution26/detail/completion_signatures.hpp>
9+
10+
// ----------------------------------------------------------------------------
11+
12+
namespace beman::execution26::detail
13+
{
14+
#if not defined(__clang__)
15+
// The version of clang current (2024-09-01) installed on my Mac crashes
16+
// with this code - thus, there is a work-around.
17+
template <typename Receiver, typename Completions>
18+
concept has_completions
19+
= requires(Completions* completions)
20+
{
21+
[]<::beman::execution26::detail::valid_completion_for<Receiver>... Signatures>
22+
(::beman::execution26::completion_signatures<Signatures...>*)
23+
{
24+
}(completions);
25+
}
26+
;
27+
#else
28+
template <typename, typename> struct has_completions_aux;
29+
template <typename Receiver, typename... Signature>
30+
struct has_completions_aux<
31+
Receiver,
32+
::beman::execution26::completion_signatures<Signature...>
33+
>
34+
{
35+
static constexpr bool value
36+
= (::beman::execution26::detail::valid_completion_for<Signature, Receiver> && ... && true)
37+
;
38+
};
39+
40+
template <typename Receiver, typename Completions>
41+
concept has_completions
42+
= has_completions_aux<Receiver, Completions>::value
43+
;
44+
#endif
45+
}
46+
47+
// ----------------------------------------------------------------------------
48+
49+
#endif

src/beman/execution26/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ target_sources(${TARGET_LIBRARY}
6666
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/get_env.hpp
6767
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/get_scheduler.hpp
6868
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/get_stop_token.hpp
69+
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/has_completions.hpp
6970
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/impls_for.hpp
7071
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/indices_for.hpp
7172
${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/indirect_meta_apply.hpp

src/beman/execution26/tests/exec-recv-concepts.pass.cpp

+89
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// src/beman/execution26/tests/exec-recv-concepts.pass.cpp -*-C++-*-
22
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
33

4+
#include <beman/execution26/detail/has_completions.hpp>
45
#include <beman/execution26/detail/valid_completion_for.hpp>
56
#include <beman/execution26/execution.hpp>
67
#include <test/execution.hpp>
@@ -15,17 +16,31 @@ namespace
1516
template <typename... T>
1617
struct value_receiver
1718
{
19+
using receiver_concept = test_std::receiver_t;
1820
auto set_value(T...) && noexcept -> void {}
1921
};
2022

2123
template <typename T>
2224
struct error_receiver
2325
{
26+
using receiver_concept = test_std::receiver_t;
2427
auto set_error(T) && noexcept -> void {}
2528
};
2629

2730
struct stopped_receiver
2831
{
32+
using receiver_concept = test_std::receiver_t;
33+
auto set_stopped() && noexcept -> void {}
34+
};
35+
36+
struct multi_receiver
37+
{
38+
using receiver_concept = test_std::receiver_t;
39+
40+
auto set_value(int) && noexcept -> void {}
41+
auto set_value(int, arg) && noexcept -> void {}
42+
auto set_value(arg, arg) && noexcept -> void {}
43+
auto set_error(error) && noexcept -> void {}
2944
auto set_stopped() && noexcept -> void {}
3045
};
3146

@@ -62,9 +77,83 @@ namespace
6277
static_assert(not test_detail::valid_completion_for<
6378
test_std::set_value_t(), stopped_receiver>);
6479
}
80+
81+
auto test_has_completions() -> void
82+
{
83+
static_assert(test_std::receiver<value_receiver<int>>);
84+
static_assert(test_detail::has_completions<
85+
value_receiver<int>,
86+
test_std::completion_signatures<>
87+
>);
88+
static_assert(test_detail::has_completions<
89+
value_receiver<int>,
90+
test_std::completion_signatures<test_std::set_value_t(int)>
91+
>);
92+
static_assert(not test_detail::has_completions<
93+
value_receiver<int>,
94+
test_std::completion_signatures<test_std::set_value_t(int, int)>
95+
>);
96+
97+
static_assert(test_std::receiver<error_receiver<int>>);
98+
static_assert(test_detail::has_completions<
99+
error_receiver<int>,
100+
test_std::completion_signatures<test_std::set_error_t(int)>
101+
>);
102+
static_assert(not test_detail::has_completions<
103+
error_receiver<int>,
104+
test_std::completion_signatures<test_std::set_error_t(error)>
105+
>);
106+
static_assert(test_detail::has_completions<
107+
error_receiver<error>,
108+
test_std::completion_signatures<test_std::set_error_t(error)>
109+
>);
110+
111+
static_assert(test_std::receiver<stopped_receiver>);
112+
static_assert(not test_detail::has_completions<
113+
error_receiver<error>,
114+
test_std::completion_signatures<test_std::set_stopped_t()>
115+
>);
116+
static_assert(test_detail::has_completions<
117+
stopped_receiver,
118+
test_std::completion_signatures<test_std::set_stopped_t()>
119+
>);
120+
121+
static_assert(test_std::receiver<stopped_receiver>);
122+
static_assert(test_detail::has_completions<
123+
multi_receiver,
124+
test_std::completion_signatures<
125+
test_std::set_value_t(int),
126+
test_std::set_value_t(int, arg),
127+
test_std::set_value_t(arg, arg),
128+
test_std::set_error_t(error),
129+
test_std::set_stopped_t()
130+
>
131+
>);
132+
static_assert(not test_detail::has_completions<
133+
multi_receiver,
134+
test_std::completion_signatures<
135+
test_std::set_value_t(int),
136+
test_std::set_value_t(arg, int),
137+
test_std::set_value_t(arg, arg),
138+
test_std::set_error_t(error),
139+
test_std::set_stopped_t()
140+
>
141+
>);
142+
static_assert(not test_detail::has_completions<
143+
multi_receiver,
144+
test_std::completion_signatures<
145+
test_std::set_value_t(int),
146+
test_std::set_value_t(int, arg),
147+
test_std::set_value_t(arg, arg),
148+
test_std::set_error_t(int),
149+
test_std::set_stopped_t()
150+
>
151+
>);
152+
}
65153
}
66154

67155
auto main() -> int
68156
{
69157
test_valid_completion_for();
158+
test_has_completions();
70159
}

0 commit comments

Comments
 (0)