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