3#include <scl/feature/detail/executor_access.h>
4#include <scl/feature/type_traits/wrapper.h>
5#include <scl/utility/type_traits/forward_like.h>
17#define SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(cv_ref) \
18 constexpr wrapper(self_type cv_ref other) \
19 noexcept(::std::is_nothrow_constructible_v<executor_type, executor_type cv_ref>) \
20 requires(::std::constructible_from<executor_type, executor_type cv_ref>) \
21 : m_executor{::scl::forward_like<self_type cv_ref>(other.m_executor)} \
29#define SCL_WRAPPER_CONSTRUCTOR_FOR_SELF \
30 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(&) \
31 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const &) \
32 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(volatile &) \
33 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const volatile &) \
34 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(&&) \
35 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const &&) \
36 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(volatile &&) \
37 SCL_WRAPPER_CONSTRUCTOR_FOR_SELF_PROTOTYPE(const volatile &&)
46#define SCL_WRAPPER_CONSTRUCTOR_FOR_OTHER \
47 template <typename Other> \
48 constexpr wrapper(Other && other) \
49 noexcept(noexcept(::std::declval<wrapper_constructor_resolver<self_type, Other &&>>().resolve())) \
50 requires(::scl::feature::is_wrapper_v<Other> && !::std::same_as<::std::remove_cvref_t<Other>, self_type> && \
51 ::std::constructible_from<executor_type, \
52 decltype(::std::declval<wrapper_constructor_resolver<self_type, Other &&>>().resolve())>) \
53 : m_executor{wrapper_constructor_resolver<self_type, Other &&>{::std::forward<Other>(other)}.resolve()} \
62#define SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(cv_ref) \
63 constexpr wrapper & operator=(self_type cv_ref other) \
65 executor_type::access(::std::declval<executor_type &>()) = \
66 executor_type::access(::std::declval<executor_type cv_ref>()))) \
68 executor_type::access(::std::declval<executor_type &>()) = \
69 executor_type::access(::std::declval<executor_type cv_ref>()); \
72 executor_type::execute(m_executor, [](auto && scl_self, auto && scl_source) -> decltype(auto) { \
73 return executor_type::access(::std::forward<decltype(scl_self)>(scl_self)) = \
74 executor_type::access(::std::forward<decltype(scl_source)>(scl_source)); \
75 }, m_executor, ::scl::forward_like<self_type cv_ref>(other.m_executor)); \
81#define SCL_WRAPPER_ASSIGNMENT_FOR_SELF \
82 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(&) \
83 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(const &) \
84 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(volatile &) \
85 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(const volatile &) \
86 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(&&) \
87 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(const &&) \
88 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(volatile &&) \
89 SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(const volatile &&)
98#define SCL_WRAPPER_ASSIGNMENT_FOR_OTHER \
99 template <typename Other> \
100 constexpr wrapper & operator=(Other && other) \
102 executor_type::access(::std::declval<executor_type &>()) = ::std::remove_cvref_t<Other>::executor_type::access( \
103 ::std::declval<::scl::forward_like_t<Other, typename ::std::remove_cvref_t<Other>::executor_type>>()))) \
104 requires(::scl::feature::is_wrapper_v<Other> && !::std::same_as<::std::remove_cvref_t<Other>, self_type> && \
106 executor_type::access(::std::declval<executor_type &>()) = ::std::remove_cvref_t< \
107 Other>::executor_type::access(::std::declval<::scl::forward_like_t<Other, \
108 typename ::std::remove_cvref_t<Other>::executor_type>>()); \
111 executor_type::execute(m_executor, [](auto && scl_self, auto && scl_source) -> decltype(auto) { \
112 return executor_type::access(::std::forward<decltype(scl_self)>(scl_self)) = ::std::remove_cvref_t< \
113 Other>::executor_type::access(::std::forward<decltype(scl_source)>(scl_source)); \
114 }, m_executor, ::scl::feature::detail::executor_access::get(::std::forward<Other>(other))); \