3#include <scl/feature/detail/wrapper_guard.h>
4#include <scl/feature/type_traits/wrapper.h>
5#include <scl/utility/type_traits/forward_like.h>
10namespace scl::feature::detail
19 template <
typename Left,
typename Right>
20 class wrapper_constructor_resolver;
42 template <
typename LeftWrapper,
typename RightRefer>
43 requires ::scl::feature::is_wrapper_v<::std::remove_cvref_t<RightRefer>>
44 class guarded_wrapper_constructor_resolver
46 using guard_type = wrapper_guard<RightRefer, wrapper_guard_case::wrapper>;
47 using inner_refer_t =
decltype(::std::declval<guard_type &>().value());
48 using inner_resolver_t = wrapper_constructor_resolver<LeftWrapper, inner_refer_t>;
51 constexpr explicit guarded_wrapper_constructor_resolver(RightRefer right)
52 : m_guard{::std::forward<RightRefer>(right)}
53 , m_resolver{m_guard.value()}
56 constexpr decltype(
auto) resolve() {
return m_resolver.resolve(); }
60 inner_resolver_t m_resolver;
119 template <
typename LeftValue,
template <
typename>
class LeftExecutor,
typename RightRefer>
120 class wrapper_constructor_resolver<wrapper<LeftValue, LeftExecutor>, RightRefer>
122 using left_type = wrapper<LeftValue, LeftExecutor>;
123 using right_type = ::std::remove_cvref_t<RightRefer>;
126 explicit constexpr wrapper_constructor_resolver(RightRefer right) noexcept
127 : m_right{::std::forward<RightRefer>(right)}
130 constexpr wrapper_constructor_resolver(wrapper_constructor_resolver &) =
default;
131 constexpr wrapper_constructor_resolver(wrapper_constructor_resolver &&) =
default;
132 constexpr wrapper_constructor_resolver(wrapper_constructor_resolver
const &) =
default;
134 constexpr decltype(
auto) resolve()
139 return executor_access::get(::std::forward<RightRefer>(m_right));
144 return ::std::forward<RightRefer>(m_right);
149 using right_executor =
typename right_type::executor_type;
150 using right_executor_refer = ::scl::forward_like_t<RightRefer, right_executor>;
152 constexpr bool has_unguard =
153 requires(right_executor_refer e) {
154 right_executor::template unguard<right_executor_refer>(e);
157 if constexpr (has_unguard)
160 return guarded_wrapper_constructor_resolver<left_type, RightRefer>{
161 ::std::forward<RightRefer>(m_right)}
167 decltype(
auto) executor = executor_access::get(::std::forward<RightRefer>(m_right));
170 requires { right_executor::template guard<right_executor_refer>(executor); })
171 right_executor::template guard<right_executor_refer>(executor);
173 decltype(
auto) inner = right_executor::template value<right_executor_refer>(
174 ::std::forward<
decltype(executor)>(executor));
176 return wrapper_constructor_resolver<left_type,
decltype(inner)>{
177 ::std::forward<decltype(inner)>(inner)}
184 return ::std::forward<RightRefer>(m_right);
constexpr bool is_compatible_with_v
Checks whether Test is compatible with (usable in place of) Expected.
Definition wrapper.h:62
constexpr bool is_compatible_with_part_of_v
Checks whether Expected (a wrapper) recursively contains a value that is compatible with Test (also a...
Definition wrapper.h:101
constexpr bool is_wrapper_v
Checks whether Type is a wrapper specialization.
Definition wrapper.h:28