mirror of
https://github.com/boostorg/python.git
synced 2026-02-02 21:12:15 +00:00
Added reference, deep and shallow pointer to_python conversions
[SVN r13152]
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
# define POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/to_python_function_type.hpp>
|
||||
# include <boost/python/converter/pointer_type_id.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// pointee_to_python_function --
|
||||
//
|
||||
// essentially a "templated global reference" which holds the
|
||||
// converter for converting a type to Python by-value. We "normalize"
|
||||
// T by adding "const volatile&" so that fewer global variables and
|
||||
// associated static initializations are generated.
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct pointee_to_python_function_base
|
||||
{
|
||||
static to_python_function_t const& value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
to_python_function_t const&
|
||||
pointee_to_python_function_base<T>::value
|
||||
= converter::registry::get_to_python_function(pointer_type_id<T>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct pointee_to_python_function
|
||||
: detail::pointee_to_python_function_base<
|
||||
typename add_reference<
|
||||
typename add_cv<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/converter/find_from_python.hpp>
|
||||
#include <boost/python/reference.hpp>
|
||||
#include <boost/python/detail/none.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
@@ -25,7 +26,10 @@ namespace detail
|
||||
, const_cast<char*>("no to_python (by-value) converter found for type"));
|
||||
throw error_already_set();
|
||||
}
|
||||
return converter(const_cast<void*>(source));
|
||||
|
||||
return source == 0
|
||||
? python::detail::none()
|
||||
: converter(const_cast<void*>(source));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +49,14 @@ namespace detail
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_class_registered()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("class not registered for to_python type"));
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <boost/python/returning.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/python/ptr.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
@@ -42,9 +43,24 @@ X apply_X_X(PyObject* f, X x)
|
||||
return returning<X>::call(f, x);
|
||||
}
|
||||
|
||||
void apply_void_X_ref(PyObject* f, X x)
|
||||
void apply_void_X_ref(PyObject* f, X& x)
|
||||
{
|
||||
returning<X>::call(f, boost::ref(x));
|
||||
returning<void>::call(f, boost::ref(x));
|
||||
}
|
||||
|
||||
void apply_void_X_cref(PyObject* f, X const& x)
|
||||
{
|
||||
returning<void>::call(f, boost::cref(x));
|
||||
}
|
||||
|
||||
void apply_void_X_ptr(PyObject* f, X* x)
|
||||
{
|
||||
returning<void>::call(f, ptr(x));
|
||||
}
|
||||
|
||||
void apply_void_X_deep_ptr(PyObject* f, X* x)
|
||||
{
|
||||
returning<void>::call(f, x);
|
||||
}
|
||||
|
||||
int X::counter;
|
||||
@@ -56,6 +72,9 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext)
|
||||
.def("apply_void_int", apply_void_int)
|
||||
.def("apply_X_X", apply_X_X)
|
||||
.def("apply_void_X_ref", apply_void_X_ref)
|
||||
.def("apply_void_X_cref", apply_void_X_cref)
|
||||
.def("apply_void_X_ptr", apply_void_X_ptr)
|
||||
.def("apply_void_X_deep_ptr", apply_void_X_deep_ptr)
|
||||
.add(
|
||||
class_<X>("X")
|
||||
.def_init(args<int>())
|
||||
@@ -67,5 +86,4 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -27,6 +27,45 @@
|
||||
>>> apply_void_X_ref(increment, x)
|
||||
>>> x.value()
|
||||
43
|
||||
|
||||
>>> apply_void_X_cref(increment, x)
|
||||
>>> x.value() # const-ness is not respected, sorry!
|
||||
44
|
||||
|
||||
>>> last_x = 1
|
||||
>>> def decrement(x):
|
||||
... global last_x
|
||||
... last_x = x
|
||||
... if x is not None:
|
||||
... x.set(x.value() - 1)
|
||||
|
||||
>>> apply_void_X_ptr(decrement, x)
|
||||
>>> x.value()
|
||||
43
|
||||
>>> last_x.value()
|
||||
43
|
||||
>>> increment(last_x)
|
||||
>>> x.value()
|
||||
44
|
||||
>>> last_x.value()
|
||||
44
|
||||
|
||||
>>> apply_void_X_ptr(decrement, None)
|
||||
>>> assert last_x is None
|
||||
>>> x.value()
|
||||
44
|
||||
|
||||
>>> last_x = 1
|
||||
>>> apply_void_X_deep_ptr(decrement, None)
|
||||
>>> assert last_x is None
|
||||
>>> x.value()
|
||||
44
|
||||
|
||||
>>> apply_void_X_deep_ptr(decrement, x)
|
||||
>>> x.value()
|
||||
44
|
||||
>>> last_x.value()
|
||||
43
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
|
||||
Reference in New Issue
Block a user