GeezerVison is showing github.com — Added reference, deep and shallow pointer to_python conversions · boostorg/python@f271726
File treeExpand file treeCollapse file tree Open diff view settings include/boost/python/converter
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +51Lines changed: 51 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// Copyright David Abrahams 2002. Permission to copy, use, | | 2 | +// modify, sell and distribute this software is granted provided this | | 3 | +// copyright notice appears in all copies. This software is provided | | 4 | +// "as is" without express or implied warranty, and with no claim as | | 5 | +// to its suitability for any purpose. | | 6 | +#ifndef POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP | | 7 | +# define POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP | | 8 | + | | 9 | +# include <boost/python/detail/wrap_python.hpp> | | 10 | +# include <boost/type_traits/transform_traits.hpp> | | 11 | +# include <boost/type_traits/cv_traits.hpp> | | 12 | +# include <boost/python/converter/type_id.hpp> | | 13 | +# include <boost/python/converter/registry.hpp> | | 14 | +# include <boost/python/converter/to_python_function_type.hpp> | | 15 | +# include <boost/python/converter/pointer_type_id.hpp> | | 16 | + | | 17 | +namespace boost { namespace python { namespace converter { | | 18 | + | | 19 | +// pointee_to_python_function -- | | 20 | +// | | 21 | +// essentially a "templated global reference" which holds the | | 22 | +// converter for converting a type to Python by-value. We "normalize" | | 23 | +// T by adding "const volatile&" so that fewer global variables and | | 24 | +// associated static initializations are generated. | | 25 | +namespace detail | | 26 | +{ | | 27 | + template <class T> | | 28 | + struct pointee_to_python_function_base | | 29 | + { | | 30 | + static to_python_function_t const& value; | | 31 | + }; | | 32 | + | | 33 | + template <class T> | | 34 | + to_python_function_t const& | | 35 | + pointee_to_python_function_base<T>::value | | 36 | + = converter::registry::get_to_python_function(pointer_type_id<T>()); | | 37 | +} | | 38 | + | | 39 | +template <class T> | | 40 | +struct pointee_to_python_function | | 41 | + : detail::pointee_to_python_function_base< | | 42 | + typename add_reference< | | 43 | + typename add_cv<T>::type | | 44 | + >::type | | 45 | + > | | 46 | +{ | | 47 | +}; | | 48 | + | | 49 | +}}} // namespace boost::python::converter | | 50 | + | | 51 | +#endif // POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP |
Collapse file Copy file name to clipboardExpand all lines: src/converter/callback.cpp +13-1Lines changed: 13 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 8 | 8 | #include <boost/python/errors.hpp> | 9 | 9 | #include <boost/python/converter/find_from_python.hpp> | 10 | 10 | #include <boost/python/reference.hpp> | | 11 | +#include <boost/python/detail/none.hpp> | 11 | 12 |
| 12 | 13 | namespace boost { namespace python { namespace converter { | 13 | 14 |
| @@ -25,7 +26,10 @@ namespace detail | 25 | 26 | , const_cast<char*>("no to_python (by-value) converter found for type")); | 26 | 27 | throw error_already_set(); | 27 | 28 | } | 28 | | - return converter(const_cast<void*>(source)); | | 29 | + | | 30 | + return source == 0 | | 31 | + ? python::detail::none() | | 32 | + : converter(const_cast<void*>(source)); | 29 | 33 | } | 30 | 34 | } | 31 | 35 |
| @@ -45,6 +49,14 @@ namespace detail | 45 | 49 | throw error_already_set(); | 46 | 50 | } | 47 | 51 | } | | 52 | + | | 53 | + BOOST_PYTHON_DECL void throw_no_class_registered() | | 54 | + { | | 55 | + PyErr_SetString( | | 56 | + PyExc_TypeError | | 57 | + , const_cast<char*>("class not registered for to_python type")); | | 58 | + throw error_already_set(); | | 59 | + } | 48 | 60 |
| 49 | 61 | BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage) | 50 | 62 | { | |
Collapse file Copy file name to clipboardExpand all lines: test/callbacks.cpp +22-4Lines changed: 22 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 7 | 7 | #include <boost/python/returning.hpp> | 8 | 8 | #include <boost/python/class.hpp> | 9 | 9 | #include <boost/ref.hpp> | | 10 | +#include <boost/python/ptr.hpp> | 10 | 11 |
| 11 | 12 | using namespace boost::python; | 12 | 13 |
| @@ -42,9 +43,24 @@ X apply_X_X(PyObject* f, X x) | 42 | 43 | return returning<X>::call(f, x); | 43 | 44 | } | 44 | 45 |
| 45 | | -void apply_void_X_ref(PyObject* f, X x) | | 46 | +void apply_void_X_ref(PyObject* f, X& x) | 46 | 47 | { | 47 | | - returning<X>::call(f, boost::ref(x)); | | 48 | + returning<void>::call(f, boost::ref(x)); | | 49 | +} | | 50 | + | | 51 | +void apply_void_X_cref(PyObject* f, X const& x) | | 52 | +{ | | 53 | + returning<void>::call(f, boost::cref(x)); | | 54 | +} | | 55 | + | | 56 | +void apply_void_X_ptr(PyObject* f, X* x) | | 57 | +{ | | 58 | + returning<void>::call(f, ptr(x)); | | 59 | +} | | 60 | + | | 61 | +void apply_void_X_deep_ptr(PyObject* f, X* x) | | 62 | +{ | | 63 | + returning<void>::call(f, x); | 48 | 64 | } | 49 | 65 |
| 50 | 66 | int X::counter; | @@ -56,6 +72,9 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) | 56 | 72 | .def("apply_void_int", apply_void_int) | 57 | 73 | .def("apply_X_X", apply_X_X) | 58 | 74 | .def("apply_void_X_ref", apply_void_X_ref) | | 75 | + .def("apply_void_X_cref", apply_void_X_cref) | | 76 | + .def("apply_void_X_ptr", apply_void_X_ptr) | | 77 | + .def("apply_void_X_deep_ptr", apply_void_X_deep_ptr) | 59 | 78 | .add( | 60 | 79 | class_<X>("X") | 61 | 80 | .def_init(args<int>()) | @@ -67,5 +86,4 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) | 67 | 86 | ; | 68 | 87 | } | 69 | 88 |
| 70 | | - | 71 | | - | | 89 | +#include "module_tail.cpp" |
Collapse file Copy file name to clipboardExpand all lines: test/callbacks.py +39Lines changed: 39 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 27 | 27 | >>> apply_void_X_ref(increment, x) | 28 | 28 | >>> x.value() | 29 | 29 | 43 | | 30 | +
| | 31 | +>>> apply_void_X_cref(increment, x) | | 32 | +>>> x.value() # const-ness is not respected, sorry! | | 33 | +44 | | 34 | +
| | 35 | +>>> last_x = 1 | | 36 | +>>> def decrement(x): | | 37 | +... global last_x | | 38 | +... last_x = x | | 39 | +... if x is not None: | | 40 | +... x.set(x.value() - 1) | | 41 | +
| | 42 | +>>> apply_void_X_ptr(decrement, x) | | 43 | +>>> x.value() | | 44 | +43 | | 45 | +>>> last_x.value() | | 46 | +43 | | 47 | +>>> increment(last_x) | | 48 | +>>> x.value() | | 49 | +44 | | 50 | +>>> last_x.value() | | 51 | +44 | | 52 | +
| | 53 | +>>> apply_void_X_ptr(decrement, None) | | 54 | +>>> assert last_x is None | | 55 | +>>> x.value() | | 56 | +44 | | 57 | +
| | 58 | +>>> last_x = 1 | | 59 | +>>> apply_void_X_deep_ptr(decrement, None) | | 60 | +>>> assert last_x is None | | 61 | +>>> x.value() | | 62 | +44 | | 63 | +
| | 64 | +>>> apply_void_X_deep_ptr(decrement, x) | | 65 | +>>> x.value() | | 66 | +44 | | 67 | +>>> last_x.value() | | 68 | +43 | 30 | 69 | ''' | 31 | 70 |
| 32 | 71 | def run(args = None): | |
|