Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
TypeInfo.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef TypInfo_INCLUDE_ONCE
33 #define TypInfo_INCLUDE_ONCE
34 
35 #include <vlCore/MurmurHash3.hpp>
36 
37 namespace vl
38 {
44  //---------------------------------------------------------------------------------------------------------------------
46  struct TypeInfo
47  {
49  TypeInfo(const char* name): mName(name)
50  {
51  // compute string length
52  const char* ptr = name;
53  while( *ptr ) ++ptr;
54  vl::MurmurHash3_x86_32(name, (int)(ptr - name), 0, &mHash);
55  // printf("--- --- TypeInfo : %s = %x\n", name, mHash);
56  }
57 
59  bool operator==(const TypeInfo& other) const { return mHash == other.mHash; }
60 
62  bool operator<(const TypeInfo& other) const { return mHash < other.mHash; }
63 
65  const char* name() const { return mName; }
66 
68  u32 hash() const { return mHash; }
69 
70  private:
71  // we could also use u32 mHash[4] and MurmurHash3_x86_128() for extra safety.
72  u32 mHash;
73  const char* mName;
74  };
75 }
76 //---------------------------------------------------------------------------------------------------------------------
77 #define VL_GROUP(...) __VA_ARGS__
78 #define VL_TO_STR(...) #__VA_ARGS__
79 //---------------------------------------------------------------------------------------------------------------------
80 #define VL_INSTRUMENT_BASE_CLASS(ClassName) \
81 public: \
82  /* static functions */ \
83  \
84  static const char* Name() { return VL_TO_STR(ClassName); } \
85  \
86  static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
87  \
88  /* virtual functions */ \
89  \
90  virtual const char* className() const { return VL_TO_STR(ClassName); } \
91  \
92  virtual const ::vl::TypeInfo& classType() const { return Type(); } \
93  \
94  virtual bool isOfType(const ::vl::TypeInfo& type) const \
95  { \
96  return type == Type(); \
97  } \
98  /* virtual Object* createThisType() const { return new ClassName; } */ \
99 private:
100 //---------------------------------------------------------------------------------------------------------------------
101 #define VL_INSTRUMENT_ABSTRACT_BASE_CLASS(ClassName) \
102 public: \
103  /* static functions */ \
104  \
105  static const char* Name() { return VL_TO_STR(ClassName); } \
106  \
107  static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
108  \
109  /* virtual functions */ \
110  \
111  virtual const char* className() const { return VL_TO_STR(ClassName); } \
112  \
113  virtual const ::vl::TypeInfo& classType() const { return Type(); } \
114  \
115  virtual bool isOfType(const ::vl::TypeInfo& type) const \
116  { \
117  return type == Type(); \
118  } \
119  /* virtual Object* createThisType() const = 0; */ \
120 private:
121 //---------------------------------------------------------------------------------------------------------------------
122 #define VL_INSTRUMENT_CLASS(ClassName, BaseClass) \
123 private: \
124  typedef BaseClass super; \
125 public: \
126  /* static functions */ \
127  \
128  static const char* Name() { return VL_TO_STR(ClassName); } \
129  \
130  static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
131  \
132  /* virtual functions */ \
133  \
134  virtual const char* className() const { return VL_TO_STR(ClassName); } \
135  \
136  virtual const ::vl::TypeInfo& classType() const { return Type(); } \
137  \
138  virtual bool isOfType(const ::vl::TypeInfo& type) const \
139  { \
140  return type == Type() || super::isOfType(type); \
141  } \
142  /* virtual Object* createThisType() const { return new ClassName; } */ \
143 private:
144 //---------------------------------------------------------------------------------------------------------------------
145 #define VL_INSTRUMENT_ABSTRACT_CLASS(ClassName, BaseClass) \
146 private: \
147  typedef BaseClass super; \
148 public: \
149  /* static functions */ \
150  \
151  static const char* Name() { return VL_TO_STR(ClassName); } \
152  \
153  static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
154  \
155  /* virtual functions */ \
156  \
157  virtual const char* className() const { return VL_TO_STR(ClassName); } \
158  \
159  virtual const ::vl::TypeInfo& classType() const { return Type(); } \
160  \
161  virtual bool isOfType(const ::vl::TypeInfo& type) const \
162  { \
163  return type == Type() || super::isOfType(type); \
164  } \
165  /* virtual Object* createThisType() const = 0; */ \
166 private:
167 //---------------------------------------------------------------------------------------------------------------------
168 #define VL_INSTRUMENT_CLASS_2(ClassName, BaseClass1, BaseClass2) \
169 private: \
170  typedef BaseClass1 super1; \
171  typedef BaseClass2 super2; \
172 public: \
173  /* static functions */ \
174  \
175  static const char* Name() { return VL_TO_STR(ClassName); } \
176  \
177  static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
178  \
179  /* virtual functions */ \
180  \
181  virtual const char* className() const { return VL_TO_STR(ClassName); } \
182  \
183  virtual const ::vl::TypeInfo& classType() const { return Type(); } \
184  \
185  virtual bool isOfType(const ::vl::TypeInfo& type) const \
186  { \
187  return type == Type() || super1::isOfType(type) || super2::isOfType(type); \
188  } \
189  /* virtual Object* createThisType() const { return new ClassName; } */ \
190 private:
191 //---------------------------------------------------------------------------------------------------------------------
192 #define VL_INSTRUMENT_ABSTRACT_CLASS_2(ClassName, BaseClass1, BaseClass2) \
193 private: \
194  typedef BaseClass1 super1; \
195  typedef BaseClass2 super2; \
196 public: \
197  /* static functions */ \
198  \
199  static const char* Name() { return VL_TO_STR(ClassName); } \
200  \
201  static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
202  \
203  /* virtual functions */ \
204  \
205  virtual const char* className() const { return VL_TO_STR(ClassName); } \
206  \
207  virtual const ::vl::TypeInfo& classType() const { return Type(); } \
208  \
209  virtual bool isOfType(const ::vl::TypeInfo& type) const \
210  { \
211  return type == Type() || super1::isOfType(type) || super2::isOfType(type); \
212  } \
213  /* virtual Object* createThisType() const = 0; */ \
214 private:
215 //---------------------------------------------------------------------------------------------------------------------
216 namespace vl
217 {
218  template<class B, class A>
219  B* cast(A* obj)
220  {
221  if(obj && obj->isOfType(B::Type()))
222  return static_cast<B*>(obj);
223  else
224  return NULL;
225  }
226  //---------------------------------------------------------------------------------------------------------------------
227  template<class B, class A>
228  const B* cast_const(const A* obj) // need rename to cast_const for GCC
229  {
230  if(obj && obj->isOfType(B::Type()))
231  return static_cast<const B*>(obj);
232  else
233  return NULL;
234  }
235 }
236 //---------------------------------------------------------------------------------------------------------------------
237 
238 //---------------------------------------------------------------------------------------------------------------------
239 // USAGE EXAMPLES
240 //---------------------------------------------------------------------------------------------------------------------
241 
242 /***
243 
244 namespace ns
245 {
246  // NO INHERITANCE FROM INSTRUMENTED BASE CLASS
247  class Base
248  {
249  VL_INSTRUMENT_BASE_CLASS(Base)
250  };
251 
252  // SIMPLE INHERITANCE OF INSTRUMENTED CLASS
253  class ClassA: public virtual Base
254  {
255  VL_INSTRUMENT_CLASS(ns::ClassA, Base)
256  };
257 
258  // SIMPLE INHERITANCE OF INSTRUMENTED CLASS
259  class ClassB: public virtual Base
260  {
261  VL_INSTRUMENT_CLASS(ns::ClassB, Base)
262  };
263 
264  // MULTIPLE INHERITANCE
265  class ClassAB: public ClassA, public ClassB
266  {
267  VL_INSTRUMENT_CLASS_2(ns::ClassAB, ClassA, ClassB)
268  };
269 
270  // TEMPLATE CLASSES WITH MORE THAN 1 PARAMS
271  template<class T1, class T2>
272  class ClassT: public Base
273  {
274  VL_INSTRUMENT_CLASS(VL_GROUP(ns::ClassT<T1, T2>), Base)
275  };
276 
277  // SUBCLASSES OF TEMPLATES WITH MORE THAN 1 PARAMS
278  class ClassSubT: public ClassT<int, float>
279  {
280  VL_INSTRUMENT_CLASS(ns::ClassSubT, VL_GROUP(ClassT<int, float>))
281  };
282 }
283 
284 IMPORTANT NOTE:
285  - The "ClassName" parameter of VL_INSTRUMENT_* should ALWAYS specify the full NAMESPACE.
286  - The "BaseClass" parameter of VL_INSTRUMENT_* should not specify the namespace unless strictly necessary.
287 
288 --- dynamic casting example ---
289 
290 ns::ClassAB AB;
291 ns::ClassA* pA = &AB;
292 ns::ClassB* pB = &AB;
293 assert( vl::cast<ns::ClassAB>(pA) != NULL )
294 assert( vl::cast<ns::ClassAB>(pB) != NULL )
295 assert( vl::cast<ns::ClassSubT>(pA) == NULL )
296 
297 or
298 
299 assert( pA->as<ns::ClassAB>() != NULL )
300 assert( pB->as<ns::ClassAB>() != NULL )
301 assert( pA->as<ns::ClassSubT>() == NULL )
302 
303 NOTE THAT UNLIKE dynamic_cast<> AND static_cast<> WE USE:
304 
305  vl::cast<ns::ClassAB>(pB)
306 
307 INSTEAD OF:
308 
309  vl::cast<ns::ClassAB*>(pB)
310 
311 REMARKS:
312 
313  There is no need to say that, similarly to dynamic_cast<>, one should avoid using VL TypeInfo facilities
314  inside "fast" loops otherwise they won't be that "fast" anymore!
315 
316 ***/
317 
318 #endif
TypeInfo(const char *name)
Constructor.
Definition: TypeInfo.hpp:49
u32 hash() const
The 32 bit hash of the name of the class including the namespace.
Definition: TypeInfo.hpp:68
B * cast(A *obj)
Definition: TypeInfo.hpp:219
Visualization Library main namespace.
Represents a class type.
Definition: TypeInfo.hpp:46
unsigned int u32
32 bits unsigned integer
Definition: std_types.hpp:51
VLCORE_EXPORT void MurmurHash3_x86_32(const void *key, int len, u32 seed, void *out)
Definition: MurmurHash3.cpp:97
const B * cast_const(const A *obj)
Definition: TypeInfo.hpp:228
#define NULL
Definition: OpenGLDefs.hpp:81
bool operator<(const TypeInfo &other) const
Less operator.
Definition: TypeInfo.hpp:62
bool operator==(const TypeInfo &other) const
Equal operator.
Definition: TypeInfo.hpp:59
const char * name() const
The name of the class including the namespace.
Definition: TypeInfo.hpp:65