]> Creatis software - crea.git/blob - src/creaRTTI.h
Feature #1763
[crea.git] / src / creaRTTI.h
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image 
5 #                        pour la Santé)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 #
8 #  This software is governed by the CeCILL-B license under French law and 
9 #  abiding by the rules of distribution of free software. You can  use, 
10 #  modify and/ or redistribute the software under the terms of the CeCILL-B 
11 #  license as circulated by CEA, CNRS and INRIA at the following URL 
12 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
13 #  or in the file LICENSE.txt.
14 #
15 #  As a counterpart to the access to the source code and  rights to copy,
16 #  modify and redistribute granted by the license, users are provided only
17 #  with a limited warranty  and the software's author,  the holder of the
18 #  economic rights,  and the successive licensors  have only  limited
19 #  liability. 
20 #
21 #  The fact that you are presently reading this means that you have had
22 #  knowledge of the CeCILL-B license and that you accept its terms.
23 # ------------------------------------------------------------------------ */ 
24
25 /*=========================================================================
26                                                                                 
27   Program:   crea
28   Module:    $RCSfile: creaRTTI.h,v $
29   Language:  C++
30   Date:      $Date: 2012/11/15 09:07:32 $
31   Version:   $Revision: 1.3 $
32     
33 =========================================================================*/
34 /**
35  *\file
36  *\brief RTTI tools (system dependent).
37  */
38
39 #ifndef __CREARTTI_H_INCLUDED__
40 #define __CREARTTI_H_INCLUDED__
41
42 #include "creaSystem.h"
43 #include <vector>
44
45 //-----------------------------------------------------------------------------
46 // RRTI type_info.name() demangling
47 // For type_info.name() demangling (gcc >= 3.1, see http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaceabi.html)
48 // Test for GCC > 3.1.0 //
49 #if __GNUC__ > 3 ||                                     \
50   (__GNUC__ == 3 && (__GNUC_MINOR__ > 1 ||              \
51                      (__GNUC_MINOR__ == 1 &&            \
52                       __GNUC_PATCHLEVEL__ > 0)))
53 #include <cxxabi.h>
54 #include <stdlib.h>
55 namespace crea
56 {
57   inline std::string demangle_type_name(const char* name) 
58   {
59     int  status;
60     char* dem = abi::__cxa_demangle(name, 0, 0, &status);
61     std::string demangled(dem);
62     free(dem);
63     if (!status) return demangled;
64     return name;
65   }
66
67 }
68
69 #define CREA_DEMANGLE_TYPE_NAME(NAME) crea::demangle_type_name(NAME)
70
71 //==========================================================================
72 #elif defined(_WIN32)
73 // WIN32
74 //#include "Windows.h"
75 //#include "stdafx.h"
76 #include <windows.h>
77 #include <imagehlp.h>
78 // include the right library in the linker stage
79 #pragma comment( lib, "imagehlp.lib" )
80
81 namespace crea
82 {
83
84   
85   
86   
87   inline std::string demangle_type_name(const char* name) 
88   {
89     char demangled[513]; 
90     if (UnDecorateSymbolName(name, demangled, 
91                              sizeof(name), UNDNAME_COMPLETE))
92       {
93                   return name; //demangled;
94       }
95     else 
96       {
97         return name;
98       }
99   }
100 }
101 #define CREA_DEMANGLE_TYPE_NAME(NAME) crea::demangle_type_name(NAME)
102
103 #else 
104 // OTHER
105 #define CREA_DEMANGLE_TYPE_NAME(NAME) NAME
106 #endif 
107
108 #define CREA_GET_CURRENT_OBJECT_NAME \
109   CREA_DEMANGLE_TYPE_NAME(typeid(*this).name())
110
111 #define CREA_GET_TYPE_NAME(A)           \
112   CREA_DEMANGLE_TYPE_NAME(typeid(A).name())
113 //-----------------------------------------------------------------------------
114
115
116 namespace crea 
117 {
118   /// Template method which returns the name of a type
119   template <class T>
120   inline std::string TypeName() 
121   { return CREA_DEMANGLE_TYPE_NAME(typeid(T).name()); }
122   /// Template method which returns the name of the type of a variable
123   template <class T>
124   inline std::string TypeName(const T& t) 
125   { return CREA_DEMANGLE_TYPE_NAME(typeid(t).name()); }
126   /// Specialisation of TypeName when the type passed is already a type_info :
127   /// The user does not want to know the type of the type_info class but of 
128   /// the class whose type_info is passed !
129   template <> 
130   inline std::string TypeName<std::type_info>(const std::type_info& t)
131   { return CREA_DEMANGLE_TYPE_NAME(t.name()); }
132
133   /// Template method which returns the human readable name of a type
134   template <class T>
135   inline std::string HumanTypeName() 
136   { return TypeName<T>(); }
137   /// Template method which returns the human readable name of the type of a variable
138   template <class T>
139   inline std::string HumanTypeName(const T& t) 
140   { return TypeName(t); }
141   /// Specialisation of TypeName when the type passed is already a type_info :
142   /// The user does not want to know the type of the type_info class but of 
143   /// the class whose type_info is passed !
144   template <> 
145   inline std::string HumanTypeName<std::type_info>(const std::type_info& t)
146   { return TypeName<std::type_info>(t); }
147   /// Macro to specialise the template function TypeName for certain types 
148   /// (typically highly template types, such as STL types) 
149   /// in order to return a **really** human readable string
150 #define CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(TYPE,NAME)                 \
151   template <> inline std::string HumanTypeName< TYPE >()                \
152   { return NAME; }                                                      \
153     template <> inline std::string HumanTypeName< TYPE >(const TYPE&)   \
154     { return NAME; }    
155   
156   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(std::string,"String");
157   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(signed char,"Char");
158   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(signed short,"Short");
159   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(signed int,"Int");
160   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned char,"UChar");
161   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned short,"UShort");
162   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(unsigned int,"UInt");
163   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(float,"Float");
164   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(double,"Double");
165   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(bool,"Bool");
166   CREA_DEFINE_HUMAN_READABLE_TYPE_NAME(long,"Long");
167
168   // Human readable strings for std::vector
169 #define CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(TYPE)               \
170   template <> inline std::string HumanTypeName< std::vector<TYPE> >()   \
171   { return "Vector"+HumanTypeName<TYPE>(); }                            \
172     template <> inline std::string HumanTypeName< std::vector<TYPE> >   \
173     (const std::vector<TYPE>&) { return "Vector"+HumanTypeName<TYPE>(); }       
174
175   /*
176   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(int8_t);
177   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(uint8_t);
178   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(int16_t);
179   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(uint16_t);
180   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(int32_t);
181   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(uint32_t);
182   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(long);
183   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(float);
184   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(double);
185   CREA_DEFINE_HUMAN_READABLE_VECTOR_TYPE_NAME(std::string);
186 */
187 /// 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)) 
188   typedef const std::type_info& TypeInfo;
189
190
191   CREA_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
192                                   const std::type_info& source_type,
193                                   void*  source_pointer
194                                   );
195  CREA_EXPORT void*  run_time_up_or_down_cast( const std::type_info& target_type,
196                                   const std::type_info& source_type,
197                                   const void*  source_pointer
198                                   );
199
200
201 }
202
203 #endif
204