]> Creatis software - crea.git/blob - src/creaRTTI.h
df9ce561380712cbb4a255d27322ef30db8b9c62
[crea.git] / src / creaRTTI.h
1 /*=========================================================================
2                                                                                 
3   Program:   crea
4   Module:    $RCSfile: creaRTTI.h,v $
5   Language:  C++
6   Date:      $Date: 2008/10/02 12:29:45 $
7   Version:   $Revision: 1.2 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See doc/license.txt or
11   http://www.creatis.insa-lyon.fr/Public/crea/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 /**
19  *\file
20  *\brief RTTI tools (system dependent).
21  */
22
23 #ifndef __CREARTTI_H_INCLUDED__
24 #define __CREARTTI_H_INCLUDED__
25
26 #include "creaSystem.h"
27 #include <vector>
28
29 //-----------------------------------------------------------------------------
30 // RRTI type_info.name() demangling
31 // For type_info.name() demangling (gcc >= 3.1, see http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaceabi.html)
32 // Test for GCC > 3.1.0 //
33 #if __GNUC__ > 3 ||                                     \
34   (__GNUC__ == 3 && (__GNUC_MINOR__ > 1 ||              \
35                      (__GNUC_MINOR__ == 1 &&            \
36                       __GNUC_PATCHLEVEL__ > 0)))
37 #include <cxxabi.h>
38 #include <stdlib.h>
39 namespace crea
40 {
41   inline std::string demangle_type_name(const char* name) 
42   {
43     int  status;
44     char* dem = abi::__cxa_demangle(name, 0, 0, &status);
45     std::string demangled(dem);
46     free(dem);
47     if (!status) return demangled;
48     return name;
49   }
50
51 }
52
53 #define CREA_DEMANGLE_TYPE_NAME(NAME) crea::demangle_type_name(NAME)
54
55 //==========================================================================
56 #elif defined(_WIN32)
57 // WIN32
58 //#include "Windows.h"
59 //#include "stdafx.h"
60 #include <windows.h>
61 #include <imagehlp.h>
62 // include the right library in the linker stage
63 #pragma comment( lib, "imagehlp.lib" )
64
65 namespace crea
66 {
67
68   
69   
70   
71   inline std::string demangle_type_name(const char* name) 
72   {
73     char demangled[513]; 
74     if (UnDecorateSymbolName(name, demangled, 
75                              sizeof(name), UNDNAME_COMPLETE))
76       {
77                   return name; //demangled;
78       }
79     else 
80       {
81         return name;
82       }
83   }
84 }
85 #define CREA_DEMANGLE_TYPE_NAME(NAME) crea::demangle_type_name(NAME)
86
87 #else 
88 // OTHER
89 #define CREA_DEMANGLE_TYPE_NAME(NAME) NAME
90 #endif 
91
92 #define CREA_GET_CURRENT_OBJECT_NAME \
93   CREA_DEMANGLE_TYPE_NAME(typeid(*this).name())
94
95 #define CREA_GET_TYPE_NAME(A)           \
96   CREA_DEMANGLE_TYPE_NAME(typeid(A).name())
97 //-----------------------------------------------------------------------------
98
99
100 namespace crea 
101 {
102   /// Template method which returns the name of a type
103   template <class T>
104   inline std::string TypeName() 
105   { return CREA_DEMANGLE_TYPE_NAME(typeid(T).name()); }
106   /// Template method which returns the name of the type of a variable
107   template <class T>
108   inline std::string TypeName(const T& t) 
109   { return CREA_DEMANGLE_TYPE_NAME(typeid(t).name()); }
110   /// Specialisation of TypeName when the type passed is already a type_info :
111   /// The user does not want to know the type of the type_info class but of 
112   /// the class whose type_info is passed !
113   template <> 
114   inline std::string TypeName<std::type_info>(const std::type_info& t)
115   { return CREA_DEMANGLE_TYPE_NAME(t.name()); }
116
117   /// Template method which returns the human readable name of a type
118   template <class T>
119   inline std::string HumanTypeName() 
120   { return TypeName<T>(); }
121   /// Template method which returns the human readable name of the type of a variable
122   template <class T>
123   inline std::string HumanTypeName(const T& t) 
124   { return TypeName(t); }
125   /// Specialisation of TypeName when the type passed is already a type_info :
126   /// The user does not want to know the type of the type_info class but of 
127   /// the class whose type_info is passed !
128   template <> 
129   inline std::string HumanTypeName<std::type_info>(const std::type_info& t)
130   { return TypeName<std::type_info>(t); }
131   /// Macro to specialise the template function TypeName for certain types 
132   /// (typically highly template types, such as STL types) 
133   /// in order to return a **really** human readable string
134 #define CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(TYPE,NAME)                 \
135   template <> inline std::string HumanTypeName< TYPE >()                \
136   { return NAME; }                                                      \
137     template <> inline std::string HumanTypeName< TYPE >(const TYPE&)   \
138     { return NAME; }    
139   
140   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(std::string,"String");
141   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(signed char,"Char");
142   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(signed short,"Short");
143   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(signed int,"Int");
144   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned char,"UChar");
145   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned short,"UShort");
146   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned int,"UInt");
147   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(float,"Float");
148   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(double,"Double");
149   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(bool,"Bool");
150   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(long,"Long");
151
152   // Human readable strings for std::vector
153 #define CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(TYPE)               \
154   template <> inline std::string HumanTypeName< std::vector<TYPE> >()   \
155   { return "Vector"+HumanTypeName<TYPE>(); }                            \
156     template <> inline std::string HumanTypeName< std::vector<TYPE> >   \
157     (const std::vector<TYPE>&) { return "Vector"+HumanTypeName<TYPE>(); }       
158
159   /*
160   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(int8_t);
161   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(uint8_t);
162   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(int16_t);
163   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(uint16_t);
164   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(int32_t);
165   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(uint32_t);
166   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(long);
167   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(float);
168   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(double);
169   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(std::string);
170 */
171 /// The crea::TypeInfo type is a const ref on std::type_info (which can only be manipulated as such (because typeid returns const std::type_info& and type_info has all constructors private)) 
172   typedef const std::type_info& TypeInfo;
173
174
175   CREA_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
176                                   const std::type_info& source_type,
177                                   void*  source_pointer
178                                   );
179  CREA_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
180                                   const std::type_info& source_type,
181                                   const void*  source_pointer
182                                   );
183
184
185 }
186
187 #endif
188