type_id.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/detail/msvc_typeinfo.hpp>
  9. # include <boost/operators.hpp>
  10. # include <typeinfo>
  11. # include <cstring>
  12. # include <ostream>
  13. # include <boost/static_assert.hpp>
  14. # include <boost/detail/workaround.hpp>
  15. # include <boost/python/detail/type_traits.hpp>
  16. # ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
  17. # if defined(__GNUC__) \
  18. && !defined(__EDG_VERSION__)
  19. # define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
  20. # endif
  21. # endif
  22. namespace boost { namespace python {
  23. // for this compiler at least, cross-shared-library type_info
  24. // comparisons don't work, so use typeid(x).name() instead. It's not
  25. // yet clear what the best default strategy is.
  26. # if defined(__GNUC__) \
  27. || defined(_AIX) \
  28. || ( defined(__sgi) && defined(__host_mips)) \
  29. || (defined(__hpux) && defined(__HP_aCC)) \
  30. || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
  31. # define BOOST_PYTHON_TYPE_ID_NAME
  32. # endif
  33. #ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
  34. // Runtime detection of broken cxxabi::__cxa_demangle versions,
  35. // to avoid #ifdef clutter.
  36. bool cxxabi_cxa_demangle_is_broken();
  37. #define BOOST_PYTHON_HAVE_CXXABI_CXA_DEMANGLE_IS_BROKEN
  38. #endif
  39. // type ids which represent the same information as std::type_info
  40. // (i.e. the top-level reference and cv-qualifiers are stripped), but
  41. // which works across shared libraries.
  42. struct type_info : private totally_ordered<type_info>
  43. {
  44. inline type_info(std::type_info const& = typeid(void));
  45. inline bool operator<(type_info const& rhs) const;
  46. inline bool operator==(type_info const& rhs) const;
  47. char const* name() const;
  48. friend BOOST_PYTHON_DECL std::ostream& operator<<(
  49. std::ostream&, type_info const&);
  50. private: // data members
  51. # ifdef BOOST_PYTHON_TYPE_ID_NAME
  52. typedef char const* base_id_t;
  53. # else
  54. typedef std::type_info const* base_id_t;
  55. # endif
  56. base_id_t m_base_type;
  57. };
  58. // This macro is obsolete. Port away and remove.
  59. # define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
  60. template <class T>
  61. inline type_info type_id()
  62. {
  63. return type_info(
  64. # if !defined(_MSC_VER) \
  65. || !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700)
  66. typeid(T)
  67. # else // strip the decoration which Intel mistakenly leaves in
  68. python::detail::msvc_typeid((boost::type<T>*)0)
  69. # endif
  70. );
  71. }
  72. # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
  73. || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
  74. // Older EDG-based compilers seems to mistakenly distinguish "int" from
  75. // "signed int", etc., but only in typeid() expressions. However
  76. // though int == signed int, the "signed" decoration is propagated
  77. // down into template instantiations. Explicit specialization stops
  78. // that from taking hold.
  79. # define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
  80. template <> \
  81. inline type_info type_id<T>() \
  82. { \
  83. return type_info(typeid(T)); \
  84. }
  85. BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
  86. BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int)
  87. BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long)
  88. // using Python's macro instead of Boost's - we don't seem to get the
  89. // config right all the time.
  90. # ifdef HAVE_LONG_LONG
  91. BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
  92. # endif
  93. # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
  94. # endif
  95. //
  96. inline type_info::type_info(std::type_info const& id)
  97. : m_base_type(
  98. # ifdef BOOST_PYTHON_TYPE_ID_NAME
  99. id.name()
  100. # else
  101. &id
  102. # endif
  103. )
  104. {
  105. }
  106. inline bool type_info::operator<(type_info const& rhs) const
  107. {
  108. # ifdef BOOST_PYTHON_TYPE_ID_NAME
  109. return std::strcmp(m_base_type, rhs.m_base_type) < 0;
  110. # else
  111. return m_base_type->before(*rhs.m_base_type);
  112. # endif
  113. }
  114. inline bool type_info::operator==(type_info const& rhs) const
  115. {
  116. # ifdef BOOST_PYTHON_TYPE_ID_NAME
  117. return !std::strcmp(m_base_type, rhs.m_base_type);
  118. # else
  119. return *m_base_type == *rhs.m_base_type;
  120. # endif
  121. }
  122. # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
  123. namespace detail
  124. {
  125. BOOST_PYTHON_DECL char const* gcc_demangle(char const*);
  126. }
  127. # endif
  128. inline char const* type_info::name() const
  129. {
  130. char const* raw_name
  131. = m_base_type
  132. # ifndef BOOST_PYTHON_TYPE_ID_NAME
  133. ->name()
  134. # endif
  135. ;
  136. # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
  137. return detail::gcc_demangle(raw_name);
  138. # else
  139. return raw_name;
  140. # endif
  141. }
  142. BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);
  143. template<>
  144. inline type_info type_id<void>()
  145. {
  146. return type_info (typeid (void *));
  147. }
  148. # ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
  149. template<>
  150. inline type_info type_id<const volatile void>()
  151. {
  152. return type_info (typeid (void *));
  153. }
  154. # endif
  155. }} // namespace boost::python
  156. #endif // TYPE_ID_DWA2002517_HPP