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

source code of boost/boost/python/type_id.hpp