Embedded Template Library  1.0
type_lookup_generator.h
1 /******************************************************************************
2 The MIT License(MIT)
3 
4 Embedded Template Library.
5 https://github.com/ETLCPP/etl
6 https://www.etlcpp.com
7 
8 Copyright(c) 2017 jwellbelove
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files(the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions :
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 ******************************************************************************/
28 
29 #ifndef ETL_TYPE_LOOKUP_INCLUDED
30 #define ETL_TYPE_LOOKUP_INCLUDED
31 
32 #include <limits.h>
33 
34 #include "platform.h"
35 #include "type_traits.h"
36 #include "static_assert.h"
37 #include "integral_limits.h"
38 #include "null_type.h"
39 
40 #undef ETL_FILE
41 #define ETL_FILE "45"
42 
43 /*[[[cog
44 import cog
45 cog.outl("#if 0")
46 ]]]*/
47 /*[[[end]]]*/
48 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE.
49 /*[[[cog
50 import cog
51 cog.outl("#endif")
52 ]]]*/
53 /*[[[end]]]*/
54 
55 /*[[[cog
56 import cog
57 cog.outl("//***************************************************************************")
58 cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.")
59 cog.outl("//***************************************************************************")
60 ]]]*/
61 /*[[[end]]]*/
62 
63 namespace etl
64 {
65  //***************************************************************************
67  //***************************************************************************
68  template <typename T, int ID_>
69  struct type_id_pair
70  {
71  typedef T type;
72 
73  enum
74  {
75  ID = ID_
76  };
77  };
78 
79  //***************************************************************************
81  //***************************************************************************
82  template <typename T1, typename T2>
84  {
85  typedef T1 type1;
86  typedef T2 type2;
87  };
88 
89 #if ETL_CPP11_SUPPORTED && !defined(ETL_TYPE_SELECT_FORCE_CPP03)
90  //***************************************************************************
91  // type_id_lookup
92  //***************************************************************************
93  template <typename... TTypes>
94  struct type_id_lookup
95  {
96  private:
97 
98  // The type for no match.
99  struct nulltype {};
100 
101  // For N type pairs.
102  template <size_t ID, typename T1, typename... TRest>
103  struct type_from_id_helper
104  {
105  using type = typename etl::conditional<ID == T1::ID,
106  typename T1::type,
107  typename type_from_id_helper<ID, TRest...>::type>::type;
108  };
109 
110  // Specialisation for 1 type pair.
111  template <size_t ID, typename T1>
112  struct type_from_id_helper<ID, T1>
113  {
114  using type = typename etl::conditional<ID == T1::ID,
115  typename T1::type,
116  nulltype>::type;
117  };
118 
119  public:
120 
121  //************************************
122  // type_from_id
123  //************************************
124  template <int ID>
125  struct type_from_id
126  {
127  using type = typename type_from_id_helper<ID, TTypes...>::type;
128 
129  static_assert(!(etl::is_same<nulltype, type>::value), "Invalid id");
130  };
131 
132 #if ETL_CPP14_SUPPORTED
133  template <int ID>
134  using type_from_id_t = typename type_from_id<ID>::type;
135 #endif
136 
137  private:
138 
139  static constexpr size_t UNKNOWN = etl::integral_limits<size_t>::max;
140 
141  // For N type pairs.
142  template <typename T, typename T1, typename... TRest>
143  struct id_from_type_helper
144  {
145  static constexpr size_t value = etl::is_same<T, typename T1::type>::value ? T1::ID : id_from_type_helper<T, TRest...>::value;
146  };
147 
148  // Specialisation for 1 type pair.
149  template <typename T, typename T1>
150  struct id_from_type_helper<T, T1>
151  {
152  static constexpr size_t value = etl::is_same<T, typename T1::type>::value ? T1::ID : UNKNOWN;
153  };
154 
155  public:
156 
157  //************************************
158  // id_from_type
159  //************************************
160  template <typename T>
161  struct id_from_type
162  {
163  static constexpr size_t value = id_from_type_helper<T, TTypes...>::value;
164 
165  static_assert(value != UNKNOWN, "Invalid type");
166  };
167 
168 #if ETL_CPP17_SUPPORTED
169  template <typename T>
170  static constexpr size_t id_from_type_v = id_from_type<T>::value;
171 #endif
172 
173  //************************************
174  template <typename T>
175  static unsigned int get_id_from_type(const T&)
176  {
177  return get_id_from_type<T>();
178  }
179 
180  //************************************
181  template <typename T>
182  static unsigned int get_id_from_type()
183  {
184  return id_from_type<T>::value;
185  }
186  };
187 
188  //***************************************************************************
189  // type_type_lookup
190  //***************************************************************************
191  template <typename... TTypes>
192  class type_type_lookup
193  {
194  private:
195 
196  // The type for no match.
197  struct nulltype {};
198 
199  template <typename T, typename T1, typename... TRest>
200  struct type_from_type_helper
201  {
203  typename T1::type2,
204  typename type_from_type_helper<T, TRest...>::type>::type;
205  };
206 
207  template <typename T, typename T1>
208  struct type_from_type_helper<T, T1>
209  {
211  typename T1::type2,
212  nulltype>::type;
213  };
214 
215  public:
216 
217  template <typename T>
218  class type_from_type
219  {
220  public:
221 
222  // The matched type or nulltype
223  using type = typename type_from_type_helper<T, TTypes...>::type;
224 
225  static_assert(!etl::is_same<type, nulltype>::value, "Type match not found");
226  };
227 
228 #if ETL_CPP14_SUPPORTED
229  // Template alias.
230  template <typename T>
231  using type_from_type_t = typename type_from_type<T>::type;
232 #endif
233  };
234 
235 #else
236 
237  /*[[[cog
238  import cog
239  cog.outl("//***************************************************************************")
240  cog.outl("// For %s types." % int(NTypes))
241  cog.outl("//***************************************************************************")
242  cog.outl("template <typename T1,")
243  for n in range(2, int(NTypes)):
244  cog.outl(" typename T%s = etl::type_id_pair<etl::null_type<0>, -%s>," %(n, n))
245  cog.outl(" typename T%s = etl::type_id_pair<etl::null_type<0>, -%s> >" %(NTypes, NTypes))
246  cog.outl("struct type_id_lookup")
247  cog.outl("{")
248  cog.outl("public:")
249  cog.outl("")
250  cog.outl(" //************************************")
251  cog.outl(" template <int ID>")
252  cog.outl(" struct type_from_id")
253  cog.outl(" {")
254  cog.outl(" typedef ")
255  for n in range(1, int(NTypes) + 1):
256  cog.outl(" typename etl::conditional<ID == T%s::ID, typename T%s::type," %(n, n))
257  cog.out(" etl::null_type<0> >")
258  for n in range(1, int(NTypes) + 1):
259  if n == int(NTypes):
260  cog.outl("::type type;")
261  else:
262  cog.out("::type>")
263  if n % 4 == 0:
264  if n != int(NTypes):
265  cog.outl("")
266  cog.out(" ")
267  cog.outl("")
268  cog.outl(" ETL_STATIC_ASSERT(!(etl::is_same<etl::null_type<0>, type>::value), \"Invalid id\");")
269  cog.outl(" };")
270  cog.outl("")
271  cog.outl(" //************************************")
272  cog.outl(" enum")
273  cog.outl(" {")
274  cog.outl(" UNKNOWN = UINT_MAX")
275  cog.outl(" };")
276  cog.outl("")
277  cog.outl(" template <typename T>")
278  cog.outl(" struct id_from_type")
279  cog.outl(" {")
280  cog.outl(" enum")
281  cog.outl(" {")
282  cog.outl(" value =")
283  for n in range(1, int(NTypes) + 1) :
284  cog.outl(" (unsigned int) etl::is_same<T, typename T%s::type>::value ? T%s::ID :" % (n, n))
285  cog.outl(" (unsigned int) UNKNOWN")
286  cog.outl(" };")
287  cog.outl("")
288  cog.outl(" ETL_STATIC_ASSERT(((unsigned int)value != (unsigned int)UNKNOWN), \"Invalid type\");")
289  cog.outl(" };")
290  cog.outl("")
291  cog.outl(" //************************************")
292  cog.outl(" template <typename T>")
293  cog.outl(" static unsigned int get_id_from_type(const T&)")
294  cog.outl(" {")
295  cog.outl(" return get_id_from_type<T>();")
296  cog.outl(" }")
297  cog.outl("")
298  cog.outl(" //************************************")
299  cog.outl(" template <typename T>")
300  cog.outl(" static unsigned int get_id_from_type()")
301  cog.outl(" {")
302  cog.outl(" return id_from_type<T>::value;")
303  cog.outl(" }")
304  cog.outl("};")
305  cog.outl("")
306  cog.outl("//***************************************************************************")
307  cog.outl("// For %s types." % int(NTypes))
308  cog.outl("//***************************************************************************")
309  cog.outl("template <typename T1,")
310  for n in range(2, int(NTypes)):
311  cog.outl(" typename T%s = etl::type_type_pair<etl::null_type<0>, etl::null_type<0> >," %n)
312  cog.outl(" typename T%s = etl::type_type_pair<etl::null_type<0>, etl::null_type<0> > >" %NTypes)
313  cog.outl("struct type_type_lookup")
314  cog.outl("{")
315  cog.outl("public:")
316  cog.outl("")
317  cog.outl(" //************************************")
318  cog.outl(" template <typename T>")
319  cog.outl(" struct type_from_type")
320  cog.outl(" {")
321  cog.outl(" typedef ")
322  for n in range(1, int(NTypes) + 1):
323  cog.outl(" typename etl::conditional<etl::is_same<T, typename T%s::type1>::value, typename T%s::type2," %(n, n))
324  cog.out(" etl::null_type<0> >")
325  for n in range(1, int(NTypes) + 1):
326  if n == int(NTypes):
327  cog.outl("::type type;")
328  else:
329  cog.out("::type>")
330  if n % 8 == 0:
331  if n != int(NTypes):
332  cog.outl("")
333  cog.out(" ")
334  cog.outl("")
335  cog.outl(" ETL_STATIC_ASSERT(!(etl::is_same<etl::null_type<0>, type>::value), \"Invalid type\");")
336  cog.outl(" };")
337  cog.outl("};")
338  ]]]*/
339  /*[[[end]]]*/
340 
341 #endif
342 }
343 
344 #undef ETL_FILE
345 
346 #endif
Definition: integral_limits.h:54
conditional
Definition: type_traits_generator.h:1202
is_same
Definition: type_traits_generator.h:981
Definition: absolute.h:37
Definition: type_lookup.h:245
The type/id pair type to use for type/id lookup template parameters.
Definition: type_lookup_generator.h:70
The type/type pair type to use for type/type lookup template parameters.
Definition: type_lookup_generator.h:84