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

libcwd/type_info.h

Go to the documentation of this file.
00001 // $Header: /cvsroot/libcwd/libcwd/include/libcwd/type_info.h,v 1.7 2004/08/13 00:59:02 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) { }
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   // type_info_of
00088 
00089   // _private_::
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   // Specialization for general pointers.
00100   // _private_::
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   // Specialization for `void*'.
00111   // _private_::
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   // _private_::
00122   template<typename T>
00123     type_info_ct type_info<T>::S_value;
00124     
00125   // _private_::
00126   template<typename T>
00127     bool type_info<T>::S_initialized;
00128 
00129   // _private_::
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   // _private_::
00142   template<typename T>
00143     type_info_ct type_info<T*>::S_value;
00144 
00145   // _private_::
00146   template<typename T>
00147     bool type_info<T*>::S_initialized;
00148 
00149   // _private_::
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 } // namespace _private_
00162 
00163 } // namespace libcwd
00164 
00165 //---------------------------------------------------------------------------------------------------
00166 // libcwd_type_info_exact
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 // Specialization for general pointers.
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 // Specialization for `void*'.
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 // Prototype of `type_info_of'.
00237 template<typename T>
00238   inline
00239   type_info_ct const&
00240   type_info_of(T const&
00241 #ifdef LIBCWD_DOXYGEN
00242       instance
00243 #endif
00244       );
00245 
00262 template<typename T>
00263   inline
00264   type_info_ct const&
00265   type_info_of(void)
00266   {
00267     return ::libcwd_type_info_exact<T>::value();
00268   }
00269 
00276 template<typename T>
00277   inline
00278   type_info_ct const&
00279   type_info_of(T const&)                // If we don't use a reference, this would _still_ cause the copy constructor to be called.
00280                                         // Besides, using `const&' doesn't harm the result as typeid() always ignores the top-level
00281                                         // CV-qualifiers anyway (see C++ standard ISO+IEC+14882, 5.2.8 point 5).
00282   {
00283     return _private_::type_info<T>::value();
00284   }
00285 
00286 extern type_info_ct const unknown_type_info_c;
00287 
00290 } // namespace libcwd
00291 
00292 #endif // LIBCWD_TYPE_INFO_H
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.