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