]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/python/detail/unwind_type.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / python / detail / unwind_type.hpp
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
7
8 # include <boost/python/detail/cv_category.hpp>
9 # include <boost/python/detail/indirect_traits.hpp>
10 # include <boost/python/detail/type_traits.hpp>
11
12 namespace boost { namespace python { namespace detail {
13
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);
21
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);
26 #endif
27
28 template <class Generator, class U>
29 inline typename Generator::result_type
30 unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
31 {
32 return Generator::execute(p);
33 }
34
35 template <class Generator, class U>
36 inline typename Generator::result_type
37 unwind_type_cv(U const* p, const_, Generator* = 0)
38 {
39 return unwind_type(const_cast<U*>(p), (Generator*)0);
40 }
41
42 template <class Generator, class U>
43 inline typename Generator::result_type
44 unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
45 {
46 return unwind_type(const_cast<U*>(p), (Generator*)0);
47 }
48
49 template <class Generator, class U>
50 inline typename Generator::result_type
51 unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
52 {
53 return unwind_type(const_cast<U*>(p), (Generator*)0);
54 }
55
56 template <class Generator, class U>
57 inline typename Generator::result_type
58 unwind_ptr_type(U* p, Generator* = 0)
59 {
60 typedef typename cv_category<U>::type tag;
61 return unwind_type_cv<Generator>(p, tag());
62 }
63
64 template <bool is_ptr>
65 struct unwind_helper
66 {
67 template <class Generator, class U>
68 static typename Generator::result_type
69 execute(U p, Generator* = 0)
70 {
71 return unwind_ptr_type(p, (Generator*)0);
72 }
73 };
74
75 template <>
76 struct unwind_helper<false>
77 {
78 template <class Generator, class U>
79 static typename Generator::result_type
80 execute(U& p, Generator* = 0)
81 {
82 return unwind_ptr_type(&p, (Generator*)0);
83 }
84 };
85
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*)
90 #else
91 unwind_type(U const& p, Generator* = 0)
92 #endif
93 {
94 return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
95 }
96
97 enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
98 template <int indirection> struct unwind_helper2;
99
100 template <>
101 struct unwind_helper2<direct_>
102 {
103 template <class Generator, class U>
104 static typename Generator::result_type
105 execute(U(*)(), Generator* = 0)
106 {
107 return unwind_ptr_type((U*)0, (Generator*)0);
108 }
109 };
110
111 template <>
112 struct unwind_helper2<pointer_>
113 {
114 template <class Generator, class U>
115 static typename Generator::result_type
116 execute(U*(*)(), Generator* = 0)
117 {
118 return unwind_ptr_type((U*)0, (Generator*)0);
119 }
120 };
121
122 template <>
123 struct unwind_helper2<reference_>
124 {
125 template <class Generator, class U>
126 static typename Generator::result_type
127 execute(U&(*)(), Generator* = 0)
128 {
129 return unwind_ptr_type((U*)0, (Generator*)0);
130 }
131 };
132
133 template <>
134 struct unwind_helper2<reference_to_pointer_>
135 {
136 template <class Generator, class U>
137 static typename Generator::result_type
138 execute(U&(*)(), Generator* = 0)
139 {
140 return unwind_ptr_type(U(0), (Generator*)0);
141 }
142 };
143
144 // Call this one with both template parameters explicitly specified
145 // and no function arguments:
146 //
147 // return unwind_type<my_generator,T>();
148 //
149 // Doesn't work if T is an array type; we could handle that case, but
150 // why bother?
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*)
155 #else
156 unwind_type(boost::type<U>*p =0, Generator* =0)
157 #endif
158 {
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
164 ? reference_
165 : 0));
166
167 return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
168 }
169
170 }}} // namespace boost::python::detail
171
172 #endif // UNWIND_TYPE_DWA200222_HPP