-
Notifications
You must be signed in to change notification settings - Fork 220
Expand file tree
/
Copy pathunwind_type.hpp
More file actions
172 lines (151 loc) · 4.77 KB
/
unwind_type.hpp
File metadata and controls
172 lines (151 loc) · 4.77 KB
Edit and raw actions
OlderNewer
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