30#pragma GCC diagnostic ignored "-Wcast-function-type-mismatch"
31#pragma GCC diagnostic ignored "-Wmicrosoft-template-shadow"
32#pragma GCC diagnostic ignored "-Wunused-local-typedef"
33#pragma GCC diagnostic ignored "-Wextra-semi"
35#if defined(__GNUC__) and !defined(__clang__)
36#pragma GCC diagnostic ignored "-Wunknown-pragmas"
37#pragma GCC diagnostic ignored "-Wcast-function-type"
38#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
42#define ANYXX_USE_EBO __declspec(empty_bases)
46#if defined(_MSC_VER) && not defined(__clang__)
47#define LIFETIMEBOUND [[msvc::lifetimebound]]
49#include <CppCoreCheck/Warnings.h>
50#pragma warning(default : CPPCORECHECK_LIFETIME_WARNINGS)
54#elif defined(__clang__)
55#define LIFETIMEBOUND [[clang::lifetimebound]]
60#if defined(_MSC_VER) && not defined(__clang__)
61#define AYXFORCEDINLINE __forceinline
62#pragma warning(disable : 4714)
64#define AYXFORCEDINLINE inline __attribute__((always_inline))
71#define ANYXX_EXTRACT(...) ANYXX_EXTRACT __VA_ARGS__
72#define ANYXX_NOTHING_ANYXX_EXTRACT
73#define ANYXX_PASTE(x, ...) x##__VA_ARGS__
74#define ANYXX_EVALUATING_PASTE(x, ...) ANYXX_PASTE(x, __VA_ARGS__)
75#define ANYXX_UNPAREN(x) ANYXX_EVALUATING_PASTE(ANYXX_NOTHING_, ANYXX_EXTRACT x)
77static_assert(std::same_as<ANYXX_UNPAREN(
int),
int>);
78static_assert(std::same_as<ANYXX_UNPAREN((
int)),
int>);
80#define ANYXX_JACKET_RETURN(...) \
81 anyxx::jacket_return<ANYXX_UNPAREN(ANYXX_UNPAREN(__VA_ARGS__))>
83#define _detail_EXPAND(...) \
85 _detail_EXPAND4(_detail_EXPAND4(_detail_EXPAND4(__VA_ARGS__))))
86#define _detail_EXPAND4(...) \
88 _detail_EXPAND3(_detail_EXPAND3(_detail_EXPAND3(__VA_ARGS__))))
89#define _detail_EXPAND3(...) \
91 _detail_EXPAND2(_detail_EXPAND2(_detail_EXPAND2(__VA_ARGS__))))
92#define _detail_EXPAND2(...) \
94 _detail_EXPAND1(_detail_EXPAND1(_detail_EXPAND1(__VA_ARGS__))))
95#define _detail_EXPAND1(...) __VA_ARGS__
97#define _detail_EXPAND_(...) \
99 _detail_EXPAND_4(_detail_EXPAND_4(_detail_EXPAND_4(__VA_ARGS__))))
100#define _detail_EXPAND_4(...) \
102 _detail_EXPAND_3(_detail_EXPAND_3(_detail_EXPAND_3(__VA_ARGS__))))
103#define _detail_EXPAND_3(...) \
105 _detail_EXPAND_2(_detail_EXPAND_2(_detail_EXPAND_2(__VA_ARGS__))))
106#define _detail_EXPAND_2(...) \
108 _detail_EXPAND_1(_detail_EXPAND_1(_detail_EXPAND_1(__VA_ARGS__))))
109#define _detail_EXPAND_1(...) __VA_ARGS__
110#define _detail_PARENS ()
111#define _detail_APPLY(macro, args) macro args
112#define _detail_REMOVE_PARENS(l) _detail_APPLY(_detail_EXPAND_1, l)
113#define _detail_foreach_macro_h(macro, a, ...) \
115 __VA_OPT__(_detail_foreach_macro_a _detail_PARENS(macro, __VA_ARGS__))
116#define _detail_foreach_macro_a() _detail_foreach_macro_h
117#define _detail_foreach_macro(macro, ...) \
118 _detail_EXPAND(_detail_foreach_macro_h(macro, __VA_ARGS__))
119#define _detail_map_macro_h(macro, a, ...) \
120 macro(a) __VA_OPT__(, _detail_map_macro_a _detail_PARENS(macro, __VA_ARGS__))
121#define _detail_map_macro(macro, ...) \
122 _detail_EXPAND(_detail_map_macro_h(macro, __VA_ARGS__))
123#define _detail_map_macro_a() _detail_map_macro_h
124#define _detail_CONCAT_H(a, b) a##b
125#define _detail_CONCAT(a, b) _detail_CONCAT_H(a, b)
127#define _detail_ANYXX_FORWARD_PARAM_LIST_H(b, c, f, ...) \
128 std::forward<decltype(c)>(c) \
129 __VA_OPT__(, _detail_ANYXX_FORWARD_PARAM_LIST_A _detail_PARENS( \
130 b, _detail_CONCAT(b, c), __VA_ARGS__))
131#define _detail_ANYXX_FORWARD_PARAM_LIST_A() _detail_ANYXX_FORWARD_PARAM_LIST_H
132#define _detail_ANYXX_FORWARD_PARAM_LIST(...) \
133 _detail_EXPAND_(_detail_ANYXX_FORWARD_PARAM_LIST_H(__VA_ARGS__))
135#define _detail_ANYXX_CONCEPT_ARG_LIST_H(b, c, f, ...) \
136 c __VA_OPT__(, _detail_ANYXX_FORWARD_PARAM_LIST_A _detail_PARENS( \
137 b, _detail_CONCAT(b, c), __VA_ARGS__))
138#define _detail_ANYXX_FORWARD_PARAM_LIST_A() _detail_ANYXX_FORWARD_PARAM_LIST_H
139#define _detail_ANYXX_FORWARD_PARAM_LIST(...) \
140 _detail_EXPAND_(_detail_ANYXX_FORWARD_PARAM_LIST_H(__VA_ARGS__))
142#define _detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP_H(b, c, param_type, ...) \
143 anyxx::v_table_to_map<Concrete, ANYXX_UNPAREN(param_type)>:: \
144 template forward<decltype(c)>(std::forward<decltype(c)>(c)) __VA_OPT__( \
145 , _detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP_A _detail_PARENS( \
146 b, _detail_CONCAT(b, c), __VA_ARGS__))
147#define _detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP_A() \
148 _detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP_H
149#define _detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP(...) \
150 _detail_EXPAND_(_detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP_H(__VA_ARGS__))
152#define _detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP_H(b, c, param_type, \
154 anyxx::forward_trait_to_map<traited_t, ANYXX_UNPAREN(param_type)>:: \
155 template forward<decltype(c)>(std::forward<decltype(c)>(c)) __VA_OPT__( \
156 , _detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP_A _detail_PARENS( \
157 b, _detail_CONCAT(b, c), __VA_ARGS__))
158#define _detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP_A() \
159 _detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP_H
160#define _detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP(...) \
161 _detail_EXPAND_(_detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP_H(__VA_ARGS__))
163#define _detail_ANYXX_JACKET_PARAM_LIST_H(b, c, param_type, ...) \
164 [[maybe_unused]] auto&& c __VA_OPT__( \
165 , _detail_ANYXX_JACKET_PARAM_LIST_A _detail_PARENS( \
166 b, _detail_CONCAT(b, c), __VA_ARGS__))
167#define _detail_ANYXX_JACKET_PARAM_LIST_A() _detail_ANYXX_JACKET_PARAM_LIST_H
168#define _detail_ANYXX_JACKET_PARAM_LIST(...) \
169 _detail_EXPAND_(_detail_ANYXX_JACKET_PARAM_LIST_H(__VA_ARGS__))
170#define _detail_EXPAND_LIST(...) __VA_ARGS__
172#define _detail_ANYXX_V_TABLE_PARAM_LIST_H(b, c, param_type, ...) \
173 [[maybe_unused]] anyxx::v_table_param<any_value_t, \
174 ANYXX_UNPAREN(param_type)> c \
175 __VA_OPT__(, _detail_ANYXX_V_TABLE_PARAM_LIST_A _detail_PARENS( \
176 b, _detail_CONCAT(b, c), __VA_ARGS__))
177#define _detail_ANYXX_V_TABLE_PARAM_LIST_A() _detail_ANYXX_V_TABLE_PARAM_LIST_H
178#define _detail_ANYXX_V_TABLE_PARAM_LIST(...) \
179 _detail_EXPAND_(_detail_ANYXX_V_TABLE_PARAM_LIST_H(__VA_ARGS__))
181#define _detail_ANYXX_MAP_PARAM_LIST_H(b, c, param_type, ...) \
182 [[maybe_unused]] auto&& c __VA_OPT__( \
183 , _detail_ANYXX_MAP_PARAM_LIST_A _detail_PARENS(b, _detail_CONCAT(b, c), \
185#define _detail_ANYXX_MAP_PARAM_LIST_A() _detail_ANYXX_MAP_PARAM_LIST_H
186#define _detail_ANYXX_MAP_PARAM_LIST(...) \
187 _detail_EXPAND_(_detail_ANYXX_MAP_PARAM_LIST_H(__VA_ARGS__))
189#define _detail_ANYXX_CONCEPT_PARAM_LIST_H(b, c, param_type, ...) \
190 [[maybe_unused]] anyxx::concept_arg<T, ANYXX_UNPAREN(param_type)> c \
191 __VA_OPT__(, _detail_ANYXX_CONCEPT_PARAM_LIST_A _detail_PARENS( \
192 b, _detail_CONCAT(b, c), __VA_ARGS__))
193#define _detail_ANYXX_CONCEPT_PARAM_LIST_A() _detail_ANYXX_CONCEPT_PARAM_LIST_H
194#define _detail_ANYXX_CONCEPT_PARAM_LIST(...) \
195 _detail_EXPAND_(_detail_ANYXX_CONCEPT_PARAM_LIST_H(__VA_ARGS__))
197#define _detail_ANYXX_EXACT_PARAM_LIST_H(b, c, param_type, ...) \
198 [[maybe_unused]] ANYXX_UNPAREN(param_type) c __VA_OPT__( \
199 , _detail_ANYXX_EXACT_PARAM_LIST_A _detail_PARENS( \
200 b, _detail_CONCAT(b, c), __VA_ARGS__))
201#define _detail_ANYXX_EXACT_PARAM_LIST_A() _detail_ANYXX_EXACT_PARAM_LIST_H
202#define _detail_ANYXX_EXACT_PARAM_LIST(...) \
203 _detail_EXPAND_(_detail_ANYXX_EXACT_PARAM_LIST_H(__VA_ARGS__))
205#define _detail_ANYXX_TYPENAME_PARAM_H(t) _detail_ANYXX_TYPENAME_PARAM t
206#define _detail_ANYXX_TYPENAME_PARAM(t) , typename t
207#define _detail_ANYXX_TYPENAME_PARAM_LIST(head, ...) \
208 typename _detail_REMOVE_PARENS(head) __VA_OPT__( \
209 _detail_foreach_macro(_detail_ANYXX_TYPENAME_PARAM_H, __VA_ARGS__))
211#define _detail_ANYXX_DUMMY_INT_PARAM_LIST_H(b, c, param_type, ...) \
212 int __VA_OPT__(, _detail_ANYXX_DUMMY_INT_PARAM_LIST_A _detail_PARENS( \
213 b, _detail_CONCAT(b, c), __VA_ARGS__))
214#define _detail_ANYXX_DUMMY_INT_PARAM_LIST_A() \
215 _detail_ANYXX_DUMMY_INT_PARAM_LIST_H
216#define _detail_ANYXX_DUMMY_INT_PARAM_LIST(...) \
218 <_detail_ANYXX_DUMMY_INT_PARAM_LIST_H(dummy1, dummy2, __VA_ARGS__)>)
220#define _detail_ANYXX_OPTIONAL_TEMPLATE(...) __VA_OPT__(template)
222#define _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST(...) \
223 __VA_OPT__(template <_detail_ANYXX_TYPENAME_PARAM_LIST(__VA_ARGS__)>)
224#define _detail_ANYXX_OPTIONAL_MORE_TYPENAMES_PARAM_LIST(...) \
225 __VA_OPT__(, _detail_ANYXX_TYPENAME_PARAM_LIST(__VA_ARGS__))
227#define _detail_ANYXX_TEMPLATE_ARG_H(t) _detail_ANYXX_TEMPLATE_ARG t
228#define _detail_ANYXX_TEMPLATE_ARG(t) , t
229#define _detail_ANYXX_TEMPLATE_ARGS1(head, ...) \
230 _detail_REMOVE_PARENS(head) __VA_OPT__( \
231 _detail_foreach_macro(_detail_ANYXX_TEMPLATE_ARG_H, __VA_ARGS__))
232#define _detail_ANYXX_TEMPLATE_ARGS(...) \
233 __VA_OPT__(_detail_ANYXX_TEMPLATE_ARGS1(__VA_ARGS__))
234#define _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(...) \
235 __VA_OPT__(<_detail_ANYXX_TEMPLATE_ARGS(__VA_ARGS__)>)
237#define _detail_ANYXX_V_TABLE_TEMPLATE_FORMAL_ARGS_H(...) \
238 __VA_OPT__(<_detail_ANYXX_TEMPLATE_ARGS(__VA_ARGS__), anyxx::dyn>)
239#define _detail_ANYXX_V_TABLE_TEMPLATE_FORMAL_ARGS(t) \
240 _detail_ANYXX_V_TABLE_TEMPLATE_FORMAL_ARGS_H t
242#define _detail_LEAD_COMMA_H(...) __VA_OPT__(, )
243#define _detail_ANYXX_FPD_H(l) _detail_ANYXX_FUNCTION_PTR_DECL l
244#define _detail_ANYXX_MEMEBER_LIMP_H(l) _detail_ANYXX_LAMBDA_TO_MEMEBER_IMPL l
246#define _detail_LEAD_COMMA_H_E(l) _detail_LEAD_COMMA_H l
248#define __detail_ANYXX_ADD_HEAD(h, ...) h __VA_OPT__(, ) __VA_ARGS__
249#define __detail_ANYXX_ADD_HEAD_LIST(l, ...) \
250 __detail_ANYXX_ADD_HEAD(_detail_REMOVE_PARENS(l), __VA_ARGS__)
257#define __detail_ANYXX_ADD_TAIL(t, ...) __VA_ARGS__ __VA_OPT__(, ) t
262#define _typename _typename1
263#define _typename1(t) t
265#define _detail_ANYXX_TEMPLATE_FORMAL_ARG_H(l) \
266 _detail_ANYXX_TEMPLATE_FORMAL_ARG l
267#define _detail_ANYXX_TEMPLATE_FORMAL_ARG(_typename) , typename _typename
268#define _detail_ANYXX_TEMPLATE_FORMAL_ARGS(...) \
269 __VA_OPT__(_detail_ANYXX_TEMPLATE_FORMAL_ARGS1(__VA_ARGS__))
270#define _detail_ANYXX_TEMPLATE_FORMAL_ARGS1(h, ...) \
271 typename _typename h __VA_OPT__( \
272 _detail_ANYXX_TEMPLATE_FORMAL_ARGS2((__VA_ARGS__)))
273#define _detail_ANYXX_TEMPLATE_FORMAL_ARGS2(l) \
274 _detail_foreach_macro(_detail_ANYXX_TEMPLATE_FORMAL_ARG_H, \
275 _detail_EXPAND_LIST l)
277#define _detail_ANYXX_V_TABLE_TEMPLATE_HEADER_H(...) \
278 __VA_OPT__(template <_detail_ANYXX_TEMPLATE_FORMAL_ARGS(__VA_ARGS__)>)
280#define _detail_ANYXX_V_TABLE_TEMPLATE_HEADER(t) \
281 _detail_ANYXX_V_TABLE_TEMPLATE_HEADER_H t
283#define _detail_ANYXX_INVOKE_TEMPLATE_PARAMS_H(...) __VA_OPT__(<__VA_ARGS__>)
285#define _detail_ANYXX_INVOKE_TEMPLATE_PARAMS(t) \
286 _detail_ANYXX_INVOKE_TEMPLATE_PARAMS_H t
288#define _detail_ANYXX_EXPAND_WITH_LEADING_COMMA(...) __VA_OPT__(, ) __VA_ARGS__
290#define _detail_ANYXX_OPTIONAL_TEMPLATE(...) __VA_OPT__(template)
292#define _detail_ANYXX_MAP_LIMP_H(l) _detail_ANYXX_MAP_IMPL l
293#define _detail_ANYXX_MAP_IMPL(access, overload, type, name, name_ext, \
294 exact_const, const_, trait_body, ...) \
296 static AYXFORCEDINLINE auto name([[maybe_unused]] T const_& x __VA_OPT__( \
297 , _detail_ANYXX_MAP_PARAM_LIST_H(a, _sig, __VA_ARGS__))) \
298 -> anyxx::map_return<T, ANYXX_UNPAREN(type)> { \
299 using namespace anyxx; \
300 return _detail_REMOVE_PARENS(trait_body)( \
301 __VA_OPT__(_detail_ANYXX_FORWARD_PARAM_LIST(a, _sig, __VA_ARGS__))); \
304#define _detail_ANYXX_CONCEPT_FN_H(l) _detail_ANYXX_CONCEPT_FN l
305#define _detail_ANYXX_CONCEPT_FN(access, overload, type, name, name_ext, \
306 exact_const, const_, trait_body, ...) \
308 __VA_OPT__(_detail_ANYXX_CONCEPT_PARAM_LIST_H(a, sig_, __VA_ARGS__))) { \
310 model_map.name(model __VA_OPT__( \
311 , _detail_ANYXX_CONCEPT_ARG_LIST_H(a, sig_, __VA_ARGS__))) \
312 } -> std::convertible_to<anyxx::map_return<T, ANYXX_UNPAREN(type)>>; \
315#define _detail_ANYXX_CONCEPT_STATIC_FN_H(l) _detail_ANYXX_CONCEPT_STATIC_FN l
316#define _detail_ANYXX_CONCEPT_STATIC_FN(template_params, return_type, name, \
319 __VA_OPT__(_detail_ANYXX_CONCEPT_PARAM_LIST_H(a, sig_, __VA_ARGS__))) { \
321 model_map.name(trait_class __VA_OPT__( \
322 , _detail_ANYXX_CONCEPT_ARG_LIST_H(a, sig_, __VA_ARGS__))) \
324 -> std::convertible_to<anyxx::map_return<T, ANYXX_UNPAREN(return_type)>>; \
327#define _detail_ANYXX_CONCEPT_TYPE_H(l) _detail_ANYXX_CONCEPT_TYPE l
328#define _detail_ANYXX_CONCEPT_TYPE(template_params, name, erased, default_) \
329 requires !std::same_as< \
330 typename decltype(model_map)::_detail_ANYXX_OPTIONAL_TEMPLATE( \
331 _detail_REMOVE_PARENS(template_params)) name \
332 _detail_ANYXX_DUMMY_INT_PARAM_LIST(ANYXX_UNPAREN(template_params)), \
338#define _detail_ANYXX_MAP_STATIC_H(l) _detail_ANYXX_MAP_STATIC l
339#define _detail_ANYXX_MAP_STATIC(template_params, return_type, name, body, \
342 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST( \
343 _detail_REMOVE_PARENS(template_params)) static AYXFORCEDINLINE auto \
344 name([[maybe_unused]] auto trait_class __VA_OPT__( \
345 , _detail_ANYXX_MAP_PARAM_LIST_H(a, _sig, __VA_ARGS__))) \
346 -> anyxx::map_return<T, ANYXX_UNPAREN(return_type)> { \
347 using namespace anyxx; \
348 return _detail_REMOVE_PARENS(body).template \
349 operator()<anyxx::use_as<T, typename decltype(trait_class)::trait_t>>( \
350 trait_class __VA_OPT__( \
351 , _detail_ANYXX_FORWARD_PARAM_LIST(a, _sig, __VA_ARGS__))); \
366#define _detail_ANYXX_JACKET_STATIC_H(l) _detail_ANYXX_JACKET_STATIC l
367#define _detail_ANYXX_JACKET_STATIC(template_params, return_type, name, body, \
369 template <typename Self _detail_ANYXX_OPTIONAL_MORE_TYPENAMES_PARAM_LIST( \
370 _detail_REMOVE_PARENS(template_params))> \
371 AYXFORCEDINLINE decltype(auto) name( \
372 [[maybe_unused]] this Self&& self __VA_OPT__(, ) \
373 __VA_OPT__(_detail_ANYXX_JACKET_PARAM_LIST(a, _sig, __VA_ARGS__))) { \
374 using self_t = std::decay_t<Self>; \
375 static_assert(!self_t::dyn); \
376 using T = typename self_t::T; \
377 using proxy_t = typename self_t::proxy_t; \
378 using map_t = typename self_t::template static_dispatch_map_t<T>; \
379 using traited_t = typename proxy_t::value_t; \
380 using trait_t = typename self_t::trait_t; \
381 return ANYXX_JACKET_RETURN(return_type)::forward( \
382 map_t::_detail_ANYXX_OPTIONAL_TEMPLATE( \
383 _detail_REMOVE_PARENS(template_params)) \
384 name _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
385 _detail_REMOVE_PARENS(template_params))( \
386 anyxx::trait_class_<T, trait_t> __VA_OPT__( \
387 , _detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP( \
388 a, _sig, __VA_ARGS__))), \
389 std::forward<Self>(self)); \
407#define _detail_ANYXX_MAP_TYPE_H(l) _detail_ANYXX_MAP_TYPE l
408#define _detail_ANYXX_MAP_TYPE(template_params, name, erased, default_) \
410 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST(_detail_REMOVE_PARENS( \
411 template_params)) using name = _detail_REMOVE_PARENS(default_);
418#define _detail_ANYXX_JACKET_TYPE_H(l) _detail_ANYXX_JACKET_TYPE l
419#define _detail_ANYXX_JACKET_TYPE(template_params, name, erased, default_) \
420 template <typename Q _detail_ANYXX_OPTIONAL_MORE_TYPENAMES_PARAM_LIST( \
421 _detail_REMOVE_PARENS(template_params))> \
422 using name = std::conditional_t< \
423 std::same_as<void, Q>, erased, \
424 typename static_dispatch_map_t<Q>::_detail_ANYXX_OPTIONAL_TEMPLATE( \
425 _detail_REMOVE_PARENS(template_params)) \
426 name _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
427 _detail_REMOVE_PARENS(template_params))>;
436#define _detail_ANYXX_MAP_VARIANT_LIMP_H(l) _detail_ANYXX_MAP_VARIANT_IMPL l
437#define _detail_ANYXX_MAP_VARIANT_IMPL(access, overload, type, name, name_ext, \
438 exact_const, const_, trait_body, ...) \
439 static AYXFORCEDINLINE auto name([[maybe_unused]] T const_& x __VA_OPT__( \
440 , _detail_ANYXX_MAP_PARAM_LIST_H(a, _sig, __VA_ARGS__))) \
441 -> decltype(auto) { \
444 [&]<typename V>(V&& v) { \
445 return x_model_map<std::decay_t<V>>::name( \
446 std::forward<V>(v) __VA_OPT__(, ) \
447 __VA_OPT__(_detail_ANYXX_FORWARD_PARAM_LIST( \
448 a, _sig, __VA_ARGS__))); \
450 [&]<anyxx::is_any Any>([[maybe_unused]] Any&& any) { \
451 return std::forward<Any>(any).name(__VA_OPT__( \
452 _detail_ANYXX_FORWARD_PARAM_LIST(a, _sig, __VA_ARGS__))); \
457#define _detail_ANYXX_FUNCTION_PTR_DECL(access, overload, type, name, \
458 name_ext, exact_const, const_, \
460 anyxx::v_table_return<any_value_t, ANYXX_UNPAREN(type)> (*name)( \
461 void const_* __VA_OPT__( \
462 , _detail_ANYXX_V_TABLE_PARAM_LIST(a, _sig, __VA_ARGS__)));
464#define _detail_ANYXX_LAMBDA_TO_MEMEBER_IMPL(access, overload, type, name, \
465 name_ext, exact_const, const_, \
467 name = [](void const_* _vp __VA_OPT__( \
468 , _detail_ANYXX_V_TABLE_PARAM_LIST(a, _sig, __VA_ARGS__))) \
469 -> anyxx::v_table_return<any_value_t, ANYXX_UNPAREN(type)> { \
470 if constexpr (std::same_as<anyxx::self&, ANYXX_UNPAREN(type)>) { \
472 *anyxx::unchecked_unerase_cast<Concrete>(_vp) __VA_OPT__(, ) \
473 __VA_OPT__(_detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP( \
474 a, _sig, __VA_ARGS__))); \
475 return anyxx::handle_self_ref_return<ANYXX_UNPAREN(type)>{}(); \
477 return model_map{}.name( \
478 *anyxx::unchecked_unerase_cast<Concrete>(_vp) __VA_OPT__(, ) \
479 __VA_OPT__(_detail_ANYXX_FORWARD_PARAM_LIST_TO_MAP( \
480 a, _sig, __VA_ARGS__))); \
484#define _detail_ANYXX_FN_H(l) _detail_ANYXX_FN l
485#define _detail_ANYXX_FN(access, overload, type, name, name_ext, exact_const, \
486 const_, map_body, ...) \
487 overload template <typename Self> \
488 AYXFORCEDINLINE decltype(auto) name_ext(this Self&& self __VA_OPT__( \
489 , ) __VA_OPT__(_detail_ANYXX_JACKET_PARAM_LIST(a, _sig, __VA_ARGS__))) \
490 requires(::anyxx::const_correct_call_for_proxy_and_self< \
491 void const_*, typename std::decay_t<Self>::proxy_t, \
492 std::is_const_v<std::remove_reference_t<Self>>, exact_const>) \
494 using self_t = std::decay_t<Self>; \
495 using T = typename self_t::T; \
496 using proxy_t = typename self_t::proxy_t; \
498 if constexpr (!self_t::dyn) { \
499 using traited_t = typename proxy_t::value_t; \
500 if constexpr (std::same_as<void, ANYXX_UNPAREN(type)>) { \
501 return static_dispatch_map_t<T>::name( \
502 get_proxy_value(self) __VA_OPT__(, ) \
503 __VA_OPT__(_detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP( \
504 a, _sig, __VA_ARGS__))); \
506 return ANYXX_JACKET_RETURN(type)::forward( \
507 static_dispatch_map_t<T>::name( \
508 get_proxy_value(self) __VA_OPT__(, ) \
509 __VA_OPT__(_detail_ANYXX_FORWARD_JACKET_PARAM_LIST_TO_MAP( \
510 a, _sig, __VA_ARGS__))), \
511 std::forward<Self>(self)); \
514 if constexpr (std::same_as<void, ANYXX_UNPAREN(type)>) { \
515 return get_v_table(self)->name(anyxx::get_proxy_ptr(self) __VA_OPT__( \
516 , _detail_ANYXX_FORWARD_PARAM_LIST(a, _sig, __VA_ARGS__))); \
518 return ANYXX_JACKET_RETURN(type)::forward( \
519 get_v_table(self)->name(anyxx::get_proxy_ptr(self) __VA_OPT__( \
520 , _detail_ANYXX_FORWARD_PARAM_LIST(a, _sig, __VA_ARGS__))), \
521 std::forward<Self>(self)); \
526#define _detail_ANYXX_CONCEPT_FUNCTIONS(...) \
527 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_CONCEPT_FN_H, \
528 _detail_EXPAND_LIST __VA_ARGS__))
530#define _detail_ANYXX_CONCEPT_STATIC_FUNCTIONS(...) \
531 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_CONCEPT_STATIC_FN_H, \
532 _detail_EXPAND_LIST __VA_ARGS__))
534#define _detail_ANYXX_CONCEPT_TYPES(...) \
535 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_CONCEPT_TYPE_H, \
536 _detail_EXPAND_LIST __VA_ARGS__))
538#define _detail_ANYXX_MAP_FUNCTIONS(...) \
539 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_MAP_LIMP_H, \
540 _detail_EXPAND_LIST __VA_ARGS__))
542#define _detail_ANYXX_MAP_STATIC_FUNCTIONS(...) \
543 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_MAP_STATIC_H, \
544 _detail_EXPAND_LIST __VA_ARGS__))
546#define _detail_ANYXX_MAP_TYPES(...) \
547 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_MAP_TYPE_H, \
548 _detail_EXPAND_LIST __VA_ARGS__))
550#define _detail_ANYXX_MAP_VARIANT_FUNCTIONS(...) \
551 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_MAP_VARIANT_LIMP_H, \
552 _detail_EXPAND_LIST __VA_ARGS__))
554#define _detail_ANYXX_V_TABLE_FUNCTION_PTRS(...) \
555 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_FPD_H, \
556 _detail_EXPAND_LIST __VA_ARGS__));
558#define _detail_ANYXX_V_TABLE_LAMBDAS(...) \
559 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_MEMEBER_LIMP_H, \
560 _detail_EXPAND_LIST __VA_ARGS__));
562#define _detail_ANYXX_FNS(...) \
563 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_FN_H, \
564 _detail_EXPAND_LIST __VA_ARGS__))
566#define _detail_ANYXX_JACKET_STATIC_FNS(...) \
567 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_JACKET_STATIC_H, \
568 _detail_EXPAND_LIST __VA_ARGS__))
570#define _detail_ANYXX_JACKET_TYPES(...) \
571 __VA_OPT__(_detail_foreach_macro(_detail_ANYXX_JACKET_TYPE_H, \
572 _detail_EXPAND_LIST __VA_ARGS__))
574#define _detail_ANYXX_MAKE_V_TABLE_FUNCTION_NAME(n) \
575 _detail_CONCAT(make_, _detail_CONCAT(n, _v_table))
578#define TRAIT_META_FUNCTION( \
579 any_template_params, model_map_template_params, concrete_template_params, \
580 static_dispatch_template_params, variant_model_map_template_params, n, \
581 BASE, base_template_params, base_model_map_template_params, l, static_fns, \
582 typedefs, decoration) \
584 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST(any_template_params) struct n; \
586 template <_detail_ANYXX_TYPENAME_PARAM_LIST(model_map_template_params)> \
587 struct n##_default_model_map { \
588 using default_map = n##_default_model_map; \
589 _detail_ANYXX_MAP_FUNCTIONS(l); \
590 _detail_ANYXX_MAP_STATIC_FUNCTIONS(static_fns); \
591 _detail_ANYXX_MAP_TYPES(typedefs); \
593 template <_detail_ANYXX_TYPENAME_PARAM_LIST(model_map_template_params)> \
594 struct n##_model_map : n##_default_model_map<_detail_ANYXX_TEMPLATE_ARGS( \
595 model_map_template_params)> {}; \
597 template <_detail_ANYXX_TYPENAME_PARAM_LIST(model_map_template_params)> \
598 requires(anyxx::is_variant<T>) \
600 _model_map<_detail_ANYXX_TEMPLATE_ARGS(model_map_template_params)> { \
601 template <typename V> \
602 using x_model_map = n##_model_map<_detail_ANYXX_TEMPLATE_ARGS( \
603 variant_model_map_template_params)>; \
604 _detail_ANYXX_MAP_VARIANT_FUNCTIONS(l) \
607 struct n##_has_open_dispatch; \
609 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST( \
610 any_template_params) struct n##_v_table \
612 _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(base_template_params)::v_table_t, \
613 anyxx::dispatch_holder<anyxx::is_type_complete<n##_has_open_dispatch>, \
614 n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
615 any_template_params)> { \
616 using v_table_base_t = typename BASE _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
617 base_template_params)::v_table_t; \
619 using v_table_t = n##_v_table; \
621 using any_value_t = \
622 anyxx::any<anyxx::val, n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
623 any_template_params)>; \
625 static constexpr bool open_dispatch_enabeled = \
626 anyxx::is_type_complete<n##_has_open_dispatch>; \
627 using own_dispatch_holder_t = typename anyxx::dispatch_holder< \
628 open_dispatch_enabeled, \
629 n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(any_template_params)>; \
631 static bool static_is_derived_from(const std::type_info& from) { \
632 if constexpr (std::derived_from<v_table_base_t, \
633 anyxx::observeable_rtti_v_table>) { \
634 return typeid(v_table_t) == from \
636 : v_table_base_t::static_is_derived_from(from); \
644 _detail_ANYXX_V_TABLE_FUNCTION_PTRS(l); \
646 template <typename Concrete> \
647 explicit(false) n##_v_table(std::in_place_type_t<Concrete> concrete); \
650 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST(any_template_params) struct n \
652 _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(base_template_params) { \
653 using any_value_t = \
654 anyxx::any<anyxx::val, n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
655 any_template_params)>; \
658 BASE _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(base_template_params); \
660 using v_table_base_t = base_t::v_table_t; \
662 n##_v_table _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(any_template_params); \
663 template <typename StaticDispatchType> \
664 using static_dispatch_map_t = n##_model_map<_detail_ANYXX_TEMPLATE_ARGS( \
665 static_dispatch_template_params)>; \
667 template <typename M> \
668 constexpr static bool modeled_by(); \
670 _detail_ANYXX_FNS(l); \
671 _detail_ANYXX_JACKET_STATIC_FNS(static_fns); \
672 _detail_ANYXX_JACKET_TYPES(typedefs); \
673 _detail_REMOVE_PARENS(decoration); \
676 template <_detail_ANYXX_TYPENAME_PARAM_LIST(model_map_template_params)> \
677 concept _detail_CONCAT(_detail_CONCAT(is_, n), _model) = \
680 anyxx::any_trait_class<T, n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
681 any_template_params)> \
683 n##_model_map<_detail_ANYXX_TEMPLATE_ARGS( \
684 model_map_template_params)> \
686 requires anyxx::is_type_complete<T>; \
687 _detail_ANYXX_CONCEPT_FUNCTIONS(l) \
688 _detail_ANYXX_CONCEPT_STATIC_FUNCTIONS(static_fns) \
689 _detail_ANYXX_CONCEPT_TYPES(typedefs) \
691 BASE _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
692 base_template_params)::template modeled_by<T>(); \
694 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST( \
695 any_template_params) template <typename T> \
696 constexpr bool n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
697 any_template_params)::modeled_by() { \
698 return _detail_CONCAT( \
699 _detail_CONCAT(is_, n), \
700 _model)<_detail_ANYXX_TEMPLATE_ARGS(model_map_template_params)>; \
703 _detail_ANYXX_OPTIONAL_TYPENAME_PARAM_LIST( \
704 any_template_params) template <typename Concrete> \
706 _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(any_template_params)::n##_v_table( \
707 std::in_place_type_t<Concrete> concrete) \
708 : v_table_base_t(concrete) { \
710 n##_model_map<_detail_ANYXX_TEMPLATE_ARGS(concrete_template_params)>; \
712 _detail_ANYXX_V_TABLE_LAMBDAS(l); \
714 if constexpr (open_dispatch_enabeled) { \
715 own_dispatch_holder_t::set_dispatch_table( \
716 ::anyxx::dispatch_table_instance<n##_v_table, Concrete>()); \
719 ::anyxx::set_is_derived_from<v_table_t>(this); \
722#define __detail_ANYXX_TRAIT_(t, n, BASE, l, static_fns, typedefs, decoration) \
723 TRAIT_META_FUNCTION(, (T), (Concrete), (StaticDispatchType), (V), n, BASE, , \
724 (T), l, static_fns, typedefs, decoration)
756#define TRAIT_EX_(n, BASE, l, static_fns, typedefs, decoration) \
757 __detail_ANYXX_TRAIT_(, n, BASE, l, static_fns, typedefs, decoration)
762#define TRAIT_(n, BASE, l) TRAIT_EX_(n, BASE, l, , , ())
774#define TRAIT(n, fns) TRAIT_(n, anyxx::base_trait, fns)
782#define TRAIT_EX(n, ...) TRAIT_EX_(n, anyxx::base_trait, __VA_ARGS__)
790#define TRAIT_TEMPLATE_EX_(t, n, base, base_template_types, l, static_fns, \
791 typedefs, decoration) \
792 TRAIT_META_FUNCTION( \
793 _detail_REMOVE_PARENS(t), \
794 __detail_ANYXX_ADD_HEAD((T), _detail_REMOVE_PARENS(t)), \
795 __detail_ANYXX_ADD_HEAD((Concrete), _detail_REMOVE_PARENS(t)), \
796 __detail_ANYXX_ADD_HEAD((StaticDispatchType), _detail_REMOVE_PARENS(t)), \
797 __detail_ANYXX_ADD_HEAD((V), _detail_REMOVE_PARENS(t)), n, base, \
798 _detail_REMOVE_PARENS(base_template_types), \
799 __detail_ANYXX_ADD_HEAD((T), \
800 _detail_REMOVE_PARENS(base_template_types)), \
801 l, static_fns, typedefs, decoration)
806#define TRAIT_TEMPLATE_EX(t, n, l, static_fns, typedefs, decoration) \
807 TRAIT_TEMPLATE_EX_(t, n, anyxx::base_trait, (), l, static_fns, typedefs, \
813#define TRAIT_TEMPLATE_(t, n, base, base_template_types, l) \
814 TRAIT_TEMPLATE_EX_(t, n, base, base_template_types, l, , , ())
819#define TRAIT_TEMPLATE(t, n, l) TRAIT_TEMPLATE_(t, n, anyxx::base_trait, (), l)
823#define ANY_META_FUNCTION(pure_template_params, \
824 any_template_params_with_defaults, n) \
826 template <_detail_ANYXX_TYPENAME_PARAM_LIST( \
827 any_template_params_with_defaults)> \
828 using any_##n = anyxx::any<Proxy, n _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS( \
829 pure_template_params)>;
833#define __detail_ANYXX_ANY_CMF(t, t_with_defaults, n) \
834 ANY_META_FUNCTION(, _detail_REMOVE_PARENS(t_with_defaults), n)
836#define __detail_ANYXX_ANY_EX_(n, proxy_default) \
837 __detail_ANYXX_ANY_CMF( \
838 ((Proxy)), ((Proxy = anyxx::default_proxy<proxy_default>::type)), n)
843#define ANY_EX_(n, BASE, l, proxy_default, decoration) \
844 TRAIT_EX_(n, BASE, l, decoration) \
845 __detail_ANYXX_ANY_EX_(n, proxy_default)
850#define ANY_EX(n, l, proxy_default, decoration) \
851 TRAIT_EX(n, l, decoration) \
852 __detail_ANYXX_ANY_EX_(n, proxy_default)
857#define ANY_(n, BASE, l, proxy_default) \
859 __detail_ANYXX_ANY_EX_(n, proxy_default)
884#define ANY(n, l, ...) \
886 __detail_ANYXX_ANY_EX_(n, __VA_ARGS__)
888#define __detail_ANYXX_ANY_TEMPLATE_CMF(t, n, proxy_default) \
889 ANY_META_FUNCTION(_detail_REMOVE_PARENS(t), \
890 __detail_ANYXX_ADD_TAIL( \
891 (Proxy = anyxx::default_proxy<proxy_default>::type), \
892 _detail_REMOVE_PARENS(t)), \
899#define ANY_TEMPLATE_EX_(t, n, BASE, bt, l, proxy_default, decoration) \
900 TRAIT_TEMPLATE_EX_(t, n, BASE, bt, l, decoration) \
901 __detail_ANYXX_ANY_TEMPLATE_CMF(t, n, proxy_default)
907#define ANY_TEMPLATE_(t, n, BASE, bt, l, proxy_default) \
908 TRAIT_TEMPLATE_(t, n, BASE, bt, l) \
909 __detail_ANYXX_ANY_TEMPLATE_CMF(t, n, proxy_default)
915#define ANY_TEMPLATE(t, n, l, proxy_default) \
916 TRAIT_TEMPLATE(t, n, l) \
917 __detail_ANYXX_ANY_TEMPLATE_CMF(t, n, proxy_default)
923#define ANY_TEMPLATE_EX(t, n, l, proxy_default, static_fns, typedefs, \
925 TRAIT_TEMPLATE_EX(t, n, l, static_fns, typedefs, decoration) \
926 __detail_ANYXX_ANY_TEMPLATE_CMF(t, n, proxy_default)
930#define ANY_FN_(...) (__VA_ARGS__)
931#define ANY_OVERLOAD(name) using base_t::name;
933#define __detail_ANYXX_MEMBER_FN(access, overload, ret, name, name_ext, \
934 exact_const, const_, params) \
935 ANY_FN_(access, overload, ret, name, name_ext, exact_const, const_, \
936 (x.name_ext), _detail_EXPAND params)
982#define ANY_FN_PURE(ret, name, params, const_) \
983 ANY_FN_(private, , ret, name, name, false, const_, \
984 (_detail_ANYXX_TRAIT_ERROR_MESSAGE(name, ret)), \
985 _detail_EXPAND params)
990#define ANY_FN_PURE_EXACT(ret, name, params, const_) \
991 ANY_FN_(private, , ret, name, name, true, const_, \
992 (_detail_ANYXX_TRAIT_ERROR_MESSAGE(name, ret)), \
993 _detail_EXPAND params)
998#define ANY_FN_DEF(access, ret, name, params, const_, ...) \
999 ANY_FN_(access, , ret, name, name, false, const_, (__VA_ARGS__), \
1000 _detail_EXPAND params)
1004#define ANY_FN_DEF_EXACT(access, ret, name, params, const_, ...) \
1005 ANY_FN_(access, , ret, name, name, true, const_, (__VA_ARGS__), \
1006 _detail_EXPAND params)
1019#define ANY_FN(ret, name, params, const_) \
1020 __detail_ANYXX_MEMBER_FN(public, , ret, name, name, false, const_, params)
1026#define ANY_FN_EXACT(ret, name, params, const_) \
1027 __detail_ANYXX_MEMBER_FN(public, , ret, name, name, true, const_, params)
1034#define ANY_FN_OVERLOAD(ret, name, params, const_) \
1035 __detail_ANYXX_MEMBER_FN(public, ANY_OVERLOAD(name), ret, name, name, false, \
1043#define ANY_FN_OVERLOAD_EXACT(ret, name, params, const_) \
1044 __detail_ANYXX_MEMBER_FN(public, ANY_OVERLOAD(name), ret, name, name, true, \
1052#define ANY_OP_MAP_NAMED(ret, op, name, params, const_) \
1053 __detail_ANYXX_MEMBER_FN(public, , ret, name, operator op, false, const_, \
1059#define ANY_OP(ret, op, params, const_) \
1060 ANY_OP_MAP_NAMED(ret, op, _detail_CONCAT(__op__, __COUNTER__), params, const_)
1066#define ANY_OP_DEF(access, ret, op, name, params, const_, ...) \
1067 ANY_FN_(access, , ret, name, operator op, false, const_, (__VA_ARGS__), \
1068 _detail_EXPAND params)
1070#define ANY_OP_EXACT_MAP_NAMED(ret, op, name, params, const_) \
1071 __detail_ANYXX_MEMBER_FN(public, , ret, name, operator op, true, const_, \
1078#define ANY_OP_EXACT(ret, op, params, const_) \
1079 ANY_OP_EXACT_MAP_NAMED(ret, op, _detail_CONCAT(__op__, __COUNTER__), params, \
1087#define ANY_OP_EXACT_DEF(access, ret, op, name, params, const_, ...) \
1088 ANY_FN_(access, , ret, name, operator op, true, const_, (__VA_ARGS__), \
1089 _detail_EXPAND params)
1096#define ANY_OP_EXACT_OVERLOAD_MAP_NAMED(ret, op, name, params, const_) \
1097 __detail_ANYXX_MEMBER_FN(ANY_OVERLOAD(operator op), ret, name, operator op, \
1098 true, const_, params)
1105#define ANY_OP_EXACT_OVERLOAD(ret, op, params, const_) \
1106 ANY_OP_EXACT_OVERLOAD_MAP_NAMED( \
1107 ret, op, _detail_CONCAT(__op__, __COUNTER__), params, const_)
1113#define ANY_OP_EXACT_OVERLOAD_DEF(access, ret, op, name, params, const_, ...) \
1114 ANY_FN_(access, ANY_OVERLOAD(operator op), ret, name, operator op, true, \
1115 const_, (__VA_ARGS__), _detail_EXPAND params)
1122#define ANY_FN_STATIC_PURE(template_params, return_type, name, params, ...) \
1123 ANY_FN_(template_params, return_type, name, \
1124 (_detail_ANYXX_TRAIT_ERROR_MESSAGE(name, return_type)), \
1125 _detail_EXPAND params)
1132#define ANY_FN_STATIC_DEF(template_params, return_type, name, params, ...) \
1133 ANY_FN_(template_params, return_type, name, (__VA_ARGS__), \
1134 _detail_EXPAND params)
1146#define ANY_TYPE(...) (__VA_ARGS__)
1155#define __ANY_MODEL_MAP(trait_, t) \
1157 struct trait_##_model_map<_detail_ANYXX_TEMPLATE_ARGS(t)> \
1158 : trait_##_default_model_map<_detail_ANYXX_TEMPLATE_ARGS(t)>
1169#define ANY_TEMPLATE_MODEL_MAP(model_, trait_, trait_types) \
1170 __ANY_MODEL_MAP(trait_, __detail_ANYXX_ADD_HEAD( \
1171 model_, _detail_REMOVE_PARENS(trait_types)))
1182#define TRAIT_TYPE(Name, T, Trait, ...) \
1183 typename Trait::template Name<T, __VA_ARGS__>
1192#define ANY_MODEL_MAP(model_, trait_) __ANY_MODEL_MAP(trait_, model_)
1195#define _detail_ANYXX_TRAIT_ERROR_MESSAGE(name, ret) \
1196 []<typename... Args>([[maybe_unused]] Args...) -> ret { \
1197 static_assert(anyxx::missing_trait_error<T>::not_specialized, \
1199 "' is missing in the specialization of this proxy_trait!"); \
1205template <
typename,
typename =
void>
1206struct is_type_complete_impl : std::false_type {};
1207template <
typename T>
1208struct is_type_complete_impl<
1209 T, std::enable_if_t<std::is_object<T>::value &&
1210 !std::is_pointer<T>::value && (sizeof(T) > 0)>>
1211 : std::true_type {};
1212template <
typename T>
1213constexpr static inline bool is_type_complete = is_type_complete_impl<T>::value;
1215template <
class... Ts>
1216struct overloads : Ts... {
1217 using Ts::operator()...;
1220template <
typename T>
1221struct is_variant_impl : std::false_type {};
1222template <
typename... Args>
1223struct is_variant_impl<std::variant<Args...>> : std::true_type {};
1224template <
typename T>
1225inline constexpr bool is_variant = is_variant_impl<T>::value;
1228constexpr bool is_in_dll_mode =
true;
1230constexpr bool is_in_dll_mode =
false;
1233class error :
public std::runtime_error {
1234 using std::runtime_error::runtime_error;
1236class type_mismatch_error :
public error {
1240struct member_dispatch {};
1241struct dyn : member_dispatch {};
1242struct static_ : member_dispatch {};
1244template <
typename Dispatch>
1245concept is_member_dispatch = std::derived_from<Dispatch, member_dispatch>;
1246static_assert(is_member_dispatch<dyn>);
1247static_assert(is_member_dispatch<static_>);
1249template <
typename T>
1250struct missing_trait_error {
1251 static constexpr bool not_specialized =
false;
1253template <
typename Value>
1255template <
typename Type>
1258using const_void =
void const*;
1259using mutable_void =
void*;
1260template <
typename V>
1262 (std::same_as<V, const_void> || std::same_as<V, mutable_void>);
1263template <
voidness Vo
idness>
1264struct is_const_void_;
1266struct is_const_void_<void*> : std::false_type {};
1268struct is_const_void_<void const*> : std::true_type {};
1269template <
typename Vo
idness>
1270concept is_const_void = is_const_void_<Voidness>::value;
1274template <
typename Model>
1275constexpr inline std::size_t compute_model_size() {
1276 if constexpr (std::is_trivially_copyable_v<Model> &&
1277 sizeof(Model) <=
sizeof(mutable_void)) {
1280 return sizeof(Model);
1286template <
bool HasDispatch,
typename Trait>
1287struct dispatch_holder;
1288using dispatch_table_function_t = void (*)();
1289using dispatch_table_dispatch_index_t = std::size_t;
1290using dispatch_table_entry_t =
unsigned long long;
1291using dispatch_table_t = std::vector<dispatch_table_entry_t>;
1292template <
typename AnyVTable,
typename Class>
1293dispatch_table_t* dispatch_table_instance_implementation() {
1294 static dispatch_table_t dispatch_table;
1295 return &dispatch_table;
1298template <
typename AnyVTable,
typename Class>
1299dispatch_table_t* dispatch_table_instance();
1301template <
typename AnyVTable,
typename Class>
1302dispatch_table_t* dispatch_table_instance() {
1303 return dispatch_table_instance_implementation<AnyVTable, Class>();
1311template <
typename VTable,
typename Concrete>
1312VTable* v_table_instance();
1320 template <
typename Concrete>
1322 [[maybe_unused]] std::in_place_type_t<Concrete> concrete) {}
1324 static bool static_is_derived_from(
const std::type_info& from) {
1334 template <
typename Concrete>
1336 [[maybe_unused]] std::in_place_type_t<Concrete> concrete)
1338 get_type_info(+[]() noexcept -> std::type_info const& {
1339 return typeid(Concrete);
1341 is_derived_from_(+[](
const std::type_info& from) {
1342 return static_is_derived_from(from);
1345 std::type_info
const& (*get_type_info)()
noexcept;
1346 bool (*is_derived_from_)(
const std::type_info&);
1348 static bool static_is_derived_from(
const std::type_info& from) {
1352 meta_data* meta_data_ =
nullptr;
1355template <
typename VTable>
1356void set_is_derived_from(
auto v_table) {
1357 if constexpr (std::is_base_of_v<observeable_rtti_v_table, VTable>) {
1358 v_table->is_derived_from_ = +[](
const std::type_info& from) {
1359 return VTable::static_is_derived_from(from);
1373 template <
typename Concrete>
1374 explicit any_v_table([[maybe_unused]] std::in_place_type_t<Concrete> concrete)
1376 model_size(compute_model_size<Concrete>()),
1377 allocate(+[] -> mutable_void {
1378 return std::allocator<Concrete>{}.allocate(1);
1380 copy_constructor(+[]([[maybe_unused]] mutable_void placement,
1381 [[maybe_unused]] const_void from) -> mutable_void {
1382 if constexpr (std::is_copy_constructible_v<Concrete>) {
1383 return std::construct_at<Concrete>(
1384 static_cast<Concrete*
>(placement),
1385 *
static_cast<Concrete const*
>(from));
1391 +[]([[maybe_unused]] mutable_void placement,
1392 [[maybe_unused]] mutable_void from) -> mutable_void {
1393 if constexpr (std::is_move_constructible_v<Concrete>) {
1394 return std::construct_at<Concrete>(
1395 static_cast<Concrete*
>(placement),
1396 std::move(*
static_cast<Concrete*
>(from)));
1401 destructor(+[](mutable_void data)
noexcept ->
void {
1402 std::destroy_at(
static_cast<Concrete*
>(data));
1404 delete_(+[](mutable_void data)
noexcept ->
void {
1406 auto p =
static_cast<Concrete*
>(data);
1408 std::allocator<Concrete>{}.deallocate(p, 1);
1410 set_is_derived_from<v_table_t>(
this);
1413 std::size_t model_size = 0u;
1414 mutable_void (*allocate)();
1415 mutable_void (*copy_constructor)(mutable_void placement, const_void from);
1416 mutable_void (*move_constructor)(mutable_void placement, mutable_void from);
1417 void (*destructor)(mutable_void data)
noexcept;
1418 void (*delete_)(mutable_void)
noexcept;
1419 static bool static_is_derived_from(
const std::type_info& from) {
1420 return typeid(v_table_t) == from
1422 : v_table_base_t::static_is_derived_from(from);
1426inline bool is_derived_from(
const std::type_info& from,
1427 any_v_table
const* v_table) {
1428 return v_table->is_derived_from_(from);
1431inline std::size_t model_size(any_v_table* v_table) {
1432 return v_table ? v_table->model_size : 0u;
1434inline mutable_void copy_construct_at(any_v_table* v_table,
1435 mutable_void placement, const_void from) {
1436 return v_table->copy_constructor(placement, from);
1438inline mutable_void copy_construct(any_v_table* v_table, const_void from) {
1439 return copy_construct_at(v_table, v_table->allocate(), from);
1441inline mutable_void move_construct_at(any_v_table* v_table,
1442 mutable_void placement,
1443 mutable_void from) {
1444 return v_table->move_constructor(placement, from);
1446inline mutable_void move_construct(any_v_table* v_table, mutable_void from) {
1447 return move_construct_at(v_table, v_table->allocate(), from);
1449inline void delete_(any_v_table* v_table, mutable_void& data)
noexcept {
1452 v_table->delete_(data);
1456template <
typename U>
1457bool type_match(any_v_table* v_table);
1459template <
typename U>
1460void check_type_match(any_v_table* v_table) {
1461 if (!type_match<U>(v_table))
throw type_mismatch_error(
"type mismatch");
1464template <
typename Data>
1467template <
typename Proxy>
1468struct basic_proxy_trait {
1469 inline static constexpr bool is_weak =
false;
1470 inline static constexpr bool is_lifetime_bound =
false;
1471 inline static constexpr bool is_object =
true;
1473 static void move_to(
auto& to, [[maybe_unused]]
auto,
auto&& from,
1474 [[maybe_unused]]
auto) {
1475 to = std::move(from);
1478 static void copy_construct_from(Proxy& to, [[maybe_unused]]
void*,
1479 auto const& from, [[maybe_unused]]
auto) {
1483 static void destroy([[maybe_unused]] Proxy
const& data,
1484 [[maybe_unused]]
void* v_table) {}
1490template <
typename E>
1492 typename proxy_trait<E>::void_t;
1493 typename proxy_trait<E>::static_dispatch_t;
1494 typename proxy_trait<E>::required_v_table_t;
1495 { proxy_trait<E>::is_constructibile_from_const } -> std::convertible_to<bool>;
1496 { proxy_trait<E>::is_owner } -> std::convertible_to<bool>;
1497 requires requires(proxy_trait<E>::required_v_table_t* required_v_table) {
1499 proxy_trait<E>::get_proxy_ptr_in(e, required_v_table)
1500 } -> std::convertible_to<typename proxy_trait<E>::void_t>;
1502 { proxy_trait<E>::is_weak } -> std::convertible_to<bool>;
1503 { proxy_trait<E>::clone_from(void_data, v_table) };
1504 { proxy_trait<E>::is_lifetime_bound } -> std::convertible_to<bool>;
1505 { proxy_trait<E>::is_object } -> std::convertible_to<bool>;
1508template <
typename T>
1509struct is_type_class_impl : std::false_type {};
1510template <
typename T>
1511struct is_type_class_impl<trait_class<T>> : std::true_type {};
1512template <
typename T>
1513inline constexpr bool is_type_class =
1514 is_proxy<T> && is_type_class_impl<T>::value;
1516struct observeable_trait {
1518 static constexpr bool modeled_by() {
1521 using v_table_t = observeable_v_table;
1523struct observeable_rtti_trait : observeable_trait {
1524 using v_table_t = observeable_rtti_v_table;
1526struct base_trait : observeable_rtti_trait {
1527 using v_table_t = any_v_table;
1530template <
typename Model>
1531concept is_base_trait_model =
true;
1534template <
typename T>
1536 std::derived_from<typename T::v_table_t, observeable_v_table>;
1538template <is_proxy Proxy,
typename Trait = base_trait>
1542template <
typename Proxy>
1544 is_proxy<Proxy> && voidness<typename proxy_trait<Proxy>::static_dispatch_t>;
1546template <
typename I>
1547concept is_proxy_holder_impl =
requires(I i) {
1548 typename I::proxy_t;
1549 typename I::proxy_trait_t;
1551template <
typename I>
1552concept is_proxy_holder = is_proxy_holder_impl<std::decay_t<I>>;
1554template <
typename I>
1555concept is_any_impl = is_proxy_holder_impl<I> &&
1556 requires(I::proxy_t ed) {
typename I::v_table_t; };
1557template <
typename I>
1558concept is_any = is_any_impl<std::decay_t<I>>;
1561concept is_typed_any = is_any<E> &&
requires(E e) {
1562 typename E::proxy_trait_t;
1563 typename E::value_t;
1564 { E::is_const } -> std::convertible_to<bool>;
1567template <
typename ConstructedWith,
typename Proxy,
typename BASE>
1568concept erased_constructibile_for =
1569 (!std::derived_from<std::remove_cvref_t<ConstructedWith>, BASE> &&
1570 !is_proxy<std::remove_cvref_t<ConstructedWith>> &&
1571 (!std::is_const_v<std::remove_reference_t<ConstructedWith>> ||
1572 proxy_trait<Proxy>::is_constructibile_from_const));
1574template <
typename ConstructedWith,
typename Proxy>
1575concept constructibile_for =
1576 (proxy_trait<Proxy>::template is_constructibile_from<
1577 ConstructedWith>::value) ||
1578 (erased_constructibile_for<ConstructedWith, Proxy, any<Proxy>> &&
1579 !is_proxy_holder<ConstructedWith> &&
1580 !is_typed_any<std::remove_cvref_t<ConstructedWith>>);
1582template <is_proxy Data>
1583using data_void = proxy_trait<Data>::void_t;
1585template <
typename Proxy>
1586concept is_const_data = is_proxy<Proxy> && is_const_void<data_void<Proxy>>;
1588template <
typename Proxy>
1589concept is_object_proxy = is_proxy<Proxy> && proxy_trait<Proxy>::is_object;
1591template <
typename Proxy>
1592concept is_weak_data = is_proxy<Proxy> && proxy_trait<Proxy>::is_weak;
1594template <
typename Proxy>
1595concept is_lifetime_bound =
1596 is_proxy<Proxy> && proxy_trait<Proxy>::is_lifetime_bound;
1598template <
bool ToIsConst,
bool FromIsConst,
bool FromIsWeak>
1599concept const_correct_move_to_from =
1600 !FromIsWeak && ((ToIsConst == FromIsConst) || !FromIsConst);
1602constexpr inline bool is_const_correct_call_for_proxy_and_self(
1603 bool call_is_const,
bool proxy_is_const,
bool self_is_const,
bool exact) {
1604 if (call_is_const) {
1606 return (call_is_const == proxy_is_const);
1612 if (proxy_is_const || self_is_const)
return false;
1615 return (call_is_const == proxy_is_const);
1620template <
typename CALL,
typename Proxy,
bool SelfIsConst,
bool Exact>
1621concept const_correct_call_for_proxy_and_self =
1622 is_object_proxy<Proxy> && !is_weak_data<Proxy> && voidness<CALL> &&
1624 is_const_correct_call_for_proxy_and_self(
1625 is_const_void<CALL>, is_const_data<Proxy>, SelfIsConst, Exact);
1627template <is_proxy Proxy,
typename From>
1628Proxy erased(From&& from) {
1629 return proxy_trait<Proxy>::erase(std::forward<From>(from));
1632template <is_proxy Proxy,
typename ConstructedWith>
1634 proxy_trait<Proxy>::template unerased<std::decay_t<ConstructedWith>>;
1636template <is_proxy Proxy>
1637void const* get_proxy_ptr(
1638 Proxy
const& vv,
typename proxy_trait<Proxy>::required_v_table_t* v_table)
1639 requires std::same_as<void const*, typename proxy_trait<Proxy>::void_t>
1641 return proxy_trait<Proxy>::get_proxy_ptr_in(vv, v_table);
1643template <is_proxy Proxy>
1644void* get_proxy_ptr(Proxy
const& vv,
1645 typename proxy_trait<Proxy>::required_v_table_t* v_table)
1646 requires std::same_as<void*, typename proxy_trait<Proxy>::void_t>
1648 return proxy_trait<Proxy>::get_proxy_ptr_in(vv, v_table);
1651template <
typename U>
1652auto unchecked_unerase_cast(
void const* p) {
1653 return static_cast<U const*
>(p);
1655template <
typename U>
1656auto unchecked_unerase_cast(
void* p) {
1657 return static_cast<U*
>(p);
1660template <
typename U, is_proxy Proxy>
1661auto unchecked_unerase_cast(
1662 Proxy
const& o,
typename proxy_trait<Proxy>::required_v_table_t* v_table) {
1663 return unchecked_unerase_cast<U>(get_proxy_ptr(o, v_table));
1665template <
typename U, is_proxy Proxy>
1666auto unchecked_unerase_cast(
1667 Proxy
const& o,
typename proxy_trait<Proxy>::required_v_table_t* v_table)
1668 requires(!is_const_data<Proxy>)
1670 return unchecked_unerase_cast<U>(get_proxy_ptr(o, v_table));
1673template <
typename U, is_proxy Proxy>
1674auto unerase_cast(Proxy
const& o, any_v_table* v_table) {
1675 check_type_match<U>(v_table);
1676 return unchecked_unerase_cast<U>(o, v_table);
1678template <
typename U, is_proxy Proxy>
1679U
const* unerase_cast_if(Proxy
const& o, any_v_table* v_table) {
1680 if (type_match<U>(v_table))
return unchecked_unerase_cast<U>(o, v_table);
1683template <
typename U, is_proxy Proxy>
1684U* unerase_cast_if(Proxy
const& o, any_v_table* v_table)
1685 requires(!is_const_data<Proxy>)
1687 if (type_match<U>(v_table))
return unchecked_unerase_cast<U>(o, v_table);
1694static_assert(std::is_const_v<std::remove_reference_t<int const&>>);
1695static_assert(!std::is_const_v<std::remove_reference_t<int&>>);
1696static_assert(!std::is_const_v<std::remove_reference_t<int>>);
1701template <
typename V>
1702struct proxy_trait<using_<V>> : basic_proxy_trait<using_<V>> {
1703 using void_t = std::conditional_t<std::is_const_v<std::remove_reference_t<V>>,
1704 const_void, mutable_void>;
1705 using static_dispatch_t = V;
1706 using required_v_table_t = observeable_v_table;
1707 static constexpr bool is_constructibile_from_const =
true;
1708 template <
typename ConstructedWith>
1709 struct is_constructibile_from {
1710 static constexpr bool value = std::is_constructible_v<
1711 V, ConstructedWith>;
1713 static constexpr bool is_owner =
true;
1714 static auto clone_from([[maybe_unused]] const_void data_ptr,
1715 [[maybe_unused]] any_v_table* v_table) {
1719 static auto get_proxy_ptr_in(
auto& val,
1720 [[maybe_unused]] observeable_v_table* v_table) {
1724 template <
typename ConstructedWith>
1725 using unerased = ConstructedWith;
1727 static auto construct_in_place(V&& v) {
return std::move(v); }
1728 template <
typename... Args>
1729 static auto construct_type_in_place([[maybe_unused]] Args&&... args) {
1730 return V{std::forward<Args>(args)...};
1732 template <
typename Vx>
1733 static auto erase(Vx&& v) {
1734 return using_<V>{std::forward<Vx>(v)};
1738template <
typename Type>
1739struct proxy_trait<trait_class<Type>> : basic_proxy_trait<trait_class<Type>> {
1740 using void_t = const_void;
1741 using static_dispatch_t = Type;
1742 static constexpr bool is_constructibile_from_const =
true;
1743 static constexpr bool is_object =
false;
1744 using required_v_table_t = observeable_v_table;
1745 template <
typename ConstructedWith>
1746 struct is_constructibile_from {
1747 static constexpr bool value =
true;
1749 static constexpr bool is_owner =
false;
1750 static auto clone_from([[maybe_unused]] const_void data_ptr,
1751 [[maybe_unused]] any_v_table* v_table) {}
1753 static auto get_proxy_ptr_in([[maybe_unused]]
auto& val,
1754 [[maybe_unused]]
void* v_table) {
1758 template <
typename ConstructedWith>
1759 using unerased = ConstructedWith;
1761 static auto construct_in_place(
auto) {}
1762 template <
typename... Args>
1763 static auto construct_type_in_place([[maybe_unused]] Args&&... args) {}
1764 template <
typename Vx>
1765 static auto erase([[maybe_unused]] Vx&& v) {
1766 return trait_class<Vx>{};
1779template <
template <
typename>
typename Any, is_proxy Proxy,
typename... Types>
1783template <
template <
typename>
typename Any,
is_proxy Proxy,
typename... Types>
1786template <
typename VanyVariant>
1787struct vany_variant_trait {
1788 using vany_variant_val = VanyVariant;
1790 template <
typename... Types>
1791 struct concrete_variant_impl;
1792 template <
typename First,
typename... Types>
1793 struct concrete_variant_impl<std::variant<First, Types...>> {
1794 using type = std::variant<Types...>;
1796 using concrete_variant =
typename concrete_variant_impl<vany_variant>::type;
1797 using any_in_variant =
typename std::variant_alternative_t<0, vany_variant>;
1800template <
typename Vany>
1801struct vany_type_trait {
1803 using vany_variant =
typename Vany::proxy_t;
1804 using concrete_variant =
1805 typename vany_variant_trait<vany_variant>::concrete_variant;
1806 using any_in_variant =
1807 typename vany_variant_trait<vany_variant>::any_in_variant;
1810template <
template <
typename>
typename Any, is_proxy Proxy,
typename... Types>
1811struct proxy_trait<using_<
vany_variant<Any, Proxy, Types...>>>
1812 : basic_proxy_trait<using_<vany_variant<Any, Proxy, Types...>>> {
1813 using vany_variant_t =
vany_variant<Any, Proxy, Types...>;
1814 using void_t =
typename proxy_trait<Proxy>::void_t;
1815 using required_v_table_t = observeable_v_table;
1816 using static_dispatch_t = vany_variant_t;
1817 static constexpr bool is_constructibile_from_const =
1818 proxy_trait<Proxy>::is_constructibile_from_const;
1819 template <
typename ConstructedWith>
1820 struct is_constructibile_from {
1821 static constexpr bool value =
1822 std::is_constructible_v<vany_variant_t, ConstructedWith>;
1824 static constexpr bool is_owner = proxy_trait<Proxy>::is_owner;
1825 static constexpr bool is_weak =
1826 proxy_trait<Proxy>::is_weak;
1828 static auto clone_from([[maybe_unused]] const_void data_ptr,
1829 [[maybe_unused]] any_v_table* v_table) {
1833 static auto get_proxy_ptr_in(
auto& val,
1834 [[maybe_unused]] observeable_v_table* v_table) {
1838 template <
typename ConstructedWith>
1839 using unerased = ConstructedWith;
1841 template <
typename V>
1842 static vany_variant_t construct_in_place(V&& v) {
1843 return using_<vany_variant_t>{std::forward<V>(v)};
1845 template <
typename T,
typename... Args>
1846 static auto construct_type_in_place([[maybe_unused]] Args&&... args) {
1847 return using_<vany_variant_t>{T{std::forward<Args>(args)...}};
1849 template <
typename Vx>
1850 static auto erase(Vx&& v) {
1851 return using_<vany_variant_t>{std::forward<Vx>(v)};
1858template <
voidness Vo
idness>
1859using observer = Voidness;
1869template <
voidness Vo
idness>
1870struct observer_trait : basic_proxy_trait<Voidness> {
1871 using void_t = Voidness;
1872 using static_dispatch_t = void_t;
1874 static constexpr bool is_const = is_const_void<void_t>;
1875 static constexpr bool is_constructibile_from_const = is_const;
1876 static constexpr bool is_lifetime_bound =
true;
1877 template <
typename ConstructedWith>
1878 struct is_constructibile_from {
1879 static constexpr bool value =
false;
1881 static constexpr bool is_owner =
false;
1882 static auto clone_from([[maybe_unused]] const_void data_ptr,
1886 static void move_to(Voidness& to, [[maybe_unused]]
auto, Voidness from,
1887 [[maybe_unused]]
auto) {
1891 static Voidness get_proxy_ptr_in(
1896 template <
typename ConstructedWith>
1897 using unerased = ConstructedWith;
1899 template <
typename V>
1900 static auto construct_in_place(V&&) {
1901 static_assert(
false);
1904 template <
typename T,
typename... Args>
1905 static auto construct_type_in_place([[maybe_unused]] Args&&... args) {
1906 static_assert(
false);
1909 template <
typename V>
1910 static auto erase(V& v) {
1911 static_assert(!std::is_const_v<std::remove_reference_t<V>>);
1912 return static_cast<Voidness
>(&v);
1914 template <
typename V>
1915 static auto erase(
const V& v)
1918 return static_cast<Voidness
>(&v);
1923struct proxy_trait<cref> : observer_trait<cref> {};
1925struct proxy_trait<
mutref> : observer_trait<mutref> {};
1927static_assert(proxy_trait<cref>::is_const);
1928static_assert(!proxy_trait<mutref>::is_const);
1929static_assert(is_proxy<cref>);
1930static_assert(is_proxy<mutref>);
1931static_assert(is_proxy<mutref>);
1932static_assert(is_proxy<cref>);
1948 mutable_void ptr =
nullptr;
1949 explicit unique(mutable_void p =
nullptr) : ptr(p) {}
1950 unique(unique
const&) =
delete;
1951 unique& operator=(unique
const&) =
delete;
1952 unique(unique&& other)
noexcept { std::swap(ptr, other.ptr); }
1953 unique& operator=(unique&& other)
noexcept {
1955 std::swap(ptr, other.ptr);
1958 ~unique() =
default;
1959 explicit operator bool()
const {
return static_cast<bool>(ptr); }
1963struct proxy_trait<
unique> : basic_proxy_trait<unique> {
1964 using void_t =
void*;
1965 using static_dispatch_t = void_t;
1967 template <
typename V>
1968 using typed_t = std::decay_t<V>;
1969 static constexpr bool is_constructibile_from_const =
true;
1970 template <
typename ConstructedWith>
1971 struct is_constructibile_from {
1972 static constexpr bool value =
false;
1974 static constexpr bool is_owner =
true;
1975 static auto clone_from([[maybe_unused]] const_void data_ptr,
1976 [[maybe_unused]] any_v_table* v_table) {
1977 return unique{copy_construct(v_table, data_ptr)};
1979 static void move_to(unique& to, any_v_table* v_table_to, unique&& from,
1980 [[maybe_unused]] any_v_table* v_table_from) {
1981 mutable_void old =
nullptr;
1982 std::swap(to.ptr, old);
1983 std::swap(to.ptr, from.ptr);
1984 delete_(v_table_to, old);
1987 static void* get_proxy_ptr_in(
const auto& ptr,
1988 [[maybe_unused]] observeable_v_table* v_table) {
1992 static void destroy(unique& u, any_v_table* v_table) {
1993 assert(v_table || !u.ptr);
1994 if (v_table) delete_(v_table, u.ptr);
1997 template <
typename ConstructedWith>
1998 struct unerased_impl {
1999 using type = std::decay_t<ConstructedWith>;
2001 template <
typename V>
2002 struct unerased_impl<std::unique_ptr<V>> {
2003 using type = std::decay_t<V>;
2005 template <
typename ConstructedWith>
2006 using unerased = unerased_impl<ConstructedWith>::type;
2008 template <
typename V>
2009 static auto construct_in_place(V&& v) {
2010 return unique{
new V{std::forward<V>(v)}};
2012 template <
typename T,
typename... Args>
2013 static auto construct_type_in_place(Args&&... args) {
2014 return unique{
new T{std::forward<Args>(args)...}};
2016 template <
typename V>
2017 static auto erase(std::unique_ptr<V>&& v) {
2018 return unique{v.release()};
2022static_assert(is_proxy<unique>);
2037using weak = std::weak_ptr<void const>;
2040struct proxy_trait<
shared> : basic_proxy_trait<shared> {
2041 using void_t =
void const*;
2042 using static_dispatch_t = void_t;
2044 template <
typename V>
2045 using typed_t =
const std::decay_t<V>;
2046 static constexpr bool is_constructibile_from_const =
true;
2047 template <
typename ConstructedWith>
2048 struct is_constructibile_from {
2049 static constexpr bool value =
false;
2051 static constexpr bool is_owner =
true;
2052 static auto clone_from(const_void data_ptr,
any_v_table* v_table) {
2053 return shared{copy_construct(v_table, data_ptr), v_table->delete_};
2056 shared&& from, [[maybe_unused]]
auto) {
2057 to = std::move(from);
2061 mutable_void p =
nullptr;
2062 std::swap(from.ptr, p);
2063 to =
shared{p, v_table->delete_};
2066 static void const* get_proxy_ptr_in(
2071 template <
typename ConstructedWith>
2072 struct unerased_impl {
2073 using type = std::decay_t<ConstructedWith>;
2075 template <
typename V>
2076 struct unerased_impl<std::shared_ptr<V>> {
2077 using type = std::decay_t<V>;
2079 template <
typename ConstructedWith>
2080 using unerased = unerased_impl<ConstructedWith>::type;
2082 template <
typename V>
2083 static auto construct_in_place(V&& v) {
2084 return std::make_shared<V>(std::forward<V>(v));
2086 template <
typename T,
typename... Args>
2087 static auto construct_type_in_place(Args&&... args) {
2088 return std::make_shared<T>(std::forward<Args>(args)...);
2090 template <
typename V>
2091 static auto erase(std::shared_ptr<V>
const& v) {
2092 return static_pointer_cast<void const>(v);
2097struct proxy_trait<weak> : basic_proxy_trait<weak> {
2098 using void_t =
void const*;
2099 using static_dispatch_t = void_t;
2100 using required_v_table_t = observeable_v_table;
2101 template <
typename V>
2102 using typed_t =
const std::decay_t<V>;
2103 static constexpr bool is_constructibile_from_const =
true;
2104 template <
typename ConstructedWith>
2105 struct is_constructibile_from {
2106 static constexpr bool value =
false;
2108 static constexpr bool is_owner =
false;
2109 static constexpr bool is_weak =
2111 static auto clone_from([[maybe_unused]] const_void data_ptr,
2112 [[maybe_unused]] any_v_table* v_table) {
2116 static void const* get_proxy_ptr_in(
2117 [[maybe_unused]]
const auto& ptr,
2118 [[maybe_unused]] observeable_v_table* v_table) {
2122 template <
typename ConstructedWith>
2123 using unerased = std::decay_t<typename ConstructedWith::element_type>;
2125 template <
typename V>
2126 static auto construct_in_place(V&&) {
2127 static_assert(
false);
2130 template <
typename T,
typename... Args>
2131 static auto construct_type_in_place([[maybe_unused]] Args&&... args) {
2132 static_assert(
false);
2135 template <
typename V>
2136 static auto erase(std::shared_ptr<V>
const& v) {
2137 return weak{static_pointer_cast<void const>(v)};
2139 template <
typename V>
2140 static auto erase(std::weak_ptr<V>
const& v) {
2141 return erase(v.lock());
2145static_assert(is_proxy<shared>);
2146static_assert(is_proxy<weak>);
2152 mutable_void ptr =
nullptr;
2153 heap_data(heap_data
const&) {}
2154 heap_data& operator=(heap_data
const&) {
2158 explicit heap_data(mutable_void p =
nullptr) : ptr(p) {}
2159 heap_data(heap_data&& other)
noexcept { std::swap(ptr, other.ptr); }
2160 heap_data& operator=(heap_data&& other)
noexcept {
2162 std::swap(ptr, other.ptr);
2165 ~heap_data() =
default;
2166 mutable_void release() noexcept {
2167 mutable_void p = ptr;
2171 friend void swap(heap_data& l, heap_data& r)
noexcept { std::swap(l, r); }
2174template <
bool Trivial>
2175struct local_data : std::array<std::byte, sizeof(mutable_void)> {
2176 static constexpr inline bool is_trivial = Trivial;
2190 val(mutable_void ptr = 0) : heap{ptr} {}
2191 val([[maybe_unused]] val
const& other)
noexcept { trivial = other.trivial; }
2192 val& operator=([[maybe_unused]] val
const& other)
noexcept {
2193 trivial = other.trivial;
2198 local_data<false> local;
2199 local_data<true> trivial;
2202template <
typename V>
2203auto visit_value(
auto&& visitor, V&& v, std::size_t size) ->
decltype(
auto) {
2204 if (size >
sizeof(mutable_void)) {
2205 return std::forward<decltype(visitor)>(visitor)(std::forward<V>(v).heap);
2206 }
else if (size > 0) {
2207 return std::forward<decltype(visitor)>(visitor)(std::forward<V>(v).local);
2210 return std::forward<decltype(visitor)>(visitor)(std::forward<V>(v).trivial);
2213template <
typename V2>
2214auto visit_value(
auto&& visitor, val& v1, std::size_t size1, V2&& v2,
2215 std::size_t size2) ->
decltype(
auto) {
2216 if (size1 >
sizeof(mutable_void)) {
2217 if (size2 >
sizeof(mutable_void)) {
2218 return std::forward<decltype(visitor)>(visitor)(
2219 v1.heap, std::forward<V2>(v2).heap);
2220 }
else if (size2 > 0) {
2221 return std::forward<decltype(visitor)>(visitor)(
2222 v1.heap, std::forward<V2>(v2).local);
2225 return std::forward<decltype(visitor)>(visitor)(
2226 v1.heap, std::forward<V2>(v2).trivial);
2227 }
else if (size1 > 0) {
2228 if (size2 >
sizeof(mutable_void)) {
2229 return std::forward<decltype(visitor)>(visitor)(
2230 v1.local, std::forward<V2>(v2).heap);
2231 }
else if (size2 > 0) {
2232 return std::forward<decltype(visitor)>(visitor)(
2233 v1.local, std::forward<V2>(v2).local);
2236 return std::forward<decltype(visitor)>(visitor)(
2237 v1.local, std::forward<V2>(v2).trivial);
2240 if (size2 >
sizeof(mutable_void)) {
2241 return std::forward<decltype(visitor)>(visitor)(v1.trivial,
2242 std::forward<V2>(v2).heap);
2243 }
else if (size2 > 0) {
2244 return std::forward<decltype(visitor)>(visitor)(v1.trivial,
2245 std::forward<V2>(v2).local);
2248 return std::forward<decltype(visitor)>(visitor)(v1.trivial,
2249 std::forward<V2>(v2).trivial);
2252template <
typename T,
typename... Args>
2253auto make_local_value(Args&&... args) {
2254 static_assert(
alignof(T) <=
alignof(mutable_void));
2255 static_assert(
sizeof(T) <=
sizeof(mutable_void));
2256 constexpr bool is_trivial = std::is_trivial_v<T>;
2257 using local_data_type = local_data<is_trivial>;
2259 auto location =
static_cast<T*
>(
static_cast<mutable_void
>(v.local.data()));
2260 std::construct_at<T>(location, std::forward<Args>(args)...);
2264template <
typename T,
typename... Args>
2265auto make_value(Args&&... args) {
2266 static_assert(
alignof(T) <=
alignof(mutable_void));
2267 if constexpr (
sizeof(T) <=
sizeof(mutable_void)) {
2268 return make_local_value<T>(std::forward<Args>(args)...);
2270 return val{
new T(std::forward<Args>(args)...)};
2275struct proxy_trait<val> : basic_proxy_trait<val> {
2276 using void_t =
void*;
2277 using static_dispatch_t = void_t;
2278 using required_v_table_t = any_v_table;
2279 template <
typename V>
2280 using typed_t = std::decay_t<V>;
2281 static constexpr bool is_constructibile_from_const =
true;
2282 template <
typename ConstructedWith>
2283 struct is_constructibile_from {
2284 static constexpr bool value =
false;
2286 static constexpr bool is_owner =
true;
2287 static auto clone_from([[maybe_unused]] const_void data_ptr,
2288 [[maybe_unused]] any_v_table* v_table) {
2291 visit_value(overloads{[&](heap_data& heap) {
2292 heap.ptr = copy_construct(v_table, data_ptr);
2294 [&]<
bool Trivial>(local_data<Trivial>& local) {
2297 static_cast<mutable_void
>(local.data()),
2300 v, v_table->model_size);
2304 static void move_to(val& to, [[maybe_unused]] any_v_table* v_table_to,
2305 val&& from, [[maybe_unused]] any_v_table* v_table_from) {
2306 if (!v_table_from && !v_table_to)
return;
2309 [&](heap_data& t, heap_data& f) {
2313 delete_(v_table_to, old.ptr);
2315 [&](heap_data& t, local_data<false>& f) {
2316 delete_(v_table_to, t.ptr);
2317 v_table_from->move_constructor(to.local.data(), f.data());
2319 [&](heap_data& t, local_data<true>& f) {
2320 delete_(v_table_to, t.ptr);
2321 to.trivial = std::move(f);
2323 [&](local_data<false>& t, heap_data& f) {
2324 if (v_table_to) v_table_to->destructor(t.data());
2325 to.heap.ptr = f.release();
2327 [&](local_data<false>& t, local_data<false>& f) {
2328 if (v_table_to) v_table_to->destructor(t.data());
2329 v_table_from->move_constructor(t.data(), f.data());
2331 [&](local_data<false>& t, local_data<true>& f) {
2332 if (v_table_to) v_table_to->destructor(t.data());
2333 to.trivial = std::move(f);
2335 [&]([[maybe_unused]] local_data<true>& t, heap_data& f) {
2336 to.heap.ptr = f.release();
2338 [&]([[maybe_unused]] local_data<true>& t, local_data<false>& f) {
2339 v_table_from->move_constructor(to.local.data(), f.data());
2341 [&](local_data<true>& t, local_data<true>& f) {
2344 to, model_size(v_table_to), from, v_table_from->model_size);
2362 static void copy_construct_from(val& to, any_v_table* to_v_table,
2363 val
const& from, any_v_table* from_v_table) {
2364 if (!from_v_table)
return;
2367 [&](heap_data& to_data, heap_data
const& from_data) {
2368 delete_(to_v_table, to_data.ptr);
2369 to_data.ptr =
nullptr;
2371 to_data.ptr = copy_construct(from_v_table, from_data.ptr);
2373 [&](heap_data& t, local_data<false>
const& f) {
2374 delete_(to_v_table, t.ptr);
2375 from_v_table->copy_constructor(to.local.data(), f.data());
2377 [&](heap_data& t, local_data<true>
const& f) {
2378 delete_(to_v_table, t.ptr);
2381 [&](local_data<false>& t, heap_data
const& f) {
2382 if (to_v_table) to_v_table->destructor(t.data());
2383 to.heap.ptr = copy_construct(from_v_table, f.ptr);
2385 [&](local_data<false>& t, local_data<false>
const& f) {
2386 if (to_v_table) to_v_table->destructor(t.data());
2387 from_v_table->copy_constructor(t.data(), f.data());
2389 [&](local_data<false>& t, local_data<true>
const& f) {
2390 if (to_v_table) to_v_table->destructor(t.data());
2393 [&]([[maybe_unused]] local_data<true>& t, heap_data
const& f) {
2394 to.heap.ptr = copy_construct(from_v_table, f.ptr);
2396 [&]([[maybe_unused]] local_data<true>& t,
2397 local_data<false>
const& f) {
2398 from_v_table->copy_constructor(to.local.data(), f.data());
2400 [&](local_data<true>& t, local_data<true>
const& f) { t = f; }},
2401 to, model_size(to_v_table), from, from_v_table->model_size);
2404 static void destroy(val& v, any_v_table* v_table) {
2405 visit_value(overloads{[&](heap_data& heap) {
2406 assert(v_table || !heap.ptr);
2407 if (v_table) delete_(v_table, heap.ptr);
2409 [&](local_data<false>& local) {
2410 if (v_table) v_table->destructor(local.data());
2412 [&]([[maybe_unused]] local_data<true>& local) {}},
2413 v, model_size(v_table));
2416 template <
typename V>
2417 static void* get_proxy_ptr_in(V&& v, [[maybe_unused]] any_v_table* v_table) {
2418 if (!v_table)
return nullptr;
2419 auto model_size = v_table->model_size;
2421 overloads{[&](heap_data
const& heap) {
return heap.ptr; },
2423 local_data<Trivial>
const& local) -> mutable_void {
2424 return static_cast<mutable_void
>(
2425 const_cast<std::byte*
>(local.data()));
2427 std::forward<V>(v), model_size);
2430 template <
typename ConstructedWith>
2431 using unerased = ConstructedWith;
2433 template <
typename V>
2434 static auto construct_in_place(V&& v) {
2435 return make_value<V>(std::forward<V>(v));
2437 template <
typename T,
typename... Args>
2438 static auto construct_type_in_place(Args&&... args) {
2439 return make_value<T>(std::forward<Args>(args)...);
2441 template <
typename ConstructedWith>
2442 static auto erase(ConstructedWith&& v) {
2443 return make_value<std::decay_t<ConstructedWith>>(
2444 std::forward<ConstructedWith>(v));
2448static_assert(is_proxy<val>);
2449static_assert(is_object_proxy<val>);
2456template <
typename TYPE>
2457auto& runtime_implementation();
2460template <
typename T>
2461meta_data& get_meta_data();
2463template <
typename T>
2464meta_data& get_meta_data() {
2465 return runtime_implementation<std::decay_t<T>>();
2469template <
bool dynamic,
typename Trait>
2470struct v_table_holder;
2471template <
typename Trait>
2472struct v_table_holder<false, Trait> {
2473 struct v_table_t {};
2475 v_table_holder() =
default;
2476 explicit v_table_holder(v_table_t*) {}
2477 static void set_v_table_ptr(
auto) {}
2478 static auto get_v_table_ptr() {
return nullptr; }
2479 template <
typename...>
2480 static void init_v_table() {}
2481 static auto release_v_table() {
return nullptr; }
2484template <
typename Trait>
2485struct with_open_dispatch : std::false_type {};
2487template <
typename Trait>
2488struct v_table_holder<true, Trait> {
2490 using v_table_t = Trait::v_table_t;
2493 v_table_t* v_table_ =
nullptr;
2496 v_table_holder() =
default;
2497 explicit v_table_holder(v_table_t* v_table) : v_table_(v_table) {}
2498 void set_v_table_ptr(v_table_t* v_table) { v_table_ = v_table; }
2500 auto get_v_table_ptr()
const {
return v_table_; }
2502 template <
typename Proxy,
typename Concrete>
2503 void init_v_table() {
2504 v_table_ = v_table_instance<v_table_t, anyxx::unerased<Proxy, Concrete>>();
2506 auto release_v_table() {
return std::exchange(v_table_,
nullptr); }
2509void insert_function(dispatch_table_t* table, std::size_t index,
auto fp) {
2510 if (table->size() <= index) table->resize(index + 1);
2511 auto& entry = table->at(index);
2512 entry =
reinterpret_cast<unsigned long long>(fp);
2514inline dispatch_table_function_t get_function(dispatch_table_t* table,
2515 std::size_t index) {
2516 if (table->size() <= index)
return {};
2517 return reinterpret_cast<dispatch_table_function_t
>(table->at(index));
2520inline dispatch_table_dispatch_index_t get_multi_dispatch_index_at(
2521 dispatch_table_t* table, std::size_t index) {
2522 if (table->size() <= index)
return {};
2523 if (
auto const entry = table->at(index))
2524 return static_cast<dispatch_table_dispatch_index_t
>(entry);
2528inline void set_multi_dispatch_index_at(
2529 dispatch_table_t* table, std::size_t index_multi_dispatch,
2530 dispatch_table_dispatch_index_t
2531 dispatch_index_of_class_in_dispatch_matrix) {
2532 if (table->size() <= index_multi_dispatch)
2533 table->resize(index_multi_dispatch + 1);
2534 auto& entry = table->at(index_multi_dispatch);
2535 entry = dispatch_index_of_class_in_dispatch_matrix;
2539 std::type_info
const &to, &from;
2543 const std::type_info& type_info_;
2544 std::vector<any_v_table*> i_table_;
2547 template <
typename CLASS>
2548 explicit constexpr meta_data(std::in_place_type_t<CLASS>)
2549 : type_info_(typeid(CLASS)) {}
2551 constexpr const std::type_info& get_type_info()
const {
return type_info_; }
2553 auto& get_i_table() {
return i_table_; }
2554 auto& get_i_table()
const {
return i_table_; }
2556 std::expected<any_v_table*, cast_error> get_v_table(
2557 std::type_info
const& typeid_)
const {
2558 auto const& i_table = get_i_table();
2559 for (
auto v_table : i_table)
2560 if (is_derived_from(typeid_, v_table))
return v_table;
2561 return std::unexpected(cast_error{.to = typeid_, .from = get_type_info()});
2563 auto register_v_table(any_v_table* v_table) {
2564 v_table->meta_data_ =
this;
2565 if (std::ranges::find(get_i_table(), v_table) == get_i_table().end())
2566 i_table_.push_back(v_table);
2571template <
typename TYPE>
2572auto& runtime_implementation() {
2573 static meta_data meta_data_{std::in_place_type<TYPE>};
2577template <
typename VTable,
typename Concrete>
2578auto bind_v_table_to_meta_data() {
2579 auto v_table = v_table_instance<VTable, Concrete>();
2580 get_meta_data<Concrete>().register_v_table(v_table);
2584template <
typename U>
2585bool type_match(any_v_table* v_table) {
2586 return v_table->get_type_info() ==
typeid(std::decay_t<U>);
2592template <is_proxy To, is_proxy From>
2595template <
typename To,
typename From,
typename FromVTable>
2596concept borrowable_from =
2597 is_proxy<From> && is_proxy<To> &&
2598 std::derived_from<FromVTable,
2599 typename proxy_trait<To>::required_v_table_t> &&
2600 requires(From f, FromVTable* v_table) {
2601 { borrow_trait<To, From>{}(f, v_table) } -> std::same_as<To>;
2604template <
typename To,
typename From,
typename FromVTable>
2605 requires borrowable_from<To, From, FromVTable>
2606To borrow_as(From
const& from, FromVTable* v_table) {
2607 return borrow_trait<To, From>{}(from, v_table);
2610template <is_proxy From>
2611 requires(!is_const_data<From> && !is_weak_data<From>)
2612struct borrow_trait<mutref, From> {
2613 auto operator()(
const auto& from,
auto* v_table)
const {
2614 return mutref{get_proxy_ptr(from, v_table)};
2617template <is_proxy From>
2618 requires(!is_weak_data<From>)
2619struct borrow_trait<cref, From> {
2620 auto operator()(
const auto& from, [[maybe_unused]]
auto* v_table)
const {
2621 return cref{get_proxy_ptr(from, v_table)};
2626 auto operator()(
const auto& from, [[maybe_unused]]
auto* v_table)
const {
2632 auto operator()(
const auto& from, [[maybe_unused]]
auto* v_table)
const {
2638 auto operator()(
const auto& from, [[maybe_unused]]
auto* v_table)
const {
2643static_assert(!borrowable_from<mutref, cref, observeable_v_table>);
2644static_assert(borrowable_from<mutref, mutref, observeable_v_table>);
2645static_assert(borrowable_from<mutref, unique, observeable_v_table>);
2646static_assert(!borrowable_from<mutref, shared, observeable_v_table>);
2647static_assert(!borrowable_from<mutref, weak, observeable_v_table>);
2648static_assert(borrowable_from<mutref, val, any_v_table>);
2650static_assert(borrowable_from<cref, cref, observeable_v_table>);
2651static_assert(borrowable_from<cref, mutref, observeable_v_table>);
2652static_assert(borrowable_from<cref, unique, observeable_v_table>);
2653static_assert(borrowable_from<cref, shared, observeable_v_table>);
2654static_assert(!borrowable_from<cref, weak, observeable_v_table>);
2655static_assert(borrowable_from<cref, val, any_v_table>);
2657static_assert(!borrowable_from<shared, cref, observeable_v_table>);
2658static_assert(!borrowable_from<shared, mutref, observeable_v_table>);
2659static_assert(!borrowable_from<shared, unique, observeable_v_table>);
2660static_assert(borrowable_from<shared, shared, observeable_v_table>);
2661static_assert(!borrowable_from<shared, weak, observeable_v_table>);
2662static_assert(!borrowable_from<shared, val, any_v_table>);
2664static_assert(!borrowable_from<weak, cref, observeable_v_table>);
2665static_assert(!borrowable_from<weak, mutref, observeable_v_table>);
2666static_assert(!borrowable_from<weak, unique, observeable_v_table>);
2667static_assert(borrowable_from<weak, shared, observeable_v_table>);
2668static_assert(borrowable_from<weak, weak, observeable_v_table>);
2669static_assert(!borrowable_from<weak, val, any_v_table>);
2671static_assert(!borrowable_from<unique, cref, observeable_v_table>);
2672static_assert(!borrowable_from<unique, mutref, observeable_v_table>);
2673static_assert(!borrowable_from<unique, unique, observeable_v_table>);
2674static_assert(!borrowable_from<unique, shared, observeable_v_table>);
2675static_assert(!borrowable_from<unique, weak, observeable_v_table>);
2676static_assert(!borrowable_from<unique, val, any_v_table>);
2678static_assert(!borrowable_from<val, cref, observeable_v_table>);
2679static_assert(!borrowable_from<val, mutref, observeable_v_table>);
2680static_assert(!borrowable_from<val, unique, observeable_v_table>);
2681static_assert(!borrowable_from<val, shared, observeable_v_table>);
2682static_assert(!borrowable_from<val, weak, observeable_v_table>);
2683static_assert(!borrowable_from<val, val, any_v_table>);
2688template <is_proxy To>
2691template <
typename To>
2692concept cloneable_to = is_proxy<To> && proxy_trait<To>::is_owner;
2694template <is_proxy To, is_proxy From>
2695 requires cloneable_to<To>
2696To clone_to(From
const& from, any_v_table* v_table) {
2697 return proxy_trait<To>::clone_from(get_proxy_ptr(from, v_table), v_table);
2700static_assert(!cloneable_to<mutref>);
2701static_assert(!cloneable_to<cref>);
2702static_assert(cloneable_to<shared>);
2703static_assert(!cloneable_to<weak>);
2704static_assert(cloneable_to<unique>);
2705static_assert(cloneable_to<val>);
2710template <
typename To,
typename From>
2711inline static bool constexpr can_move_to_from =
false;
2713template <
typename To,
typename From>
2714concept moveable_from =
2715 is_proxy<From> && is_proxy<To> && can_move_to_from<To, From>;
2717template <is_proxy X>
2718inline static bool constexpr can_move_to_from<X, X> =
true;
2721inline bool constexpr can_move_to_from<shared, unique> =
true;
2724inline bool constexpr can_move_to_from<weak, shared> =
true;
2726template <
voidness To,
voidness From>
2727 requires const_correct_move_to_from<is_const_void<To>, is_const_void<From>,
2729inline static bool constexpr can_move_to_from<To, From> =
true;
2731template <is_proxy To, is_proxy From>
2732 requires moveable_from<To, std::decay_t<From>>
2733void move_to(To& to, any_v_table* to_v_table, From&& from,
2734 any_v_table* from_v_table) {
2735 return proxy_trait<From>::move_to(to, to_v_table, std::move(from),
2739static_assert(!moveable_from<mutref, cref>);
2740static_assert(moveable_from<mutref, mutref>);
2741static_assert(!moveable_from<mutref, unique>);
2742static_assert(!moveable_from<mutref, shared>);
2743static_assert(!moveable_from<mutref, weak>);
2744static_assert(!moveable_from<mutref, val>);
2746static_assert(moveable_from<cref, cref>);
2747static_assert(moveable_from<cref, mutref>);
2748static_assert(!moveable_from<cref, unique>);
2749static_assert(!moveable_from<cref, shared>);
2750static_assert(!moveable_from<cref, weak>);
2751static_assert(!moveable_from<cref, val>);
2753static_assert(!moveable_from<shared, cref>);
2754static_assert(!moveable_from<shared, mutref>);
2755static_assert(moveable_from<shared, unique>);
2756static_assert(moveable_from<shared, shared>);
2757static_assert(!moveable_from<shared, weak>);
2758static_assert(!moveable_from<shared, val>);
2760static_assert(!moveable_from<weak, cref>);
2761static_assert(!moveable_from<weak, mutref>);
2762static_assert(!moveable_from<weak, unique>);
2763static_assert(moveable_from<weak, shared>);
2764static_assert(moveable_from<weak, weak>);
2765static_assert(!moveable_from<weak, val>);
2767static_assert(!moveable_from<unique, cref>);
2768static_assert(!moveable_from<unique, mutref>);
2769static_assert(moveable_from<unique, unique>);
2770static_assert(!moveable_from<unique, shared>);
2771static_assert(!moveable_from<unique, weak>);
2772static_assert(!moveable_from<unique, val>);
2774static_assert(!moveable_from<val, cref>);
2775static_assert(!moveable_from<val, mutref>);
2776static_assert(!moveable_from<val, unique>);
2777static_assert(!moveable_from<val, shared>);
2778static_assert(!moveable_from<val, weak>);
2779static_assert(moveable_from<val, val>);
2805template <is_proxy Proxy,
typename Trait>
2806class ANYXX_USE_EBO any :
public v_table_holder<is_dyn<Proxy>, Trait>,
public Trait {
2808 using proxy_t = Proxy;
2809 using proxy_trait_t = proxy_trait<proxy_t>;
2810 using void_t =
typename proxy_trait_t::void_t;
2811 using v_table_holder_t = v_table_holder<is_dyn<Proxy>, Trait>;
2812 using trait_t = Trait;
2813 using v_table_t =
typename v_table_holder_t::v_table_t;
2814 using T = proxy_trait_t::static_dispatch_t;
2815 using any_value_t = any<val, Trait>;
2828 template <
typename ConstructedWith>
2829 explicit(
false) any(ConstructedWith&& constructed_with)
2830 requires constructibile_for<ConstructedWith, Proxy> &&
2831 (!std::same_as<any, std::decay_t<ConstructedWith>>) &&
2832 (!is_lifetime_bound<Proxy>)
2834 erased<proxy_t>(std::forward<ConstructedWith>(constructed_with))) {
2835 v_table_holder_t::template init_v_table<Proxy, ConstructedWith>();
2840 template <
typename ConstructedWith>
2842 any(ConstructedWith&& constructed_with LIFETIMEBOUND)
2843 requires constructibile_for<ConstructedWith, Proxy> &&
2844 (!std::same_as<any, std::decay_t<ConstructedWith>>) &&
2845 (is_lifetime_bound<Proxy>)
2847 erased<proxy_t>(std::forward<ConstructedWith>(constructed_with))) {
2848 v_table_holder_t::template init_v_table<Proxy, ConstructedWith>();
2858 template <
typename V>
2859 requires(!is_lifetime_bound<Proxy>)
2861 : proxy_(proxy_trait<Proxy>::construct_in_place(std::forward<V>(v))) {
2862 v_table_holder_t::template init_v_table<Proxy, V>();
2870 template <
typename T,
typename... Args>
2871 requires(!is_lifetime_bound<Proxy>)
2872 any(std::in_place_type_t<T>, Args&&... args)
2873 : proxy_(proxy_trait_t::template construct_type_in_place<T>(
2874 std::forward<Args>(args)...)) {
2875 v_table_holder_t::template init_v_table<Proxy, T>();
2880 proxy_trait_t::destroy(proxy_, v_table_holder_t::get_v_table_ptr());
2883 any(
const any& other)
2884 requires(dyn && std::copyable<proxy_t>)
2885 : v_table_holder_t(other.get_v_table_ptr()) {
2886 proxy_trait_t::copy_construct_from(proxy_,
nullptr, other.proxy_,
2887 other.get_v_table_ptr());
2889 any(
const any& other)
2890 requires(!dyn && std::copyable<proxy_t>)
2891 : v_table_holder_t(other.get_v_table_ptr()), proxy_(other.proxy_) {}
2892 any& operator=(any
const& other)
2893 requires std::copyable<proxy_t>
2895 if (
this == &other)
return *
this;
2896 auto const v_table_ptr = v_table_holder_t::get_v_table_ptr();
2897 proxy_trait_t::copy_construct_from(proxy_, v_table_ptr, other.proxy_,
2898 other.get_v_table_ptr());
2899 v_table_holder_t::set_v_table_ptr(other.get_v_table_ptr());
2903 template <is_any Other>
2904 explicit(
false) any(
const Other& other)
2905 requires(borrowable_from<proxy_t,
typename Other::proxy_t,
2906 typename Other::v_table_t> &&
2908 std::derived_from<typename Other::v_table_t, v_table_t>))
2909 : v_table_holder_t(other.get_v_table_ptr()),
2910 proxy_(borrow_as<Proxy>(other.proxy_, other.get_v_table_ptr())) {}
2911 template <is_any Other>
2912 any& operator=(Other
const& other)
2913 requires(borrowable_from<proxy_t,
typename Other::proxy_t,
2914 typename Other::v_table_t> &&
2916 std::derived_from<typename Other::v_table_t, v_table_t>))
2918 v_table_holder_t::set_v_table_ptr(other.get_v_table_ptr());
2919 proxy_ = borrow_as<Proxy>(other.proxy_, other.get_v_table_ptr());
2923 template <is_proxy OtherErasedData>
2924 requires(moveable_from<proxy_t, OtherErasedData>)
2925 explicit any(OtherErasedData&& proxy, v_table_t* v_table) noexcept
2926 : v_table_holder_t(v_table) {
2927 proxy_trait_t::move_to(proxy_,
nullptr, std::move(proxy), v_table);
2929 template <is_proxy OtherErasedData>
2930 requires(moveable_from<proxy_t, OtherErasedData> && !dyn)
2931 explicit any(OtherErasedData&& proxy, v_table_t* v_table) noexcept
2932 : v_table_holder_t(v_table), proxy_(std::move(proxy)) {}
2933 template <is_any Other>
2934 explicit(
false) any(Other&& other)
noexcept
2935 requires(moveable_from<proxy_t, typename Other::proxy_t> &&
2937 std::derived_from<typename Other::v_table_t, v_table_t>))
2938 : any(std::move(other.proxy_), other.release_v_table()) {}
2939 template <is_any Other>
2940 any& operator=(Other&& other)
noexcept
2941 requires(moveable_from<proxy_t, typename Other::proxy_t> &&
2943 std::derived_from<typename Other::v_table_t, v_table_t>))
2945 proxy_trait_t::move_to(proxy_, v_table_holder_t::get_v_table_ptr(),
2946 std::move(other.proxy_), other.get_v_table_ptr());
2947 v_table_holder_t::set_v_table_ptr(other.release_v_table());
2950 template <
typename Box>
2951 using type_for = any<Box, Trait>;
2953 template <is_any Friend>
2954 friend inline auto& get_proxy(Friend
const& any);
2955 template <is_any Friend>
2956 friend inline auto& get_proxy(Friend& any);
2957 template <is_any Friend>
2958 friend inline decltype(
auto) move_proxy(Friend&& any);
2959 template <is_any Friend>
2960 friend inline auto get_proxy_ptr(Friend
const& any);
2962 template <is_proxy Other,
typename OtherTrait>
2965 template <
typename Friend>
2966 requires is_any<Friend> && Friend::dyn
2967 friend inline auto get_v_table(Friend
const& any);
2969 template <is_any To, is_any From>
2970 friend inline To unchecked_downcast_to(From from)
2972 std::derived_from<typename To::v_table_t, typename From::v_table_t>);
2974 explicit operator bool()
const {
2975 if constexpr (!voidness<typename proxy_trait_t::static_dispatch_t>) {
2976 if constexpr (is_type_class<proxy_t>) {
2979 return proxy_.value_;
2982 auto p = get_proxy_ptr(*
this);
2983 return p !=
nullptr;
2988template <is_any Any>
2989inline auto& get_proxy(Any
const& any) {
2992template <is_any Any>
2993inline auto& get_proxy(Any& any) {
2996template <
typename Any>
2997 requires is_any<std::decay_t<Any>> && (!std::decay_t<Any>::dyn)
2998inline auto& get_proxy_value(Any&& any) {
2999 return get_proxy(std::forward<Any>(any)).value_;
3001template <
typename Any>
3002 requires is_any<std::decay_t<Any>> && (!std::decay_t<Any>::dyn)
3003inline auto const& get_proxy_value(Any
const& any) {
3004 return get_proxy(any).value_;
3006template <is_any Any>
3007inline decltype(
auto) move_proxy(Any&& any) {
3008 return std::move(any.proxy_);
3010template <is_any Any>
3011inline auto get_proxy_ptr(Any
const& any) {
3012 return get_proxy_ptr(get_proxy(any), get_v_table(any));
3015template <is_any Any>
3016inline const auto& get_meta_data(Any
const& any) {
3017 return *get_v_table(any)->meta_data_;
3020template <is_any Any>
3021inline std::type_info
const& get_type_info(Any
const& any) {
3022 return get_v_table(any)->get_type_info();
3025template <is_any Any>
3026 requires std::derived_from<typename Any::v_table_t, observeable_rtti_v_table>
3027bool is_derived_from(
const std::type_info& from, Any
const& any) {
3028 return get_v_table(any)->is_derived_from_(from);
3030template <is_any From, is_any Any>
3031 requires std::derived_from<
typename From::v_table_t,
3032 observeable_rtti_v_table> &&
3033 std::derived_from<typename Any::v_table_t, observeable_rtti_v_table>
3034bool is_derived_from(Any
const& any) {
3035 return is_derived_from(
typeid(
typename From::v_table_t), any);
3038template <
typename To>
3039 requires(!is_any<To> && std::derived_from<To, observeable_v_table>)
3040auto unchecked_v_table_downcast_to(observeable_v_table* v_table) {
3041 return static_cast<To*
>(v_table);
3043template <
typename To>
3044 requires is_any<To> &&
3045 std::derived_from<typename To::v_table_t, observeable_v_table>
3046auto unchecked_v_table_downcast_to(observeable_v_table* v_table) {
3047 return unchecked_v_table_downcast_to<typename To::v_table_t>(v_table);
3050template <
typename Any>
3051 requires is_any<Any> && Any::dyn
3052inline auto get_v_table(Any
const& any) {
3053 return unchecked_v_table_downcast_to<Any>(any.get_v_table_ptr());
3056template <is_any To, is_any From>
3057inline To unchecked_downcast_to(From from)
3058 requires(std::derived_from<typename To::v_table_t, typename From::v_table_t>)
3060 return To{std::move(from.proxy_),
3061 unchecked_v_table_downcast_to<To>(get_v_table(from))};
3073template <is_any To, is_any From>
3075 requires(std::derived_from<typename To::v_table_t, typename From::v_table_t>)
3077 if (is_derived_from<To>(from))
3078 return {unchecked_downcast_to<To>(std::move(from))};
3082template <
typename U, is_any Any>
3083inline auto unchecked_unerase_cast(Any
const& o) {
3084 return unchecked_unerase_cast<U>(get_proxy(o), get_v_table(o));
3089template <
typename U,
typename Any>
3090 requires is_any<Any> && Any::dyn
3091inline auto unerase_cast(Any
const& o) {
3092 return unerase_cast<U>(get_proxy(o), get_v_table(o));
3097template <
typename U,
typename Any>
3098 requires is_any<Any> && Any::dyn
3099inline auto unerase_cast_if(Any
const& o) {
3100 return unerase_cast_if<U>(get_proxy(o), get_v_table(o));
3115template <
typename Value>
3117 template <
typename V>
3118 requires(!std::same_as<std::decay_t<V>, using_>)
3119 using_(V&& v) : value_(std::forward<V>(v)) {}
3121 using value_t = Value;
3122 operator Value()
const {
return value_; }
3125 template <
typename Trait>
3131template <
typename Type,
typename Trait>
3136template <
typename Type,
template <
typename...>
typename Trait,
typename... Ts>
3142template <
typename Trait,
typename T>
3152template <
typename Type>
3154 using value_t = Type;
3162template <
typename Type,
typename Trait>
3168template <
typename Type,
typename Trait>
3171template <
typename VTable,
typename Concrete>
3172VTable* v_table_instance() {
3173 static VTable v_table{std::in_place_type<Concrete>};
3177template <
typename I>
3178concept has_open_dispatch_enabeled =
3179 is_any<I> && I::v_table_t::open_dispatch_enabeled;
3181template <
typename Trait>
3182struct dispatch_holder<false, Trait> {
3183 static void set_dispatch_table([[maybe_unused]] dispatch_table_t* t) {}
3185template <
typename Trait>
3186struct dispatch_holder<true, Trait> {
3187 void set_dispatch_table(dispatch_table_t* t) { dispatch_table = t; }
3188 dispatch_table_t* dispatch_table =
nullptr;
3191template <is_any ToAny>
3192auto query_v_table(any_v_table* from)
3193 -> std::expected<typename ToAny::v_table_t*, anyxx::cast_error> {
3194 using v_table_t =
typename ToAny::v_table_t;
3195 if (from->is_derived_from_(
typeid(v_table_t)))
3196 return static_cast<v_table_t*
>(from);
3197 return from->meta_data_->get_v_table(
typeid(v_table_t))
3198 .transform([](
auto v_table) {
return static_cast<v_table_t*
>(v_table); });
3201template <
typename ToAny>
3202auto query_v_table(any_v_table* from) {
3203 return find_v_table<ToAny>(*from->meta_data_);
3211template <
typename Param>
3212struct jacket_return;
3214template <
typename Param>
3215 requires(!std::is_reference_v<Param>)
3216struct jacket_return<Param> {
3217 template <
typename Sig>
3218 static Param forward(Sig&& sig,
auto&&) {
3219 return std::forward<Sig>(sig);
3222template <
typename Param>
3223 requires std::is_reference_v<Param>
3224struct jacket_return<Param> {
3225 template <
typename Sig>
3226 static decltype(
auto) forward(Sig&& sig,
auto&&) {
3227 return std::forward<Sig>(sig);
3230static_assert(!is_type_class<val>);
3232struct jacket_return<self> {
3233 template <
typename Sig,
typename Any>
3234 static decltype(
auto) forward(Sig&& sig, Any
const&) {
3235 using sig_t = std::decay_t<Sig>;
3236 if constexpr (is_type_class<typename std::decay_t<Any>::proxy_t>) {
3238 any<using_<typename Any::proxy_t::value_t>,
typename Any::trait_t>;
3239 if constexpr (is_any<sig_t>) {
3240 return target_t{get_proxy_value(std::forward<Sig>(sig))};
3242 return target_t{std::forward<Sig>(sig)};
3245 if constexpr (is_any<sig_t> && !Any::dyn) {
3246 return Any{get_proxy_value(sig)};
3248 return Any{std::forward<Sig>(sig)};
3254struct jacket_return<self&> {
3255 static auto& forward(
auto,
auto&& any) {
3261 (
ANY_TYPE(((AnyValue)), v_table_param,
void, (T)),
3262 ANY_TYPE(((AnyValue)), v_table_return,
void, (T)),
3263 ANY_TYPE(((Model)), map_return,
void, (T)),
3264 ANY_TYPE(((Model)), concept_arg,
void, (T))),
3267 template <
typename AnyValue>
3268 using v_table_param = any<cref>;
3269 template <
typename AnyValue>
3270 using v_table_return = AnyValue;
3271 template <
typename Model>
3272 using map_return = Model;
3273 template <
typename Model>
3274 using concept_arg = Model;
3277 template <
typename AnyValue>
3278 using v_table_param = any<cref>;
3279 template <
typename AnyValue>
3280 using v_table_return = int;
3281 template <
typename Model>
3282 using map_return = Model
const&;
3283 template <
typename Model>
3284 using concept_arg = Model
const&;
3287 template <
typename AnyValue>
3288 using v_table_param = any<mutref>;
3289 template <
typename AnyValue>
3290 using v_table_return = int;
3291 template <
typename Model>
3292 using map_return = Model&;
3293 template <
typename Model>
3294 using concept_arg = Model&;
3296template <
typename AnyValue,
typename Param>
3297using v_table_param =
TRAIT_TYPE(v_table_param, Param, translate_sig, AnyValue);
3298template <
typename AnyValue,
typename Return>
3299using v_table_return =
TRAIT_TYPE(v_table_return, Return, translate_sig,
3301template <
typename Model,
typename Param>
3302using map_return =
TRAIT_TYPE(map_return, Param, translate_sig, Model);
3303template <
typename Model,
typename Param>
3304using concept_arg =
TRAIT_TYPE(concept_arg, Param, translate_sig, Model);
3309template <
typename T>
3310struct handle_self_ref_return {
3311 static T operator()() {
3312 static std::remove_reference_t<T> dummy;
3317struct handle_self_ref_return<void> {
3318 static void operator()() {}
3321struct handle_self_ref_return<self&> {
3322 static int operator()() {
return 0; }
3325template <
typename Concrete,
typename T>
3326struct v_table_to_map {
3327 template <
typename Sig>
3328 static Sig&& forward(Sig&& sig) {
3329 return std::forward<Sig>(sig);
3332template <
typename Concrete>
3333struct v_table_to_map<Concrete, self&> {
3334 template <
typename Sig>
3335 static Concrete& forward(Sig&& sig) {
3336 return *unerase_cast<Concrete>(sig);
3339template <
typename Concrete>
3340struct v_table_to_map<Concrete, self const&> {
3341 template <
typename Sig>
3342 static Concrete
const& forward(Sig&& sig) {
3343 return *unerase_cast<Concrete>(sig);
3347template <
typename,
typename T>
3348struct forward_trait_to_map {
3349 template <
typename Sig>
3350 static Sig&& forward(Sig&& sig) {
3351 return std::forward<Sig>(sig);
3354template <
typename Traited>
3355struct forward_trait_to_map<Traited, self&> {
3356 template <
typename Sig>
3357 static Traited& forward(Sig&& sig) {
3358 return get_proxy_value(std::forward<Sig>(sig));
3361template <
typename Traited>
3362struct forward_trait_to_map<Traited, self const&> {
3363 template <
typename Sig>
3364 static Traited
const& forward(Sig&& sig) {
3365 return get_proxy_value(std::forward<Sig>(sig));
3373template <is_proxy Proxy = shared>
3374struct default_proxy {
3381template <
typename V, is_any Any>
3382struct typed_any :
public Any {
3384 using proxy_t =
typename any_t::proxy_t;
3385 using proxy_trait_t = any_t::proxy_trait_t;
3386 using void_t = proxy_trait_t::void_t;
3387 static constexpr bool is_const = is_const_void<void_t>;
3393 explicit(
false) typed_any(V
const& v) : any_t(v) {}
3394 explicit(
false) typed_any(V&& v) : any_t(std::move(v)) {}
3395 explicit(
false) typed_any(any_t i) : any_t(i) {
3396 check_type_match<V>(get_v_table(*
this));
3400 value_t
const& operator*()
const {
3401 return *unchecked_unerase_cast<value_t const>(*
this);
3403 value_t
const* operator->()
const {
3404 return unchecked_unerase_cast<value_t const>(*
this);
3406 value_t
const* get()
const {
3407 return unchecked_unerase_cast<value_t const>(*
this);
3409 value_t& operator*() const
3412 return *unchecked_unerase_cast<value_t>(*
this);
3414 value_t* operator->() const
3417 return unchecked_unerase_cast<value_t>(*
this);
3419 value_t* get() const
3422 return unchecked_unerase_cast<value_t>(*
this);
3424 explicit operator bool()
const {
return static_cast<bool>(this->proxy_); }
3427template <
typename V, is_any Any>
3428auto as(Any source) {
3429 return typed_any<V, Any>{std::move(source)};
3432template <
typename To,
typename V, is_any Any>
3433auto as(typed_any<V, Any> source)
3434 requires std::convertible_to<V*, To*>
3436 if constexpr (typed_any<V, Any>::is_const) {
3437 return typed_any<To const, Any>{std::move(source.proxy_)};
3439 return typed_any<To, Any>{std::move(source.proxy_)};
3446template <is_any ToAny, is_proxy FromProxy,
typename FromVTable>
3447 requires borrowable_from<typename ToAny::proxy_t, FromProxy, FromVTable>
3448std::expected<ToAny, cast_error> borrow_as(FromProxy
const& from,
3449 FromVTable* from_v_table) {
3450 using to =
typename ToAny::proxy_t;
3451 return query_v_table<ToAny>(from_v_table).transform([&](
auto v_table) {
3452 return ToAny{borrow_as<to>(from, v_table), v_table};
3459template <is_any ToAny, is_any FromAny>
3460 requires borrowable_from<
typename ToAny::proxy_t,
typename FromAny::proxy_t,
3461 typename FromAny::v_table_t>
3462std::expected<ToAny, cast_error> borrow_as(FromAny
const& from) {
3463 if constexpr (std::same_as<
typename ToAny::v_table_t,
3464 typename FromAny::v_table_t>) {
3465 return {ToAny{from}};
3466 }
else if constexpr (std::derived_from<
typename ToAny::v_table_t,
3467 typename FromAny::v_table_t>) {
3469 return borrow_as<ToAny>(get_proxy(from), get_v_table(from));
3471 return borrow_as<ToAny>(get_proxy(from), get_v_table(from));
3477template <is_any ToAny, is_any FromAny>
3478std::expected<ToAny, cast_error> clone_to(FromAny
const& from) {
3479 using vv_to_t =
typename ToAny::proxy_t;
3481 return query_v_table<ToAny>(get_v_table(from)).transform([&](
auto v_table) {
3482 return ToAny{clone_to<vv_to_t>(get_proxy(from), v_table), v_table};
3488template <is_any FromAny>
3489 requires std::same_as<typename FromAny::proxy_t, weak>
3490auto lock(FromAny
const& from_interface) {
3491 using to_interface_t = FromAny::template type_for<shared>;
3492 static_assert(is_any<to_interface_t>);
3493 using return_t = std::optional<to_interface_t>;
3494 if (
auto locked = get_proxy(from_interface).
lock())
3496 to_interface_t{std::move(locked), get_v_table(from_interface)}};
3503template <is_any ToAny, is_any FromAny>
3504ToAny move_to(FromAny&& from) {
3505 auto to_v_table = query_v_table<ToAny>(from.release_v_table());
3506 return ToAny{move_proxy(std::move(from)), *to_v_table};
3513template <
typename R,
typename... Args>
3515template <
typename R,
typename... Args>
3516class hook<R(Args...)> {
3518 struct connection_info {
3523 connection_info info_;
3526 connection(connection
const&) =
delete;
3527 connection& operator=(connection
const&) =
delete;
3531 explicit(
false) connection(connection_info info) : info_(info) {}
3533 connection& operator=(connection_info info) {
3538 connection(connection&&) =
default;
3539 connection& operator=(connection&&) =
default;
3541 if (info_.owner) info_.owner->remove(info_.id);
3542 info_.owner =
nullptr;
3545 ~connection() { close(); }
3553 super(
int index, hook
const& hook) : index_(index), hook_(hook) {}
3556 explicit operator bool()
const {
return index_ >= 0; }
3557 R operator()(Args&&... args)
const {
3558 assert(index_ >= 0);
3559 return hook_.callees_[((std::size_t)index_)].second(
3560 super{index_ - 1, hook_}, std::forward<Args>(args)...);
3564 using callee = std::function<R(super
const&, Args...)>;
3566 R operator()(Args&&... args)
const {
3567 assert(!callees_.empty());
3568 return callees_.back().second(super{((int)callees_.size()) - 2, *
this},
3569 std::forward<Args>(args)...);
3572 connection_info insert(callee
const& f) {
3573 callees_.emplace_back(entry{next_id_, f});
3574 return connection_info{next_id_++,
this};
3578 void remove(
int id) {
3579 std::erase_if(callees_, [&](
auto const id_callee_pair) {
3580 return id_callee_pair.first == id;
3585 using entry = std::pair<int, callee>;
3586 std::vector<entry> callees_;
3592class unkonwn_factory_key_error :
public error {
3596template <
typename Tag>
3599 friend auto operator<=>(
key,
key) =
default;
3601template <
typename T>
3602struct is_key_impl : std::false_type {};
3603template <
typename T>
3604struct is_key_impl<key<T>> : std::true_type {};
3605template <
typename T>
3606concept is_key = is_key_impl<T>::value;
3609template <
template <
typename...>
typename Any,
typename Key,
typename... Args>
3611 using unique_constructor_t = std::function<Any<unique>(Args...)>;
3612 using shared_const_constructor_t = std::function<Any<shared>(Args...)>;
3613 using val_constructor_t = std::function<Any<val>(Args...)>;
3614 std::map<Key, unique_constructor_t> unique_factory_map_;
3615 std::map<Key, shared_const_constructor_t> shared_factory_map_;
3616 std::map<Key, val_constructor_t> val_factory_map_;
3618 template <is_proxy Proxy>
3619 auto register_impl(
auto& map, Key
key,
auto const& construct) {
3620 map[
key] = [construct](Args... args) -> Any<Proxy> {
3621 return Any<Proxy>{std::in_place, construct(std::forward<Args>(args)...)};
3625 template <is_proxy Proxy>
3626 auto construct_impl(
auto const& map, Key
key, Args... args) {
3627 if (
auto found = map.find(
key); found != map.end())
3628 return found->second(std::forward<Args>(args)...);
3629 if constexpr (std::same_as<Key, std::string>) {
3630 throw unkonwn_factory_key_error{
key};
3631 }
else if constexpr (is_key<Key>) {
3632 throw unkonwn_factory_key_error{
key.label};
3634 throw unkonwn_factory_key_error{std::to_string(
key)};
3639 auto register_(Key
const&
key,
auto const& construct) {
3640 register_impl<unique>(unique_factory_map_,
key, construct);
3641 register_impl<shared>(shared_factory_map_,
key, construct);
3642 register_impl<val>(val_factory_map_,
key, construct);
3645 template <is_proxy Proxy>
3646 auto construct(
auto key, Args&&... args) {
3647 if constexpr (std::same_as<Proxy, unique>) {
3648 return construct_impl<Proxy>(unique_factory_map_,
key,
3649 std::forward<Args>(args)...);
3650 }
else if constexpr (std::same_as<Proxy, shared>) {
3651 static_assert(std::same_as<Proxy, shared>);
3652 return construct_impl<Proxy>(shared_factory_map_,
key,
3653 std::forward<Args>(args)...);
3655 static_assert(std::same_as<Proxy, val>);
3656 return construct_impl<Proxy>(val_factory_map_,
key,
3657 std::forward<Args>(args)...);
3666template <
typename InObject>
3667std::size_t& members_count();
3669template <
typename InObject>
3670std::size_t& members_count() {
3671 static std::size_t count = 0;
3677template <
typename InObject>
3679 members() : table_(members_count<InObject>()) {}
3681 std::vector<any_value_t> table_;
3682 template <
typename Member,
typename Arg>
3683 void set(Member member, Arg&& arg) {
3684 using value_t =
typename Member::value_t;
3685 table_[member.index] =
3686 any_value_t{std::in_place_type<value_t>, std::forward<Arg>(arg)};
3688 template <
typename Member>
3689 typename Member::value_t
const* get(Member member)
const {
3690 const auto&
val = table_[member.index];
3691 if (!
val)
return {};
3692 return unchecked_unerase_cast<typename Member::value_t>(
val);
3694 template <
typename Member>
3695 typename Member::value_t* get(Member member) {
3696 auto&
val = table_[member.index];
3697 if (!
val)
return {};
3698 return unchecked_unerase_cast<typename Member::value_t>(
val);
3700 template <
typename Member>
3701 typename Member::value_t& operator[](Member member) {
3702 if (
auto val = get(member)) {
3705 using value_t =
typename Member::value_t;
3706 set(member, value_t());
3707 return *get(member);
3711template <
typename InObject,
typename ValueType>
3713 using object_t = InObject;
3714 using value_t = ValueType;
3715 std::size_t index = members_count<InObject>()++;
3722template <
typename AnyVTable>
3723std::size_t& dispatchs_count();
3726template <
typename AnyVTable>
3728 static std::size_t count = 0;
3737template <is_any Any>
3742template <
typename Arg>
3743struct translate_erased_function_param {
3746template <is_any Any>
3747struct translate_erased_function_param<virtual_<Any>> {
3748 using type =
typename Any::void_t;
3751template <
typename RET,
typename... Args>
3752struct translate_erased_function {
3753 using type = RET (*)(
typename translate_erased_function_param<Args>::type...);
3756template <std::size_t I,
typename First,
typename... Args>
3757auto arg_n(First first, Args... args) {
3758 if constexpr (I == 0) {
3761 return arg_n<I - 1>(std::forward<Args>(args)...);
3765template <std::size_t COUNT,
typename... Args>
3766constexpr std::size_t dispatch_dimension_count = COUNT;
3767template <std::size_t COUNT, is_any Any,
typename... Args>
3768constexpr std::size_t dispatch_dimension_count<COUNT, virtual_<Any>, Args...> =
3769 dispatch_dimension_count<COUNT + 1, Args...>;
3771template <
typename R,
typename... Classes>
3772struct ensure_function_ptr_from_functor_t {
3773 template <
typename FUNCTOR,
typename... Args>
3774 struct striped_virtuals {
3775 static R function(Classes&... classes, Args... args) {
3776 return FUNCTOR{}(classes..., args...);
3779 template <
typename FUNCTOR, is_any Any,
typename... Args>
3780 struct striped_virtuals<FUNCTOR, virtual_<Any>, Args...>
3781 : striped_virtuals<FUNCTOR, Args...> {};
3783 template <
typename... Args>
3784 static auto instance(
3788 using functor_t =
decltype(functor);
3789 if constexpr (std::is_pointer_v<functor_t>) {
3792 return striped_virtuals<functor_t, Args...>::function;
3797template <
typename... DispatchArgs>
3798struct args_to_tuple {
3799 template <
typename T,
typename... ActualArgs>
3800 auto operator()(T&& dispatch_args, ActualArgs&&... actual_args) {
3801 return std::tuple_cat(
3802 std::forward<T>(dispatch_args),
3803 std::make_tuple(std::forward<ActualArgs>(actual_args)...));
3806template <is_any Any,
typename... DispatchArgs>
3807struct args_to_tuple<virtual_<Any>, DispatchArgs...> {
3808 template <
typename T,
typename ACTUAL_ARG,
typename... ActualArgs>
3809 auto operator()(T&& dispatch_args, ACTUAL_ARG&& dispatch_arg,
3810 ActualArgs&&... actual_args) {
3811 return args_to_tuple<DispatchArgs...>{}(
3812 std::tuple_cat(std::forward<T>(dispatch_args),
3813 std::make_tuple(get_proxy_ptr(dispatch_arg))),
3814 std::forward<ActualArgs>(actual_args)...);
3818template <std::size_t FirstN,
typename... Ts>
3819auto get_tuple_head(std::tuple<Ts...> from) {
3820 return [&]<std::size_t... I>(std::index_sequence<I...>) {
3821 return std::make_tuple(std::get<I>(from)...);
3822 }(std::make_index_sequence<FirstN>{});
3824template <std::size_t FromN,
typename... Ts>
3825auto get_tuple_tail(std::tuple<Ts...> from) {
3826 return [&]<std::size_t... I>(std::index_sequence<I...>) {
3827 return std::make_tuple(std::get<I>(from)...);
3828 }(std::make_index_sequence<std::tuple_size_v<std::tuple<Ts...>> - FromN>{});
3831template <
typename R,
typename... FArgs>
3832struct dispatch_function;
3833template <
typename R,
typename... FArgs>
3834struct dispatch_function<R, std::tuple<FArgs...>> {
3835 using type = R (*)(FArgs...);
3838class no_default_function_error :
public error {
3842template <
typename R,
typename... OuterArgs>
3843struct dispatch_function_types {
3844 template <is_any... Anys>
3846 template <
typename... Args>
3847 struct implemenation {
3849 using function_t = hook<R(Anys
const&..., Args...)>;
3850 static auto function() {
3851 return []([[maybe_unused]]
auto super,
3852 [[maybe_unused]] Anys
const&... anys,
3853 [[maybe_unused]] Args... args) -> R {
3854 if constexpr (std::same_as<R, void>) {
3857 if constexpr (std::is_default_constructible_v<R>) {
3860 throw no_default_function_error(
"no default function");
3867 template <is_any Any,
typename... Args>
3868 struct implemenation<virtual_<Any>, Args...> : implemenation<Args...> {};
3869 template <
typename... Args>
3870 using type =
typename implemenation<Args...>::type;
3873 template <
typename... Args>
3875 template <is_any... Anys>
3876 using type = inner<Anys...>::template type<Args...>;
3878 template <is_any Any,
typename... Args>
3879 struct outer<virtual_<Any>, Args...> {
3880 template <is_any... Anys>
3881 using type = outer<Args...>::template type<Any, Anys...>;
3884 using default_type = outer<OuterArgs...>::template type<>;
3887template <
typename F,
typename... Args>
3888struct dispatch_matrix {
3891template <
typename DispatchMatrix, is_any Any,
typename... Args>
3892struct dispatch_matrix<DispatchMatrix, virtual_<Any>, Args...> {
3894 typename dispatch_matrix<std::vector<DispatchMatrix>, Args...>::type;
3903template <
typename R,
typename... Args>
3926template <
typename R,
typename... Args>
3929 using erased_function_t =
3930 typename translate_erased_function<R, Args...>::type;
3932 static constexpr std::size_t dimension_count =
3933 dispatch_dimension_count<0, Args...>;
3935 using dispatch_matrix_t = dispatch_matrix<erased_function_t, Args...>::type;
3936 dispatch_matrix_t dispatch_matrix_;
3938 using default_ =
typename dispatch_function_types<R, Args...>::default_type;
3939 default_::function_t dispatch_default_hook_;
3940 default_::function_t::connection default_connection_ =
3941 dispatch_default_hook_.insert(default_::function());
3943 enum class kind { single, multiple };
3944 template <kind Kind, std::size_t Dimension,
typename... DispatchArgs>
3945 struct dispatch_access;
3947 template <
typename... DispatchArgs>
3948 struct dispatch_access<kind::multiple, dimension_count, DispatchArgs...> {
3949 auto define(
auto fp,
auto& matrix) {
3950 matrix =
reinterpret_cast<erased_function_t
>(fp);
3953 template <
typename F,
typename ArgsTuple>
3954 std::optional<R> invoke(F
const& target, ArgsTuple&& dispatch_args_tuple,
3956 if (!target)
return {};
3957 auto typed_target =
reinterpret_cast<
3958 typename dispatch_function<R, std::decay_t<ArgsTuple>
>::type>(target);
3959 return std::apply(typed_target,
3960 std::forward<ArgsTuple>(dispatch_args_tuple));
3964 template <std::size_t Dimension, is_any Any,
typename... DispatchArgs>
3965 struct dispatch_access<kind::multiple, Dimension,
virtual_<Any>,
3967 : dispatch_access<kind::multiple, Dimension + 1, DispatchArgs...> {
3968 using interface_t = Any;
3969 using v_table_t =
typename interface_t::v_table_t;
3971 dispatch_access<kind::multiple, Dimension + 1, DispatchArgs...>;
3975 std::size_t dispatch_dimension_size_ = 1;
3977 template <
typename Class>
3978 std::size_t get_dispatch_index() {
3979 if constexpr (std::same_as<Any, Class>) {
3982 auto dispatch_table = dispatch_table_instance<v_table_t, Class>();
3983 if (
auto index = get_multi_dispatch_index_at(dispatch_table, index_))
3986 set_multi_dispatch_index_at(dispatch_table, index_,
3987 dispatch_dimension_size_);
3988 return dispatch_dimension_size_++;
3992 template <
typename Class,
typename... Classes>
3993 auto define(
auto fp,
auto& matrix) {
3994 auto dispatch_index = get_dispatch_index<Class>();
3995 if (matrix.size() <= dispatch_index) matrix.resize(dispatch_index + 1);
3996 return next_t::template
define<Classes...>(fp, matrix[dispatch_index]);
3999 template <
typename DispatchMatrix,
typename ArgsTuple,
4000 typename... ActualArgs>
4001 std::optional<R> invoke(DispatchMatrix
const& target,
4002 ArgsTuple&& dispatch_args_tuple, Any
const&
any,
4003 ActualArgs&&... actual_args)
const {
4004 auto dispatch_table = get_v_table(
any)->dispatch_table;
4005 auto dispatch_dim = get_multi_dispatch_index_at(dispatch_table, index_);
4006 if (dispatch_dim && target.size() > dispatch_dim)
4008 next_t::invoke(target[dispatch_dim],
4009 std::forward<ArgsTuple>(dispatch_args_tuple),
4010 std::forward<ActualArgs>(actual_args)...))
4014 return next_t::invoke(
4016 std::tuple_cat(get_tuple_head<Dimension>(dispatch_args_tuple),
4017 std::make_tuple(&
any),
4018 get_tuple_tail<Dimension + 1>(dispatch_args_tuple)),
4019 std::forward<ActualArgs>(actual_args)...);
4024 template <is_any Any,
typename... AccessArgs>
4025 struct dispatch_access<kind::single, 0,
virtual_<Any>, AccessArgs...> {
4026 using interface_t = Any;
4027 using v_table_t =
typename interface_t::v_table_t;
4030 template <
typename CLASS>
4031 auto define(
auto fp,
auto&) {
4032 auto v_table = dispatch_table_instance<v_table_t, CLASS>();
4033 insert_function(v_table, index_, fp);
4037 template <
typename... Other>
4038 R invoke(default_::function_t
const& default_, Any
const&
any,
4039 Other&&... other)
const {
4040 auto v_table = get_v_table(
any)->dispatch_table;
4041 auto target = get_function(v_table, index_);
4043 return std::invoke(default_,
any, std::forward<Other>(other)...);
4044 auto erased_function =
reinterpret_cast<erased_function_t
>(target);
4045 return std::invoke(erased_function, get_proxy_ptr(
any),
4046 std::forward<Other>(other)...);
4050 static const constexpr kind dispatch_kind =
4051 (dimension_count > 1) ? kind::multiple : kind::single;
4052 dispatch_access<dispatch_kind, 0, Args...> dispatch_access_;
4061 template <
typename... Classes>
4063 auto fp = ensure_function_ptr_from_functor_t<
4064 R, Classes...>::template instance<Args...>(f);
4065 return dispatch_access_.template
define<Classes...>(fp, dispatch_matrix_);
4074 template <
typename... ActualArgs>
4076 if constexpr (dispatch_kind == kind::multiple) {
4077 auto dispatch_args_tuple = args_to_tuple<Args...>{}(
4078 std::tuple<>{}, std::forward<ActualArgs>(actual_args)...);
4079 return *dispatch_access_
4080 .invoke(dispatch_matrix_, dispatch_args_tuple,
4081 std::forward<ActualArgs>(actual_args)...)
4082 .or_else([&]() -> std::optional<R> {
4084 dispatch_default_hook_,
4085 std::forward<ActualArgs>(actual_args)...);
4088 return dispatch_access_.invoke(dispatch_default_hook_,
4089 std::forward<ActualArgs>(actual_args)...);
4092 auto& get_dispatch_default_hook() {
return dispatch_default_hook_; };
4095template <
size_t At,
typename Tuple,
size_t... Is>
4096auto make_tuple_from_elements(Tuple&& tuple, std::index_sequence<Is...>) {
4097 return std::forward_as_tuple(
4098 std::get<Is + At>(std::forward<Tuple>(tuple))...);
4100template <
size_t At,
size_t N,
typename Tuple>
4101auto make_tuple_from_elements_at(Tuple&& tuple) {
4102 return make_tuple_from_elements<At>(std::forward<Tuple>(tuple),
4103 std::make_index_sequence<N>{});
4106template <
typename Vany,
typename DynamicDispatch, auto StaticDispatch>
4107class dispatch_vany {
4108 DynamicDispatch dynamic_dispatch_;
4109 constexpr static const std::size_t dimension_count =
4110 DynamicDispatch::dimension_count;
4112 template <
typename Vany1,
typename... Args>
4113 auto invoke1(Vany1&& vany, Args&&... args)
const {
4115 [&]<
typename TypedArg>([[maybe_unused]] TypedArg&& arg) {
4118 [&]<is_any Any,
typename... Vargs>(Any&& any, Vargs&&... vargs) {
4119 return dynamic_dispatch_(std::forward<Any>(any),
4120 std::forward<Vargs>(vargs)...);
4121 }}(std::forward<TypedArg>(arg), std::forward<Args>(args)...);
4123 get_proxy_value(std::forward<Vany1>(vany)));
4126 template <is_any Vany1, is_any Vany2,
typename... Args>
4127 auto invoke2(Vany1&& vany1, Vany2&& vany2, Args&&... args)
const {
4128 using vany1_t = std::decay_t<Vany1>;
4129 using vany2_t = std::decay_t<Vany2>;
4130 using cv1_t = anyxx::vany_type_trait<vany1_t>::concrete_variant;
4131 using any_v1 = anyxx::vany_type_trait<vany1_t>::any_in_variant;
4132 using cv2_t = anyxx::vany_type_trait<vany2_t>::concrete_variant;
4133 using any_v2 = anyxx::vany_type_trait<vany2_t>::any_in_variant;
4135 auto dispatch_combined = [&]<
typename DA1,
typename DA2>(DA1&& da1,
4137 auto dyn_case1 = [&]<is_any A1, is_any A2,
typename... VAs>(
4138 A1&& a1, A2&& a2, VAs&&... vas) {
4139 return dynamic_dispatch_(std::forward<A1>(a1), std::forward<A2>(a2),
4140 std::forward<VAs>(vas)...);
4142 auto dyn_case2 = [&]<is_any A1,
typename A2,
typename... VAs>(
4143 A1&& a1, A2 a2, VAs&&... vas)
4144 requires std::constructible_from<cv2_t, A2>
4146 return dynamic_dispatch_(std::forward<A1>(a1),
4147 any_v2{std::in_place, cv2_t{std::move(a2)}},
4148 std::forward<VAs>(vas)...);
4150 auto dyn_case3 = [&]<
typename A1, is_any A2,
typename... VAs>(
4151 A1 a1, A2&& a2, VAs&&... vas)
4152 requires std::constructible_from<cv1_t, A1>
4154 return dynamic_dispatch_(any_v1{std::in_place, cv1_t{std::move(a1)}},
4155 std::forward<A2>(a2),
4156 std::forward<VAs>(vas)...);
4158 auto dyn_case4 = [&]<
typename A1,
typename A2,
typename... VAs>(
4159 A1 a1, A2 a2, VAs&&... vas)
4160 requires(std::constructible_from<cv1_t, A1> &&
4161 std::constructible_from<cv2_t, A2>)
4163 return dynamic_dispatch_(any_v1{std::in_place, cv1_t{std::move(a1)}},
4164 any_v2{std::in_place, cv2_t{std::move(a2)}},
4165 std::forward<VAs>(vas)...);
4167 return overloads{StaticDispatch, dyn_case1, dyn_case2, dyn_case3,
4168 dyn_case4}(std::forward<DA1>(da1),
4169 std::forward<DA2>(da2),
4170 std::forward<Args>(args)...);
4173 return std::visit(dispatch_combined,
4174 get_proxy_value(std::forward<Vany1>(vany1)),
4175 get_proxy_value(std::forward<Vany2>(vany2)));
4179 template <
typename... Classes>
4180 auto define(
auto f) {
4181 return dynamic_dispatch_.template define<Classes...>(f);
4184 template <
typename... Args>
4185 auto operator()(Args&&... args)
const {
4186 if constexpr (dimension_count == 1) {
4187 return invoke1(std::forward<Args>(args)...);
4189 if constexpr (dimension_count == 2) {
4190 return invoke2(std::forward<Args>(args)...);
4192 static_assert(dimension_count <= 2,
4193 "dispatch_vany only supports one and two dimensions");
4200#define ANY_MERGE_(a, b) a##b
4201#define ANY_LABEL_(a) ANY_MERGE_(unique_name_, a)
4202#define ANY_UNIQUE_NAME_ ANY_LABEL_(__COUNTER__)
4203#define ANY_UNIQUE_NAME ANY_UNIQUE_NAME_
4204#define __ ANY_UNIQUE_NAME_
4224#define ANY_SINGLETON_DECLARE(export_, name, ...) \
4225 using name##_t = __VA_ARGS__; \
4226 export_ extern name##_t& get_##name(); \
4227 static inline name##_t& name = get_##name();
4235#define ANY_SINGLETON(namespace_, name, ...) \
4236 namespace_::name##_t& namespace_::get_##name() { \
4237 static name##_t singleton_{__VA_ARGS__}; \
4238 return singleton_; \
4256#define VANY_DISPACH_DECLARE(export_, name, vany, signature, static_dispatch) \
4257 constexpr static inline auto name##_static_dispatch = \
4258 anyxx::overloads{_detail_REMOVE_PARENS(static_dispatch)}; \
4260 using name##_vany = vany; \
4261 using name##_dynamic_dispatch = \
4262 anyxx::dispatch<_detail_REMOVE_PARENS(signature)>; \
4264 ANY_SINGLETON_DECLARE( \
4266 anyxx::dispatch_vany<name##_vany, name##_dynamic_dispatch, \
4267 name##_static_dispatch>)
4274#define VANY_DISPACH(namespace_, name) ANY_SINGLETON(namespace_, name);
4279#define ANY_META_CLASS_FWD(export_, ...) \
4281 export_ anyxx::meta_data& anyxx::get_meta_data<__VA_ARGS__>();
4283#define ANY_META_CLASS(...) \
4285 anyxx::meta_data& anyxx::get_meta_data<std::decay_t<__VA_ARGS__>>() { \
4286 return runtime_implementation<__VA_ARGS__>(); \
4301#define ANY_META_CLASS_FWD(...)
4306#define ANY_META_CLASS(...)
4310#define ANY_META_CLASS_STATIC(...) \
4311 ANY_META_CLASS_FWD(, __VA_ARGS__) \
4312 ANY_META_CLASS(__VA_ARGS__)
4323#define ANY_REGISTER_MODEL(class_, interface_, ...) \
4325 static auto __ = anyxx::bind_v_table_to_meta_data< \
4326 interface_##_v_table _detail_ANYXX_OPTIONAL_TEMPLATE_ARGS(__VA_ARGS__), \
4327 ANYXX_UNPAREN(class_)>(); \
4334#define ANY_MEMBERS_COUNT_FWD(export_, ns_, c_) \
4340 export_ std::size_t& members_count<ns_::c_>(); \
4343#define ANY_MEMBERS_COUNT_IMPL(ns_, c_) \
4345 std::size_t& anyxx::members_count<ns_::c_>() { \
4346 static std::size_t count = 0; \
4350#define ANY_MEMBER_FWD(export_, object_, member_, type_) \
4351 export_ anyxx::member<object_, type_>& _inintialize_##member_(); \
4352 inline const anyxx::member<object_, type_>& member_ = \
4353 _inintialize_##member_();
4355#define ANY_MEMBER_IMPL(ns_, object_, member_, type_) \
4356 anyxx::member<object_, type_>& ns_::_inintialize_##member_() { \
4357 static anyxx::member<object_, type_> instance; \
4363#define ANY_MEMBERS_COUNT_FWD(...)
4364#define ANY_MEMBERS_COUNT_IMPL(...)
4365#define ANY_MEMBER_FWD(...)
4366#define ANY_MEMBER_IMPL(...)
4372#define ANY_DISPATCH_COUNT_FWD(export_, ns_, any_) \
4376 export_ std::size_t& dispatchs_count<ns_::any_##_v_table>(); \
4379#define ANY_DISPATCH_COUNT(ns_, any_) \
4381 std::size_t& anyxx::dispatchs_count<ns_::any_##_v_table>() { \
4382 static std::size_t count = 0; \
4386#define ANY_DISPATCH_FOR_FWD(export_, class_, interface_namespace_, \
4390 export_ dispatch_table_t* dispatch_table_instance< \
4391 interface_namespace_::interface_##_v_table, class_>(); \
4394#define ANY_DISPATCH_FOR(class_, interface_namespace_, interface_) \
4396 anyxx::dispatch_table_t* anyxx::dispatch_table_instance< \
4397 interface_namespace_::interface_##_v_table, class_>() { \
4398 return dispatch_table_instance_implementation< \
4399 interface_namespace_::interface_##_v_table, class_>(); \
4428#define ANY_DISPATCH_COUNT_FWD(...)
4434#define ANY_DISPATCH_COUNT(...)
4442#define ANY_DISPATCH_FOR_FWD(...)
4449#define ANY_DISPATCH_FOR(...)
any< using_< Type >, Trait > use_as
Definition anyxx.hpp:3132
Any< using_< vany_variant< Any, Proxy, Types... > > > make_vany
A factory type to direct get the any for the vany.
Definition anyxx.hpp:1784
any< trait_class< Type >, Trait > any_trait_class
Definition anyxx.hpp:3163
any< using_< Type >, Trait< Ts... > > use_as_
Definition anyxx.hpp:3137
auto trait_as(T &&v)
Definition anyxx.hpp:3143
std::size_t & dispatchs_count()
A counter for dispatch tables per v-table type.
Definition anyxx.hpp:3727
The core class template to control dispatch for external polymorphism.
Definition anyxx.hpp:2806
any(std::in_place_type_t< T >, Args &&... args)
Definition anyxx.hpp:2872
any(std::in_place_t, V &&v)
Definition anyxx.hpp:2860
auto define(auto f)
Register a dispatch target for the model provided in the type parameter.
Definition anyxx.hpp:4062
auto operator()(ActualArgs &&... actual_args) const
Invoke the dispatch.
Definition anyxx.hpp:4075
Open dispatch method. Solves the expression problem. See dispatch<R(Args...)> for details.
Definition anyxx.hpp:3904
A class template to implement a factory for any objects.
Definition anyxx.hpp:3610
A class template to implement a hook/callback chain.
Definition anyxx.hpp:3514
Requirements for a trait type.
Definition anyxx.hpp:1535
Requirements for a dynamic (i.e., type-erased) Proxy.
Definition anyxx.hpp:1543
Requirements for a proxy type.
Definition anyxx.hpp:1491
std::optional< To > downcast_to(From from)
Safe downcast to a derived trait using runtime information from the v-Tables.
Definition anyxx.hpp:3074
auto lock(FromAny const &from_interface)
Lock a shared any.
Definition anyxx.hpp:3490
#define ANY_MODEL_MAP(model_, trait_)
ANY_MODEL_MAP macro.
Definition anyxx.hpp:1192
#define TRAIT_TYPE(Name, T, Trait,...)
translates to the type defined in the model map of a trait. This is useful for associated types,...
Definition anyxx.hpp:1182
observer< const_void > cref
Definition anyxx.hpp:1863
std::shared_ptr< void const > shared
Definition anyxx.hpp:2033
observer< mutable_void > mutref
Definition anyxx.hpp:1867
std::weak_ptr< void const > weak
Definition anyxx.hpp:2037
std::variant< Any< Proxy >, Types... > vany_variant
Definition anyxx.hpp:1780
#define ANY_TYPE(...)
Dependent type definition in a TRAIT. This is useful for defining associated types,...
Definition anyxx.hpp:1146
#define TRAIT_EX(n,...)
TRAIT with decoration.
Definition anyxx.hpp:782
Basic lifetime functionality.
Definition anyxx.hpp:1368
any_v_table(std::in_place_type_t< Concrete > concrete)
Type-erasing constructor.
Definition anyxx.hpp:1374
A key type for factory registration.
Definition anyxx.hpp:3597
observeable_rtti_v_table(std::in_place_type_t< Concrete > concrete)
Type-erasing constructor.
Definition anyxx.hpp:1335
Definition anyxx.hpp:1316
observeable_v_table(std::in_place_type_t< Concrete > concrete)
Type-erasing constructor.
Definition anyxx.hpp:1321
Definition anyxx.hpp:3153
Use this type to indicate, that the ANY_TYPE must be specified in the model map.
Definition anyxx.hpp:1309
Definition anyxx.hpp:1947
Definition anyxx.hpp:3116
any< using_< Value >, Trait > as
Definition anyxx.hpp:3126
A tag to indicate that the corresponding function parameter is an any used for dispatch.
Definition anyxx.hpp:3738
Proxy to manage the captured object as value with small object optimization.
Definition anyxx.hpp:2189