Main Page   Reference Manual   Namespace List   Compound List   Namespace Members   Compound Members   File Members  

/usr/src/libcwd/libcwd/include/libcwd/type_info.h

Go to the documentation of this file.
00001 // $Header: /cvsroot/libcwd/libcwd/include/libcwd/type_info.h,v 1.6 2004/07/14 00:29:35 libcw Exp $
00002 //
00003 // Copyright (C) 2000 - 2004, by
00004 // 
00005 // Carlo Wood, Run on IRC <carlo@alinoe.com>
00006 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
00007 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
00008 //
00009 // This file may be distributed under the terms of the Q Public License
00010 // version 1.0 as appearing in the file LICENSE.QPL included in the
00011 // packaging of this file.
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>             // Needed for typeid()
00027 #endif
00028 #ifndef LIBCW_CSTDDEF
00029 #define LIBCW_CSTDDEF
00030 #include <cstddef>              // Needed for size_t
00031 #endif
00032 
00033 namespace libcwd {
00034 
00035 namespace _private_ {
00036   extern char const* make_label(char const* mangled_name);
00037 } // namespace _private_
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) :
00056       M_type_size(0), M_type_ref_size(0), M_name(NULL), M_dem_name("<unknown type>") { }
00061   type_info_ct(char const* type_encoding, size_t s, size_t rs) :
00062       M_type_size(s), M_type_ref_size(rs), M_name(type_encoding),
00063       M_dem_name(_private_::make_label(type_encoding)) { }
00065   char const* demangled_name(void) const { return M_dem_name; }
00067   char const* name(void) const { return M_name; }
00069   size_t size(void) const { return M_type_size; }
00071   size_t ref_size(void) const { return M_type_ref_size; }
00072 };
00073 
00074 namespace _private_ {
00075 
00076   extern char const* extract_exact_name(char const*, char const* LIBCWD_COMMA_TSD_PARAM);
00077 
00078   //-------------------------------------------------------------------------------------------------
00079   // type_info_of
00080 
00081   // _private_::
00082   template<typename T>
00083     struct type_info {
00084       static type_info_ct const value_c;
00085     };
00086 
00087   // Specialization for general pointers.
00088   // _private_::
00089   template<typename T>
00090     struct type_info<T*> {
00091       static type_info_ct const value_c;
00092     };
00093 
00094   // Specialization for `void*'.
00095   // _private_::
00096   template<>
00097     struct type_info<void*> {
00098       static type_info_ct const value_c;
00099     };
00100 
00101   // NOTE:
00102   // Compiler versions 2.95.x will terminate with an "Internal compiler error"
00103   // in the line below if you use the option '-fno-rtti'.  Either upgrade to version
00104   // 2.96 or higher, or don't use '-fno-rtti'.  The exact reason for the compiler
00105   // crash is the use of `typeid'.
00106   // _private_::
00107   template<typename T>
00108     type_info_ct const type_info<T>::value_c(typeid(T).name(), sizeof(T), 0);
00109 
00110   // _private_::
00111   template<typename T>
00112     type_info_ct const type_info<T*>::value_c(typeid(T*).name(), sizeof(T*), sizeof(T));
00113 
00114 } // namespace _private_
00115 
00116 } // namespace libcwd
00117 
00118 //---------------------------------------------------------------------------------------------------
00119 // libcwd_type_info_exact
00120 
00121 template<typename T>
00122   struct libcwd_type_info_exact {
00123     static ::libcwd::type_info_ct const value_c;
00124   };
00125 
00126 // Specialization for general pointers.
00127 template<typename T>
00128   struct libcwd_type_info_exact<T*> {
00129     static ::libcwd::type_info_ct const value_c;
00130   };
00131 
00132 // Specialization for `void*'.
00133 template<>
00134   struct libcwd_type_info_exact<void*> {
00135     static ::libcwd::type_info_ct const value_c;
00136   };
00137 
00138 template<typename T>
00139   ::libcwd::type_info_ct const libcwd_type_info_exact<T>::value_c(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T>).name(), typeid(T).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T), 0);
00140 
00141 template<typename T>
00142   ::libcwd::type_info_ct const libcwd_type_info_exact<T*>::value_c(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T*>).name(), typeid(T*).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T*), sizeof(T));
00143 
00144 namespace libcwd {
00145 
00149 // Prototype of `type_info_of'.
00150 template<typename T>
00151   inline
00152   type_info_ct const&
00153   type_info_of(T const&
00154 #ifdef LIBCWD_DOXYGEN
00155       instance
00156 #endif
00157       );
00158 
00159 // This is really only necessary for GNU g++ version 2, otherwise
00160 // libcwd::type_info<>::value_c could be used directly.
00177 template<typename T>
00178   inline
00179   type_info_ct const&
00180   type_info_of(void)
00181   {
00182     return ::libcwd_type_info_exact<T>::value_c;
00183   }
00184 
00185 // We could have used type_info_of<typeof(obj)>(), but typeof(obj) doesn't
00186 // work when obj has a template parameter as type (not supported in 2.95.3 and
00187 // broken in 3.0; see also http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=2703&database=gcc).
00194 template<typename T>
00195   inline
00196   type_info_ct const&
00197   type_info_of(T const&)                // If we don't use a reference, this would _still_ cause the copy constructor to be called.
00198                                         // Besides, using `const&' doesn't harm the result as typeid() always ignores the top-level
00199                                         // CV-qualifiers anyway (see C++ standard ISO+IEC+14882, 5.2.8 point 5).
00200   {
00201     return _private_::type_info<T>::value_c;
00202   }
00203 
00204 extern type_info_ct const unknown_type_info_c;
00205 
00208 } // namespace libcwd
00209 
00210 #endif // LIBCWD_TYPE_INFO_H
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.