185 lines
5.3 KiB
Plaintext
185 lines
5.3 KiB
Plaintext
|
// 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>
|
||
|
|
||
|
# ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
||
|
# if defined(__GNUC__) \
|
||
|
&& !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__) \
|
||
|
|| 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;
|
||
|
};
|
||
|
|
||
|
|
||
|
// This macro is obsolete. Port away and remove.
|
||
|
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
|
||
|
|
||
|
template <class T>
|
||
|
inline type_info type_id()
|
||
|
{
|
||
|
return type_info(
|
||
|
# if !defined(_MSC_VER) \
|
||
|
|| !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700)
|
||
|
typeid(T)
|
||
|
# else // strip the decoration which Intel mistakenly leaves 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>() \
|
||
|
{ \
|
||
|
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&);
|
||
|
|
||
|
template<>
|
||
|
inline type_info type_id<void>()
|
||
|
{
|
||
|
return type_info (typeid (void *));
|
||
|
}
|
||
|
# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||
|
template<>
|
||
|
inline type_info type_id<const volatile void>()
|
||
|
{
|
||
|
return type_info (typeid (void *));
|
||
|
}
|
||
|
# endif
|
||
|
|
||
|
}} // namespace boost::python
|
||
|
|
||
|
#endif // TYPE_ID_DWA2002517_HPP
|