rtti.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: rtti.h,v 1.27 2005/12/23 17:01:39 amoll Exp $
00005 //
00006 
00007 #ifndef BALL_COMMON_RTTI_H
00008 #define BALL_COMMON_RTTI_H
00009 
00010 #ifndef BALL_CONFIG_CONFIG_H
00011 # include <BALL/CONFIG/config.h>
00012 #endif
00013 
00014 #ifndef BALL_COMMON_H
00015 # include <BALL/common.h>
00016 #endif
00017 
00018 #include <string>
00019 #include <typeinfo>
00020 using std::string;
00021 
00022 namespace BALL 
00023 {
00024 
00025 # ifdef __GNUC__
00026   // EGCS produces a nearly unreadable name mangling that requires 
00027   // further interpretation
00028   namespace GNUDemangling 
00029   {
00030     BALL_EXPORT string demangle(string s);
00031   }
00032 # endif
00033 
00044   BALL_EXPORT string streamClassName(const std::type_info& t);
00045 
00068   namespace RTTI
00069   {
00070 
00076     template <typename T>
00077     const T& getDefault() 
00078     {
00079       static T t;
00080       return t;
00081     }
00082 
00088     template <typename T>
00089     void* getNew()
00090     {
00091       return static_cast<void*>(new T);
00092     }
00093 
00098     template <typename T>
00099     const char* getName()
00100     {
00101       return typeid(getDefault<T>()).name();
00102     }
00103 
00106     template <typename T>
00107     void* getClassID()
00108     {
00109       static char dummy;
00110       return (void*)&dummy;
00111     }
00112 
00123     template <typename T>
00124     const char* getStreamName()
00125     {
00126       // define portable names for the portable
00127       // types (some platforms use Size, some unsigned int, 
00128       // SUN CC even unsigned  for the Size type)
00129       if ((typeid(T) == typeid(Size)) 
00130           || (typeid(T) == typeid(Position))
00131           || (typeid(T) == typeid(HashIndex))
00132           || (typeid(T) == typeid(Property))
00133           || (typeid(T) == typeid(Handle)))
00134       {
00135         return "BALL::Size";
00136       }
00137       if ((typeid(T) == typeid(Index))
00138           || (typeid(T) == typeid(ErrorCode))
00139           || (typeid(T) == typeid(Distance)))
00140       {
00141         return "BALL::Index";
00142       }
00143       if (typeid(T) == typeid(::std::string))
00144       {
00145         return "::std::string";
00146       }
00147       if (typeid(T) == typeid(LongSize))
00148       {
00149         return "BALL::LongSize";
00150       }
00151       if (typeid(T) == typeid(bool))
00152       {
00153         return "bool";
00154       }
00155       if (typeid(T) == typeid(float))
00156       {
00157         return "float";
00158       }
00159       if (typeid(T) == typeid(char))
00160       {
00161         return "char";
00162       }
00163       if (typeid(T) == typeid(unsigned char))
00164       {
00165         return "unsigned_char";
00166       }
00167       if (typeid(T) == typeid(double))
00168       {
00169         return "double";
00170       }
00171       static string s("");
00172       static bool is_set = false;
00173 
00174       if (!is_set)
00175       {
00176         is_set = true;
00177         s = streamClassName(typeid(getDefault<T>()));
00178       }
00179 
00180       return s.c_str();
00181     }
00182 
00193     template <typename T, typename U>
00194     bool isKindOf(const U&  u)
00195     {
00196       return (0 != dynamic_cast<const T*>(&u));
00197     }
00198 
00216     template <typename T, typename U>
00217     T* castTo(const U& u)
00218     {
00219       return const_cast<T*>(dynamic_cast<const T*>(&u));
00220     }
00221 
00227     template <typename T, typename U>
00228     bool isInstanceOf(const U& u)
00229     {
00230       T   t;
00231       return (typeid(u) == typeid(t));
00232     }
00233 
00234   } // namespace RTTI
00235 } // namespace BALL
00236 
00237 #endif // BALL_COMMON_RTTI_H