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
8 # include <boost/python/detail/prefix.hpp>
10 # include <boost/python/detail/msvc_typeinfo.hpp>
11 # include <boost/operators.hpp>
15 # include <boost/static_assert.hpp>
16 # include <boost/detail/workaround.hpp>
17 # include <boost/type_traits/same_traits.hpp>
18 # include <boost/type_traits/broken_compiler_spec.hpp>
20 # ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
21 # if defined(__GNUC__) \
22 && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) \
23 && !defined(__EDG_VERSION__)
24 # define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
28 namespace boost
{ namespace python
{
30 // for this compiler at least, cross-shared-library type_info
31 // comparisons don't work, so use typeid(x).name() instead. It's not
32 // yet clear what the best default strategy is.
33 # if (defined(__GNUC__) && __GNUC__ >= 3) \
35 || ( defined(__sgi) && defined(__host_mips)) \
36 || (defined(__hpux) && defined(__HP_aCC)) \
37 || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
38 # define BOOST_PYTHON_TYPE_ID_NAME
41 #ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
42 // Runtime detection of broken cxxabi::__cxa_demangle versions,
43 // to avoid #ifdef clutter.
44 bool cxxabi_cxa_demangle_is_broken();
45 #define BOOST_PYTHON_HAVE_CXXABI_CXA_DEMANGLE_IS_BROKEN
48 // type ids which represent the same information as std::type_info
49 // (i.e. the top-level reference and cv-qualifiers are stripped), but
50 // which works across shared libraries.
51 struct type_info
: private totally_ordered
<type_info
>
53 inline type_info(std::type_info
const& = typeid(void));
55 inline bool operator<(type_info
const& rhs
) const;
56 inline bool operator==(type_info
const& rhs
) const;
58 char const* name() const;
59 friend BOOST_PYTHON_DECL
std::ostream
& operator<<(
60 std::ostream
&, type_info
const&);
62 private: // data members
63 # ifdef BOOST_PYTHON_TYPE_ID_NAME
64 typedef char const* base_id_t
;
66 typedef std::type_info
const* base_id_t
;
69 base_id_t m_base_type
;
72 # ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
73 # define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type<T>*
75 # define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
79 inline type_info
type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T
))
82 # if !defined(_MSC_VER) \
83 || (!BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
84 && !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700))
86 # else // strip the decoration which msvc and Intel mistakenly leave in
87 python::detail::msvc_typeid((boost::type
<T
>*)0)
92 # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
93 || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
94 // Older EDG-based compilers seems to mistakenly distinguish "int" from
95 // "signed int", etc., but only in typeid() expressions. However
96 // though int == signed int, the "signed" decoration is propagated
97 // down into template instantiations. Explicit specialization stops
98 // that from taking hold.
100 # define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
102 inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T)) \
104 return type_info(typeid(T)); \
107 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
108 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int)
109 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long)
110 // using Python's macro instead of Boost's - we don't seem to get the
111 // config right all the time.
112 # ifdef HAVE_LONG_LONG
113 BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
115 # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
119 inline type_info::type_info(std::type_info
const& id
)
121 # ifdef BOOST_PYTHON_TYPE_ID_NAME
130 inline bool type_info::operator<(type_info
const& rhs
) const
132 # ifdef BOOST_PYTHON_TYPE_ID_NAME
133 return std::strcmp(m_base_type
, rhs
.m_base_type
) < 0;
135 return m_base_type
->before(*rhs
.m_base_type
);
139 inline bool type_info::operator==(type_info
const& rhs
) const
141 # ifdef BOOST_PYTHON_TYPE_ID_NAME
142 return !std::strcmp(m_base_type
, rhs
.m_base_type
);
144 return *m_base_type
== *rhs
.m_base_type
;
148 # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
151 BOOST_PYTHON_DECL
char const* gcc_demangle(char const*);
155 inline char const* type_info::name() const
159 # ifndef BOOST_PYTHON_TYPE_ID_NAME
164 # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
165 return detail::gcc_demangle(raw_name
);
172 BOOST_PYTHON_DECL
std::ostream
& operator<<(std::ostream
&, type_info
const&);
174 # if !BOOST_WORKAROUND(BOOST_MSVC, == 1200)
176 inline type_info type_id
<void>(BOOST_PYTHON_EXPLICIT_TT_DEF(void))
178 return type_info (typeid (void *));
180 # ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
182 inline type_info type_id
<const volatile void>(BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile void))
184 return type_info (typeid (void *));
190 }} // namespace boost::python
192 #endif // TYPE_ID_DWA2002517_HPP