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 UNWIND_TYPE_DWA200222_HPP
6 # define UNWIND_TYPE_DWA200222_HPP
8 # include <boost/python/detail/cv_category.hpp>
9 # include <boost/python/detail/indirect_traits.hpp>
10 # include <boost/type_traits/object_traits.hpp>
12 namespace boost { namespace python { namespace detail {
14 #ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline
15 // forward declaration, required (at least) by Tru64 cxx V6.5-042
16 template <class Generator, class U>
17 inline typename Generator::result_type
18 unwind_type(U const& p, Generator* = 0);
20 // forward declaration, required (at least) by Tru64 cxx V6.5-042
21 template <class Generator, class U>
22 inline typename Generator::result_type
23 unwind_type(boost::type<U>*p = 0, Generator* = 0);
26 template <class Generator, class U>
27 inline typename Generator::result_type
28 unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
30 return Generator::execute(p);
33 template <class Generator, class U>
34 inline typename Generator::result_type
35 unwind_type_cv(U const* p, const_, Generator* = 0)
37 return unwind_type(const_cast<U*>(p), (Generator*)0);
40 template <class Generator, class U>
41 inline typename Generator::result_type
42 unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
44 return unwind_type(const_cast<U*>(p), (Generator*)0);
47 template <class Generator, class U>
48 inline typename Generator::result_type
49 unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
51 return unwind_type(const_cast<U*>(p), (Generator*)0);
54 template <class Generator, class U>
55 inline typename Generator::result_type
56 unwind_ptr_type(U* p, Generator* = 0)
58 typedef typename cv_category<U>::type tag;
59 return unwind_type_cv<Generator>(p, tag());
62 template <bool is_ptr>
65 template <class Generator, class U>
66 static typename Generator::result_type
67 execute(U p, Generator* = 0)
69 return unwind_ptr_type(p, (Generator*)0);
74 struct unwind_helper<false>
76 template <class Generator, class U>
77 static typename Generator::result_type
78 execute(U& p, Generator* = 0)
80 return unwind_ptr_type(&p, (Generator*)0);
84 template <class Generator, class U>
85 inline typename Generator::result_type
87 unwind_type(U const& p, Generator*)
89 unwind_type(U const& p, Generator* = 0)
92 return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
95 enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
96 template <int indirection> struct unwind_helper2;
99 struct unwind_helper2<direct_>
101 template <class Generator, class U>
102 static typename Generator::result_type
103 execute(U(*)(), Generator* = 0)
105 return unwind_ptr_type((U*)0, (Generator*)0);
110 struct unwind_helper2<pointer_>
112 template <class Generator, class U>
113 static typename Generator::result_type
114 execute(U*(*)(), Generator* = 0)
116 return unwind_ptr_type((U*)0, (Generator*)0);
121 struct unwind_helper2<reference_>
123 template <class Generator, class U>
124 static typename Generator::result_type
125 execute(U&(*)(), Generator* = 0)
127 return unwind_ptr_type((U*)0, (Generator*)0);
132 struct unwind_helper2<reference_to_pointer_>
134 template <class Generator, class U>
135 static typename Generator::result_type
136 execute(U&(*)(), Generator* = 0)
138 return unwind_ptr_type(U(0), (Generator*)0);
142 // Call this one with both template parameters explicitly specified
143 // and no function arguments:
145 // return unwind_type<my_generator,T>();
147 // Doesn't work if T is an array type; we could handle that case, but
149 template <class Generator, class U>
150 inline typename Generator::result_type
152 unwind_type(boost::type<U>*, Generator*)
154 unwind_type(boost::type<U>*p =0, Generator* =0)
157 BOOST_STATIC_CONSTANT(int, indirection
158 = (boost::is_pointer<U>::value ? pointer_ : 0)
159 + (indirect_traits::is_reference_to_pointer<U>::value
160 ? reference_to_pointer_
161 : boost::is_reference<U>::value
165 return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
168 }}} // namespace boost::python::detail
170 #endif // UNWIND_TYPE_DWA200222_HPP