00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #ifndef LIBCWD_TYPE_INFO_H
00019 #define LIBCWD_TYPE_INFO_H
00020
00021 #ifndef LIBCWD_PRIVATE_THREADING_H
00022 #include <libcwd/private_threading.h>
00023 #endif
00024 #ifndef LIBCW_TYPEINFO
00025 #define LIBCW_TYPEINFO
00026 #include <typeinfo>
00027 #endif
00028 #ifndef LIBCW_CSTDDEF
00029 #define LIBCW_CSTDDEF
00030 #include <cstddef>
00031 #endif
00032
00033 namespace libcwd {
00034
00035 namespace _private_ {
00036 extern char const* make_label(char const* mangled_name);
00037 }
00038
00044 class type_info_ct {
00045 protected:
00046 size_t M_type_size;
00047 size_t M_type_ref_size;
00048 char const* M_name;
00049 char const* M_dem_name;
00050 public:
00055 type_info_ct(void) { }
00060 type_info_ct(int) : M_type_size(0), M_type_ref_size(0), M_name(NULL), M_dem_name("<unknown type>") { }
00065 void init(char const* type_encoding, size_t s, size_t rs)
00066 {
00067 M_type_size = s;
00068 M_type_ref_size = rs;
00069 M_name = type_encoding;
00070 M_dem_name = _private_::make_label(type_encoding);
00071 }
00073 char const* demangled_name(void) const { return M_dem_name; }
00075 char const* name(void) const { return M_name; }
00077 size_t size(void) const { return M_type_size; }
00079 size_t ref_size(void) const { return M_type_ref_size; }
00080 };
00081
00082 namespace _private_ {
00083
00084 extern char const* extract_exact_name(char const*, char const* LIBCWD_COMMA_TSD_PARAM);
00085
00086
00087
00088
00089
00090 template<typename T>
00091 struct type_info {
00092 private:
00093 static type_info_ct S_value;
00094 static bool S_initialized;
00095 public:
00096 static type_info_ct const& value(void);
00097 };
00098
00099
00100
00101 template<typename T>
00102 struct type_info<T*> {
00103 private:
00104 static type_info_ct S_value;
00105 static bool S_initialized;
00106 public:
00107 static type_info_ct const& value(void);
00108 };
00109
00110
00111
00112 template<>
00113 struct type_info<void*> {
00114 private:
00115 static type_info_ct S_value;
00116 static bool S_initialized;
00117 public:
00118 static type_info_ct const& value(void);
00119 };
00120
00121
00122 template<typename T>
00123 type_info_ct type_info<T>::S_value;
00124
00125
00126 template<typename T>
00127 bool type_info<T>::S_initialized;
00128
00129
00130 template<typename T>
00131 type_info_ct const& type_info<T>::value(void)
00132 {
00133 if (!S_initialized)
00134 {
00135 S_value.init(typeid(T).name(), sizeof(T), 0);
00136 S_initialized = true;
00137 }
00138 return S_value;
00139 }
00140
00141
00142 template<typename T>
00143 type_info_ct type_info<T*>::S_value;
00144
00145
00146 template<typename T>
00147 bool type_info<T*>::S_initialized;
00148
00149
00150 template<typename T>
00151 type_info_ct const& type_info<T*>::value(void)
00152 {
00153 if (!S_initialized)
00154 {
00155 S_value.init(typeid(T*).name(), sizeof(T*), sizeof(T));
00156 S_initialized = true;
00157 }
00158 return S_value;
00159 }
00160
00161 }
00162
00163 }
00164
00165
00166
00167
00168 template<typename T>
00169 struct libcwd_type_info_exact {
00170 private:
00171 static ::libcwd::type_info_ct S_value;
00172 static bool S_initialized;
00173 public:
00174 static ::libcwd::type_info_ct const& value(void);
00175 };
00176
00177
00178 template<typename T>
00179 struct libcwd_type_info_exact<T*> {
00180 private:
00181 static ::libcwd::type_info_ct S_value;
00182 static bool S_initialized;
00183 public:
00184 static ::libcwd::type_info_ct const& value(void);
00185 };
00186
00187
00188 template<>
00189 struct libcwd_type_info_exact<void*> {
00190 private:
00191 static ::libcwd::type_info_ct S_value;
00192 static bool S_initialized;
00193 public:
00194 static ::libcwd::type_info_ct const& value(void);
00195 };
00196
00197 template<typename T>
00198 ::libcwd::type_info_ct libcwd_type_info_exact<T>::S_value;
00199
00200 template<typename T>
00201 bool libcwd_type_info_exact<T>::S_initialized;
00202
00203 template<typename T>
00204 ::libcwd::type_info_ct const& libcwd_type_info_exact<T>::value(void)
00205 {
00206 if (!S_initialized)
00207 {
00208 S_value.init(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T>).name(), typeid(T).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T), 0);
00209 S_initialized = true;
00210 }
00211 return S_value;
00212 }
00213
00214 template<typename T>
00215 ::libcwd::type_info_ct libcwd_type_info_exact<T*>::S_value;
00216
00217 template<typename T>
00218 bool libcwd_type_info_exact<T*>::S_initialized;
00219
00220 template<typename T>
00221 ::libcwd::type_info_ct const& libcwd_type_info_exact<T*>::value(void)
00222 {
00223 if (!S_initialized)
00224 {
00225 S_value.init(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T*>).name(), typeid(T*).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T*), sizeof(T));
00226 S_initialized = true;
00227 }
00228 return S_value;
00229 }
00230
00231 namespace libcwd {
00232
00236 #ifndef LIBCWD_DOXYGEN
00237
00238 template<typename T>
00239 inline
00240 type_info_ct const&
00241 type_info_of(T const&);
00242 #endif
00243
00260 template<typename T>
00261 inline
00262 type_info_ct const&
00263 type_info_of(void)
00264 {
00265 return ::libcwd_type_info_exact<T>::value();
00266 }
00267
00274 template<typename T>
00275 inline
00276 type_info_ct const&
00277 type_info_of(T const&)
00278
00279
00280 {
00281 return _private_::type_info<T>::value();
00282 }
00283
00284 extern type_info_ct const unknown_type_info_c;
00285
00288 }
00289
00290 #endif // LIBCWD_TYPE_INFO_H