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