Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/TypeInfo.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef TypInfo_INCLUDE_ONCE
00033 #define TypInfo_INCLUDE_ONCE
00034 
00035 #include <vlCore/MurmurHash3.hpp>
00036 
00037 namespace vl
00038 {
00044   //---------------------------------------------------------------------------------------------------------------------
00046   struct TypeInfo
00047   {
00049     TypeInfo(const char* name): mName(name)
00050     {
00051       // compute string length
00052       const char* ptr = name;
00053       while( *ptr ) ++ptr;
00054       vl::MurmurHash3_x86_32(name, (int)(ptr - name), 0, &mHash);
00055       // printf("--- --- TypeInfo : %s = %x\n", name, mHash);
00056     }
00057 
00059     bool operator==(const TypeInfo& other) const { return mHash == other.mHash; }
00060 
00062     bool operator<(const  TypeInfo& other) const { return mHash < other.mHash; }
00063 
00065     const char* name() const { return mName; }
00066 
00068     u32 hash() const { return mHash; }
00069 
00070   private:
00071     // we could also use u32 mHash[4] and MurmurHash3_x86_128() for extra safety.
00072     u32 mHash;
00073     const char* mName;
00074   };
00075 }
00076 //---------------------------------------------------------------------------------------------------------------------
00077 #define VL_GROUP(...) __VA_ARGS__
00078 #define VL_TO_STR(...) #__VA_ARGS__
00079 //---------------------------------------------------------------------------------------------------------------------
00080 #define VL_INSTRUMENT_BASE_CLASS(ClassName)                                                                                \
00081 public:                                                                                                                    \
00082   /* static functions */                                                                                                   \
00083                                                                                     \
00084   static const char* Name() { return VL_TO_STR(ClassName); }                                                               \
00085                                                                                 \
00086   static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
00087                                                                                                                            \
00088   /* virtual functions */                                                                                                  \
00089                                                                            \
00090   virtual const char* className() const { return VL_TO_STR(ClassName); }                                                   \
00091                                                                        \
00092   virtual const ::vl::TypeInfo& classType() const { return Type(); }                                                       \
00093                                                        \
00094   virtual bool isOfType(const ::vl::TypeInfo& type) const                                                                  \
00095   {                                                                                                                        \
00096     return type == Type();                                                                                                 \
00097   }                                                                                                                        \
00098   /* virtual Object* createThisType() const { return new ClassName; }                                              */      \
00099 private:
00100 //---------------------------------------------------------------------------------------------------------------------
00101 #define VL_INSTRUMENT_ABSTRACT_BASE_CLASS(ClassName)                                                                       \
00102 public:                                                                                                                    \
00103   /* static functions */                                                                                                   \
00104                                                                                     \
00105   static const char* Name() { return VL_TO_STR(ClassName); }                                                               \
00106                                                                                 \
00107   static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
00108                                                                                                                            \
00109   /* virtual functions */                                                                                                  \
00110                                                                            \
00111   virtual const char* className() const { return VL_TO_STR(ClassName); }                                                   \
00112                                                                        \
00113   virtual const ::vl::TypeInfo& classType() const { return Type(); }                                                       \
00114                                                        \
00115   virtual bool isOfType(const ::vl::TypeInfo& type) const                                                                  \
00116   {                                                                                                                        \
00117     return type == Type();                                                                                                 \
00118   }                                                                                                                        \
00119   /* virtual Object* createThisType() const = 0;                                                                   */      \
00120 private:
00121 //---------------------------------------------------------------------------------------------------------------------
00122 #define VL_INSTRUMENT_CLASS(ClassName, BaseClass)                                                                          \
00123 private:                                                                                                                   \
00124   typedef BaseClass super;                                                                                                 \
00125 public:                                                                                                                    \
00126   /* static functions */                                                                                                   \
00127                                                                                     \
00128   static const char* Name() { return VL_TO_STR(ClassName); }                                                               \
00129                                                                                 \
00130   static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
00131                                                                                                                            \
00132   /* virtual functions */                                                                                                  \
00133                                                                            \
00134   virtual const char* className() const { return VL_TO_STR(ClassName); }                                                   \
00135                                                                        \
00136   virtual const ::vl::TypeInfo& classType() const { return Type(); }                                                       \
00137                                                        \
00138   virtual bool isOfType(const ::vl::TypeInfo& type) const                                                                  \
00139   {                                                                                                                        \
00140     return type == Type() || super::isOfType(type);                                                                        \
00141   }                                                                                                                        \
00142   /* virtual Object* createThisType() const { return new ClassName; }                                              */      \
00143 private:
00144 //---------------------------------------------------------------------------------------------------------------------
00145 #define VL_INSTRUMENT_ABSTRACT_CLASS(ClassName, BaseClass)                                                                 \
00146 private:                                                                                                                   \
00147   typedef BaseClass super;                                                                                                 \
00148 public:                                                                                                                    \
00149   /* static functions */                                                                                                   \
00150                                                                                     \
00151   static const char* Name() { return VL_TO_STR(ClassName); }                                                               \
00152                                                                                 \
00153   static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
00154                                                                                                                            \
00155   /* virtual functions */                                                                                                  \
00156                                                                            \
00157   virtual const char* className() const { return VL_TO_STR(ClassName); }                                                   \
00158                                                                        \
00159   virtual const ::vl::TypeInfo& classType() const { return Type(); }                                                       \
00160                                                        \
00161   virtual bool isOfType(const ::vl::TypeInfo& type) const                                                                  \
00162   {                                                                                                                        \
00163     return type == Type() || super::isOfType(type);                                                                        \
00164   }                                                                                                                        \
00165   /* virtual Object* createThisType() const = 0;                                                                   */      \
00166 private:
00167 //---------------------------------------------------------------------------------------------------------------------
00168 #define VL_INSTRUMENT_CLASS_2(ClassName, BaseClass1, BaseClass2)                                                           \
00169 private:                                                                                                                   \
00170   typedef BaseClass1 super1;                                                                                               \
00171   typedef BaseClass2 super2;                                                                                               \
00172 public:                                                                                                                    \
00173   /* static functions */                                                                                                   \
00174                                                                                     \
00175   static const char* Name() { return VL_TO_STR(ClassName); }                                                               \
00176                                                                                 \
00177   static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
00178                                                                                                                            \
00179   /* virtual functions */                                                                                                  \
00180                                                                            \
00181   virtual const char* className() const { return VL_TO_STR(ClassName); }                                                   \
00182                                                                        \
00183   virtual const ::vl::TypeInfo& classType() const { return Type(); }                                                       \
00184                                                        \
00185   virtual bool isOfType(const ::vl::TypeInfo& type) const                                                                  \
00186   {                                                                                                                        \
00187     return type == Type() || super1::isOfType(type) || super2::isOfType(type);                                             \
00188   }                                                                                                                        \
00189   /* virtual Object* createThisType() const { return new ClassName; }                                              */      \
00190 private:
00191 //---------------------------------------------------------------------------------------------------------------------
00192 #define VL_INSTRUMENT_ABSTRACT_CLASS_2(ClassName, BaseClass1, BaseClass2)                                                  \
00193 private:                                                                                                                   \
00194   typedef BaseClass1 super1;                                                                                               \
00195   typedef BaseClass2 super2;                                                                                               \
00196 public:                                                                                                                    \
00197   /* static functions */                                                                                                   \
00198                                                                                     \
00199   static const char* Name() { return VL_TO_STR(ClassName); }                                                               \
00200                                                                                 \
00201   static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \
00202                                                                                                                            \
00203   /* virtual functions */                                                                                                  \
00204                                                                            \
00205   virtual const char* className() const { return VL_TO_STR(ClassName); }                                                   \
00206                                                                        \
00207   virtual const ::vl::TypeInfo& classType() const { return Type(); }                                                       \
00208                                                        \
00209   virtual bool isOfType(const ::vl::TypeInfo& type) const                                                                  \
00210   {                                                                                                                        \
00211     return type == Type() || super1::isOfType(type) || super2::isOfType(type);                                             \
00212   }                                                                                                                        \
00213   /* virtual Object* createThisType() const = 0;                                                                   */      \
00214 private:
00215 //---------------------------------------------------------------------------------------------------------------------
00216 namespace vl
00217 {
00218   template<class B, class A>
00219   B* cast(A* obj)
00220   {
00221     if(obj && obj->isOfType(B::Type()))
00222       return static_cast<B*>(obj);
00223     else
00224       return NULL;
00225   }
00226   //---------------------------------------------------------------------------------------------------------------------
00227   template<class B, class A>
00228   const B* cast_const(const A* obj) // need rename to cast_const for GCC
00229   {
00230     if(obj && obj->isOfType(B::Type()))
00231       return static_cast<const B*>(obj);
00232     else
00233       return NULL;
00234   }
00235 }
00236 //---------------------------------------------------------------------------------------------------------------------
00237 
00238 //---------------------------------------------------------------------------------------------------------------------
00239 // USAGE EXAMPLES 
00240 //---------------------------------------------------------------------------------------------------------------------
00241 
00242 /***
00243 
00244 namespace ns
00245 {
00246   // NO INHERITANCE FROM INSTRUMENTED BASE CLASS
00247   class Base
00248   {
00249     VL_INSTRUMENT_BASE_CLASS(Base)
00250   };
00251 
00252   // SIMPLE INHERITANCE OF INSTRUMENTED CLASS
00253   class ClassA: public virtual Base
00254   {
00255     VL_INSTRUMENT_CLASS(ns::ClassA, Base)
00256   };
00257 
00258   // SIMPLE INHERITANCE OF INSTRUMENTED CLASS
00259   class ClassB: public virtual Base
00260   {
00261     VL_INSTRUMENT_CLASS(ns::ClassB, Base)
00262   };
00263 
00264   // MULTIPLE INHERITANCE
00265   class ClassAB: public ClassA, public ClassB
00266   {
00267     VL_INSTRUMENT_CLASS_2(ns::ClassAB, ClassA, ClassB)
00268   };
00269 
00270   // TEMPLATE CLASSES WITH MORE THAN 1 PARAMS
00271   template<class T1, class T2>
00272   class ClassT: public Base
00273   {
00274     VL_INSTRUMENT_CLASS(VL_GROUP(ns::ClassT<T1, T2>), Base)
00275   };
00276 
00277   // SUBCLASSES OF TEMPLATES WITH MORE THAN 1 PARAMS
00278   class ClassSubT: public ClassT<int, float>
00279   {
00280     VL_INSTRUMENT_CLASS(ns::ClassSubT, VL_GROUP(ClassT<int, float>))
00281   };
00282 }
00283 
00284 IMPORTANT NOTE:
00285   - The "ClassName" parameter of VL_INSTRUMENT_* should ALWAYS specify the full NAMESPACE.
00286   - The "BaseClass" parameter of VL_INSTRUMENT_* should not specify the namespace unless strictly necessary.
00287 
00288 --- dynamic casting example ---
00289 
00290 ns::ClassAB AB;
00291 ns::ClassA* pA = &AB;
00292 ns::ClassB* pB = &AB;
00293 assert( vl::cast<ns::ClassAB>(pA)   != NULL )
00294 assert( vl::cast<ns::ClassAB>(pB)   != NULL )
00295 assert( vl::cast<ns::ClassSubT>(pA) == NULL )
00296 
00297 or
00298 
00299 assert( pA->as<ns::ClassAB>()   != NULL )
00300 assert( pB->as<ns::ClassAB>()   != NULL )
00301 assert( pA->as<ns::ClassSubT>() == NULL )
00302 
00303 NOTE THAT UNLIKE dynamic_cast<> AND static_cast<> WE USE:
00304 
00305   vl::cast<ns::ClassAB>(pB)
00306 
00307 INSTEAD OF:
00308 
00309   vl::cast<ns::ClassAB*>(pB)
00310 
00311 REMARKS:
00312   
00313   There is no need to say that, similarly to dynamic_cast<>, one should avoid using VL TypeInfo facilities
00314   inside "fast" loops otherwise they won't be that "fast" anymore!
00315 
00316 ***/
00317 
00318 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:32.
Permission is granted to use this page to write and publish articles regarding Visualization Library.