Gorgon Game Engine
Struct.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <typeinfo>
4 #include "TMP.h"
5 
6 namespace Gorgon {
7 
8  template <int N, class ...T_>
9  struct GetElm {
10  };
11 
12  template <class T1_, class ...T_>
13  struct GetElm<0, T1_, T_...> {
14  template <T1_ V1_, T_ ...V_>
15  struct Inner {
16  static constexpr T1_ Value = V1_;
17  };
18  };
19 
20  template <int N, class T1_, class ...T_>
21  struct GetElm<N, T1_, T_...> {
22  template <T1_ V1_, T_ ...V_>
23  struct Inner {
24  static constexpr auto Value = GetElm<N-1, T_...>::template Inner<V_...>::Value;
25  };
26  };
27 
28 
29  template<class C_, class ...MT_>
30  class StructDefiner {
31  public:
32  template<MT_ ...M_>
33  struct Inner {
34 
35  template<class ...S_>
36  constexpr Inner(const S_ &...names) : Names{names...} {
37  static_assert(sizeof...(S_) == sizeof...(MT_), "Number of element names does not match with the number of elements");
38  }
39 
40  template<int N>
41  struct Member {
42  using Type = typename TMP::RemoveRValueReference<decltype(std::declval<C_>().*(GetElm<N, MT_...>::template Inner<M_...>::Value))>::Type;
43 
44  static constexpr decltype(GetElm<N, MT_...>::template Inner<M_...>::Value)
46  return std::get<N>(std::tuple<MT_...>(M_...));
47  }
48  };
49 
50  const char *Names[sizeof...(MT_)];
51 
52  static constexpr int MemberCount = sizeof...(MT_);
53 
54  static constexpr int IsGorgonReflection = true;
55  };
56  };
57 
58 
59 #ifdef _MSC_VER
60  #define CALLER(F, P) CALL_(F, P)
61  #define CALL_(F, P) F##P
62 
63  #define CONC(A, B) CONC_(A, B)
64  #define CONC_(A, B) CONC__(A, B)
65  #define CONC__(A, B) CONC___(A, B)
66  #define CONC___(A, B) CONC____(A, B)
67  #define CONC____(A, B) CONC_____(A, B)
68  #define CONC_____(A, B) CONC______(A, B)
69  #define CONC______(A, B) A##B
70 
71  #define NARGS(...) CALL_(NARGS_,(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
72  #define NARGS_(_16, _15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
73 
74 
75  #define StructDefiner_types_1(C, E) decltype(&C::E)
76  #define StructDefiner_types_2(C, E, F) decltype(&C::E), StructDefiner_types_1 (C, F)
77  #define StructDefiner_types_3(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_2 , (C, __VA_ARGS__))
78  #define StructDefiner_types_4(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_3 , (C, __VA_ARGS__))
79  #define StructDefiner_types_5(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_4 , (C, __VA_ARGS__))
80  #define StructDefiner_types_6(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_5 , (C, __VA_ARGS__))
81  #define StructDefiner_types_7(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_6 , (C, __VA_ARGS__))
82  #define StructDefiner_types_8(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_7 , (C, __VA_ARGS__))
83  #define StructDefiner_types_9(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_8 , (C, __VA_ARGS__))
84  #define StructDefiner_types_10(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_9 , (C, __VA_ARGS__))
85  #define StructDefiner_types_11(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_10, (C, __VA_ARGS__))
86  #define StructDefiner_types_12(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_11, (C, __VA_ARGS__))
87  #define StructDefiner_types_13(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_12, (C, __VA_ARGS__))
88  #define StructDefiner_types_14(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_13, (C, __VA_ARGS__))
89  #define StructDefiner_types_15(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_14, (C, __VA_ARGS__))
90  #define StructDefiner_types_16(C, E, ...) decltype(&C::E), CALL_(StructDefiner_types_15, (C, __VA_ARGS__))
91 
92  #define StructDefiner_values_1(C, E) &C::E
93  #define StructDefiner_values_2(C, E, F) &C::E, StructDefiner_values_1 (C, F)
94  #define StructDefiner_values_3(C, E, ...) &C::E, CALL_(StructDefiner_values_2 , (C, __VA_ARGS__))
95  #define StructDefiner_values_4(C, E, ...) &C::E, CALL_(StructDefiner_values_3 , (C, __VA_ARGS__))
96  #define StructDefiner_values_5(C, E, ...) &C::E, CALL_(StructDefiner_values_4 , (C, __VA_ARGS__))
97  #define StructDefiner_values_6(C, E, ...) &C::E, CALL_(StructDefiner_values_5 , (C, __VA_ARGS__))
98  #define StructDefiner_values_7(C, E, ...) &C::E, CALL_(StructDefiner_values_6 , (C, __VA_ARGS__))
99  #define StructDefiner_values_8(C, E, ...) &C::E, CALL_(StructDefiner_values_7 , (C, __VA_ARGS__))
100  #define StructDefiner_values_9(C, E, ...) &C::E, CALL_(StructDefiner_values_8 , (C, __VA_ARGS__))
101  #define StructDefiner_values_10(C, E, ...) &C::E, CALL_(StructDefiner_values_9 , (C, __VA_ARGS__))
102  #define StructDefiner_values_11(C, E, ...) &C::E, CALL_(StructDefiner_values_10, (C, __VA_ARGS__))
103  #define StructDefiner_values_12(C, E, ...) &C::E, CALL_(StructDefiner_values_11, (C, __VA_ARGS__))
104  #define StructDefiner_values_13(C, E, ...) &C::E, CALL_(StructDefiner_values_12, (C, __VA_ARGS__))
105  #define StructDefiner_values_14(C, E, ...) &C::E, CALL_(StructDefiner_values_13, (C, __VA_ARGS__))
106  #define StructDefiner_values_15(C, E, ...) &C::E, CALL_(StructDefiner_values_14, (C, __VA_ARGS__))
107  #define StructDefiner_values_16(C, E, ...) &C::E, CALL_(StructDefiner_values_15, (C, __VA_ARGS__))
108 
109  #define StructDefiner_names_1(C, E) #E
110  #define StructDefiner_names_2(C, E, F) #E, StructDefiner_names_1 (C, F)
111  #define StructDefiner_names_3(C, E, ...) #E, CALL_(StructDefiner_names_2 , (C, __VA_ARGS__))
112  #define StructDefiner_names_4(C, E, ...) #E, CALL_(StructDefiner_names_3 , (C, __VA_ARGS__))
113  #define StructDefiner_names_5(C, E, ...) #E, CALL_(StructDefiner_names_4 , (C, __VA_ARGS__))
114  #define StructDefiner_names_6(C, E, ...) #E, CALL_(StructDefiner_names_5 , (C, __VA_ARGS__))
115  #define StructDefiner_names_7(C, E, ...) #E, CALL_(StructDefiner_names_6 , (C, __VA_ARGS__))
116  #define StructDefiner_names_8(C, E, ...) #E, CALL_(StructDefiner_names_7 , (C, __VA_ARGS__))
117  #define StructDefiner_names_9(C, E, ...) #E, CALL_(StructDefiner_names_8 , (C, __VA_ARGS__))
118  #define StructDefiner_names_10(C, E, ...) #E, CALL_(StructDefiner_names_9 , (C, __VA_ARGS__))
119  #define StructDefiner_names_11(C, E, ...) #E, CALL_(StructDefiner_names_10, (C, __VA_ARGS__))
120  #define StructDefiner_names_12(C, E, ...) #E, CALL_(StructDefiner_names_11, (C, __VA_ARGS__))
121  #define StructDefiner_names_13(C, E, ...) #E, CALL_(StructDefiner_names_12, (C, __VA_ARGS__))
122  #define StructDefiner_names_14(C, E, ...) #E, CALL_(StructDefiner_names_13, (C, __VA_ARGS__))
123  #define StructDefiner_names_15(C, E, ...) #E, CALL_(StructDefiner_names_14, (C, __VA_ARGS__))
124  #define StructDefiner_names_16(C, E, ...) #E, CALL_(StructDefiner_names_15, (C, __VA_ARGS__))
125 
130  #define DefineStructMembers(C, ...) \
131  using ReflectionType = StructDefiner<C, CALLER(CALL_(CONC, (StructDefiner_types_, CONC(NARGS,(__VA_ARGS__))) ),(C, __VA_ARGS__))>::\
132  Inner<CALLER(CALL_(CONC, (StructDefiner_values_, CONC(NARGS,(__VA_ARGS__))) ),(C, __VA_ARGS__))>; \
133  static constexpr ReflectionType Reflection() { return {CALLER(CALL_(CONC, (StructDefiner_names_, CONC(NARGS,(__VA_ARGS__))) ),(C, __VA_ARGS__))}; }
134 
135 
141  #define DefineStructMembersWithName(C, Name, ...) \
142  using Name##Type = StructDefiner<C, CALLER(CALL_(CONC, (StructDefiner_types_, CONC(NARGS,(__VA_ARGS__))) ),(C, __VA_ARGS__))>::\
143  Inner<CALLER(CALL_(CONC, (StructDefiner_values_, CONC(NARGS,(__VA_ARGS__))) ),(C, __VA_ARGS__))>; \
144  static constexpr Name##Type Name() { return {CALLER(CALL_(CONC, (StructDefiner_names_, CONC(NARGS,(__VA_ARGS__))) ),(C, __VA_ARGS__))}; }
145 #else
146  #define CONC(A, B) CONC_(A, B)
147  #define CONC_(A, B) A##B
148  #define NARGS(...) NARGS_(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
149  #define NARGS_(_16, _15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
150 
151  #define StructDefiner_types_1(C, E) decltype(&C::E)
152  #define StructDefiner_types_2(C, E, ...) decltype(&C::E), StructDefiner_types_1(C, __VA_ARGS__)
153  #define StructDefiner_types_3(C, E, ...) decltype(&C::E), StructDefiner_types_2(C, __VA_ARGS__)
154  #define StructDefiner_types_4(C, E, ...) decltype(&C::E), StructDefiner_types_3(C, __VA_ARGS__)
155  #define StructDefiner_types_5(C, E, ...) decltype(&C::E), StructDefiner_types_4(C, __VA_ARGS__)
156  #define StructDefiner_types_6(C, E, ...) decltype(&C::E), StructDefiner_types_5(C, __VA_ARGS__)
157  #define StructDefiner_types_7(C, E, ...) decltype(&C::E), StructDefiner_types_6(C, __VA_ARGS__)
158  #define StructDefiner_types_8(C, E, ...) decltype(&C::E), StructDefiner_types_7(C, __VA_ARGS__)
159  #define StructDefiner_types_9(C, E, ...) decltype(&C::E), StructDefiner_types_8(C, __VA_ARGS__)
160  #define StructDefiner_types_10(C, E, ...) decltype(&C::E), StructDefiner_types_9(C, __VA_ARGS__)
161  #define StructDefiner_types_11(C, E, ...) decltype(&C::E), StructDefiner_types_10(C, __VA_ARGS__)
162  #define StructDefiner_types_12(C, E, ...) decltype(&C::E), StructDefiner_types_11(C, __VA_ARGS__)
163  #define StructDefiner_types_13(C, E, ...) decltype(&C::E), StructDefiner_types_12(C, __VA_ARGS__)
164  #define StructDefiner_types_14(C, E, ...) decltype(&C::E), StructDefiner_types_13(C, __VA_ARGS__)
165  #define StructDefiner_types_15(C, E, ...) decltype(&C::E), StructDefiner_types_14(C, __VA_ARGS__)
166  #define StructDefiner_types_16(C, E, ...) decltype(&C::E), StructDefiner_types_15(C, __VA_ARGS__)
167 
168  #define StructDefiner_values_1(C, E) &C::E
169  #define StructDefiner_values_2(C, E, ...) &C::E, StructDefiner_values_1(C, __VA_ARGS__)
170  #define StructDefiner_values_3(C, E, ...) &C::E, StructDefiner_values_2(C, __VA_ARGS__)
171  #define StructDefiner_values_4(C, E, ...) &C::E, StructDefiner_values_3(C, __VA_ARGS__)
172  #define StructDefiner_values_5(C, E, ...) &C::E, StructDefiner_values_4(C, __VA_ARGS__)
173  #define StructDefiner_values_6(C, E, ...) &C::E, StructDefiner_values_5(C, __VA_ARGS__)
174  #define StructDefiner_values_7(C, E, ...) &C::E, StructDefiner_values_6(C, __VA_ARGS__)
175  #define StructDefiner_values_8(C, E, ...) &C::E, StructDefiner_values_7(C, __VA_ARGS__)
176  #define StructDefiner_values_9(C, E, ...) &C::E, StructDefiner_values_8(C, __VA_ARGS__)
177  #define StructDefiner_values_10(C, E, ...) &C::E, StructDefiner_values_9(C, __VA_ARGS__)
178  #define StructDefiner_values_11(C, E, ...) &C::E, StructDefiner_values_10(C, __VA_ARGS__)
179  #define StructDefiner_values_12(C, E, ...) &C::E, StructDefiner_values_11(C, __VA_ARGS__)
180  #define StructDefiner_values_13(C, E, ...) &C::E, StructDefiner_values_12(C, __VA_ARGS__)
181  #define StructDefiner_values_14(C, E, ...) &C::E, StructDefiner_values_13(C, __VA_ARGS__)
182  #define StructDefiner_values_15(C, E, ...) &C::E, StructDefiner_values_14(C, __VA_ARGS__)
183  #define StructDefiner_values_16(C, E, ...) &C::E, StructDefiner_values_15(C, __VA_ARGS__)
184 
185  #define StructDefiner_names_1(C, E) #E
186  #define StructDefiner_names_2(C, E, ...) #E, StructDefiner_names_1(C, __VA_ARGS__)
187  #define StructDefiner_names_3(C, E, ...) #E, StructDefiner_names_2(C, __VA_ARGS__)
188  #define StructDefiner_names_4(C, E, ...) #E, StructDefiner_names_3(C, __VA_ARGS__)
189  #define StructDefiner_names_5(C, E, ...) #E, StructDefiner_names_4(C, __VA_ARGS__)
190  #define StructDefiner_names_6(C, E, ...) #E, StructDefiner_names_5(C, __VA_ARGS__)
191  #define StructDefiner_names_7(C, E, ...) #E, StructDefiner_names_6(C, __VA_ARGS__)
192  #define StructDefiner_names_8(C, E, ...) #E, StructDefiner_names_7(C, __VA_ARGS__)
193  #define StructDefiner_names_9(C, E, ...) #E, StructDefiner_names_8(C, __VA_ARGS__)
194  #define StructDefiner_names_10(C, E, ...) #E, StructDefiner_names_9(C, __VA_ARGS__)
195  #define StructDefiner_names_11(C, E, ...) #E, StructDefiner_names_10(C, __VA_ARGS__)
196  #define StructDefiner_names_12(C, E, ...) #E, StructDefiner_names_11(C, __VA_ARGS__)
197  #define StructDefiner_names_13(C, E, ...) #E, StructDefiner_names_12(C, __VA_ARGS__)
198  #define StructDefiner_names_14(C, E, ...) #E, StructDefiner_names_13(C, __VA_ARGS__)
199  #define StructDefiner_names_15(C, E, ...) #E, StructDefiner_names_14(C, __VA_ARGS__)
200  #define StructDefiner_names_16(C, E, ...) #E, StructDefiner_names_15(C, __VA_ARGS__)
201 
206  #define DefineStructMembers(C, ...) using ReflectionType = Gorgon::StructDefiner<C, CONC(StructDefiner_types_, NARGS(__VA_ARGS__)) (C, __VA_ARGS__)>::Inner<CONC(StructDefiner_values_, NARGS(__VA_ARGS__)) (C, __VA_ARGS__)>; \
207  static constexpr ReflectionType Reflection() { return {CONC(StructDefiner_names_, NARGS(__VA_ARGS__))(C, __VA_ARGS__)}; }
208 
214  #define DefineStructMembersWithName(C, Name, ...) using Name##Type = Gorgon::StructDefiner<C, CONC(StructDefiner_types_, NARGS(__VA_ARGS__)) (C, __VA_ARGS__)>::Inner<CONC(StructDefiner_values_, NARGS(__VA_ARGS__)) (C, __VA_ARGS__)>; \
215  static constexpr Name##Type Name() { return {CONC(StructDefiner_names_, NARGS(__VA_ARGS__))(C, __VA_ARGS__)}; }
216 
217 #endif
218 
219 }
Gorgon::StructDefiner
Definition: Struct.h:30
Gorgon::TMP::RemoveRValueReference
Definition: TMP.h:415
Gorgon::StructDefiner::Inner::Inner
constexpr Inner(const S_ &...names)
Definition: Struct.h:36
Gorgon::StructDefiner::Inner::Member::Type
typename TMP::RemoveRValueReference< decltype(std::declval< C_ >().*(GetElm< N, MT_... >::template Inner< M_... >::Value))>::Type Type
Definition: Struct.h:42
Gorgon::StructDefiner::Inner::MemberCount
static constexpr int MemberCount
Definition: Struct.h:52
Gorgon::StructDefiner::Inner::Names
const char * Names[sizeof...(MT_)]
Definition: Struct.h:50
TMP.h
This file contains template metaprogramming methods and classes used throughout Gorgon Library.
Gorgon::Input::Keyboard::Keycodes::N
constexpr Key N
Definition: Keyboard.h:93
Gorgon::StructDefiner::Inner::Member::MemberPointer
static constexpr decltype(GetElm< N, MT_... >::template Inner< M_... >::Value) MemberPointer()
Definition: Struct.h:45
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::StructDefiner::Inner
Definition: Struct.h:33
Gorgon::StructDefiner::Inner::Member
Definition: Struct.h:41
Gorgon::StructDefiner::Inner::IsGorgonReflection
static constexpr int IsGorgonReflection
Definition: Struct.h:54
Gorgon::GetElm
Definition: Struct.h:9