33
44#include < type_traits>
55
6+
7+ // Utilities
68namespace archetype {
9+
710class Base {
811public:
912 virtual ~Base () {};
@@ -28,6 +31,11 @@ template <class C> class helper {
2831template <class BASE > class identity : public BASE {};
2932} // namespace archetype
3033
34+
35+ // API
36+ #define DEFINE_METHOD (ret, name, ...) \
37+ (UNIQUE_NAME(name), ret, name, __VA_ARGS__)
38+
3139#define DEFINE_ARCHETYPE (NAME, METHODS ) \
3240 struct NAME { \
3341 NAME () = delete ; \
@@ -132,7 +140,10 @@ template <class BASE> class identity : public BASE {};
132140 }; \
133141 };
134142
135- #define EXPAND_ARCHETYPE_METHODS (METHODS ) EXPAND_ARCHETYPE_METHODS_IMPL METHODS
143+
144+ // High level expansions
145+ #define EXPAND_ARCHETYPE_METHODS (METHODS ) \
146+ EXPAND_ARCHETYPE_METHODS_IMPL METHODS
136147
137148#define EXPAND_ARCHETYPE_METHODS_IMPL (...) \
138149 FOR_EACH (ARCHETYPE_METHOD, __VA_ARGS__)
@@ -143,46 +154,60 @@ template <class BASE> class identity : public BASE {};
143154#define EXPAND_CALLSTUB_ASSIGNMENTS_IMPL (...) \
144155 FOR_EACH (CALLSTUB_ASSIGNMENT, __VA_ARGS__)
145156
146- #define EXPAND_CALLSTUB_MEMBERS (METHODS ) EXPAND_CALLSTUB_MEMBERS_IMPL METHODS
147-
148- #define EXPAND_CALLSTUB_MEMBERS_IMPL (...) FOR_EACH(CALLSTUB_MEMBER, __VA_ARGS__)
157+ #define EXPAND_CALLSTUB_MEMBERS (METHODS ) \
158+ EXPAND_CALLSTUB_MEMBERS_IMPL METHODS
149159
150- #define EXPAND_CONCEPT_REQUIREMENTS (METHODS ) \
151- EXPAND_CONCEPT_REQUIREMENTS_IMPL METHODS
152-
153- #define EXPAND_CONCEPT_REQUIREMENTS_IMPL (...) \
154- FOR_EACH (CONCEPT_REQUIREMENT, __VA_ARGS__)
160+ #define EXPAND_CALLSTUB_MEMBERS_IMPL (...) \
161+ FOR_EACH (CALLSTUB_MEMBER, __VA_ARGS__)
155162
156163#define EXPAND_ARCHETYPE_REQUIREMENTS (METHODS ) \
157164 EXPAND_ARCHETYPE_REQUIREMENTS_IMPL METHODS
158165
159166#define EXPAND_ARCHETYPE_REQUIREMENTS_IMPL (...) \
160167 FOR_EACH_SEP (ARCHETYPE_REQUIREMENT, __VA_ARGS__)
161168
162- #define EXPAND_CONCEPT_ASSERTIONS (METHODS ) \
163- EXPAND_CONCEPT_ASSERTIONS_IMPL METHODS
169+ #define EXPAND_COMPONENT_INHERITANCE (...) \
170+ EXPAND_COMPONENT_INHERITANCE_IMPL ( \
171+ FOR_EACH_SEP_CALL (APPLY_HELPER, __VA_ARGS__))
164172
165- #define EXPAND_CONCEPT_ASSERTIONS_IMPL (...) \
166- FOR_EACH (CONCEPT_ASSERTION, __VA_ARGS__)
173+ #define EXPAND_COMPONENT_INHERITANCE_IMPL (...) \
174+ TEMPLATE_CHAIN (__VA_ARGS__ COMMA_IF_ARGS ( __VA_ARGS__) B )
167175
168- #define EXPAND_COMPONENT_ASSERTIONS (...) FOR_EACH_CALL(DO_ASSERT, __VA_ARGS__)
176+ #define EXPAND_COMPONENT_REQUIREMENTS (...) \
177+ FOR_EACH_SEPX_CALL (APPEND_CHECK, &&, __VA_ARGS__)
169178
170- #define APPEND_BASE (x ) x::component
171179
172- #define APPEND_CHECK (x ) x::check<T>::value
180+ // Low level expressions
181+ #define ARCHETYPE_METHOD (unique_name, ret, name, ...) \
182+ public: \
183+ ret name (TYPED_ARGS(M_NARGS(__VA_ARGS__), __VA_ARGS__)) { \
184+ return _##unique_name##_stub (_obj COMMA_IF_ARGS (__VA_ARGS__) ARG_NAMES ( \
185+ M_NARGS (__VA_ARGS__), __VA_ARGS__)); \
186+ }
173187
174- #define APPLY_HELPER (x ) archetype::helper<x>::get
188+ #define CALLSTUB_ASSIGNMENT (unique_name, ret, name, ...) \
189+ _##unique_name##_stub = [](void *obj COMMA_IF_ARGS (__VA_ARGS__) TYPED_ARGS( \
190+ M_NARGS (__VA_ARGS__), __VA_ARGS__)) -> ret { \
191+ return static_cast <T *>(obj)->name ( \
192+ ARG_NAMES (M_NARGS (__VA_ARGS__), __VA_ARGS__)); \
193+ };
175194
176- #define EXPAND_COMPONENT_INHERITANCE_IMPL (...) \
177- TEMPLATE_CHAIN (__VA_ARGS__ COMMA_IF_ARGS (__VA_ARGS__) B)
195+ #define CALLSTUB_MEMBER (unique_name, ret, name, ...) \
196+ ret (*_##unique_name##_stub)(void *obj COMMA_IF_ARGS (__VA_ARGS__) \
197+ __VA_ARGS__);
178198
179- #define EXPAND_COMPONENT_INHERITANCE (...) \
180- EXPAND_COMPONENT_INHERITANCE_IMPL ( \
181- FOR_EACH_SEP_CALL (APPLY_HELPER, __VA_ARGS__))
199+ #define UNIQUE_NAME (base ) CAT(CAT(CAT(CAT(base, _), __LINE__), _), __COUNTER__)
182200
183- #define EXPAND_COMPONENT_REQUIREMENTS (...) \
184- FOR_EACH_SEPX_CALL (APPEND_CHECK, &&, __VA_ARGS__)
185201
202+ #define ARCHETYPE_REQUIREMENT (unique_name, ret, name, ...) \
203+ static_cast <ret (T::*)(TYPED_ARGS(M_NARGS(__VA_ARGS__), __VA_ARGS__))>( \
204+ &T::name)
205+
206+ #define APPEND_CHECK (x ) x::check<T>::value
207+ #define APPLY_HELPER (x ) archetype::helper<x>::get
208+
209+
210+ // Macro PP utilities
186211#define EXPAND (x ) x
187212#define EXPAND2 (x ) EXPAND(EXPAND(x))
188213
@@ -394,52 +419,7 @@ template <class BASE> class identity : public BASE {};
394419#define TEMPLATE_CHAIN_10 (t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 ) \
395420 t0<t1<t2<t3<t4<t5<t6<t7<t8<t9>>>>>>>>>
396421
397- // Extend as needed...
398422
399423#define ARG_NAMES (count, ...) CAT(ARG_NAMES_, count)(__VA_ARGS__)
400424
401- #define ARCHETYPE_METHOD (unique_name, ret, name, ...) \
402- public: \
403- ret name (TYPED_ARGS(M_NARGS(__VA_ARGS__), __VA_ARGS__)) { \
404- return _##unique_name##_stub (_obj COMMA_IF_ARGS (__VA_ARGS__) ARG_NAMES ( \
405- M_NARGS (__VA_ARGS__), __VA_ARGS__)); \
406- }
407-
408- #define CALLSTUB_ASSIGNMENT (unique_name, ret, name, ...) \
409- _##unique_name##_stub = [](void *obj COMMA_IF_ARGS (__VA_ARGS__) TYPED_ARGS( \
410- M_NARGS (__VA_ARGS__), __VA_ARGS__)) -> ret { \
411- return static_cast <T *>(obj)->name ( \
412- ARG_NAMES (M_NARGS (__VA_ARGS__), __VA_ARGS__)); \
413- };
414-
415- // uses comma swallowing trick
416- #define CALLSTUB_MEMBER (unique_name, ret, name, ...) \
417- ret (*_##unique_name##_stub)(void *obj COMMA_IF_ARGS (__VA_ARGS__) \
418- __VA_ARGS__);
419-
420- #define CONCEPT_REQUIREMENT (unique_name, ret, name, ...) \
421- template <typename , typename = void > \
422- struct CAT (has_, unique_name) : std::false_type {}; \
423- template <typename T> \
424- struct CAT (has_, unique_name)< \
425- T, archetype::void_t<decltype(static_cast <ret (T::*)(TYPED_ARGS( \
426- M_NARGS (__VA_ARGS__), __VA_ARGS__))>( \
427- &T::name))>> : std::true_type {};
428-
429- #define CONCEPT_ASSERTION (unique_name, ret, name, ...) \
430- static_assert ( \
431- has_##unique_name<T>::value, \
432- STRINGIFY (T must have a method FUNC_SIGNATURE (ret, name, __VA_ARGS__)));
433-
434- #define DO_ASSERT (x ) x::assert <T>();
435-
436- #define UNIQUE_NAME (base ) CAT(CAT(CAT(CAT(base, _), __LINE__), _), __COUNTER__)
437-
438- #define DEFINE_METHOD (ret, name, ...) \
439- (UNIQUE_NAME(name), ret, name, __VA_ARGS__)
440-
441- #define ARCHETYPE_REQUIREMENT (unique_name, ret, name, ...) \
442- static_cast <ret (T::*)(TYPED_ARGS(M_NARGS(__VA_ARGS__), __VA_ARGS__))>( \
443- &T::name)
444-
445425#endif // __ARCHETYPE_H__
0 commit comments