Skip to content

Commit 8ec3376

Browse files
committed
fix gcc
1 parent 612a17e commit 8ec3376

17 files changed

Lines changed: 126 additions & 48 deletions

include/exec/any_sender_of.hpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ namespace experimental::execution
118118
};
119119

120120
template <class Base>
121-
using _inject_query_memfn_t =
122-
__if_c<requires { typename Base::_has_query_memfn_t; }, Base, _inject_query_memfn<Base>>;
121+
concept _has_query_memfn = requires { typename Base::_has_query_memfn_t; };
122+
123+
template <class Base>
124+
using _inject_query_memfn_t = __if_c<_has_query_memfn<Base>, Base, _inject_query_memfn<Base>>;
123125

124126
template <class Base>
125127
struct _inject_receiver_memfns : Base
@@ -131,9 +133,11 @@ namespace experimental::execution
131133
};
132134

133135
template <class Base>
134-
using _inject_receiver_memfns_t = __if_c<requires {
135-
typename Base::_has_receiver_memfns_t;
136-
}, Base, _inject_receiver_memfns<Base>>;
136+
concept _has_receiver_memfns = requires { typename Base::_has_receiver_memfns_t; };
137+
138+
template <class Base>
139+
using _inject_receiver_memfns_t =
140+
__if_c<_has_receiver_memfns<Base>, Base, _inject_receiver_memfns<Base>>;
137141

138142
template <class QuerySig, bool Indirect = true, bool Noexcept = false>
139143
struct _iquery_memfn;
@@ -413,6 +417,7 @@ namespace experimental::execution
413417
struct _any_opstate_base final : STDEXEC::__any::__any<_iopstate>
414418
{
415419
using STDEXEC::__any::__any<_iopstate>::__any;
420+
STDEXEC_IMMOVABLE(_any_opstate_base);
416421
};
417422

418423
//////////////////////////////////////////////////////////////////////////////////////
@@ -621,27 +626,29 @@ namespace experimental::execution
621626
noexcept(STDEXEC::__nothrow_constructible_from<typename any_receiver::__any, Receiver>)
622627
: any_receiver::__any{static_cast<Receiver &&>(_rcvr)}
623628
{}
629+
630+
private:
631+
template <class, class>
632+
friend struct any_sender;
633+
using _completions_t = Sigs;
634+
using _queries_t = Queries;
624635
};
625636

