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 ARG_TO_PYTHON_DWA200265_HPP
|
Chris@16
|
6 # define ARG_TO_PYTHON_DWA200265_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # include <boost/python/ptr.hpp>
|
Chris@16
|
9 # include <boost/python/tag.hpp>
|
Chris@16
|
10 # include <boost/python/to_python_indirect.hpp>
|
Chris@16
|
11
|
Chris@16
|
12 # include <boost/python/converter/registered.hpp>
|
Chris@16
|
13 # include <boost/python/converter/registered_pointee.hpp>
|
Chris@16
|
14 # include <boost/python/converter/arg_to_python_base.hpp>
|
Chris@16
|
15 # include <boost/python/converter/shared_ptr_to_python.hpp>
|
Chris@16
|
16 // Bring in specializations
|
Chris@16
|
17 # include <boost/python/converter/builtin_converters.hpp>
|
Chris@16
|
18
|
Chris@16
|
19 # include <boost/python/object/function_handle.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 # include <boost/python/base_type_traits.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 # include <boost/python/detail/indirect_traits.hpp>
|
Chris@16
|
24 # include <boost/python/detail/convertible.hpp>
|
Chris@16
|
25 # include <boost/python/detail/string_literal.hpp>
|
Chris@16
|
26 # include <boost/python/detail/value_is_shared_ptr.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 # include <boost/type_traits/cv_traits.hpp>
|
Chris@16
|
29 # include <boost/type_traits/composite_traits.hpp>
|
Chris@16
|
30 # include <boost/type_traits/function_traits.hpp>
|
Chris@16
|
31
|
Chris@16
|
32
|
Chris@16
|
33 # include <boost/mpl/or.hpp>
|
Chris@16
|
34
|
Chris@16
|
35 namespace boost { namespace python { namespace converter {
|
Chris@16
|
36
|
Chris@16
|
37 template <class T> struct is_object_manager;
|
Chris@16
|
38
|
Chris@16
|
39 namespace detail
|
Chris@16
|
40 {
|
Chris@16
|
41 template <class T>
|
Chris@16
|
42 struct function_arg_to_python : handle<>
|
Chris@16
|
43 {
|
Chris@16
|
44 function_arg_to_python(T const& x);
|
Chris@16
|
45 };
|
Chris@16
|
46
|
Chris@16
|
47 template <class T>
|
Chris@16
|
48 struct reference_arg_to_python : handle<>
|
Chris@16
|
49 {
|
Chris@16
|
50 reference_arg_to_python(T& x);
|
Chris@16
|
51 private:
|
Chris@16
|
52 static PyObject* get_object(T& x);
|
Chris@16
|
53 };
|
Chris@16
|
54
|
Chris@16
|
55 template <class T>
|
Chris@16
|
56 struct shared_ptr_arg_to_python : handle<>
|
Chris@16
|
57 {
|
Chris@16
|
58 shared_ptr_arg_to_python(T const& x);
|
Chris@16
|
59 private:
|
Chris@16
|
60 static PyObject* get_object(T& x);
|
Chris@16
|
61 };
|
Chris@16
|
62
|
Chris@16
|
63 template <class T>
|
Chris@16
|
64 struct value_arg_to_python : arg_to_python_base
|
Chris@16
|
65 {
|
Chris@16
|
66 // Throw an exception if the conversion can't succeed
|
Chris@16
|
67 value_arg_to_python(T const&);
|
Chris@16
|
68 };
|
Chris@16
|
69
|
Chris@16
|
70 template <class Ptr>
|
Chris@16
|
71 struct pointer_deep_arg_to_python : arg_to_python_base
|
Chris@16
|
72 {
|
Chris@16
|
73 // Throw an exception if the conversion can't succeed
|
Chris@16
|
74 pointer_deep_arg_to_python(Ptr);
|
Chris@16
|
75 };
|
Chris@16
|
76
|
Chris@16
|
77 template <class Ptr>
|
Chris@16
|
78 struct pointer_shallow_arg_to_python : handle<>
|
Chris@16
|
79 {
|
Chris@16
|
80 // Throw an exception if the conversion can't succeed
|
Chris@16
|
81 pointer_shallow_arg_to_python(Ptr);
|
Chris@16
|
82 private:
|
Chris@16
|
83 static PyObject* get_object(Ptr p);
|
Chris@16
|
84 };
|
Chris@16
|
85
|
Chris@16
|
86 // Convert types that manage a Python object to_python
|
Chris@16
|
87 template <class T>
|
Chris@16
|
88 struct object_manager_arg_to_python
|
Chris@16
|
89 {
|
Chris@16
|
90 object_manager_arg_to_python(T const& x) : m_src(x) {}
|
Chris@16
|
91
|
Chris@16
|
92 PyObject* get() const
|
Chris@16
|
93 {
|
Chris@16
|
94 return python::upcast<PyObject>(get_managed_object(m_src, tag));
|
Chris@16
|
95 }
|
Chris@16
|
96
|
Chris@16
|
97 private:
|
Chris@16
|
98 T const& m_src;
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template <class T>
|
Chris@16
|
102 struct select_arg_to_python
|
Chris@16
|
103 {
|
Chris@16
|
104 typedef typename unwrap_reference<T>::type unwrapped_referent;
|
Chris@16
|
105 typedef typename unwrap_pointer<T>::type unwrapped_ptr;
|
Chris@16
|
106
|
Chris@16
|
107 typedef typename mpl::if_<
|
Chris@16
|
108 // Special handling for char const[N]; interpret them as char
|
Chris@16
|
109 // const* for the sake of conversion
|
Chris@16
|
110 python::detail::is_string_literal<T const>
|
Chris@16
|
111 , arg_to_python<char const*>
|
Chris@16
|
112
|
Chris@16
|
113 , typename mpl::if_<
|
Chris@16
|
114 python::detail::value_is_shared_ptr<T>
|
Chris@16
|
115 , shared_ptr_arg_to_python<T>
|
Chris@16
|
116
|
Chris@16
|
117 , typename mpl::if_<
|
Chris@16
|
118 mpl::or_<
|
Chris@16
|
119 is_function<T>
|
Chris@16
|
120 , indirect_traits::is_pointer_to_function<T>
|
Chris@16
|
121 , is_member_function_pointer<T>
|
Chris@16
|
122 >
|
Chris@16
|
123 , function_arg_to_python<T>
|
Chris@16
|
124
|
Chris@16
|
125 , typename mpl::if_<
|
Chris@16
|
126 is_object_manager<T>
|
Chris@16
|
127 , object_manager_arg_to_python<T>
|
Chris@16
|
128
|
Chris@16
|
129 , typename mpl::if_<
|
Chris@16
|
130 is_pointer<T>
|
Chris@16
|
131 , pointer_deep_arg_to_python<T>
|
Chris@16
|
132
|
Chris@16
|
133 , typename mpl::if_<
|
Chris@16
|
134 is_pointer_wrapper<T>
|
Chris@16
|
135 , pointer_shallow_arg_to_python<unwrapped_ptr>
|
Chris@16
|
136
|
Chris@16
|
137 , typename mpl::if_<
|
Chris@16
|
138 is_reference_wrapper<T>
|
Chris@16
|
139 , reference_arg_to_python<unwrapped_referent>
|
Chris@16
|
140 , value_arg_to_python<T>
|
Chris@16
|
141 >::type
|
Chris@16
|
142 >::type
|
Chris@16
|
143 >::type
|
Chris@16
|
144 >::type
|
Chris@16
|
145 >::type
|
Chris@16
|
146 >::type
|
Chris@16
|
147 >::type
|
Chris@16
|
148
|
Chris@16
|
149 type;
|
Chris@16
|
150 };
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 template <class T>
|
Chris@16
|
154 struct arg_to_python
|
Chris@16
|
155 : detail::select_arg_to_python<T>::type
|
Chris@16
|
156 {
|
Chris@16
|
157 typedef typename detail::select_arg_to_python<T>::type base;
|
Chris@16
|
158 public: // member functions
|
Chris@16
|
159 // Throw an exception if the conversion can't succeed
|
Chris@16
|
160 arg_to_python(T const& x);
|
Chris@16
|
161 };
|
Chris@16
|
162
|
Chris@16
|
163 //
|
Chris@16
|
164 // implementations
|
Chris@16
|
165 //
|
Chris@16
|
166 namespace detail
|
Chris@16
|
167 {
|
Chris@16
|
168 // reject_raw_object_ptr -- cause a compile-time error if the user
|
Chris@16
|
169 // should pass a raw Python object pointer
|
Chris@16
|
170 using python::detail::yes_convertible;
|
Chris@16
|
171 using python::detail::no_convertible;
|
Chris@16
|
172 using python::detail::unspecialized;
|
Chris@16
|
173
|
Chris@16
|
174 template <class T> struct cannot_convert_raw_PyObject;
|
Chris@16
|
175
|
Chris@16
|
176 template <class T, class Convertibility>
|
Chris@16
|
177 struct reject_raw_object_helper
|
Chris@16
|
178 {
|
Chris@16
|
179 static void error(Convertibility)
|
Chris@16
|
180 {
|
Chris@16
|
181 cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
|
Chris@16
|
182 }
|
Chris@16
|
183 static void error(...) {}
|
Chris@16
|
184 };
|
Chris@16
|
185
|
Chris@16
|
186 template <class T>
|
Chris@16
|
187 inline void reject_raw_object_ptr(T*)
|
Chris@16
|
188 {
|
Chris@16
|
189 reject_raw_object_helper<T,yes_convertible>::error(
|
Chris@16
|
190 python::detail::convertible<PyObject const volatile*>::check((T*)0));
|
Chris@16
|
191
|
Chris@16
|
192 typedef typename remove_cv<T>::type value_type;
|
Chris@16
|
193
|
Chris@16
|
194 reject_raw_object_helper<T,no_convertible>::error(
|
Chris@16
|
195 python::detail::convertible<unspecialized*>::check(
|
Chris@16
|
196 (base_type_traits<value_type>*)0
|
Chris@16
|
197 ));
|
Chris@16
|
198 }
|
Chris@16
|
199 // ---------
|
Chris@16
|
200
|
Chris@16
|
201 template <class T>
|
Chris@16
|
202 inline function_arg_to_python<T>::function_arg_to_python(T const& x)
|
Chris@16
|
203 : handle<>(python::objects::make_function_handle(x))
|
Chris@16
|
204 {
|
Chris@16
|
205 }
|
Chris@16
|
206
|
Chris@16
|
207 template <class T>
|
Chris@16
|
208 inline value_arg_to_python<T>::value_arg_to_python(T const& x)
|
Chris@16
|
209 : arg_to_python_base(&x, registered<T>::converters)
|
Chris@16
|
210 {
|
Chris@16
|
211 }
|
Chris@16
|
212
|
Chris@16
|
213 template <class Ptr>
|
Chris@16
|
214 inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
|
Chris@16
|
215 : arg_to_python_base(x, registered_pointee<Ptr>::converters)
|
Chris@16
|
216 {
|
Chris@16
|
217 detail::reject_raw_object_ptr((Ptr)0);
|
Chris@16
|
218 }
|
Chris@16
|
219
|
Chris@16
|
220 template <class T>
|
Chris@16
|
221 inline PyObject* reference_arg_to_python<T>::get_object(T& x)
|
Chris@16
|
222 {
|
Chris@16
|
223 to_python_indirect<T&,python::detail::make_reference_holder> convert;
|
Chris@16
|
224 return convert(x);
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 template <class T>
|
Chris@16
|
228 inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
|
Chris@16
|
229 : handle<>(reference_arg_to_python<T>::get_object(x))
|
Chris@16
|
230 {
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 template <class T>
|
Chris@16
|
234 inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x)
|
Chris@16
|
235 : handle<>(shared_ptr_to_python(x))
|
Chris@16
|
236 {
|
Chris@16
|
237 }
|
Chris@16
|
238
|
Chris@16
|
239 template <class Ptr>
|
Chris@16
|
240 inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
|
Chris@16
|
241 : handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
|
Chris@16
|
242 {
|
Chris@16
|
243 detail::reject_raw_object_ptr((Ptr)0);
|
Chris@16
|
244 }
|
Chris@16
|
245
|
Chris@16
|
246 template <class Ptr>
|
Chris@16
|
247 inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
|
Chris@16
|
248 {
|
Chris@16
|
249 to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
|
Chris@16
|
250 return convert(x);
|
Chris@16
|
251 }
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 template <class T>
|
Chris@16
|
255 inline arg_to_python<T>::arg_to_python(T const& x)
|
Chris@16
|
256 : base(x)
|
Chris@16
|
257 {}
|
Chris@16
|
258
|
Chris@16
|
259 }}} // namespace boost::python::converter
|
Chris@16
|
260
|
Chris@16
|
261 #endif // ARG_TO_PYTHON_DWA200265_HPP
|