"ScL Feature"
/
ScL Feature
0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Toggle main menu visibility
Loading...
Searching...
No Matches
method.h
Go to the documentation of this file.
1
#pragma once
2
44
45
#include <
scl/feature/reflection/access.h
>
46
#include <
scl/feature/reflection/type.h
>
47
#include <
scl/feature/type_traits/executor.h
>
48
#include <
scl/feature/type_traits/has_qualified_method.h
>
49
#include <scl/feature/wrapper_cast.h>
50
#include <scl/utility/preprocessor/forward.h>
51
52
#include <type_traits>
53
#include <utility>
54
55
// clang-format off
56
78
#define SCL_REFLECT_METHOD_EXEC_HELPERS(name) \
79
template <typename ScLExec, typename... ScLArgs> \
80
static constexpr bool method_##name##_scl_has_exec_override = \
81
requires { \
82
static_cast< \
83
decltype(::std::remove_cvref_t<ScLExec>::method_##name( \
84
::std::declval<ScLExec>(), ::std::declval<ScLArgs>()...)) \
85
(*)(ScLExec, ScLArgs...) \
86
>(&::std::remove_cvref_t<ScLExec>::method_##name); \
87
}; \
88
template <typename ScLExec, typename... ScLArgs> \
89
static constexpr bool method_##name##_scl_exec_noexcept = \
90
[]() constexpr noexcept -> bool { \
91
if constexpr (method_##name##_scl_has_exec_override<ScLExec, ScLArgs...>) \
92
return noexcept(::std::remove_cvref_t<ScLExec>::method_##name( \
93
::std::declval<ScLExec>(), ::std::declval<ScLArgs>()...)); \
94
return false; \
95
}();
96
109
#define SCL_REFLECT_METHOD_CALLER(name) \
110
struct method_##name##_scl_caller \
111
{ \
112
template <typename ScLParam, typename... ScLParams, typename ScLObj, typename... ScLArgs> \
113
static constexpr auto call(ScLObj && scl_obj, ScLArgs &&... scl_args) \
114
-> decltype(::std::forward<ScLObj>(scl_obj).template name<ScLParam, ScLParams...>( \
115
::scl::wrapper_cast(::std::forward<ScLArgs>(scl_args))...)) \
116
{ \
117
return ::std::forward<ScLObj>(scl_obj).template name<ScLParam, ScLParams...>( \
118
::scl::wrapper_cast(::std::forward<ScLArgs>(scl_args))...); \
119
} \
120
}; \
121
139
#define SCL_REFLECT_METHOD_QUALS(name) \
140
template <typename ScLVal, typename... ScLArgs> \
141
static constexpr bool method_##name##_scl_quals = \
142
SCL_HAS_QUALIFIED_METHOD(SCL_FORWARD(name), ScLVal, ScLArgs...); \
143
template <typename ScLParam, typename... ScLParams> \
144
struct method_##name##_scl_template_quals \
145
{ \
146
template <typename ScLVal, typename... ScLArgs> \
147
static constexpr bool value = \
148
SCL_HAS_QUALIFIED_METHOD( \
149
SCL_FORWARD(template name<ScLParam, ScLParams...>), \
150
ScLVal, ScLArgs...); \
151
};
152
169
#define SCL_REFLECT_METHOD_EXECUTOR_OVERRIDE_BASE(name, cv_ref) \
170
template <typename ScLExec = s_c_l_executor_type cv_ref, typename... ScLArgs> \
171
constexpr decltype(auto) name(ScLArgs &&... scl_args) cv_ref \
172
noexcept(method_##name##_scl_exec_noexcept<ScLExec, ScLArgs...>) \
173
requires \
174
(::std::is_same_v<ScLExec, s_c_l_executor_type cv_ref> \
175
&& method_##name##_scl_has_exec_override<ScLExec, ScLArgs...>) \
176
{ \
177
return ::std::remove_cvref_t<ScLExec>::method_##name( \
178
SCL_EXECUTOR_ACCESS(cv_ref), \
179
::std::forward<ScLArgs>(scl_args)...); \
180
}
181
203
#define SCL_REFLECT_METHOD_BASE(name, cv_ref) \
204
noexcept (noexcept(SCL_EXECUTE_OVERRIDED(SCL_FORWARD(name), cv_ref))) \
205
requires \
206
(!method_##name##_scl_has_exec_override<s_c_l_executor_type cv_ref, ScLArgs...> && \
207
requires \
208
{ \
209
SCL_ACCESS_DECLVAL(cv_ref).name( \
210
::scl::wrapper_cast(::std::declval<ScLArgs>())...); \
211
} && method_##name##_scl_quals<decltype(SCL_ACCESS_DECLVAL(cv_ref)), \
212
decltype(::scl::wrapper_cast(::std::declval<ScLArgs>()))...>) \
213
{ \
214
return SCL_EXECUTE_OVERRIDED(SCL_FORWARD(name), cv_ref); \
215
}
216
242
#define SCL_REFLECT_TEMPLATE_METHOD_BASE(name, caller, cv_ref) \
243
noexcept(noexcept(SCL_EXECUTE_TEMPLATE_OVERRIDED(caller, cv_ref))) \
244
requires \
245
requires \
246
{ \
247
caller::template call<ScLParam, ScLParams...>( \
248
SCL_ACCESS_DECLVAL(cv_ref), ::std::declval<ScLArgs>()...); \
249
} && method_##name##_scl_template_quals<ScLParam, ScLParams...> \
250
::template value<decltype(SCL_ACCESS_DECLVAL(cv_ref)), \
251
decltype(::scl::wrapper_cast(::std::declval<ScLArgs>()))...> \
252
{ \
253
return SCL_EXECUTE_TEMPLATE_OVERRIDED(caller, cv_ref); \
254
}
255
264
#define SCL_REFLECT_METHOD_HELPER(name, caller, cv_ref) \
265
SCL_REFLECT_METHOD_EXECUTOR_OVERRIDE_BASE(name, cv_ref) \
266
template <typename... ScLArgs> \
267
constexpr decltype(auto) name(ScLArgs &&... scl_args) cv_ref \
268
SCL_REFLECT_METHOD_BASE(name, cv_ref) \
269
template <typename ScLParam, typename... ScLParams, typename... ScLArgs> \
270
constexpr decltype(auto) name(ScLArgs &&... scl_args) cv_ref \
271
SCL_REFLECT_TEMPLATE_METHOD_BASE(name, caller, cv_ref)
272
427
#define SCL_REFLECT_METHOD(name) \
428
SCL_REFLECT_METHOD_QUALS(name) \
429
SCL_REFLECT_METHOD_CALLER(name) \
430
SCL_REFLECT_METHOD_EXEC_HELPERS(name) \
431
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, &) \
432
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, &&) \
433
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, const &) \
434
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, const &&) \
435
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, volatile &) \
436
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, volatile &&) \
437
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, const volatile &) \
438
SCL_REFLECT_METHOD_HELPER(SCL_FORWARD(name), method_##name##_scl_caller, const volatile &&)
439
440
// clang-format on
access.h
Internal accessor macros for executor and value access in reflected methods.
has_qualified_method.h
Compile-time predicate macro for cv-ref qualifier detection.
type.h
Macro for declaring the wrapper type used by reflection macros.
executor.h
Executor type traits: interface detection and noexcept helpers.
src
scl
feature
reflection
method.h
Generated by
1.18.0