Skip to content

Commit 3ed6667

Browse files
committed
added completion_domain implementation
1 parent e4bff2f commit 3ed6667

File tree

4 files changed

+187
-7
lines changed

4 files changed

+187
-7
lines changed

Makefile

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
33

44
SANITIZERS = none msan asan usan tsan
5-
.PHONY: default todo distclean clean build test all $(SANITIZERS)
5+
.PHONY: default check todo distclean clean build test all $(SANITIZERS)
66

77
CXX_FLAGS = -g
88
SANITIZER = none
@@ -53,6 +53,13 @@ build:
5353
test: build
5454
cd $(BUILD); $(MAKE) test
5555

56+
check:
57+
@for h in `find include -name \*.hpp`; \
58+
do \
59+
from=`echo -n $$h | sed -n 's@.*Beman/\(.*\).hpp.*@\1@p'`; \
60+
< $$h sed -n "/^ *# *include <Beman\//s@.*[</]Beman/\(.*\).hpp>.*@$$from \1@p"; \
61+
done | tsort > /dev/null
62+
5663
todo:
5764
bin/mk-todo.py
5865

include/Beman/Execution26/detail/completion_domain.hpp

+66-2
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,79 @@
55
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_COMPLETION_DOMAIN
66

77
#include <Beman/Execution26/detail/default_domain.hpp>
8+
#include <Beman/Execution26/detail/get_domain.hpp>
9+
#include <Beman/Execution26/detail/get_completion_scheduler.hpp>
10+
#include <Beman/Execution26/detail/get_env.hpp>
11+
#include <Beman/Execution26/detail/sender.hpp>
12+
#include <concepts>
813

914
// ----------------------------------------------------------------------------
1015

1116
namespace Beman::Execution26::Detail
1217
{
18+
struct completion_domain_undefined {};
19+
template <typename, typename>
20+
struct completion_domain_merge
21+
{
22+
};
23+
template <typename T>
24+
struct completion_domain_merge<T, T>
25+
{
26+
using type = T;
27+
};
28+
template <typename T>
29+
struct completion_domain_merge<completion_domain_undefined, T>
30+
{
31+
using type = T;
32+
};
33+
template <typename T>
34+
struct completion_domain_merge<T, completion_domain_undefined>
35+
{
36+
using type = T;
37+
};
38+
template <>
39+
struct completion_domain_merge<completion_domain_undefined, completion_domain_undefined>
40+
{
41+
using type = completion_domain_undefined;
42+
};
43+
1344
template <typename Default = ::Beman::Execution26::default_domain, typename Sender>
14-
constexpr auto completion_domain(Sender const&) noexcept
45+
constexpr auto completion_domain(Sender const& sender) noexcept
1546
{
16-
//-dk:TODO
47+
48+
static_assert(::Beman::Execution26::sender<Sender>);
49+
auto get = [&sender]<typename Tag>(Tag) {
50+
if constexpr (requires{
51+
::Beman::Execution26::get_domain(
52+
::Beman::Execution26::get_completion_scheduler<Tag>(
53+
::Beman::Execution26::get_env(sender)
54+
)
55+
);
56+
})
57+
{
58+
return ::Beman::Execution26::get_domain(
59+
::Beman::Execution26::get_completion_scheduler<Tag>(
60+
::Beman::Execution26::get_env(sender)
61+
)
62+
);
63+
}
64+
else
65+
{
66+
return completion_domain_undefined{};
67+
}
68+
};
69+
70+
using type = typename completion_domain_merge<
71+
typename completion_domain_merge<
72+
decltype(get(::Beman::Execution26::set_error)),
73+
decltype(get(::Beman::Execution26::set_stopped))
74+
>::type,
75+
decltype(get(::Beman::Execution26::set_value))
76+
>::type;
77+
return ::std::conditional_t<
78+
::std::same_as<type, completion_domain_undefined>,
79+
Default,
80+
type>();
1781
}
1882
}
1983

include/Beman/Execution26/detail/get_completion_scheduler.hpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,27 @@ namespace Beman::Execution26
3737
= BEMAN_EXECUTION26_DELETE("The environment needs a query(get_completion_scheduler_t) member");
3838

3939
template <typename Env>
40-
requires (not requires(get_completion_scheduler_t const& self,
40+
requires (requires(get_completion_scheduler_t const& self,
41+
::std::remove_cvref_t<Env> const& env) {
42+
env.query(self);
43+
}
44+
&& (not requires(get_completion_scheduler_t const& self,
4145
::std::remove_cvref_t<Env> const& env) {
4246
{ env.query(self) } noexcept;
43-
})
47+
}))
4448
auto operator()(Env&&) const noexcept
4549
= BEMAN_EXECUTION26_DELETE("The environment's query(get_completion_scheduler_t) has to be noexcept");
4650

