46#include <scl/utility/type_traits/forward_like.h>
52namespace scl::feature::detail
61 template <
typename OuterExecutorType,
typename PropertyTag>
62 struct property_execution
69 template <
typename PropertyType>
73 using value_type = PropertyType;
77 using outer_value_type = ::std::remove_reference_t<
78 decltype(OuterExecutorType::access(::std::declval<OuterExecutorType &>()))>;
82 using member_pointer_type = PropertyType outer_value_type::*;
85 ::std::ptrdiff_t m_offset;
86 member_pointer_type m_property_pointer;
103 template <
typename Self>
106 outer_exec_ptr(Self && self)
noexcept
107 requires ::std::same_as<::std::remove_cvref_t<Self>, holder>
109 using exec_obj = ::std::remove_reference_t<::scl::forward_like_t<Self, OuterExecutorType>>;
110 using byte_cv = ::std::remove_reference_t<::scl::forward_like_t<Self, ::std::byte>>;
113 byte_cv *
const cursor =
reinterpret_cast<byte_cv *
>(&self) - self.m_offset;
114 return reinterpret_cast<exec_obj *
>(cursor);
124 template <
typename Self>
125 static constexpr bool access_noexcept =
126 PropertyTag::template override_noexcept<::scl::forward_like_t<Self, OuterExecutorType>>;
133 holder(OuterExecutorType
const * exec, member_pointer_type property_pointer)
noexcept
135 : m_offset{
reinterpret_cast<::std::byte
const *
>(
this) -
reinterpret_cast<::std::byte
const *
>(exec)}
136 , m_property_pointer{property_pointer}
144 holder(holder
const &) =
default;
145 holder(holder &&) =
default;
146 holder & operator=(holder
const &) =
delete;
147 holder & operator=(holder &&) =
delete;
166 template <
typename Self>
167 static decltype(
auto) access(Self && self)
noexcept(access_noexcept<Self>)
168 requires ::std::same_as<::std::remove_cvref_t<Self>, holder>
170 using exec_refer = ::scl::forward_like_t<Self, OuterExecutorType>;
172 if constexpr (PropertyTag::template has_override<exec_refer>)
174 return PropertyTag::call_override(
175 ::scl::forward_like<Self>(*outer_exec_ptr(::std::forward<Self>(self))));
179 auto property_pointer = self.m_property_pointer;
180 auto *
const exec = outer_exec_ptr(::std::forward<Self>(self));
181 return OuterExecutorType::execute(::scl::forward_like<Self>(*exec),
182 [property_pointer](
auto && scl_e) ->
decltype(
auto) {
186 decltype(
auto) v = OuterExecutorType::access(::std::forward<
decltype(scl_e)>(scl_e));
187 using property_refer = ::scl::forward_like_t<
decltype(v), PropertyType>;
188 return static_cast<property_refer
>(::std::forward<decltype(v)>(v).*property_pointer);
189 }, ::scl::forward_like<Self>(*exec));
203 template <
typename Self,
typename Func>
204 static decltype(
auto) execute(Self && self, Func && func)
205 requires ::std::same_as<::std::remove_cvref_t<Self>, holder>
207 return OuterExecutorType::execute(
208 ::scl::forward_like<Self>(*outer_exec_ptr(::std::forward<Self>(self))),
209 ::std::forward<Func>(func));
216 template <
typename Self>
217 static void guard(Self && self)
219 requires ::std::same_as<::std::remove_cvref_t<Self>, holder> &&
221 OuterExecutorType::guard(
222 ::std::declval<::scl::forward_like_t<Self, OuterExecutorType>>());
225 OuterExecutorType::guard(
226 ::scl::forward_like<Self>(*outer_exec_ptr(::std::forward<Self>(self))));
231 template <
typename Self>
232 static void unguard(Self && self)
234 requires ::std::same_as<::std::remove_cvref_t<Self>, holder> &&
236 OuterExecutorType::unguard(
237 ::std::declval<::scl::forward_like_t<Self, OuterExecutorType>>());
240 OuterExecutorType::unguard(
241 ::scl::forward_like<Self>(*outer_exec_ptr(::std::forward<Self>(self))));
constexpr bool is_unguard_noexcept_v
true if ExecutorType::unguard() for ExecutorRefer either does not exist or is noexcept.
Definition executor.h:194
constexpr bool is_guard_noexcept_v
true if ExecutorType::guard() for ExecutorRefer either does not exist or is noexcept.
Definition executor.h:182
Executor type traits: interface detection and noexcept helpers.