stlab.adobe.com Adobe Systems Incorporated

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 /**************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google