Skip to content

Commit 6ddedb4

Browse files
authored
Merge pull request #1772 from ericniebler/constexpr-all-the-things
make almost everything constexpr that can be
2 parents e89cddc + 595fda6 commit 6ddedb4

File tree

83 files changed

+1036
-882
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1036
-882
lines changed

include/asioexec/completion_token.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ namespace asioexec {
358358
template <typename T, typename... Us>
359359
requires std::constructible_from<Initiation, T>
360360
&& std::constructible_from<args_type_, Us...>
361-
explicit constexpr sender(T&& t, Us&&... us) noexcept(
361+
constexpr explicit sender(T&& t, Us&&... us) noexcept(
362362
std::is_nothrow_constructible_v<Initiation, T>
363363
&& std::is_nothrow_constructible_v<args_type_, Us...>)
364364
: init_(static_cast<T&&>(t))
@@ -429,7 +429,7 @@ namespace asioexec {
429429
};
430430
}
431431
public:
432-
explicit constexpr executor(
432+
constexpr explicit executor(
433433
operation_state_base<Signatures, Receiver>& self,
434434
const Executor& ex) noexcept
435435
: self_(self)

include/exec/async_scope.hpp

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ namespace exec {
7070
struct __t : __task {
7171
using __id = __when_empty_op;
7272

73-
explicit __t(const __impl* __scope, _Constrained&& __sndr, _Receiver __rcvr)
73+
constexpr explicit __t(const __impl* __scope, _Constrained&& __sndr, _Receiver __rcvr)
7474
: __task{{}, __scope, __notify_waiter}
7575
, __op_(
7676
STDEXEC::connect(
@@ -93,7 +93,7 @@ namespace exec {
9393
}
9494

9595
private:
96-
static void __notify_waiter(__task* __self) noexcept {
96+
static constexpr void __notify_waiter(__task* __self) noexcept {
9797
STDEXEC::start(static_cast<__t*>(__self)->__op_);
9898
}
9999

@@ -192,7 +192,7 @@ namespace exec {
192192
__complete(__scope);
193193
}
194194

195-
void set_stopped() noexcept
195+
constexpr void set_stopped() noexcept
196196
requires __callable<set_stopped_t, _Receiver>
197197
{
198198
auto __scope = __op_->__scope_;
@@ -202,7 +202,7 @@ namespace exec {
202202
__complete(__scope);
203203
}
204204

205-
auto get_env() const noexcept -> __env_t<env_of_t<_Receiver>> {
205+
constexpr auto get_env() const noexcept -> __env_t<env_of_t<_Receiver>> {
206206
return make_env(
207207
STDEXEC::get_env(__op_->__rcvr_),
208208
STDEXEC::prop{get_stop_token, __op_->__scope_->__stop_source_.get_token()});
@@ -222,12 +222,12 @@ namespace exec {
222222
connect_result_t<_Constrained, __nest_rcvr_t> __op_;
223223

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

230-
void start() & noexcept {
230+
constexpr void start() & noexcept {
231231
STDEXEC_ASSERT(this->__scope_);
232232
auto& __active = this->__scope_->__active_;
233233
__active.fetch_add(1, __std::memory_order_relaxed);
@@ -299,7 +299,7 @@ namespace exec {
299299
struct __subscription : __immovable {
300300
void (*__complete_)(__subscription*) noexcept = nullptr;
301301

302-
void __complete() noexcept {
302+
constexpr void __complete() noexcept {
303303
__complete_(this);
304304
}
305305

@@ -316,7 +316,7 @@ namespace exec {
316316
using __forward_consumer =
317317
stop_token_of_t<env_of_t<_Receiver>>::template callback_type<__forward_stopped>;
318318

319-
void __complete_() noexcept {
319+
constexpr void __complete_() noexcept {
320320
STDEXEC_TRY {
321321
__forward_consumer_.reset();
322322
auto __state = std::move(__state_);
@@ -365,7 +365,7 @@ namespace exec {
365365
public:
366366
using __id = __future_op;
367367

368-
~__t() noexcept {
368+
constexpr ~__t() noexcept {
369369
if (__state_ != nullptr) {
370370
auto __raw_state = __state_.get();
371371
std::unique_lock __guard{__raw_state->__mutex_};
@@ -381,7 +381,9 @@ namespace exec {
381381
}
382382

383383
template <class _Receiver2>
384-
explicit __t(_Receiver2&& __rcvr, std::unique_ptr<__future_state<_Sender, _Env>> __state)
384+
constexpr explicit __t(
385+
_Receiver2&& __rcvr,
386+
std::unique_ptr<__future_state<_Sender, _Env>> __state)
385387
: __subscription{
386388
{},
387389
[](__subscription* __self) noexcept -> void {
@@ -395,7 +397,7 @@ namespace exec {
395397
__forward_stopped{&__state_->__stop_source_}) {
396398
}
397399

398-
void start() & noexcept {
400+
constexpr void start() & noexcept {
399401
STDEXEC_TRY {
400402
if (!!__state_) {
401403
std::unique_lock __guard{__state_->__mutex_};
@@ -428,7 +430,7 @@ namespace exec {
428430
#else
429431

430432
template <class _Tag, class... _Ts>
431-
auto __completion_as_tuple_(_Tag (*)(_Ts...)) -> std::tuple<_Tag, _Ts...>;
433+
constexpr auto __completion_as_tuple_(_Tag (*)(_Ts...)) -> std::tuple<_Tag, _Ts...>;
432434

433435
template <class _Fn>
434436
using __completion_as_tuple_t = decltype(__scope::__completion_as_tuple_(
@@ -458,7 +460,7 @@ namespace exec {
458460

459461
template <class _Ty>
460462
struct __dynamic_delete {
461-
__dynamic_delete()
463+
constexpr __dynamic_delete()
462464
: __delete_([](_Ty* __p) { delete __p; }) {
463465
}
464466

@@ -475,7 +477,7 @@ namespace exec {
475477
return *this;
476478
}
477479

478-
void operator()(_Ty* __p) {
480+
constexpr void operator()(_Ty* __p) {
479481
__delete_(__p);
480482
}
481483

@@ -484,7 +486,7 @@ namespace exec {
484486

485487
template <class _Completions, class _Env>
486488
struct __future_state_base {
487-
__future_state_base(_Env __env, const __impl* __scope)
489+
constexpr __future_state_base(_Env __env, const __impl* __scope)
488490
: __forward_scope_{
489491
std::in_place,
490492
__scope->__stop_source_.get_token(),
@@ -505,7 +507,7 @@ namespace exec {
505507
}
506508
}
507509

508-
void __step_from_to_(
510+
constexpr void __step_from_to_(
509511
std::unique_lock<std::mutex>& __guard,
510512
__future_step __from,
511513
__future_step __to) {
@@ -534,7 +536,7 @@ namespace exec {
534536
__future_state_base<_Completions, _Env>* __state_;
535537
const __impl* __scope_;
536538

537-
void __dispatch_result_(std::unique_lock<std::mutex>& __guard) noexcept {
539+
constexpr void __dispatch_result_(std::unique_lock<std::mutex>& __guard) noexcept {
538540
auto& __state = *__state_;
539541
auto __local_subscribers = std::move(__state.__subscribers_);
540542
__state.__forward_scope_.reset();
@@ -554,7 +556,7 @@ namespace exec {
554556
}
555557

556558
template <class _Tag, class... _As>
557-
void __save_completion(_Tag, _As&&... __as) noexcept {
559+
constexpr void __save_completion(_Tag, _As&&... __as) noexcept {
558560
auto& __state = *__state_;
559561
STDEXEC_TRY {
560562
using _Tuple = __decayed_std_tuple<_Tag, _As...>;
@@ -567,29 +569,29 @@ namespace exec {
567569
}
568570

569571
template <__movable_value... _As>
570-
void set_value(_As&&... __as) noexcept {
572+
constexpr void set_value(_As&&... __as) noexcept {
571573
auto& __state = *__state_;
572574
std::unique_lock __guard{__state.__mutex_};
573575
__save_completion(set_value_t(), static_cast<_As&&>(__as)...);
574576
__dispatch_result_(__guard);
575577
}
576578

577579
template <__movable_value _Error>
578-
void set_error(_Error&& __err) noexcept {
580+
constexpr void set_error(_Error&& __err) noexcept {
579581
auto& __state = *__state_;
580582
std::unique_lock __guard{__state.__mutex_};
581583
__save_completion(set_error_t(), static_cast<_Error&&>(__err));
582584
__dispatch_result_(__guard);
583585
}
584586

585-
void set_stopped() noexcept {
587+
constexpr void set_stopped() noexcept {
586588
auto& __state = *__state_;
587589
std::unique_lock __guard{__state.__mutex_};
588590
__save_completion(set_stopped_t());
589591
__dispatch_result_(__guard);
590592
}
591593

592-
auto get_env() const noexcept -> const __env_t<_Env>& {
594+
constexpr auto get_env() const noexcept -> const __env_t<_Env>& {
593595
return __state_->__env_;
594596
}
595597
};
@@ -603,12 +605,12 @@ namespace exec {
603605
struct __future_state : __future_state_base<__future_completions_t<_Sender, _Env>, _Env> {
604606
using _Completions = __future_completions_t<_Sender, _Env>;
605607

606-
__future_state(connect_t, _Sender&& __sndr, _Env __env, const __impl* __scope)
608+
constexpr __future_state(connect_t, _Sender&& __sndr, _Env __env, const __impl* __scope)
607609
: __future_state_base<_Completions, _Env>(static_cast<_Env&&>(__env), __scope)
608610
, __op_(static_cast<_Sender&&>(__sndr), __future_receiver_t<_Sender, _Env>{this, __scope}) {
609611
}
610612

611-
__future_state(_Sender __sndr, _Env __env, const __impl* __scope)
613+
constexpr __future_state(_Sender __sndr, _Env __env, const __impl* __scope)
612614
: __future_state(
613615
STDEXEC::connect,
614616
static_cast<_Sender&&>(__sndr),
@@ -677,7 +679,7 @@ namespace exec {
677679
private:
678680
friend struct async_scope;
679681

680-
explicit __t(std::unique_ptr<__future_state<_Sender, _Env>> __state) noexcept
682+
constexpr explicit __t(std::unique_ptr<__future_state<_Sender, _Env>> __state) noexcept
681683
: __state_(std::move(__state)) {
682684
std::unique_lock __guard{__state_->__mutex_};
683685
__state_->__step_from_to_(__guard, __future_step::__created, __future_step::__future);
@@ -699,12 +701,12 @@ namespace exec {
699701
inplace_stop_token __token_;
700702

701703
[[nodiscard]]
702-
auto query(get_stop_token_t) const noexcept -> inplace_stop_token {
704+
constexpr auto query(get_stop_token_t) const noexcept -> inplace_stop_token {
703705
return __token_;
704706
}
705707

706708
[[nodiscard]]
707-
auto query(get_scheduler_t) const noexcept -> STDEXEC::inline_scheduler {
709+
constexpr auto query(get_scheduler_t) const noexcept -> STDEXEC::inline_scheduler {
708710
return {};
709711
}
710712
};
@@ -728,7 +730,7 @@ namespace exec {
728730
using receiver_concept = STDEXEC::receiver_t;
729731
__spawn_op_base<_EnvId>* __op_;
730732

731-
void set_value() noexcept {
733+
constexpr void set_value() noexcept {
732734
__op_->__delete_(__op_);
733735
}
734736

@@ -738,11 +740,11 @@ namespace exec {
738740
std::rethrow_exception(std::move(__eptr));
739741
}
740742

741-
void set_stopped() noexcept {
743+
constexpr void set_stopped() noexcept {
742744
__op_->__delete_(__op_);
743745
}
744746

745-
auto get_env() const noexcept -> const __spawn_env_t<_Env>& {
747+
constexpr auto get_env() const noexcept -> const __spawn_env_t<_Env>& {
746748
return __op_->__env_;
747749
}
748750
};
@@ -757,7 +759,7 @@ namespace exec {
757759
using _Sender = STDEXEC::__t<_SenderId>;
758760

759761
struct __t : __spawn_op_base<_EnvId> {
760-
__t(connect_t, _Sender&& __sndr, _Env __env, const __impl* __scope)
762+
constexpr __t(connect_t, _Sender&& __sndr, _Env __env, const __impl* __scope)
761763
: __spawn_op_base<_EnvId>{
762764
__env::__join(
763765
static_cast<_Env&&>(__env),
@@ -766,7 +768,7 @@ namespace exec {
766768
, __data_(static_cast<_Sender&&>(__sndr), __spawn_receiver_t<_Env>{this}) {
767769
}
768770

769-
__t(_Sender __sndr, _Env __env, const __impl* __scope)
771+
constexpr __t(_Sender __sndr, _Env __env, const __impl* __scope)
770772
: __t(
771773
STDEXEC::connect,
772774
static_cast<_Sender&&>(__sndr),
@@ -793,12 +795,12 @@ namespace exec {
793795

794796
template <sender _Constrained>
795797
[[nodiscard]]
796-
auto when_empty(_Constrained&& __c) const -> __when_empty_sender_t<_Constrained> {
798+
constexpr auto when_empty(_Constrained&& __c) const -> __when_empty_sender_t<_Constrained> {
797799
return __when_empty_sender_t<_Constrained>{&__impl_, static_cast<_Constrained&&>(__c)};
798800
}
799801

800802
[[nodiscard]]
801-
auto on_empty() const {
803+
constexpr auto on_empty() const {
802804
return when_empty(just());
803805
}
804806

@@ -807,7 +809,7 @@ namespace exec {
807809

808810
template <sender _Constrained>
809811
[[nodiscard]]
810-
auto nest(_Constrained&& __c) -> nest_result_t<_Constrained> {
812+
constexpr auto nest(_Constrained&& __c) -> nest_result_t<_Constrained> {
811813
return nest_result_t<_Constrained>{&__impl_, static_cast<_Constrained&&>(__c)};
812814
}
813815

@@ -823,18 +825,21 @@ namespace exec {
823825
}
824826

825827
template <__movable_value _Env = env<>, sender_in<__env_t<_Env>> _Sender>
828+
[[nodiscard]]
826829
auto spawn_future(_Sender&& __sndr, _Env __env = {}) -> __future_t<_Sender, _Env> {
827830
using __state_t = __future_state<nest_result_t<_Sender>, _Env>;
828831
auto __state = std::make_unique<__state_t>(
829832
nest(static_cast<_Sender&&>(__sndr)), static_cast<_Env&&>(__env), &__impl_);
830833
return __future_t<_Sender, _Env>{std::move(__state)};
831834
}
832835

833-
auto get_stop_source() noexcept -> inplace_stop_source& {
836+
[[nodiscard]]
837+
constexpr auto get_stop_source() noexcept -> inplace_stop_source& {
834838
return __impl_.__stop_source_;
835839
}
836840

837-
auto get_stop_token() const noexcept -> inplace_stop_token {
841+
[[nodiscard]]
842+
constexpr auto get_stop_token() const noexcept -> inplace_stop_token {
838843
return __impl_.__stop_source_.get_token();
839844
}
840845

include/exec/completion_signatures.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ namespace exec {
2525
// make_completion_signatures
2626
namespace detail {
2727
template <class Tag, class... As>
28-
auto normalize_impl(As&&...) -> Tag (*)(As...);
28+
constexpr auto normalize_impl(As&&...) -> Tag (*)(As...);
2929

3030
template <class Tag, class... As>
31-
auto normalize(Tag (*)(As...))
31+
constexpr auto normalize(Tag (*)(As...))
3232
-> decltype(detail::normalize_impl<Tag>(STDEXEC::__declval<As>()...));
3333

3434
template <class... Sigs>
35-
auto make_unique(Sigs*...)
35+
constexpr auto make_unique(Sigs*...)
3636
-> STDEXEC::__mapply_q<STDEXEC::completion_signatures, STDEXEC::__mmake_set<Sigs...>>;
3737

3838
template <class... Sigs>

0 commit comments

Comments
 (0)