...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
|
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<
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/python/handle.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) {} handle<> self() { return handle<>(borrowed(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(back_references) { class_<X>("X") .def(init<int>()) .def("self", &X::self) .def("get", &X::get) .def("set", &X::set) ; class_<Y, shared_ptr<Y> >("Y") .def(init<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 13 November, 2002
© Copyright Dave Abrahams 2002. All Rights Reserved.