annotate DEPENDENCIES/generic/include/boost/python/converter/arg_from_python.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
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_FROM_PYTHON_DWA2002127_HPP
Chris@16 6 # define ARG_FROM_PYTHON_DWA2002127_HPP
Chris@16 7
Chris@16 8 # include <boost/python/detail/prefix.hpp>
Chris@16 9 # include <boost/python/converter/from_python.hpp>
Chris@16 10 # include <boost/python/detail/indirect_traits.hpp>
Chris@16 11 # include <boost/type_traits/transform_traits.hpp>
Chris@16 12 # include <boost/type_traits/cv_traits.hpp>
Chris@16 13 # include <boost/python/converter/rvalue_from_python_data.hpp>
Chris@16 14 # include <boost/mpl/eval_if.hpp>
Chris@16 15 # include <boost/mpl/if.hpp>
Chris@16 16 # include <boost/mpl/identity.hpp>
Chris@16 17 # include <boost/mpl/and.hpp>
Chris@16 18 # include <boost/mpl/or.hpp>
Chris@16 19 # include <boost/mpl/not.hpp>
Chris@16 20 # include <boost/python/converter/registry.hpp>
Chris@16 21 # include <boost/python/converter/registered.hpp>
Chris@16 22 # include <boost/python/converter/registered_pointee.hpp>
Chris@16 23 # include <boost/python/detail/void_ptr.hpp>
Chris@16 24 # include <boost/python/back_reference.hpp>
Chris@16 25 # include <boost/python/detail/referent_storage.hpp>
Chris@16 26 # include <boost/python/converter/obj_mgr_arg_from_python.hpp>
Chris@16 27
Chris@16 28 namespace boost { namespace python
Chris@16 29 {
Chris@16 30 template <class T> struct arg_from_python;
Chris@16 31 }}
Chris@16 32
Chris@16 33 // This header defines Python->C++ function argument converters,
Chris@16 34 // parametrized on the argument type.
Chris@16 35
Chris@16 36 namespace boost { namespace python { namespace converter {
Chris@16 37
Chris@16 38 //
Chris@16 39 // lvalue converters
Chris@16 40 //
Chris@16 41 // These require that an lvalue of the type U is stored somewhere in
Chris@16 42 // the Python object being converted.
Chris@16 43
Chris@16 44 // Used when T == U*const&
Chris@16 45 template <class T>
Chris@16 46 struct pointer_cref_arg_from_python
Chris@16 47 {
Chris@16 48 typedef T result_type;
Chris@16 49
Chris@16 50 pointer_cref_arg_from_python(PyObject*);
Chris@16 51 T operator()() const;
Chris@16 52 bool convertible() const;
Chris@16 53
Chris@16 54 private: // storage for a U*
Chris@16 55 // needed because not all compilers will let us declare U* as the
Chris@16 56 // return type of operator() -- we return U*const& instead
Chris@16 57 typename python::detail::referent_storage<T>::type m_result;
Chris@16 58 };
Chris@16 59
Chris@16 60 // Base class for pointer and reference converters
Chris@16 61 struct arg_lvalue_from_python_base
Chris@16 62 {
Chris@16 63 public: // member functions
Chris@16 64 arg_lvalue_from_python_base(void* result);
Chris@16 65 bool convertible() const;
Chris@16 66
Chris@16 67 protected: // member functions
Chris@16 68 void*const& result() const;
Chris@16 69
Chris@16 70 private: // data members
Chris@16 71 void* m_result;
Chris@16 72 };
Chris@16 73
Chris@16 74 // Used when T == U*
Chris@16 75 template <class T>
Chris@16 76 struct pointer_arg_from_python : arg_lvalue_from_python_base
Chris@16 77 {
Chris@16 78 typedef T result_type;
Chris@16 79
Chris@16 80 pointer_arg_from_python(PyObject*);
Chris@16 81 T operator()() const;
Chris@16 82 };
Chris@16 83
Chris@16 84 // Used when T == U& and (T != V const& or T == W volatile&)
Chris@16 85 template <class T>
Chris@16 86 struct reference_arg_from_python : arg_lvalue_from_python_base
Chris@16 87 {
Chris@16 88 typedef T result_type;
Chris@16 89
Chris@16 90 reference_arg_from_python(PyObject*);
Chris@16 91 T operator()() const;
Chris@16 92 };
Chris@16 93
Chris@16 94 // ===================
Chris@16 95
Chris@16 96 //
Chris@16 97 // rvalue converters
Chris@16 98 //
Chris@16 99 // These require only that an object of type T can be created from
Chris@16 100 // the given Python object, but not that the T object exist
Chris@16 101 // somewhere in storage.
Chris@16 102 //
Chris@16 103
Chris@16 104 // Used when T is a plain value (non-pointer, non-reference) type or
Chris@16 105 // a (non-volatile) const reference to a plain value type.
Chris@16 106 template <class T>
Chris@16 107 struct arg_rvalue_from_python
Chris@16 108 {
Chris@16 109 typedef typename boost::add_reference<
Chris@16 110 T
Chris@16 111 // We can't add_const here, or it would be impossible to pass
Chris@16 112 // auto_ptr<U> args from Python to C++
Chris@16 113 >::type result_type;
Chris@16 114
Chris@16 115 arg_rvalue_from_python(PyObject*);
Chris@16 116 bool convertible() const;
Chris@16 117
Chris@16 118 # if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
Chris@16 119 typename arg_rvalue_from_python<T>::
Chris@16 120 # endif
Chris@16 121 result_type operator()();
Chris@16 122
Chris@16 123 private:
Chris@16 124 rvalue_from_python_data<result_type> m_data;
Chris@16 125 PyObject* m_source;
Chris@16 126 };
Chris@16 127
Chris@16 128
Chris@16 129 // ==================
Chris@16 130
Chris@16 131 // Converts to a (PyObject*,T) bundle, for when you need a reference
Chris@16 132 // back to the Python object
Chris@16 133 template <class T>
Chris@16 134 struct back_reference_arg_from_python
Chris@16 135 : boost::python::arg_from_python<typename T::type>
Chris@16 136 {
Chris@16 137 typedef T result_type;
Chris@16 138
Chris@16 139 back_reference_arg_from_python(PyObject*);
Chris@16 140 T operator()();
Chris@16 141 private:
Chris@16 142 typedef boost::python::arg_from_python<typename T::type> base;
Chris@16 143 PyObject* m_source;
Chris@16 144 };
Chris@16 145
Chris@16 146
Chris@16 147 // ==================
Chris@16 148
Chris@16 149 template <class C, class T, class F>
Chris@16 150 struct if_2
Chris@16 151 {
Chris@16 152 typedef typename mpl::eval_if<C, mpl::identity<T>, F>::type type;
Chris@16 153 };
Chris@16 154
Chris@16 155 // This metafunction selects the appropriate arg_from_python converter
Chris@16 156 // type for an argument of type T.
Chris@16 157 template <class T>
Chris@16 158 struct select_arg_from_python
Chris@16 159 {
Chris@16 160 typedef typename if_2<
Chris@16 161 is_object_manager<T>
Chris@16 162 , object_manager_value_arg_from_python<T>
Chris@16 163 , if_2<
Chris@16 164 is_reference_to_object_manager<T>
Chris@16 165 , object_manager_ref_arg_from_python<T>
Chris@16 166 , if_2<
Chris@16 167 is_pointer<T>
Chris@16 168 , pointer_arg_from_python<T>
Chris@16 169 , if_2<
Chris@16 170 mpl::and_<
Chris@16 171 indirect_traits::is_reference_to_pointer<T>
Chris@16 172 , indirect_traits::is_reference_to_const<T>
Chris@16 173 , mpl::not_<indirect_traits::is_reference_to_volatile<T> >
Chris@16 174 >
Chris@16 175 , pointer_cref_arg_from_python<T>
Chris@16 176 , if_2<
Chris@16 177 mpl::or_<
Chris@16 178 indirect_traits::is_reference_to_non_const<T>
Chris@16 179 , indirect_traits::is_reference_to_volatile<T>
Chris@16 180 >
Chris@16 181 , reference_arg_from_python<T>
Chris@16 182 , mpl::if_<
Chris@16 183 boost::python::is_back_reference<T>
Chris@16 184 , back_reference_arg_from_python<T>
Chris@16 185 , arg_rvalue_from_python<T>
Chris@16 186 >
Chris@16 187 >
Chris@16 188 >
Chris@16 189 >
Chris@16 190 >
Chris@16 191 >::type type;
Chris@16 192 };
Chris@16 193
Chris@16 194 // ==================
Chris@16 195
Chris@16 196 //
Chris@16 197 // implementations
Chris@16 198 //
Chris@16 199
Chris@16 200 // arg_lvalue_from_python_base
Chris@16 201 //
Chris@16 202 inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result)
Chris@16 203 : m_result(result)
Chris@16 204 {
Chris@16 205 }
Chris@16 206
Chris@16 207 inline bool arg_lvalue_from_python_base::convertible() const
Chris@16 208 {
Chris@16 209 return m_result != 0;
Chris@16 210 }
Chris@16 211
Chris@16 212 inline void*const& arg_lvalue_from_python_base::result() const
Chris@16 213 {
Chris@16 214 return m_result;
Chris@16 215 }
Chris@16 216
Chris@16 217 // pointer_cref_arg_from_python
Chris@16 218 //
Chris@16 219 namespace detail
Chris@16 220 {
Chris@16 221 // null_ptr_reference -- a function returning a reference to a null
Chris@16 222 // pointer of type U. Needed so that extractors for T*const& can
Chris@16 223 // convert Python's None.
Chris@16 224 template <class T>
Chris@16 225 struct null_ptr_owner
Chris@16 226 {
Chris@16 227 static T value;
Chris@16 228 };
Chris@16 229 template <class T> T null_ptr_owner<T>::value = 0;
Chris@16 230
Chris@16 231 template <class U>
Chris@16 232 inline U& null_ptr_reference(U&(*)())
Chris@16 233 {
Chris@16 234 return null_ptr_owner<U>::value;
Chris@16 235 }
Chris@16 236 }
Chris@16 237
Chris@16 238 template <class T>
Chris@16 239 inline pointer_cref_arg_from_python<T>::pointer_cref_arg_from_python(PyObject* p)
Chris@16 240 {
Chris@16 241 // T == U*const&: store a U* in the m_result storage. Nonzero
Chris@16 242 // indicates success. If find returns nonzero, it's a pointer to
Chris@16 243 // a U object.
Chris@16 244 python::detail::write_void_ptr_reference(
Chris@16 245 m_result.bytes
Chris@16 246 , p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters)
Chris@16 247 , (T(*)())0);
Chris@16 248 }
Chris@16 249
Chris@16 250 template <class T>
Chris@16 251 inline bool pointer_cref_arg_from_python<T>::convertible() const
Chris@16 252 {
Chris@16 253 return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
Chris@16 254 }
Chris@16 255 template <class T>
Chris@16 256 inline T pointer_cref_arg_from_python<T>::operator()() const
Chris@16 257 {
Chris@16 258 return (*(void**)m_result.bytes == Py_None) // None ==> 0
Chris@16 259 ? detail::null_ptr_reference((T(*)())0)
Chris@16 260 // Otherwise, return a U*const& to the m_result storage.
Chris@16 261 : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
Chris@16 262 }
Chris@16 263
Chris@16 264 // pointer_arg_from_python
Chris@16 265 //
Chris@16 266 template <class T>
Chris@16 267 inline pointer_arg_from_python<T>::pointer_arg_from_python(PyObject* p)
Chris@16 268 : arg_lvalue_from_python_base(
Chris@16 269 p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters))
Chris@16 270 {
Chris@16 271 }
Chris@16 272
Chris@16 273 template <class T>
Chris@16 274 inline T pointer_arg_from_python<T>::operator()() const
Chris@16 275 {
Chris@16 276 return (result() == Py_None) ? 0 : T(result());
Chris@16 277 }
Chris@16 278
Chris@16 279 // reference_arg_from_python
Chris@16 280 //
Chris@16 281 template <class T>
Chris@16 282 inline reference_arg_from_python<T>::reference_arg_from_python(PyObject* p)
Chris@16 283 : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered<T>::converters))
Chris@16 284 {
Chris@16 285 }
Chris@16 286
Chris@16 287 template <class T>
Chris@16 288 inline T reference_arg_from_python<T>::operator()() const
Chris@16 289 {
Chris@16 290 return python::detail::void_ptr_to_reference(result(), (T(*)())0);
Chris@16 291 }
Chris@16 292
Chris@16 293
Chris@16 294 // arg_rvalue_from_python
Chris@16 295 //
Chris@16 296 template <class T>
Chris@16 297 inline arg_rvalue_from_python<T>::arg_rvalue_from_python(PyObject* obj)
Chris@16 298 : m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters))
Chris@16 299 , m_source(obj)
Chris@16 300 {
Chris@16 301 }
Chris@16 302
Chris@16 303 template <class T>
Chris@16 304 inline bool arg_rvalue_from_python<T>::convertible() const
Chris@16 305 {
Chris@16 306 return m_data.stage1.convertible != 0;
Chris@16 307 }
Chris@16 308
Chris@16 309 template <class T>
Chris@16 310 inline typename arg_rvalue_from_python<T>::result_type
Chris@16 311 arg_rvalue_from_python<T>::operator()()
Chris@16 312 {
Chris@16 313 if (m_data.stage1.construct != 0)
Chris@16 314 m_data.stage1.construct(m_source, &m_data.stage1);
Chris@16 315
Chris@16 316 return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
Chris@16 317 }
Chris@16 318
Chris@16 319 // back_reference_arg_from_python
Chris@16 320 //
Chris@16 321 template <class T>
Chris@16 322 back_reference_arg_from_python<T>::back_reference_arg_from_python(PyObject* x)
Chris@16 323 : base(x), m_source(x)
Chris@16 324 {
Chris@16 325 }
Chris@16 326
Chris@16 327 template <class T>
Chris@16 328 inline T
Chris@16 329 back_reference_arg_from_python<T>::operator()()
Chris@16 330 {
Chris@16 331 return T(m_source, base::operator()());
Chris@16 332 }
Chris@16 333
Chris@16 334 }}} // namespace boost::python::converter
Chris@16 335
Chris@16 336 #endif // ARG_FROM_PYTHON_DWA2002127_HPP