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