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/python/detail/type_traits.hpp>
12 namespace boost { namespace python { namespace detail {
14 #if (!defined(_MSC_VER) || _MSC_VER >= 1915)
15 // If forward declared, msvc6.5 does not recognize them as inline.
16 // However, as of msvc14.15 (_MSC_VER 1915/Visual Studio 15.8.0) name lookup is now consistent with other compilers.
17 // forward declaration, required (at least) by Tru64 cxx V6.5-042 and msvc14.15
18 template <class Generator, class U>
19 inline typename Generator::result_type
20 unwind_type(U const& p, Generator* = 0);
22 // forward declaration, required (at least) by Tru64 cxx V6.5-042 and msvc14.15
23 template <class Generator, class U>
24 inline typename Generator::result_type
25 unwind_type(boost::type<U>*p = 0, Generator* = 0);
28 template <class Generator, class U>
29 inline typename Generator::result_type
30 unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
32 return Generator::execute(p);
35 template <class Generator, class U>
36 inline typename Generator::result_type
37 unwind_type_cv(U const* p, const_, Generator* = 0)
39 return unwind_type(const_cast<U*>(p), (Generator*)0);
42 template <class Generator, class U>
43 inline typename Generator::result_type
44 unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
46 return unwind_type(const_cast<U*>(p), (Generator*)0);
49 template <class Generator, class U>
50 inline typename Generator::result_type
51 unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
53 return unwind_type(const_cast<U*>(p), (Generator*)0);
56 template <class Generator, class U>
57 inline typename Generator::result_type
58 unwind_ptr_type(U* p, Generator* = 0)
60 typedef typename cv_category<U>::type tag;
61 return unwind_type_cv<Generator>(p, tag());
64 template <bool is_ptr>
67 template <class Generator, class U>
68 static typename Generator::result_type
69 execute(U p, Generator* = 0)
71 return unwind_ptr_type(p, (Generator*)0);
76 struct unwind_helper<false>
78 template <class Generator, class U>
79 static typename Generator::result_type
80 execute(U& p, Generator* = 0)
82 return unwind_ptr_type(&p, (Generator*)0);
86 template <class Generator, class U>
87 inline typename Generator::result_type
88 #if (!defined(_MSC_VER) || _MSC_VER >= 1915)
89 unwind_type(U const& p, Generator*)
91 unwind_type(U const& p, Generator* = 0)
94 return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
97 enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
98 template <int indirection> struct unwind_helper2;
101 struct unwind_helper2<direct_>
103 template <class Generator, class U>
104 static typename Generator::result_type
105 execute(U(*)(), Generator* = 0)
107 return unwind_ptr_type((U*)0, (Generator*)0);
112 struct unwind_helper2<pointer_>
114 template <class Generator, class U>
115 static typename Generator::result_type
116 execute(U*(*)(), Generator* = 0)
118 return unwind_ptr_type((U*)0, (Generator*)0);
123 struct unwind_helper2<reference_>
125 template <class Generator, class U>
126 static typename Generator::result_type
127 execute(U&(*)(), Generator* = 0)
129 return unwind_ptr_type((U*)0, (Generator*)0);
134 struct unwind_helper2<reference_to_pointer_>
136 template <class Generator, class U>
137 static typename Generator::result_type
138 execute(U&(*)(), Generator* = 0)
140 return unwind_ptr_type(U(0), (Generator*)0);
144 // Call this one with both template parameters explicitly specified
145 // and no function arguments:
147 // return unwind_type<my_generator,T>();
149 // Doesn't work if T is an array type; we could handle that case, but
151 template <class Generator, class U>
152 inline typename Generator::result_type
153 #if (!defined(_MSC_VER) || _MSC_VER >= 1915)
154 unwind_type(boost::type<U>*, Generator*)
156 unwind_type(boost::type<U>*p =0, Generator* =0)
159 BOOST_STATIC_CONSTANT(int, indirection
160 = (is_pointer<U>::value ? pointer_ : 0)
161 + (indirect_traits::is_reference_to_pointer<U>::value
162 ? reference_to_pointer_
163 : is_lvalue_reference<U>::value
167 return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
170 }}} // namespace boost::python::detail
172 #endif // UNWIND_TYPE_DWA200222_HPP