"ScL Feature"/
ScL Feature 0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Loading...
Searching...
No Matches
wrapper_constructors.h
1#pragma once
2
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>
6
7#include <concepts>
8#include <type_traits>
9
16// cppcheck-suppress noExplicitConstructor
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)} \
22 {}
23
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 &&)
38
45// cppcheck-suppress noExplicitConstructor
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()} \
54 {}
55
62#define SCL_WRAPPER_ASSIGNMENT_FOR_SELF_PROTOTYPE(cv_ref) \
63 constexpr wrapper & operator=(self_type cv_ref other) /**/ \
64 noexcept(noexcept( \
65 executor_type::access(::std::declval<executor_type &>()) = \
66 executor_type::access(::std::declval<executor_type cv_ref>()))) \
67 requires requires { \
68 executor_type::access(::std::declval<executor_type &>()) = \
69 executor_type::access(::std::declval<executor_type cv_ref>()); \
70 } \
71 { \
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)); \
76 return *this; \
77 }
78
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 &&)
90
98#define SCL_WRAPPER_ASSIGNMENT_FOR_OTHER \
99 template <typename Other> \
100 constexpr wrapper & operator=(Other && other) /**/ \
101 noexcept(noexcept( \
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> && \
105 requires { \
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>>()); \
109 }) \
110 { \
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))); \
115 return *this; \
116 }