libcwd: The C++ Debugging Support Library - Reference Manual
Author: Carlo Wood
Description: C++ debugging support library with ostream debug output
Keywords: libcwd, debug output, debug facility, debug channel, object orientation, OO, C++, nested debug output, ostream, memory allocation, debugging, source file and line number

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$
    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 #ifndef LIBCWD_DOXYGEN
    00237 // Prototype of `type_info_of'.
    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&)                // If we don't use a reference, this would _still_ cause the copy constructor to be called.
    00278                                         // Besides, using `const&' doesn't harm the result as typeid() always ignores the top-level
    00279                                         // CV-qualifiers anyway (see C++ standard ISO+IEC+14882, 5.2.8 point 5).
    00280   {
    00281     return _private_::type_info<T>::value();
    00282   }
    00283
    00284 extern type_info_ct const unknown_type_info_c;
    00285
    00288 } // namespace libcwd
    00289
    00290 #endif // LIBCWD_TYPE_INFO_H