ossrv_pub/boost_apis/boost/python/type_id.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright David Abrahams 2002.
       
     2 // Distributed under the Boost Software License, Version 1.0. (See
       
     3 // accompanying file LICENSE_1_0.txt or copy at
       
     4 // http://www.boost.org/LICENSE_1_0.txt)
       
     5 #ifndef TYPE_ID_DWA2002517_HPP
       
     6 # define TYPE_ID_DWA2002517_HPP
       
     7 
       
     8 # include <boost/python/detail/prefix.hpp>
       
     9 
       
    10 # include <boost/python/detail/msvc_typeinfo.hpp>
       
    11 # include <boost/operators.hpp>
       
    12 # include <typeinfo>
       
    13 # include <cstring>
       
    14 # include <boost/static_assert.hpp>
       
    15 # include <boost/detail/workaround.hpp>
       
    16 # include <boost/type_traits/same_traits.hpp>
       
    17 # include <boost/type_traits/broken_compiler_spec.hpp>
       
    18 
       
    19 #  ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
       
    20 #   if defined(__GNUC__)                                                \
       
    21     && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))   \
       
    22     && !defined(__EDG_VERSION__)
       
    23 #    define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
       
    24 #   endif
       
    25 #  endif
       
    26 
       
    27 namespace boost { namespace python { 
       
    28 
       
    29 // for this compiler at least, cross-shared-library type_info
       
    30 // comparisons don't work, so use typeid(x).name() instead. It's not
       
    31 // yet clear what the best default strategy is.
       
    32 # if (defined(__GNUC__) && __GNUC__ >= 3) \
       
    33  || defined(_AIX) \
       
    34  || (   defined(__sgi) && defined(__host_mips)) \
       
    35  || (defined(__hpux) && defined(__HP_aCC)) \
       
    36  || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
       
    37 #  define BOOST_PYTHON_TYPE_ID_NAME
       
    38 # endif 
       
    39 
       
    40 #ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
       
    41 // Runtime detection of broken cxxabi::__cxa_demangle versions,
       
    42 // to avoid #ifdef clutter.
       
    43 bool cxxabi_cxa_demangle_is_broken();
       
    44 #define BOOST_PYTHON_HAVE_CXXABI_CXA_DEMANGLE_IS_BROKEN
       
    45 #endif
       
    46 
       
    47 // type ids which represent the same information as std::type_info
       
    48 // (i.e. the top-level reference and cv-qualifiers are stripped), but
       
    49 // which works across shared libraries.
       
    50 struct type_info : private totally_ordered<type_info>
       
    51 {
       
    52     inline type_info(std::type_info const& = typeid(void));
       
    53     
       
    54     inline bool operator<(type_info const& rhs) const;
       
    55     inline bool operator==(type_info const& rhs) const;
       
    56 
       
    57     char const* name() const;
       
    58     friend BOOST_PYTHON_DECL std::ostream& operator<<(
       
    59         std::ostream&, type_info const&);
       
    60     
       
    61  private: // data members
       
    62 #  ifdef BOOST_PYTHON_TYPE_ID_NAME
       
    63     typedef char const* base_id_t;
       
    64 #  else
       
    65     typedef std::type_info const* base_id_t;
       
    66 #  endif
       
    67     
       
    68     base_id_t m_base_type;
       
    69 };
       
    70 
       
    71 #  ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
       
    72 #   define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type<T>*
       
    73 #  else
       
    74 #   define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
       
    75 #  endif
       
    76 
       
    77 template <class T>
       
    78 inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
       
    79 {
       
    80     return type_info(
       
    81 #  if !defined(_MSC_VER)                                       \
       
    82       || (!BOOST_WORKAROUND(BOOST_MSVC, <= 1300)                \
       
    83           && !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700))
       
    84         typeid(T)
       
    85 #  else // strip the decoration which msvc and Intel mistakenly leave in
       
    86         python::detail::msvc_typeid((boost::type<T>*)0)
       
    87 #  endif 
       
    88         );
       
    89 }
       
    90 
       
    91 #  if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
       
    92    || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
       
    93 // Older EDG-based compilers seems to mistakenly distinguish "int" from
       
    94 // "signed int", etc., but only in typeid() expressions. However
       
    95 // though int == signed int, the "signed" decoration is propagated
       
    96 // down into template instantiations. Explicit specialization stops
       
    97 // that from taking hold.
       
    98 
       
    99 #   define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T)              \
       
   100 template <>                                                     \
       
   101 inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T))    \
       
   102 {                                                               \
       
   103     return type_info(typeid(T));                                \
       
   104 }
       
   105 
       
   106 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
       
   107 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int)
       
   108 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long)
       
   109 // using Python's macro instead of Boost's - we don't seem to get the
       
   110 // config right all the time.
       
   111 #   ifdef HAVE_LONG_LONG
       
   112 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
       
   113 #   endif
       
   114 #   undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
       
   115 #  endif
       
   116 
       
   117 //
       
   118 inline type_info::type_info(std::type_info const& id)
       
   119     : m_base_type(
       
   120 #  ifdef BOOST_PYTHON_TYPE_ID_NAME
       
   121         id.name()
       
   122 #  else
       
   123         &id
       
   124 #  endif
       
   125         )
       
   126 {
       
   127 }
       
   128 
       
   129 inline bool type_info::operator<(type_info const& rhs) const
       
   130 {
       
   131 #  ifdef BOOST_PYTHON_TYPE_ID_NAME
       
   132     return std::strcmp(m_base_type, rhs.m_base_type) < 0;
       
   133 #  else
       
   134     return m_base_type->before(*rhs.m_base_type);
       
   135 #  endif 
       
   136 }
       
   137 
       
   138 inline bool type_info::operator==(type_info const& rhs) const
       
   139 {
       
   140 #  ifdef BOOST_PYTHON_TYPE_ID_NAME
       
   141     return !std::strcmp(m_base_type, rhs.m_base_type);
       
   142 #  else
       
   143     return *m_base_type == *rhs.m_base_type;
       
   144 #  endif 
       
   145 }
       
   146 
       
   147 #  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
       
   148 namespace detail
       
   149 {
       
   150   BOOST_PYTHON_DECL char const* gcc_demangle(char const*);
       
   151 }
       
   152 #  endif
       
   153     
       
   154 inline char const* type_info::name() const
       
   155 {
       
   156     char const* raw_name
       
   157         = m_base_type
       
   158 #  ifndef BOOST_PYTHON_TYPE_ID_NAME
       
   159           ->name()
       
   160 #  endif
       
   161         ;
       
   162     
       
   163 #  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
       
   164     return detail::gcc_demangle(raw_name);
       
   165 #  else
       
   166     return raw_name;
       
   167 #  endif 
       
   168 }
       
   169 
       
   170 
       
   171 BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);
       
   172 
       
   173 #  if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
       
   174 template<>
       
   175 inline type_info type_id<void>(BOOST_PYTHON_EXPLICIT_TT_DEF(void))
       
   176 {
       
   177     return type_info (typeid (void *));
       
   178 }
       
   179 #   ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
       
   180 template<>
       
   181 inline type_info type_id<const volatile void>(BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile void))
       
   182 {
       
   183     return type_info (typeid (void *));
       
   184 }
       
   185 #  endif
       
   186 
       
   187 # endif 
       
   188 
       
   189 }} // namespace boost::python
       
   190 
       
   191 #endif // TYPE_ID_DWA2002517_HPP