fix doc example typo
[boost.git] / boost / python / extract.hpp
blob4e876f5009fb5f96c233122a3e251d1686184879
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
8 # include <boost/python/detail/prefix.hpp>
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>
16 # include <boost/python/object_core.hpp>
17 # include <boost/python/refcount.hpp>
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>
25 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_WIN, <= 900)
26 // workaround for VC++ 6.x or 7.0
27 # define BOOST_EXTRACT_WORKAROUND ()
28 #else
29 # define BOOST_EXTRACT_WORKAROUND
30 #endif
32 namespace boost { namespace python {
34 namespace api
36 class object;
39 namespace converter
41 template <class Ptr>
42 struct extract_pointer
44 typedef Ptr result_type;
45 extract_pointer(PyObject*);
47 bool check() const;
48 Ptr operator()() const;
50 private:
51 PyObject* m_source;
52 void* m_result;
55 template <class Ref>
56 struct extract_reference
58 typedef Ref result_type;
59 extract_reference(PyObject*);
61 bool check() const;
62 Ref operator()() const;
64 private:
65 PyObject* m_source;
66 void* m_result;
69 template <class T>
70 struct extract_rvalue : private noncopyable
72 typedef typename mpl::if_<
73 python::detail::copy_ctor_mutates_rhs<T>
74 , T&
75 , typename call_traits<T>::param_type
76 >::type result_type;
78 extract_rvalue(PyObject*);
80 bool check() const;
81 result_type operator()() const;
82 private:
83 PyObject* m_source;
84 mutable rvalue_from_python_data<T> m_data;
87 template <class T>
88 struct extract_object_manager
90 typedef T result_type;
91 extract_object_manager(PyObject*);
93 bool check() const;
94 result_type operator()() const;
95 private:
96 PyObject* m_source;
99 template <class T>
100 struct select_extract
102 BOOST_STATIC_CONSTANT(
103 bool, obj_mgr = is_object_manager<T>::value);
105 BOOST_STATIC_CONSTANT(
106 bool, ptr = is_pointer<T>::value);
108 BOOST_STATIC_CONSTANT(
109 bool, ref = is_reference<T>::value);
111 typedef typename mpl::if_c<
112 obj_mgr
113 , extract_object_manager<T>
114 , typename mpl::if_c<
116 , extract_pointer<T>
117 , typename mpl::if_c<
119 , extract_reference<T>
120 , extract_rvalue<T>
121 >::type
122 >::type
123 >::type type;
127 template <class T>
128 struct extract
129 : converter::select_extract<T>::type
131 private:
132 typedef typename converter::select_extract<T>::type base;
133 public:
134 typedef typename base::result_type result_type;
136 operator result_type() const
138 return (*this)();
141 extract(PyObject*);
142 extract(api::object const&);
146 // Implementations
148 template <class T>
149 inline extract<T>::extract(PyObject* o)
150 : base(o)
154 template <class T>
155 inline extract<T>::extract(api::object const& o)
156 : base(o.ptr())
160 namespace converter
162 template <class T>
163 inline extract_rvalue<T>::extract_rvalue(PyObject* x)
164 : m_source(x)
165 , m_data(
166 (rvalue_from_python_stage1)(x, registered<T>::converters)
171 template <class T>
172 inline bool
173 extract_rvalue<T>::check() const
175 return m_data.stage1.convertible;
178 template <class T>
179 inline typename extract_rvalue<T>::result_type
180 extract_rvalue<T>::operator()() const
182 return *(T*)(
183 // Only do the stage2 conversion once
184 m_data.stage1.convertible == m_data.storage.bytes
185 ? m_data.storage.bytes
186 : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered<T>::converters)
190 template <class Ref>
191 inline extract_reference<Ref>::extract_reference(PyObject* obj)
192 : m_source(obj)
193 , m_result(
194 (get_lvalue_from_python)(obj, registered<Ref>::converters)
199 template <class Ref>
200 inline bool extract_reference<Ref>::check() const
202 return m_result != 0;
205 template <class Ref>
206 inline Ref extract_reference<Ref>::operator()() const
208 if (m_result == 0)
209 (throw_no_reference_from_python)(m_source, registered<Ref>::converters);
211 return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0);
214 template <class Ptr>
215 inline extract_pointer<Ptr>::extract_pointer(PyObject* obj)
216 : m_source(obj)
217 , m_result(
218 obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee<Ptr>::converters)
223 template <class Ptr>
224 inline bool extract_pointer<Ptr>::check() const
226 return m_source == Py_None || m_result != 0;
229 template <class Ptr>
230 inline Ptr extract_pointer<Ptr>::operator()() const
232 if (m_result == 0 && m_source != Py_None)
233 (throw_no_pointer_from_python)(m_source, registered_pointee<Ptr>::converters);
235 return Ptr(m_result);
238 template <class T>
239 inline extract_object_manager<T>::extract_object_manager(PyObject* obj)
240 : m_source(obj)
244 template <class T>
245 inline bool extract_object_manager<T>::check() const
247 return object_manager_traits<T>::check(m_source);
250 template <class T>
251 inline T extract_object_manager<T>::operator()() const
253 return T(
254 object_manager_traits<T>::adopt(python::incref(m_source))
259 }} // namespace boost::python::converter
261 #endif // EXTRACT_DWA200265_HPP