typeinfo.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /**************************************************************************************************/ 00008 00009 #ifndef ADOBE_TYPEINFO_HPP 00010 #define ADOBE_TYPEINFO_HPP 00011 00012 /**************************************************************************************************/ 00013 00014 #include <adobe/config.hpp> 00015 00016 #include <boost/operators.hpp> 00017 #include <boost/range/as_literal.hpp> 00018 00019 #include <cstddef> 00020 #include <functional> 00021 #include <string> 00022 #include <typeinfo> 00023 00024 #include <adobe/algorithm/copy.hpp> 00025 00026 #ifndef NDEBUG 00027 #include <iosfwd> 00028 #endif 00029 00030 /**************************************************************************************************/ 00031 00032 namespace adobe { 00033 00042 /**************************************************************************************************/ 00043 00044 namespace implementation { 00045 00046 /**************************************************************************************************/ 00047 00048 const char* cppfilt(const std::type_info& type); 00049 00050 /**************************************************************************************************/ 00051 00052 struct type_instance_t 00053 { 00054 const std::type_info* type_info_m; 00055 const char* name_m; 00056 const type_instance_t* parameter_m[6]; 00057 00058 bool requires_std_rtti() const; 00059 }; 00060 00061 template <typename O> // O models OutputIterator 00062 // requires value_type(O) == char 00063 O serialize(const type_instance_t& x, O out) 00064 { 00065 if (x.type_info_m) 00066 { return copy_sentinal(cppfilt(*x.type_info_m), out).second; } 00067 00068 out = copy_sentinal(x.name_m, out).second; 00069 if (x.parameter_m[0]) { 00070 *out++ = '<'; out = serialize(*x.parameter_m[0], out); 00071 for (const type_instance_t* const* xp = &x.parameter_m[1]; *xp; ++xp) { 00072 *out++ = ','; out = serialize(**xp, out); 00073 } 00074 *out++ = '>'; 00075 } 00076 return out; 00077 }; 00078 00079 bool before(const type_instance_t& x, const type_instance_t& y); 00080 bool operator==(const type_instance_t& x, const type_instance_t& y); 00081 00082 inline bool operator!=(const type_instance_t& x, const type_instance_t& y) { return !(x == y); } 00083 00084 /**************************************************************************************************/ 00085 00086 } // namespace implementation 00087 00088 /**************************************************************************************************/ 00089 00090 namespace version_1 { 00091 00092 00093 #ifndef ADOBE_REQUIRES_STD_RTTI 00094 #define ADOBE_REQUIRES_STD_RTTI 1 00095 #endif 00096 00097 #if !ADOBE_REQUIRES_STD_RTTI 00098 00099 template <typename T, typename Any = void> 00100 struct make_type_info 00101 { }; 00102 00103 #else 00104 00105 template <typename T, typename Any = void> 00106 struct make_type_info { static const implementation::type_instance_t value; }; 00107 00108 template <typename T, typename Any> 00109 const implementation::type_instance_t make_type_info<T, Any>::value = { &typeid(T*), 0, { 0 } }; 00110 00111 #endif 00112 00113 /**************************************************************************************************/ 00114 00115 template <typename Any, typename T0, std::size_t Size> 00116 struct make_type_info<T0[Size], Any> 00117 { 00118 static const implementation::type_instance_t value; 00119 static const char name_s[256]; 00120 }; 00121 00122 template <typename Any, typename T0, std::size_t Size> 00123 const char make_type_info<T0[Size], Any>::name_s[256] 00124 = { 'a', 'r', 'r', 'a', 'y', '[' 00125 , Size / 1000000000UL % 10 + '0' 00126 , Size / 100000000UL % 10 + '0' 00127 , Size / 10000000UL % 10 + '0' 00128 , Size / 1000000UL % 10 + '0' 00129 , Size / 100000UL % 10 + '0' 00130 , Size / 10000UL % 10 + '0' 00131 , Size / 1000UL % 10 + '0' 00132 , Size / 100UL % 10 + '0' 00133 , Size / 10UL % 10 + '0' 00134 , Size / 1UL % 10 + '0' 00135 ,']' }; 00136 00137 template <typename Any, typename T0, std::size_t Size> 00138 const implementation::type_instance_t make_type_info<T0[Size], Any>::value 00139 = { 0, &name_s[0], { &make_type_info<T0>::value} }; 00140 00141 /**************************************************************************************************/ 00142 00143 template <typename Any, typename T0, std::size_t Size> 00144 struct make_type_info<const T0[Size], Any> 00145 { 00146 static const implementation::type_instance_t value; 00147 static const char name_s[256]; 00148 }; 00149 00150 template <typename Any, typename T0, std::size_t Size> 00151 const char make_type_info<const T0[Size], Any>::name_s[256] 00152 = { 'a', 'r', 'r', 'a', 'y', '[' 00153 , Size / 1000000000UL % 10 + '0' 00154 , Size / 100000000UL % 10 + '0' 00155 , Size / 10000000UL % 10 + '0' 00156 , Size / 1000000UL % 10 + '0' 00157 , Size / 100000UL % 10 + '0' 00158 , Size / 10000UL % 10 + '0' 00159 , Size / 1000UL % 10 + '0' 00160 , Size / 100UL % 10 + '0' 00161 , Size / 10UL % 10 + '0' 00162 , Size / 1UL % 10 + '0' 00163 ,']' }; 00164 00165 template <typename Any, typename T0, std::size_t Size> 00166 const implementation::type_instance_t make_type_info<const T0[Size], Any>::value 00167 = { 0, &name_s[0], { &make_type_info<const T0>::value} }; 00168 00169 /**************************************************************************************************/ 00170 00175 class type_info_t : boost::equality_comparable<type_info_t> 00176 { 00177 public: 00178 00182 const char* name() const 00183 { return identity_m->type_info_m ? identity_m->type_info_m->name() : identity_m->name_m; } 00184 00189 bool before(const type_info_t& x) const 00190 { return adobe::implementation::before(*identity_m, *x.identity_m); } 00191 00192 bool requires_std_rtti() const 00193 { return identity_m->requires_std_rtti(); } 00194 00199 friend bool inline operator==(const type_info_t& x, const type_info_t& y) 00200 { return *x.identity_m == *y.identity_m; } 00201 00202 #ifndef NDEBUG 00203 friend std::ostream& operator<<(std::ostream& out, const type_info_t& x); 00204 #endif 00205 00206 template <typename T> 00207 friend type_info_t type_info(); 00208 00209 friend struct aggregate_type_info_t; 00210 00211 template <typename O> 00212 friend inline O serialize(const type_info_t& x, O out) 00213 { return serialize(*x.identity_m, out); } 00214 00215 private: 00216 explicit type_info_t(const implementation::type_instance_t* x) : identity_m(x) { } 00217 00218 const implementation::type_instance_t* identity_m; 00219 }; 00220 00225 template <typename T> 00226 inline type_info_t type_info() 00227 { return type_info_t(&make_type_info<T>::value); } 00228 00233 template <typename T> 00234 inline type_info_t type_info(const T&) { return type_info<const T>(); } 00235 00240 template <typename T> 00241 inline type_info_t type_info(T&) { return type_info<T>(); } 00242 00243 /**************************************************************************************************/ 00244 00245 struct aggregate_type_info_t 00246 { 00247 operator type_info_t() const { return type_info_t(&private_m); } 00248 00249 const implementation::type_instance_t& private_m; 00250 }; 00251 00252 /**************************************************************************************************/ 00253 00260 #define ADOBE_NAME_TYPE_0(name, ...) \ 00261 namespace adobe { namespace version_1 { \ 00262 template <typename Any> \ 00263 struct make_type_info<__VA_ARGS__, Any> { static const implementation::type_instance_t value; }; \ 00264 template <typename Any> \ 00265 const implementation::type_instance_t make_type_info<__VA_ARGS__, Any>::value \ 00266 = { 0, name, { 0 } }; \ 00267 } } 00268 00269 /**************************************************************************************************/ 00270 00277 #define ADOBE_NAME_TYPE_1(name, ...) \ 00278 namespace adobe { namespace version_1 { \ 00279 template <typename Any, typename T0> \ 00280 struct make_type_info<__VA_ARGS__, Any> { static const implementation::type_instance_t value; }; \ 00281 template <typename Any, typename T0> \ 00282 const implementation::type_instance_t make_type_info<__VA_ARGS__, Any>::value \ 00283 = { 0, name, { &make_type_info<T0>::value } }; \ 00284 } } 00285 00286 /**************************************************************************************************/ 00287 00295 #define ADOBE_NAME_TYPE_2(name, ...) \ 00296 namespace adobe { namespace version_1 { \ 00297 template <typename Any, typename T0, typename T1> \ 00298 struct make_type_info<__VA_ARGS__, Any> { static const implementation::type_instance_t value; }; \ 00299 template <typename Any, typename T0, typename T1> \ 00300 const implementation::type_instance_t make_type_info<__VA_ARGS__, Any>::value \ 00301 = { 0, name, { &make_type_info<T0>::value, &make_type_info<T1>::value } }; \ 00302 } } 00303 00304 /**************************************************************************************************/ 00305 00312 #define ADOBE_NAME_TYPE_3(name, ...) \ 00313 namespace adobe { namespace version_1 { \ 00314 template <typename Any, typename T0, typename T1, typename T2> \ 00315 struct make_type_info<__VA_ARGS__, Any> { static const implementation::type_instance_t value; }; \ 00316 template <typename Any, typename T0, typename T1, typename T2> \ 00317 const implementation::type_instance_t make_type_info<__VA_ARGS__, Any>::value \ 00318 = { 0, name, { &make_type_info<T0>::value, &make_type_info<T1>::value, \ 00319 &make_type_info<T2>::value} }; \ 00320 } } 00321 00322 /**************************************************************************************************/ 00323 00330 #define ADOBE_NAME_TYPE_4(name, ...) \ 00331 namespace adobe { namespace version_1 { \ 00332 template <typename Any, typename T0, typename T1, typename T2, typename T3> \ 00333 struct make_type_info<__VA_ARGS__, Any> { static const implementation::type_instance_t value; }; \ 00334 template <typename Any, typename T0, typename T1, typename T2, typename T3> \ 00335 const implementation::type_instance_t make_type_info<__VA_ARGS__, Any>::value \ 00336 = { 0, name, { &make_type_info<T0>::value, &make_type_info<T1>::value, \ 00337 &make_type_info<T2>::value, &make_type_info<T3>::value} }; \ 00338 } } 00339 00340 /**************************************************************************************************/ 00341 00348 #define ADOBE_NAME_TYPE_5(name, ...) \ 00349 namespace adobe { namespace version_1 { \ 00350 template <typename Any, typename T0, typename T1, typename T2, typename T3, typename T4> \ 00351 struct make_type_info<__VA_ARGS__, Any> { static const implementation::type_instance_t value; }; \ 00352 template <typename Any, typename T0, typename T1, typename T2, typename T3, typename T4> \ 00353 const implementation::type_instance_t make_type_info<__VA_ARGS__, Any>::value \ 00354 = { 0, name, { &make_type_info<T0>::value, &make_type_info<T1>::value, \ 00355 &make_type_info<T2>::value, &make_type_info<T3>::value, \ 00356 &make_type_info<T4>::value} }; \ 00357 } } 00358 00359 /**************************************************************************************************/ 00360 00361 } // namespace version_1 00362 00363 using version_1::make_type_info; 00364 using version_1::aggregate_type_info_t; 00365 using version_1::type_info; 00366 using version_1::type_info_t; 00367 00368 /**************************************************************************************************/ 00369 00379 class bad_cast : public std::bad_cast 00380 { 00381 public: 00382 bad_cast(); 00383 bad_cast(const std::type_info& from, const std::type_info& to); 00388 bad_cast(const type_info_t& from, const type_info_t& to); 00389 bad_cast(const bad_cast&); 00390 bad_cast& operator=(const bad_cast&); 00391 virtual ~bad_cast() throw(); 00398 virtual const char* what() const throw(); 00399 00400 private: 00401 std::string what_m; 00402 }; 00403 00404 /**************************************************************************************************/ 00405 00406 // Little endian - intended to read well in the debugger. 00407 #define ADOBE_CHAR_INT(a, b, c, d) (int(a) | (int(b) << 8) | (int(c) << 16) | (int(d) << 24)) 00408 00409 template <typename T> 00410 struct short_name { enum { value = ADOBE_CHAR_INT('u','n','k','n') }; }; 00411 00412 #define ADOBE_SHORT_NAME_TYPE(a, b, c, d, T) \ 00413 namespace adobe { \ 00414 template < > struct short_name<T> { enum { value = ADOBE_CHAR_INT(a, b, c, d) }; }; \ 00415 } 00416 00417 /**************************************************************************************************/ 00418 00419 } // namespace adobe 00420 00421 /**************************************************************************************************/ 00422 00423 namespace std { 00424 00430 template <> 00431 struct less<adobe::version_1::type_info_t> : 00432 std::binary_function<adobe::version_1::type_info_t, adobe::version_1::type_info_t, bool> 00433 { 00434 bool operator()(const adobe::version_1::type_info_t& x, 00435 const adobe::version_1::type_info_t& y) const 00436 { return x.before(y); } 00437 }; 00438 00439 } // namespace std 00440 00441 /**************************************************************************************************/ 00442 00443 ADOBE_NAME_TYPE_0("double", double) 00444 ADOBE_NAME_TYPE_0("float", float) 00445 ADOBE_NAME_TYPE_0("int", int) 00446 ADOBE_NAME_TYPE_0("short", short) 00447 ADOBE_NAME_TYPE_0("long", long) 00448 ADOBE_NAME_TYPE_0("unsigned_int", unsigned int) 00449 ADOBE_NAME_TYPE_0("unsigned_short", unsigned short) 00450 ADOBE_NAME_TYPE_0("unsigned_long", unsigned long) 00451 ADOBE_NAME_TYPE_0("char", char) 00452 ADOBE_NAME_TYPE_0("signed_char", signed char) 00453 ADOBE_NAME_TYPE_0("unsigned_char", unsigned char) 00454 ADOBE_NAME_TYPE_0("bool", bool) 00455 00456 ADOBE_NAME_TYPE_1("pointer", T0*) 00457 ADOBE_NAME_TYPE_1("const", const T0) 00458 ADOBE_NAME_TYPE_1("reference", T0&) 00459 00460 ADOBE_SHORT_NAME_TYPE('d','b','l','e', double) 00461 ADOBE_SHORT_NAME_TYPE('f','l','o','t', float) 00462 ADOBE_SHORT_NAME_TYPE('i','n','t','_', int) 00463 ADOBE_SHORT_NAME_TYPE('s','h','r','t', short) 00464 ADOBE_SHORT_NAME_TYPE('l','o','n','g', long) 00465 ADOBE_SHORT_NAME_TYPE('u','i','n','t', unsigned int) 00466 ADOBE_SHORT_NAME_TYPE('u','s','h','r', unsigned short) 00467 ADOBE_SHORT_NAME_TYPE('u','l','n','g', unsigned long) 00468 ADOBE_SHORT_NAME_TYPE('c','h','a','r', char) 00469 ADOBE_SHORT_NAME_TYPE('s','c','h','r', signed char) 00470 ADOBE_SHORT_NAME_TYPE('u','c','h','r', unsigned char) 00471 ADOBE_SHORT_NAME_TYPE('b','o','o','l', bool) 00472 00473 /**************************************************************************************************/ 00474 00475 #endif 00476 00477 /**************************************************************************************************/ |