[857] | 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
|
---|