"ScL Feature"/
ScL Feature 0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Loading...
Searching...
No Matches
wrapper_constructor_resolver.h
1#pragma once
2
3#include <scl/feature/type_traits/wrapper.h>
4#include <scl/feature/wrapper_guard.h>
5#include <scl/utility/type_traits/forward_like.h>
6
7#include <type_traits>
8#include <utility>
9
10namespace scl::feature::detail
11{
19 template <typename Left, typename Right>
20 class wrapper_constructor_resolver;
21
42 template <typename LeftWrapper, typename RightRefer>
43 requires ::scl::feature::is_wrapper_v<RightRefer>
44 class guarded_wrapper_constructor_resolver
45 {
46 using guard_type = ::scl::wrapper_guard<RightRefer>;
47 using inner_refer_t = decltype(::std::declval<guard_type &>().value());
48 using inner_resolver_t = wrapper_constructor_resolver<LeftWrapper, inner_refer_t>;
49
50 public:
51 constexpr explicit guarded_wrapper_constructor_resolver(RightRefer right)
52 : m_guard{::std::forward<RightRefer>(right)}
53 , m_resolver{m_guard.value()}
54 {}
55
56 constexpr decltype(auto) resolve() { return m_resolver.resolve(); }
57
58 private:
59 guard_type m_guard;
60 inner_resolver_t m_resolver;
61 };
62
118 // NOLINTBEGIN(cppcoreguidelines-special-member-functions, bugprone-branch-clone)
119 template <typename LeftValue, template <typename> class LeftExecutor, typename RightRefer>
120 class wrapper_constructor_resolver<wrapper<LeftValue, LeftExecutor>, RightRefer>
121 {
122 using left_type = wrapper<LeftValue, LeftExecutor>;
123 using right_type = ::std::remove_cvref_t<RightRefer>;
124
125 public:
126 explicit constexpr wrapper_constructor_resolver(RightRefer right) noexcept
127 : m_right{::std::forward<RightRefer>(right)}
128 {}
129
130 constexpr decltype(auto) resolve()
131 {
133 {
134 // strategy 1: same wrapper type — forward the executor directly
135 return executor_access::get(::std::forward<RightRefer>(m_right));
136 }
138 {
139 // strategy 2: right fits into a part of left — forward the right wrapper
140 return ::std::forward<RightRefer>(m_right);
141 }
143 {
144 // strategy 3: right is a wrapper — peel one layer and recurse
145 using right_executor = typename right_type::executor_type;
146 using right_executor_refer = ::scl::forward_like_t<RightRefer, right_executor>;
147
149
150 if constexpr (has_unguard)
151 {
152 // unguard exists — need RAII wrapper_guard for guard/unguard bracketing
153 return guarded_wrapper_constructor_resolver<left_type, RightRefer>{
154 ::std::forward<RightRefer>(m_right)}
155 .resolve();
156 }
157 else
158 {
159 // no unguard — intentional: guard() without unguard() is a valid executor
160 // contract (e.g. a one-shot initializer). RAII is unnecessary because
161 // there is nothing to release; call guard() if present, then read value.
162 decltype(auto) executor = executor_access::get(::std::forward<RightRefer>(m_right));
163
165 right_executor::guard(::std::forward<right_executor_refer>(executor));
166
167 decltype(auto) inner = right_executor::template access<right_executor_refer>(
168 ::std::forward<decltype(executor)>(executor));
169
170 return wrapper_constructor_resolver<left_type, decltype(inner)>{
171 ::std::forward<decltype(inner)>(inner)}
172 .resolve();
173 }
174 }
175 else
176 {
177 // strategy 4: plain value — forward as-is
178 return ::std::forward<RightRefer>(m_right);
179 }
180 }
181
182 private:
183 RightRefer m_right;
184 };
185 // NOLINTEND(cppcoreguidelines-special-member-functions, bugprone-branch-clone)
186
187} // namespace scl::feature::detail
constexpr bool has_guard_v
true if ExecutorType has a guard() method whose first (and only) parameter type is exactly ExecutorRe...
Definition executor.h:93
constexpr bool is_compatible_with_v
Checks whether Test is compatible with (usable in place of) Expected.
Definition wrapper.h:68
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:107
constexpr bool has_unguard_v
true if ExecutorType has an unguard() method whose first (and only) parameter type is exactly Executo...
Definition executor.h:105
constexpr bool is_wrapper_v
Checks whether Type is a wrapper specialization.
Definition wrapper.h:32