Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Chapter 7. Utility and Infrastructure

Table of Contents

boost/python/has_back_reference.hpp
Introduction
Class template has_back_reference
Examples
boost/python/instance_holder.hpp
Introduction
Class template instance_holder
Examples
boost/python/pointee.hpp
Introduction
Class template pointee
Examples
boost/python/handle.hpp
Introduction
Class template handle
Function borrowed
Function allow_null
boost/python/type_id.hpp
Introduction
Class template type_info
Functions
Example
boost/python/ssize_t.hpp
Introduction
Typedefs
Constants

<boost/python/has_back_reference.hpp> defines the predicate metafunction 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.

A unary metafunction whose value is true iff its argument is a pointer_wrapper<>.

namespace boost { namespace python
{
    template<class WrappedClass> class has_back_reference
    {
        typedef mpl::false_ type;
    };
}}

A metafunction that is inspected by Boost.Python to determine how wrapped classes can be constructed.

type::value is an integral constant convertible to bool of unspecified type. Specializations may substitute a true-valued integral constant wrapper for type iff for each invocation of class_<WrappedClass>::def(init< type-sequence...>()) and the implicitly wrapped copy constructor (unless it is noncopyable), 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. The easiest way to provide this nested type is to derive the specialization from mpl::true_.

In C++:

#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;
using boost::shared_ptr;

struct X
{
    X(PyObject* self) : m_self(self), m_x(0) {}
    X(PyObject* self, int x) : m_self(self), m_x(x) {}
    X(PyObject* self, X const& other) : m_self(self), m_x(other.m_x) {}

    handle<> self() { return handle<>(borrowed(m_self)); }
    int get() { return m_x; }
    void set(int x) { m_x = x; }

    PyObject* m_self;
    int m_x;
};

// specialize has_back_reference for X
namespace boost { namespace python
{
  template <>
  struct has_back_reference<X>
    : mpl::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 m_x;
};

shared_ptr<Y>
Y_self(shared_ptr<Y> self) { 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.

In Python:

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

PrevUpHomeNext