2
0
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:
Dave Abrahams
2002-03-09 21:13:09 +00:00
parent 22f6612354
commit f271726cd8
4 changed files with 125 additions and 5 deletions

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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"

View File

@@ -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):