626637
//////////////////////////////////////////////////////////////////////////////////////
627638
// any_sender
628-
template <class... Sigs, class Queries, class SenderQueries>
629-
struct any_sender<any_receiver<STDEXEC::completion_signatures<Sigs...>, Queries>, SenderQueries>
630-
final
631-
: STDEXEC::__any::__any<
632-
_any::_isender<any_receiver<STDEXEC::completion_signatures<Sigs...>, Queries>,
633-
SenderQueries>::template _interface_>
639+
template <class AnyReceiver, class SenderQueries>
640+
struct any_sender final
641+
: STDEXEC::__any::__any<_any::_isender<AnyReceiver, SenderQueries>::template _interface_>
634642
{
635643
private:
636-
using _completions_t = STDEXEC::completion_signatures<Sigs...>;
637-
using _any_receiver_t = any_receiver<_completions_t, Queries>;
638-
using _stop_token_t = STDEXEC::stop_token_of_t<STDEXEC::env_of_t<_any_receiver_t>>;
639-
using _isender_t = _any::_isender<_any_receiver_t, SenderQueries>;
640-
using _base_t = STDEXEC::__any::__any<_isender_t::template _interface_>;
644+
using _completions_t = AnyReceiver::_completions_t;
645+
using _stop_token_t = STDEXEC::stop_token_of_t<STDEXEC::env_of_t<AnyReceiver>>;
646+
using _isender_t = _any::_isender<AnyReceiver, SenderQueries>;
647+
using _base_t = STDEXEC::__any::__any<_isender_t::template _interface_>;
641648

642649
public:
643650
template <STDEXEC::__not_same_as<any_sender> Sender>
644-
requires STDEXEC::sender_to<Sender, _any_receiver_t>
651+
requires STDEXEC::sender_to<Sender, AnyReceiver>
645652
constexpr any_sender(Sender _sndr)
646653
noexcept(STDEXEC::__nothrow_constructible_from<_base_t, Sender>)
647654
: _base_t{static_cast<Sender &&>(_sndr)}

include/exec/async_scope.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ namespace experimental::execution
143143
////////////////////////////////////////////////////////////////////////////
144144
// async_scope::nest implementation
145145
template <class _Receiver>
146-
struct __nest_opstate_base : __immovable
146+
struct __nest_opstate_base
147147
{
148148
__impl const * __scope_;
149149
STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS
@@ -222,10 +222,12 @@ namespace experimental::execution
222222

223223
template <__decays_to<_Constrained> _Sender, __decays_to<_Receiver> _Rcvr>
224224
constexpr explicit __nest_opstate(__impl const * __scope, _Sender&& __c, _Rcvr&& __rcvr)
225-
: __nest_opstate_base<_Receiver>{{}, __scope, static_cast<_Rcvr&&>(__rcvr)}
225+
: __nest_opstate_base<_Receiver>{__scope, static_cast<_Rcvr&&>(__rcvr)}
226226
, __op_(STDEXEC::connect(static_cast<_Sender&&>(__c), __nest_rcvr_t{this}))
227227
{}
228228

229+
STDEXEC_IMMOVABLE(__nest_opstate);
230+
229231
constexpr void start() & noexcept
230232
{
231233
STDEXEC_ASSERT(this->__scope_);
@@ -805,9 +807,10 @@ namespace experimental::execution
805807

806808
////////////////////////////////////////////////////////////////////////////
807809
// async_scope
808-
struct async_scope : __immovable
810+
struct async_scope
809811
{
810812
async_scope() = default;
813+
STDEXEC_IMMOVABLE(async_scope);
811814

812815
template <sender _Constrained>
813816
[[nodiscard]]

include/exec/detail/shared.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,13 @@ namespace experimental::execution::__shared
156156
}
157157

158158
////////////////////////////////////////////////////////////////////////////////////////
159-
struct __local_state_base : __immovable
159+
struct __local_state_base
160160
{
161-
__local_state_base() = default;
162161
constexpr virtual void __notify() noexcept
163162
{
164163
// should never be called
165164
}
165+
166166
__local_state_base* __next_ = nullptr;
167167
};
168168

@@ -186,6 +186,8 @@ namespace experimental::execution::__shared
186186
, __sh_state_(std::move(__sh_state))
187187
{}
188188

189+
STDEXEC_IMMOVABLE(__local_state);
190+
189191
constexpr ~__local_state()
190192
{
191193
if (__sh_state_)

include/exec/env.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,15 @@ namespace experimental::execution
123123
struct read_with_default_t;
124124

125125
template <class _Tag, class _Default, class _Receiver>
126-
struct __opstate : __immovable
126+
struct __opstate
127127
{
128+
constexpr explicit __opstate(_Default&& __default, _Receiver&& __rcvr)
129+
: __default_(static_cast<_Default&&>(__default))
130+
, __rcvr_(static_cast<_Receiver&&>(__rcvr))
131+
{}
132+
133+
STDEXEC_IMMOVABLE(__opstate);
134+
128135
constexpr void start() & noexcept
129136
{
130137
STDEXEC_TRY
@@ -171,7 +178,8 @@ namespace experimental::execution
171178
noexcept(std::is_nothrow_move_constructible_v<_Receiver>)
172179
-> __opstate<_Tag, __default_t<env_of_t<_Receiver>>, _Receiver>
173180
{
174-
return {{}, static_cast<_Self&&>(__self).__default_, static_cast<_Receiver&&>(__rcvr)};
181+
using __opstate_t = __opstate<_Tag, __default_t<env_of_t<_Receiver>>, _Receiver>;
182+
return __opstate_t{static_cast<_Self&&>(__self).__default_, static_cast<_Receiver&&>(__rcvr)};
175183
}
176184
STDEXEC_EXPLICIT_THIS_END(connect)
177185

include/exec/repeat_n.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace experimental::execution
4040
using namespace STDEXEC;
4141

4242
template <class _Receiver>
43-
struct __opstate_base : __immovable
43+
struct __opstate_base
4444
{
4545
constexpr explicit __opstate_base(_Receiver &&__rcvr, std::size_t __count) noexcept
4646
: __rcvr_{static_cast<_Receiver &&>(__rcvr)}
@@ -50,6 +50,8 @@ namespace experimental::execution
5050
"trampoline_scheduler c'tor is always expected to be noexcept");
5151
}
5252

53+
STDEXEC_IMMOVABLE(__opstate_base);
54+
5355
virtual constexpr void __cleanup() noexcept = 0;
5456
virtual constexpr void __repeat() noexcept = 0;
5557

include/exec/sequence/ignore_all_values.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ namespace experimental::execution
5959
};
6060

6161
template <class _ResultVariant>
62-
struct __result_type : __immovable
62+
struct __result_type
6363
{
6464
template <class... _Args>
6565
void __emplace(_Args&&... __args) noexcept
@@ -274,6 +274,8 @@ namespace experimental::execution
274274
, __op_{exec::subscribe(static_cast<_Sender&&>(__sndr), __receiver_t{this})}
275275
{}
276276

277+
STDEXEC_IMMOVABLE(__operation);
278+
277279
void start() & noexcept
278280
{
279281
STDEXEC::start(__op_);

include/exec/when_any.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,15 @@ namespace experimental::execution
8787
}
8888

8989
template <class _Receiver, class _ResultVariant>
90-
struct __opstate_base : __immovable
90+
struct __opstate_base
9191
{
9292
__opstate_base(_Receiver&& __rcvr, std::size_t __n_senders)
9393
: __count_{__n_senders}
9494
, __rcvr_{static_cast<_Receiver&&>(__rcvr)}
9595
{}
9696

97+
STDEXEC_IMMOVABLE(__opstate_base);
98+
9799
using __on_stop =
98100
stop_callback_for_t<stop_token_of_t<env_of_t<_Receiver>&>, __forward_stop_request<>>;
99101

@@ -211,6 +213,8 @@ namespace experimental::execution
211213
, __ops_{STDEXEC::connect(static_cast<_CvSenders&&>(__sndrs), __receiver_t{this})...}
212214
{}
213215

216+
STDEXEC_IMMOVABLE(__opstate);
217+
214218
void start() & noexcept
215219
{
216220
this->__on_stop_.emplace(get_stop_token(get_env(this->__rcvr_)),

include/stdexec/__detail/__any.hpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,38 @@ namespace STDEXEC::__any
986986
return __emplace_<_Value>(std::allocator_arg, __alloc, static_cast<_Args &&>(__args)...);
987987
}
988988

989+
template <class _Allocator, class _Fn, class... _Args>
990+
constexpr auto
991+
__emplace_from_(std::allocator_arg_t, _Allocator const &__alloc, _Fn &&__fn, _Args &&...__args)
992+
-> __call_result_t<_Fn, _Args...> &
993+
{
994+
static_assert(__simple_allocator<_Allocator>);
995+
using __value_type = __call_result_t<_Fn, _Args...>;
996+
using __model_type = __value_model<_Interface, __value_type, _Allocator>;
997+
auto &__model = //
998+
STDEXEC::__any::__emplace_into<__model_type>(__alloc,
999+
__root_ptr_,
1000+
__buff_,
1001+
std::allocator_arg,
1002+
__alloc,
1003+
__in_place_from,
1004+
static_cast<_Fn &&>(__fn),
1005+
static_cast<_Args &&>(__args)...);
1006+
return __value(__model);
1007+
}
1008+
1009+
template <class _Fn, class... _Args>
1010+
constexpr auto
1011+
__emplace_from_(_Fn &&__fn, _Args &&...__args) -> __call_result_t<_Fn, _Args...> &
1012+
{
1013+
using __value_type = __call_result_t<_Fn, _Args...>;
1014+
std::allocator<__value_type> const __alloc{};
1015+
return __emplace_from_(std::allocator_arg,
1016+
__alloc,
1017+
static_cast<_Fn &&>(__fn),
1018+
static_cast<_Args &&>(__args)...);
1019+
}
1020+
9891021
template <class _Self>
9901022
[[nodiscard]]
9911023
static constexpr auto __value_(_Self &&__self) noexcept -> auto &&
@@ -1719,10 +1751,7 @@ namespace STDEXEC::__any
17191751
constexpr explicit __any(__in_place_from_t, _Fn &&__fn, _Args &&...__args)
17201752
: __any()
17211753
{
1722-
using __value_t = __decay_t<__call_result_t<_Fn, _Args...>>;
1723-
(*this).template __emplace_<__value_t>(
1724-
__emplace_from{[&]() noexcept(__nothrow_callable<_Fn, _Args...>)
1725-
{ return static_cast<_Fn &&>(__fn)(static_cast<_Args &&>(__args)...); }});
1754+
(*this).template __emplace_from_(static_cast<_Fn &&>(__fn), static_cast<_Args &&>(__args)...);
17261755
}
17271756

17281757
// Implicit derived-to-base conversion constructor

include/stdexec/__detail/__config.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,8 @@ namespace STDEXEC
535535
# define STDEXEC_UNREACHABLE(...) std::terminate()
536536
#endif
537537

538-
// Before gcc-12, gcc really didn't like tuples or variants of immovable types
539-
#if STDEXEC_GCC() && (STDEXEC_GCC_VERSION < 12'00)
538+
// gcc struggles with copy-elision of immovable types
539+
#if STDEXEC_GCC()
540540
# define STDEXEC_IMMOVABLE(_XP) _XP(_XP&&)
541541
#else
542542
# define STDEXEC_IMMOVABLE(_XP) _XP(_XP&&) = delete

include/stdexec/__detail/__connect_awaitable.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,16 @@ namespace STDEXEC
110110
{
111111
using __opstate_t = __opstate<_Awaitable, _Receiver>;
112112

113-
struct __task : __immovable
113+
struct __task
114114
{
115115
using promise_type = __promise;
116116

117+
constexpr explicit __task(__std::coroutine_handle<__promise> __coro) noexcept
118+
: __coro_(__coro)
119+
{}
120+
121+
STDEXEC_IMMOVABLE(__task);
122+
117123
~__task()
118124
{
119125
__connect_await::__destroy_coro(__coro_);
@@ -170,7 +176,7 @@ namespace STDEXEC
170176

171177
constexpr auto get_return_object() noexcept -> __task
172178
{
173-
return __task{{}, __std::coroutine_handle<__promise>::from_promise(*this)};
179+
return __task{__std::coroutine_handle<__promise>::from_promise(*this)};
174180
}
175181

176182
[[noreturn]]

0 commit comments

Comments
 (0)