libUTL++
RunTimeClass.h
1 #pragma once
2 
4 
5 UTL_NS_BEGIN;
6 
8 // RunTimeClass ////////////////////////////////////////////////////////////////////////////////////
10 
21 
24 {
25 public:
30  RunTimeClass(const RunTimeClass* baseClass)
31  : _baseClass(baseClass)
32  , _bases(nullptr)
33  {
34  }
35 
40  RunTimeClass(const RunTimeClass& runTimeClass)
41  : _baseClass(runTimeClass._baseClass)
42  , _bases(nullptr)
43  {
44  }
45 
46  virtual ~RunTimeClass()
47  {
48  auto bases = _bases.load(std::memory_order_relaxed);
49  if (bases != _basesInline)
50  {
51  free(bases);
52  }
53  }
54 
56  static void printClassNames();
57 
64  static void add(RunTimeClass* rtc);
65 
70  virtual Object*
71  create() const
72  {
73  ABORT();
74  return nullptr;
75  }
76 
82  static const RunTimeClass* find(const char* className);
83 
89  bool _isA(const RunTimeClass* rtc) const;
90 
92  const RunTimeClass*
93  baseClass() const
94  {
95  return _baseClass;
96  }
97 
99  const char*
100  name() const
101  {
102  return vname();
103  }
104 
106  virtual const char*
107  vname() const
108  {
109  ABORT();
110  return nullptr;
111  }
112 
114  virtual size_t
115  size() const
116  {
117  ABORT();
118  return 0;
119  }
120 
121 private:
122  const RunTimeClass* _baseClass;
123  mutable std::atomic<const RunTimeClass**> _bases;
124  mutable const RunTimeClass* _basesInline[8];
125 };
126 
128 // TRunTimeClass ///////////////////////////////////////////////////////////////////////////////////
130 
141 
143 template <typename T>
145 {
146 public:
151  TRunTimeClass(const RunTimeClass* baseClass)
152  : RunTimeClass(baseClass)
153  {
154  }
155  virtual ~TRunTimeClass()
156  {
157  }
158 
159  static const char*
160  name()
161  {
162  return _name;
163  }
164 
165  virtual const char*
166  vname() const
167  {
168  return _name;
169  }
170 
171  virtual size_t
172  size() const
173  {
174  return sizeof(T);
175  }
176 
177 private:
178  static const char* _name;
179 };
180 
182 // TConcreteRunTimeClass ///////////////////////////////////////////////////////////////////////////
184 
195 
197 template <typename T>
199 {
200 public:
206  : TRunTimeClass<T>(baseClass)
207  {
208  this->add(this);
209  }
210 
211  virtual ~TConcreteRunTimeClass()
212  {
213  }
214 
215  virtual Object*
216  create() const
217  {
218  return new T();
219  }
220 };
221 
223 
230 #define isA(className) _isA(CLASS(className))
231 
233 
241 #define isA2(className, T1, T2) _isA(CLASS2(className, T1, T2))
242 
244 
249 #define CLASS(className) (className::getThisClass())
250 
252 
257 #define CLASS2(className, T1, T2) (className<T1, T2>::getThisClass())
258 
260 
265 #define UTL_CLASS_DECL_RTTI_ABC(className) \
266 public: \
267  virtual const utl::RunTimeClass* getClass() const; \
268  virtual const char* getClassName() const; \
269  static const utl::RunTimeClass* getThisClass(); \
270  static const char* getThisClassName(); \
271  static const utl::RunTimeClass* getBaseClass(); \
272  static const char* getBaseClassName(); \
273  \
274 private: \
275  static const utl::TRunTimeClass<className> ___rtc __attribute__((__used__));
276 
278 
283 #define UTL_CLASS_DECL_RTTI(className) \
284 public: \
285  virtual const utl::RunTimeClass* getClass() const; \
286  virtual const char* getClassName() const; \
287  static const utl::RunTimeClass* getThisClass(); \
288  static const char* getThisClassName(); \
289  static const utl::RunTimeClass* getBaseClass(); \
290  static const char* getBaseClassName(); \
291  \
292 private: \
293  static const utl::TConcreteRunTimeClass<className> ___rtc __attribute__((__used__));
294 
296 
302 #define UTL_CLASS_DECL_RTTI_TPL(className, T) \
303 public: \
304  virtual const utl::RunTimeClass* getClass() const; \
305  virtual const char* getClassName() const; \
306  static const utl::RunTimeClass* getThisClass(); \
307  static const char* getThisClassName(); \
308  static const utl::RunTimeClass* getBaseClass(); \
309  static const char* getBaseClassName(); \
310  \
311 private: \
312  static const utl::TConcreteRunTimeClass<className<T>> ___rtc __attribute__((__used__));
313 
315 
321 #define UTL_CLASS_DECL_RTTI_TPL2(className, T1, T2) \
322 public: \
323  virtual const utl::RunTimeClass* getClass() const; \
324  virtual const char* getClassName() const; \
325  static const utl::RunTimeClass* getThisClass(); \
326  static const char* getThisClassName(); \
327  static const utl::RunTimeClass* getBaseClass(); \
328  static const char* getBaseClassName(); \
329  \
330 private: \
331  static const utl::TConcreteRunTimeClass<className<T1, T2>> ___rtc __attribute__((__used__));
332 
334 
335 #define UTL_CLASS_IMPL_RTTI_CMN(className) \
336  const utl::RunTimeClass* className::getClass() const \
337  { \
338  return &___rtc; \
339  } \
340  const char* className::getClassName() const \
341  { \
342  return ___rtc.name(); \
343  } \
344  const utl::RunTimeClass* className::getThisClass() \
345  { \
346  return &___rtc; \
347  } \
348  const char* className::getThisClassName() \
349  { \
350  return ___rtc.name(); \
351  } \
352  const utl::RunTimeClass* className::getBaseClass() \
353  { \
354  return ___rtc.baseClass(); \
355  } \
356  const char* className::getBaseClassName() \
357  { \
358  return getBaseClass()->name(); \
359  }
360 
362 
367 #define UTL_CLASS_IMPL_RTTI_ABC(className) \
368  UTL_CLASS_IMPL_RTTI_CMN(className); \
369  const utl::TRunTimeClass<className> className::___rtc(CLASS(className::super)); \
370  template class utl::TRunTimeClass<className>;
371 
373 
378 #define UTL_CLASS_IMPL_RTTI(className) \
379  UTL_CLASS_IMPL_RTTI_CMN(className); \
380  const utl::TConcreteRunTimeClass<className> className::___rtc(CLASS(className::super)); \
381  template class utl::TRunTimeClass<className>; \
382  template class utl::TConcreteRunTimeClass<className>;
383 
385 
391 #define UTL_CLASS_IMPL_RTTI_TPL(className, T) \
392  template <typename T> \
393  const utl::RunTimeClass* className<T>::getClass() const \
394  { \
395  return &___rtc; \
396  } \
397  template <typename T> \
398  const char* className<T>::getClassName() const \
399  { \
400  return ___rtc.name(); \
401  } \
402  template <typename T> \
403  const utl::RunTimeClass* className<T>::getThisClass() \
404  { \
405  return &___rtc; \
406  } \
407  template <typename T> \
408  const char* className<T>::getThisClassName() \
409  { \
410  return ___rtc.name(); \
411  } \
412  template <typename T> \
413  const utl::RunTimeClass* className<T>::getBaseClass() \
414  { \
415  return ___rtc.baseClass(); \
416  } \
417  template <typename T> \
418  const char* className<T>::getBaseClassName() \
419  { \
420  return getBaseClass()->name(); \
421  } \
422  template <typename T> \
423  const utl::TConcreteRunTimeClass<className<T>> className<T>::___rtc( \
424  CLASS(className<T>::super));
425 
427 
428 #define UTL_CLASS_IMPL_RTTI_TPL2_CMN(className, T1, T2) \
429  template <typename T1, typename T2> \
430  const utl::RunTimeClass* className<T1, T2>::getClass() const \
431  { \
432  return &___rtc; \
433  } \
434  template <typename T1, typename T2> \
435  const char* className<T1, T2>::getClassName() const \
436  { \
437  return ___rtc.name(); \
438  } \
439  template <typename T1, typename T2> \
440  const utl::RunTimeClass* className<T1, T2>::getThisClass() \
441  { \
442  return &___rtc; \
443  } \
444  template <typename T1, typename T2> \
445  const char* className<T1, T2>::getThisClassName() \
446  { \
447  return ___rtc.name(); \
448  } \
449  template <typename T1, typename T2> \
450  const utl::RunTimeClass* className<T1, T2>::getBaseClass() \
451  { \
452  return ___rtc.baseClass(); \
453  } \
454  template <typename T1, typename T2> \
455  const char* className<T1, T2>::getBaseClassName() \
456  { \
457  return getBaseClass()->name(); \
458  }
459 
461 
467 #define UTL_CLASS_IMPL_RTTI_TPL2(className, T1, T2) \
468  UTL_CLASS_IMPL_RTTI_TPL2_CMN(className, T1, T2); \
469  template <typename T1, typename T2> \
470  const utl::TConcreteRunTimeClass<className<T1, T2>> className<T1, T2>::___rtc( \
471  className<T1, T2>::super::getThisClass());
472 
474 
479 #define UTL_CLASS_IMPL_NAME(className) \
480  template <> \
481  const char* utl::TRunTimeClass<className>::_name = #className;
482 
484 
489 #define UTL_CLASS_IMPL_NAME_TPL(className, T) \
490  template <> \
491  const char* utl::TRunTimeClass<className<T>>::_name = #className "<" #T ">";
492 
494 
499 #define UTL_CLASS_IMPL_NAME_TPL2(className, T1, T2) \
500  template <> \
501  const char* utl::TRunTimeClass<className<T1, T2>>::_name = #className "<" #T1 "," #T2 ">";
502 
504 
510 #define UTL_CLASS_IMPL_NAME_TPLxTPL2(className, TC, T1, T2) \
511  template <> \
512  const char* utl::TRunTimeClass<className<TC<T1, T2>>>::_name \
513  = #className "<" #TC "<" #T1 "," #T2 \
514  ">" \
515  ">";
516 
518 
519 UTL_NS_END;
const char * name() const
Get the name.
Definition: RunTimeClass.h:100
virtual Object * create() const
Create a new instance of this class.
Definition: RunTimeClass.h:71
virtual size_t size() const
Get the size of this class (as in sizeof()).
Definition: RunTimeClass.h:115
virtual Object * create() const
Create a new instance of this class.
Definition: RunTimeClass.h:216
Store information about a class.
Definition: RunTimeClass.h:23
virtual const char * vname() const
Get the name.
Definition: RunTimeClass.h:107
virtual size_t size() const
Get the size of this class (as in sizeof()).
Definition: RunTimeClass.h:172
virtual const char * vname() const
Get the name.
Definition: RunTimeClass.h:166
RunTimeClass(const RunTimeClass *baseClass)
Constructor.
Definition: RunTimeClass.h:30
Encapsulate class-related knowledge for concrete classes.
Definition: RunTimeClass.h:198
#define ABORT()
Immediately terminates the program.
Definition: macros.h:59
Template version of RunTimeClass.
Definition: RunTimeClass.h:144
TRunTimeClass(const RunTimeClass *baseClass)
Constructor.
Definition: RunTimeClass.h:151
Root of UTL++ class hierarchy.
Definition: Object.h:52
const RunTimeClass * baseClass() const
Get the base class.
Definition: RunTimeClass.h:93
TConcreteRunTimeClass(const RunTimeClass *baseClass)
Constructor.
Definition: RunTimeClass.h:205
RunTimeClass(const RunTimeClass &runTimeClass)
Copy constructor.
Definition: RunTimeClass.h:40