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 EXTRACT_DWA200265_HPP |
6 | # define |
7 | |
8 | # include <boost/python/detail/prefix.hpp> |
9 | |
10 | # include <boost/python/converter/object_manager.hpp> |
11 | # include <boost/python/converter/from_python.hpp> |
12 | # include <boost/python/converter/rvalue_from_python_data.hpp> |
13 | # include <boost/python/converter/registered.hpp> |
14 | # include <boost/python/converter/registered_pointee.hpp> |
15 | |
16 | # include <boost/python/object_core.hpp> |
17 | # include <boost/python/refcount.hpp> |
18 | |
19 | # include <boost/python/detail/copy_ctor_mutates_rhs.hpp> |
20 | # include <boost/python/detail/void_ptr.hpp> |
21 | # include <boost/python/detail/void_return.hpp> |
22 | # include <boost/call_traits.hpp> |
23 | |
24 | #if BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900) |
25 | # define BOOST_EXTRACT_WORKAROUND () |
26 | #else |
27 | # define |
28 | #endif |
29 | |
30 | namespace boost { namespace python { |
31 | |
32 | namespace api |
33 | { |
34 | class object; |
35 | } |
36 | |
37 | namespace converter |
38 | { |
39 | template <class Ptr> |
40 | struct |
41 | { |
42 | typedef Ptr ; |
43 | (PyObject*); |
44 | |
45 | bool check() const; |
46 | Ptr operator()() const; |
47 | |
48 | private: |
49 | PyObject* ; |
50 | void* ; |
51 | }; |
52 | |
53 | template <class Ref> |
54 | struct |
55 | { |
56 | typedef Ref ; |
57 | (PyObject*); |
58 | |
59 | bool check() const; |
60 | Ref operator()() const; |
61 | |
62 | private: |
63 | PyObject* ; |
64 | void* ; |
65 | }; |
66 | |
67 | template <class T> |
68 | struct : private noncopyable |
69 | { |
70 | typedef typename mpl::if_< |
71 | python::detail::copy_ctor_mutates_rhs<T> |
72 | , T& |
73 | , typename call_traits<T>::param_type |
74 | >::type ; |
75 | |
76 | (PyObject*); |
77 | |
78 | bool check() const; |
79 | result_type operator()() const; |
80 | private: |
81 | PyObject* ; |
82 | mutable rvalue_from_python_data<T> ; |
83 | }; |
84 | |
85 | template <class T> |
86 | struct |
87 | { |
88 | typedef T ; |
89 | (PyObject*); |
90 | |
91 | bool check() const; |
92 | result_type operator()() const; |
93 | private: |
94 | PyObject* ; |
95 | }; |
96 | |
97 | template <class T> |
98 | struct |
99 | { |
100 | BOOST_STATIC_CONSTANT( |
101 | bool, = is_object_manager<T>::value); |
102 | |
103 | BOOST_STATIC_CONSTANT( |
104 | bool, = is_pointer<T>::value); |
105 | |
106 | BOOST_STATIC_CONSTANT( |
107 | bool, = is_reference<T>::value); |
108 | |
109 | typedef typename mpl::if_c< |
110 | obj_mgr |
111 | , extract_object_manager<T> |
112 | , typename mpl::if_c< |
113 | ptr |
114 | , extract_pointer<T> |
115 | , typename mpl::if_c< |
116 | ref |
117 | , extract_reference<T> |
118 | , extract_rvalue<T> |
119 | >::type |
120 | >::type |
121 | >::type ; |
122 | }; |
123 | } |
124 | |
125 | template <class T> |
126 | struct |
127 | : converter::select_extract<T>::type |
128 | { |
129 | private: |
130 | typedef typename converter::select_extract<T>::type ; |
131 | public: |
132 | typedef typename base::result_type ; |
133 | |
134 | () const |
135 | { |
136 | return (*this)(); |
137 | } |
138 | |
139 | (PyObject*); |
140 | extract(api::object const&); |
141 | }; |
142 | |
143 | // |
144 | // Implementations |
145 | // |
146 | template <class T> |
147 | inline extract<T>::(PyObject* o) |
148 | : base(o) |
149 | { |
150 | } |
151 | |
152 | template <class T> |
153 | inline extract<T>::(api::object const& o) |
154 | : base(o.ptr()) |
155 | { |
156 | } |
157 | |
158 | namespace converter |
159 | { |
160 | template <class T> |
161 | inline extract_rvalue<T>::(PyObject* x) |
162 | : m_source(x) |
163 | , m_data( |
164 | (rvalue_from_python_stage1)(x, registered<T>::converters) |
165 | ) |
166 | { |
167 | } |
168 | |
169 | template <class T> |
170 | inline bool |
171 | extract_rvalue<T>::() const |
172 | { |
173 | return m_data.stage1.convertible; |
174 | } |
175 | |
176 | template <class T> |
177 | inline typename extract_rvalue<T>::result_type |
178 | extract_rvalue<T>::() const |
179 | { |
180 | return *(T*)( |
181 | // Only do the stage2 conversion once |
182 | m_data.stage1.convertible == m_data.storage.bytes |
183 | ? m_data.storage.bytes |
184 | : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered<T>::converters) |
185 | ); |
186 | } |
187 | |
188 | template <class Ref> |
189 | inline extract_reference<Ref>::(PyObject* obj) |
190 | : m_source(obj) |
191 | , m_result( |
192 | (get_lvalue_from_python)(obj, registered<Ref>::converters) |
193 | ) |
194 | { |
195 | } |
196 | |
197 | template <class Ref> |
198 | inline bool extract_reference<Ref>::() const |
199 | { |
200 | return m_result != 0; |
201 | } |
202 | |
203 | template <class Ref> |
204 | inline Ref extract_reference<Ref>::() const |
205 | { |
206 | if (m_result == 0) |
207 | (throw_no_reference_from_python)(m_source, registered<Ref>::converters); |
208 | |
209 | return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0); |
210 | } |
211 | |
212 | template <class Ptr> |
213 | inline extract_pointer<Ptr>::(PyObject* obj) |
214 | : m_source(obj) |
215 | , m_result( |
216 | obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee<Ptr>::converters) |
217 | ) |
218 | { |
219 | } |
220 | |
221 | template <class Ptr> |
222 | inline bool extract_pointer<Ptr>::() const |
223 | { |
224 | return m_source == Py_None || m_result != 0; |
225 | } |
226 | |
227 | template <class Ptr> |
228 | inline Ptr extract_pointer<Ptr>::() const |
229 | { |
230 | if (m_result == 0 && m_source != Py_None) |
231 | (throw_no_pointer_from_python)(m_source, registered_pointee<Ptr>::converters); |
232 | |
233 | return Ptr(m_result); |
234 | } |
235 | |
236 | template <class T> |
237 | inline extract_object_manager<T>::(PyObject* obj) |
238 | : m_source(obj) |
239 | { |
240 | } |
241 | |
242 | template <class T> |
243 | inline bool extract_object_manager<T>::() const |
244 | { |
245 | return object_manager_traits<T>::check(m_source); |
246 | } |
247 | |
248 | template <class T> |
249 | inline T extract_object_manager<T>::() const |
250 | { |
251 | return T( |
252 | object_manager_traits<T>::adopt(python::incref(m_source)) |
253 | ); |
254 | } |
255 | } |
256 | |
257 | }} // namespace boost::python::converter |
258 | |
259 | #endif // EXTRACT_DWA200265_HPP |
260 | |