4751
template <typename Env>
48-
requires (not requires(get_completion_scheduler_t const& self,
52+
requires (requires(get_completion_scheduler_t const& self,
53+
::std::remove_cvref_t<Env> const& env) {
54+
env.query(self);
55+
}
56+
&& requires(get_completion_scheduler_t const& self,
57+
::std::remove_cvref_t<Env> const& env) {
58+
{ env.query(self) } noexcept;
59+
}
60+
&& (not requires(get_completion_scheduler_t const& self,
4961
get_completion_scheduler_t<::Beman::Execution26::set_value_t> const& value_self,
5062
::std::remove_cvref_t<Env> const& env) {
5163
{
@@ -56,7 +68,7 @@ namespace Beman::Execution26
5668
::Beman::Execution26::schedule(env.query(self))
5769
).query(value_self)
5870
} -> ::Beman::Execution26::Detail::decayed_same_as<decltype(env.query(self))>;
59-
})
71+
}))
6072
auto operator()(Env&&) const noexcept
6173
= BEMAN_EXECUTION26_DELETE("The environment's query(get_completion_scheduler_t) has to return a scheduler");
6274

src/Beman/Execution26/tests/exec-snd-expos.pass.cpp

+97
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,99 @@ namespace
198198
assert(dom == domain{17});
199199
}
200200

201+
namespace completion_domain {
202+
struct domain {};
203+
struct other {};
204+
struct common {};
205+
struct none {};
206+
struct mismatch {};
207+
208+
template <typename> struct env;
209+
template <typename> struct scheduler;
210+
211+
template <typename W>
212+
struct sender
213+
{
214+
using sender_concept = test_std::sender_t;
215+
auto get_env() const noexcept -> env<W> { return {}; }
216+
};
217+
template <typename W>
218+
struct scheduler
219+
{
220+
using scheduler_concept = test_std::scheduler_t;
221+
auto schedule() noexcept -> sender<W> { return {}; }
222+
auto operator== (scheduler const&) const -> bool = default;
223+
auto query(test_std::get_domain_t const&) const noexcept -> domain { return {}; }
224+
};
225+
226+
template <>
227+
struct scheduler<none>
228+
{
229+
using scheduler_concept = test_std::scheduler_t;
230+
auto schedule() noexcept -> sender<none> { return {}; }
231+
auto operator== (scheduler const&) const -> bool = default;
232+
};
233+
234+
template <>
235+
struct env<common>
236+
{
237+
template <typename Tag>
238+
auto query(test_std::get_completion_scheduler_t<Tag> const&) const noexcept
239+
-> scheduler<common>
240+
{
241+
return {};
242+
}
243+
};
244+
245+
template <>
246+
struct env<none>
247+
{
248+
template <typename Tag>
249+
auto query(test_std::get_completion_scheduler_t<Tag> const&) const noexcept
250+
-> scheduler<none>
251+
{
252+
return {};
253+
}
254+
};
255+
256+
struct one_missing {};
257+
template <>
258+
struct env<one_missing>
259+
{
260+
template <typename Tag>
261+
auto query(test_std::get_completion_scheduler_t<Tag> const&) const noexcept
262+
-> scheduler<one_missing>
263+
{
264+
return {};
265+
}
266+
auto query(test_std::get_completion_scheduler_t<test_std::set_error_t> const&) const noexcept = delete;
267+
};
268+
269+
struct two_missing {};
270+
template <>
271+
struct env<two_missing>
272+
{
273+
auto query(test_std::get_completion_scheduler_t<test_std::set_value_t> const&) const noexcept
274+
-> scheduler<two_missing>
275+
{
276+
return {};
277+
}
278+
};
279+
}
280+
auto test_completion_domain() -> void
281+
{
282+
namespace cd = completion_domain;
283+
static_assert(test_std::sender<cd::sender<cd::common>>);
284+
static_assert(std::same_as<cd::env<cd::common>, decltype(test_std::get_env(cd::sender<cd::common>{}))>);
285+
static_assert(std::same_as<cd::domain, decltype(test_std::get_domain(test_std::get_completion_scheduler<test_std::set_error_t>(cd::env<cd::common>{})))>);
286+
static_assert(std::same_as<cd::domain, decltype(test_std::get_domain(test_std::get_completion_scheduler<test_std::set_stopped_t>(cd::env<cd::common>{})))>);
287+
static_assert(std::same_as<cd::domain, decltype(test_std::get_domain(test_std::get_completion_scheduler<test_std::set_value_t>(cd::env<cd::common>{})))>);
288+
static_assert(std::same_as<cd::domain, decltype(test_detail::completion_domain((cd::sender<cd::common>{})))>);
289+
static_assert(std::same_as<cd::domain, decltype(test_detail::completion_domain((cd::sender<cd::one_missing>{})))>);
290+
static_assert(std::same_as<cd::domain, decltype(test_detail::completion_domain((cd::sender<cd::two_missing>{})))>);
291+
static_assert(std::same_as<test_std::default_domain, decltype(test_detail::completion_domain((cd::sender<cd::none>{})))>);
292+
}
293+
201294
auto test_query_with_default() -> void
202295
{
203296
auto result1{test_detail::query_with_default(test_std::get_domain,
@@ -215,11 +308,14 @@ namespace
215308

216309
auto test_get_domain_late() -> void
217310
{
311+
#if 0
218312
static_assert(test_std::sender<test_sender>);
219313
env const e;
220314
test_sender const sndr;
221315
auto dom{test_detail::get_domain_late(sndr, e)};
222316
(void)dom;
317+
//-dk:TOO test
318+
#endif
223319
}
224320
}
225321

@@ -230,6 +326,7 @@ auto main() -> int
230326
test_join_env();
231327
test_sched_attrs();
232328
test_sched_env();
329+
test_completion_domain();
233330
test_query_with_default();
234331
test_get_domain_late();
235332
}

0 commit comments

Comments
 (0)