]> Creatis software - bbtk.git/blob - kernel/src/bbtkRTTI.h
Allow user to always forget .bbs
[bbtk.git] / kernel / src / bbtkRTTI.h
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkRTTI.h,v $
5   Language:  C++
6   Date:      $Date: 2008/01/22 15:02:00 $
7   Version:   $Revision: 1.1 $
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/bbtk/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 __BBTKRTTI_H_INCLUDED__
24 #define __BBTKRTTI_H_INCLUDED__
25
26 #include "bbtkSystem.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 namespace bbtk
39 {
40   inline std::string demangle_type_name(const char* name) 
41   {
42     int  status;
43     char* dem = abi::__cxa_demangle(name, 0, 0, &status);
44     std::string demangled(dem);
45     free(dem);
46     if (!status) return demangled;
47     return name;
48   }
49
50 }
51
52 #define BBTK_DEMANGLE_TYPE_NAME(NAME) bbtk::demangle_type_name(NAME)
53
54 //==========================================================================
55 #elif defined(_WIN32)
56 // WIN32
57 //#include "Windows.h"
58 //#include "stdafx.h"
59 #include <windows.h>
60 #include <imagehlp.h>
61 // include the right library in the linker stage
62 #pragma comment( lib, "imagehlp.lib" )
63
64 namespace bbtk
65 {
66
67   
68   
69   
70   inline std::string demangle_type_name(const char* name) 
71   {
72     char demangled[513]; 
73     if (UnDecorateSymbolName(name, demangled, 
74                              sizeof(name), UNDNAME_COMPLETE))
75       {
76                   return name; //demangled;
77       }
78     else 
79       {
80         return name;
81       }
82   }
83 }
84 #define BBTK_DEMANGLE_TYPE_NAME(NAME) bbtk::demangle_type_name(NAME)
85
86 #else 
87 // OTHER
88 #define BBTK_DEMANGLE_TYPE_NAME(NAME) NAME
89 #endif 
90
91 #define BBTK_GET_CURRENT_OBJECT_NAME \
92   BBTK_DEMANGLE_TYPE_NAME(typeid(*this).name())
93
94 #define BBTK_GET_TYPE_NAME(A)           \
95   BBTK_DEMANGLE_TYPE_NAME(typeid(A).name())
96 //-----------------------------------------------------------------------------
97
98
99 namespace bbtk 
100 {
101   /// Template method which returns the name of a type
102   template <class T>
103   inline std::string TypeName() 
104   { return BBTK_DEMANGLE_TYPE_NAME(typeid(T).name()); }
105   /// Template method which returns the name of the type of a variable
106   template <class T>
107   inline std::string TypeName(const T& t) 
108   { return BBTK_DEMANGLE_TYPE_NAME(typeid(t).name()); }
109   /// Specialisation of TypeName when the type passed is already a type_info :
110   /// The user does not want to know the type of the type_info class but of 
111   /// the class whose type_info is passed !
112   template <> 
113   inline std::string TypeName<std::type_info>(const std::type_info& t)
114   { return BBTK_DEMANGLE_TYPE_NAME(t.name()); }
115
116   /// Template method which returns the human readable name of a type
117   template <class T>
118   inline std::string HumanTypeName() 
119   { return TypeName<T>(); }
120   /// Template method which returns the human readable name of the type of a variable
121   template <class T>
122   inline std::string HumanTypeName(const T& t) 
123   { return TypeName(t); }
124   /// Specialisation of TypeName when the type passed is already a type_info :
125   /// The user does not want to know the type of the type_info class but of 
126   /// the class whose type_info is passed !
127   template <> 
128   inline std::string HumanTypeName<std::type_info>(const std::type_info& t)
129   { return TypeName<std::type_info>(t); }
130   /// Macro to specialise the template function TypeName for certain types 
131   /// (typically highly template types, such as STL types) 
132   /// in order to return a **really** human readable string
133 #define BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(TYPE,NAME)                 \
134   template <> inline std::string HumanTypeName< TYPE >()                \
135   { return NAME; }                                                      \
136     template <> inline std::string HumanTypeName< TYPE >(const TYPE&)   \
137     { return NAME; }    
138   
139   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::string,"std::string");
140   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(signed char,"char");
141   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(signed short,"short");
142   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(signed int,"int");
143   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned char,"unsigned char");
144   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned short,"unsigned short");
145   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned int,"unsigned int");
146   
147   // Human readable strings for std::vector
148   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<int8_t>,
149                                        "std::vector<char>");
150   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<uint8_t>,
151                                        "std::vector<uchar>");
152   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<int16_t>,
153                                        "std::vector<short>");
154   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<uint16_t>,
155                                        "std::vector<ushort>");
156   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<int32_t>,
157                                        "std::vector<int>");
158   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<uint32_t>,
159                                        "std::vector<uint>");
160   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<long>,
161                                        "std::vector<long>");
162   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<float>,
163                                        "std::vector<float>");
164   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<double>,
165                                        "std::vector<double>");
166   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::vector<std::string>,
167                                        "std::vector<std::string>");
168
169
170 /// The bbtk::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)) 
171   typedef const std::type_info& TypeInfo;
172
173
174   BBTK_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
175                                   const std::type_info& source_type,
176                                   void*  source_pointer
177                                   );
178  BBTK_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
179                                   const std::type_info& source_type,
180                                   const void*  source_pointer
181                                   );
182
183
184 }
185
186 #endif
187