source: NonGTP/Boost/boost/python/type_id.hpp @ 857

Revision 857, 5.0 KB checked in by igarcia, 18 years ago (diff)
Line 
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
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__) && __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.
41struct 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
68template <class T>
69inline 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)              \
91template <>                                                     \
92inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T))    \
93{                                                               \
94    return type_info(typeid(T));                                \
95}
96
97BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
98BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int)
99BOOST_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
103BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
104#   endif
105#   undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
106#  endif
107
108//
109inline 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
120inline 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
129inline 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
139namespace detail
140{
141  BOOST_PYTHON_DECL char const* gcc_demangle(char const*);
142}
143#  endif
144   
145inline 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
162BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);
163
164}} // namespace boost::python
165
166#endif // TYPE_ID_DWA2002517_HPP
Note: See TracBrowser for help on using the repository browser.