@@ -11,6 +11,57 @@ using namespace exec;
1111namespace
1212{
1313
14+ struct noncopyable_error
15+ {
16+ noncopyable_error () = default ;
17+ noncopyable_error (noncopyable_error const &) = delete ;
18+ noncopyable_error& operator =(noncopyable_error const &) = delete ;
19+ };
20+
21+ struct error_sender
22+ {
23+ using sender_concept = ex::sender_tag;
24+ using completion_signatures = ex::completion_signatures<ex::set_error_t (noncopyable_error&)>;
25+
26+ template <class Receiver >
27+ struct operation
28+ {
29+ noncopyable_error* error_;
30+ Receiver receiver_;
31+
32+ void start () & noexcept
33+ {
34+ ex::set_error (static_cast <Receiver&&>(receiver_), *error_);
35+ }
36+ };
37+
38+ template <class Receiver >
39+ auto connect (Receiver receiver) const noexcept -> operation<Receiver>
40+ {
41+ return {error_, static_cast <Receiver&&>(receiver)};
42+ }
43+
44+ noncopyable_error* error_;
45+ };
46+
47+ struct error_receiver
48+ {
49+ using receiver_concept = ex::receiver_tag;
50+
51+ void set_value (ex::set_error_t , noncopyable_error& error) && noexcept
52+ {
53+ *called_ = &error == expected_;
54+ }
55+
56+ void set_stopped () && noexcept
57+ {
58+ *called_ = false ;
59+ }
60+
61+ noncopyable_error* expected_;
62+ bool * called_;
63+ };
64+
1465 template <class _Tag , class ... _Args>
1566 requires __completion_tag<std::decay_t <_Tag>>
1667 using __dematerialize_value = completion_signatures<std::decay_t <_Tag>(_Args...)>;
@@ -62,6 +113,21 @@ namespace
62113 static_assert (std::same_as<decltype (tag), set_stopped_t >);
63114 }
64115
116+ TEST_CASE (" materialize preserves error references" , " [adaptors][materialize]" )
117+ {
118+ noncopyable_error error;
119+ bool called = false ;
120+ auto sndr = materialize (error_sender{&error});
121+
122+ static_assert (
123+ set_equivalent<completion_signatures_of_t <decltype (sndr)>,
124+ completion_signatures<set_value_t (set_error_t , noncopyable_error&)>>);
125+
126+ auto op = connect (std::move (sndr), error_receiver{&error, &called});
127+ start (op);
128+ CHECK (called);
129+ }
130+
65131 TEST_CASE (" dematerialize value" , " [adaptors][materialize]" )
66132 {
67133 auto just_42 = dematerialize (materialize (just (42 )));
0 commit comments