|
Boost.PythonHeader <boost/python/has_back_reference.hpp> |
has_back_reference
has_back_reference
synopsis
<boost/python/has_back_reference.hpp>
defines the traits class template
has_back_reference<>
, which can be
specialized by the user to indicate that a wrapped class
instance holds a PyObject*
corresponding to a
Python object.
has_back_reference
A unary metafunction whose value
is true iff
its argument is a pointer_wrapper<>
.
has_back_reference
synopsisnamespace boost { namespace python { template<class WrappedClass> class has_back_reference { static unspecified value = false; }; }}
A "traits class" which is inspected by Boost.Python to determine how wrapped classes can be constructed.
value
is an integral constant convertible
to bool of unspecified type.
true
for value
iff for each invocation of
class_<WrappedClass>::def_init(args<
type-sequence...>())
,
there exists a corresponding constructor
WrappedClass::WrappedClass(PyObject*,
type-sequence...)
. If
such a specialization exists, the WrappedClass
constructors will be called with a "back reference" pointer
to the corresponding Python object whenever they are invoked from
Python.
#include <boost/python/class.hpp> #include <boost/python/module.hpp> #include <boost/python/has_back_reference.hpp> #include <boost/shared_ptr.hpp> using namespace boost::python; struct X { X(PyObject* self) : m_self(self), m_x(0) {} X(PyObject* self, int x) : m_self(self), m_x(x) {} PyObject* self() { return m_self; } int get() { return m_x; } void set(int x) { m_x = x; } PyObject* m_self; int x; }; // specialize has_back_reference for X namespace boost { namespace python { template <> struct has_back_reference<X> { enum { value = true; } } }} struct Y { Y() : m_x(0) {} Y(int x) : m_x(x) {} int get() { return m_x; } void set(int x) { m_x = x; } int x; }; boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { return self; } BOOST_PYTHON_MODULE_INIT(back_references) { module("back_references") .add( class_<X>("X") .def_init() .def_init(args<int>()) .def("self", &X::self) .def("get", &X::get) .def("set", &X::set) ) .add( class_<Y, shared_ptr<Y> >("Y") .def_init() .def_init(args<int>()) .def("get", &Y::get) .def("set", &Y::set) .def("self", Y_self) ) ; }The following Python session illustrates that
x.self()
returns the same Python object on which it is invoked, while
y.self()
must create a new Python object which refers to
the same Y instance.
>>> from back_references import * >>> x = X(1) >>> x2 = x.self() >>> x2 is x 1 >>> (x.get(), x2.get()) (1, 1) >>> x.set(10) >>> (x.get(), x2.get()) (10, 10) >>> >>> >>> y = Y(2) >>> y2 = y.self() >>> y2 is y 0 >>> (y.get(), y2.get()) (2, 2) >>> y.set(20) >>> (y.get(), y2.get()) (20, 20)
Revised 07 May, 2002
© Copyright Dave Abrahams 2002. All Rights Reserved.