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 |
|
---|
18 | # ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
---|
19 | # if defined(__GNUC__) \
|
---|
20 | && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) \
|
---|
21 | && !defined(__EDG_VERSION__)
|
---|
22 | # define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
---|
23 | # endif
|
---|
24 | # endif
|
---|
25 |
|
---|
26 | namespace 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__) && __GNUC__ >= 3) \
|
---|
32 | || defined(_AIX) \
|
---|
33 | || ( defined(__sgi) && defined(__host_mips)) \
|
---|
34 | || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
|
---|
35 | # define BOOST_PYTHON_TYPE_ID_NAME
|
---|
36 | # endif
|
---|
37 |
|
---|
38 | // type ids which represent the same information as std::type_info
|
---|
39 | // (i.e. the top-level reference and cv-qualifiers are stripped), but
|
---|
40 | // which works across shared libraries.
|
---|
41 | struct type_info : private totally_ordered<type_info>
|
---|
42 | {
|
---|
43 | inline type_info(std::type_info const& = typeid(void));
|
---|
44 |
|
---|
45 | inline bool operator<(type_info const& rhs) const;
|
---|
46 | inline bool operator==(type_info const& rhs) const;
|
---|
47 |
|
---|
48 | char const* name() const;
|
---|
49 | friend BOOST_PYTHON_DECL std::ostream& operator<<(
|
---|
50 | std::ostream&, type_info const&);
|
---|
51 |
|
---|
52 | private: // data members
|
---|
53 | # ifdef BOOST_PYTHON_TYPE_ID_NAME
|
---|
54 | typedef char const* base_id_t;
|
---|
55 | # else
|
---|
56 | typedef std::type_info const* base_id_t;
|
---|
57 | # endif
|
---|
58 |
|
---|
59 | base_id_t m_base_type;
|
---|
60 | };
|
---|
61 |
|
---|
62 | # ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
|
---|
63 | # define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type<T>*
|
---|
64 | # else
|
---|
65 | # define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
|
---|
66 | # endif
|
---|
67 |
|
---|
68 | template <class T>
|
---|
69 | inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
|
---|
70 | {
|
---|
71 | return type_info(
|
---|
72 | # if !defined(_MSC_VER) \
|
---|
73 | || (!BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
---|
74 | && !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700))
|
---|
75 | typeid(T)
|
---|
76 | # else // strip the decoration which msvc and Intel mistakenly leave in
|
---|
77 | python::detail::msvc_typeid((boost::type<T>*)0)
|
---|
78 | # endif
|
---|
79 | );
|
---|
80 | }
|
---|
81 |
|
---|
82 | # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
---|
83 | || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 741)
|
---|
84 | // Older EDG-based compilers seems to mistakenly distinguish "int" from
|
---|
85 | // "signed int", etc., but only in typeid() expressions. However
|
---|
86 | // though int == signed int, the "signed" decoration is propagated
|
---|
87 | // down into template instantiations. Explicit specialization stops
|
---|
88 | // that from taking hold.
|
---|
89 |
|
---|
90 | # define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
|
---|
91 | template <> \
|
---|
92 | inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T)) \
|
---|
93 | { \
|
---|
94 | return type_info(typeid(T)); \
|
---|
95 | }
|
---|
96 |
|
---|
97 | BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
|
---|
98 | BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int)
|
---|
99 | BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long)
|
---|
100 | // using Python's macro instead of Boost's - we don't seem to get the
|
---|
101 | // config right all the time.
|
---|
102 | # ifdef HAVE_LONG_LONG
|
---|
103 | BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
|
---|
104 | # endif
|
---|
105 | # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
|
---|
106 | # endif
|
---|
107 |
|
---|
108 | //
|
---|
109 | inline type_info::type_info(std::type_info const& id)
|
---|
110 | : m_base_type(
|
---|
111 | # ifdef BOOST_PYTHON_TYPE_ID_NAME
|
---|
112 | id.name()
|
---|
113 | # else
|
---|
114 | &id
|
---|
115 | # endif
|
---|
116 | )
|
---|
117 | {
|
---|
118 | }
|
---|
119 |
|
---|
120 | inline bool type_info::operator<(type_info const& rhs) const
|
---|
121 | {
|
---|
122 | # ifdef BOOST_PYTHON_TYPE_ID_NAME
|
---|
123 | return std::strcmp(m_base_type, rhs.m_base_type) < 0;
|
---|
124 | # else
|
---|
125 | return m_base_type->before(*rhs.m_base_type);
|
---|
126 | # endif
|
---|
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);
|
---|
133 | # else
|
---|
134 | return *m_base_type == *rhs.m_base_type;
|
---|
135 | # endif
|
---|
136 | }
|
---|
137 |
|
---|
138 | # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
---|
139 | namespace detail
|
---|
140 | {
|
---|
141 | BOOST_PYTHON_DECL char const* gcc_demangle(char const*);
|
---|
142 | }
|
---|
143 | # endif
|
---|
144 |
|
---|
145 | inline char const* type_info::name() const
|
---|
146 | {
|
---|
147 | char const* raw_name
|
---|
148 | = m_base_type
|
---|
149 | # ifndef BOOST_PYTHON_TYPE_ID_NAME
|
---|
150 | ->name()
|
---|
151 | # endif
|
---|
152 | ;
|
---|
153 |
|
---|
154 | # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
---|
155 | return detail::gcc_demangle(raw_name);
|
---|
156 | # else
|
---|
157 | return raw_name;
|
---|
158 | # endif
|
---|
159 | }
|
---|
160 |
|
---|
161 |
|
---|
162 | BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);
|
---|
163 |
|
---|
164 | }} // namespace boost::python
|
---|
165 |
|
---|
166 | #endif // TYPE_ID_DWA2002517_HPP
|
---|