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

Click here to view the latest version of this page.

C++ Boost

Boost.Python

Header <boost/python/with_custodian_and_ward.hpp>


Contents

Introduction
Classes
Class Template with_custodian_and_ward
Class Template with_custodian_and_ward synopsis
Class with_custodian_and_ward static functions
Class Template with_custodian_and_ward_postcall
Class Template with_custodian_and_ward_postcall synopsis
Class with_custodian_and_ward_postcall static functions
Example

Introduction

This header provides faciliites for establishing a lifetime dependency between two of a function's Python argument or result objects. The ward object will not be destroyed until after the custodian as long as the custodian object supports weak references (Boost.Python extension classes all support weak references). If the custodian object does not support weak references and is not None, an appropriate exception will be thrown. The two class templates with_custodian_and_ward and with_custodian_and_ward_postcall differ in the point at which they take effect.

In order to reduce the chance of inadvertently creating dangling pointers, the default is to do lifetime binding before the underlying C++ object is invoked. However, before invocation the result object is not available, so with_custodian_and_ward_postcall is provided to bind lifetimes after invocation. Also, if a C++ exception is thrown after with_custodian_and_ward<>::precall but before the underlying C++ object actually stores a pointer, the lifetime of the custodian and ward objects will be artificially bound together, so one might choose with_custodian_and_ward_postcall instead, depending on the semantics of the function being wrapped.

Please note that this is not the appropriate tool to use when wrapping functions which transfer ownership of a raw pointer across the function-call boundary. Please see the FAQ if you want to do that.

Classes

Class template with_custodian_and_ward

with_custodian_and_ward template parameters
Parameter Requirements Description Default
custodian A positive compile-time constant of type std::size_t. The 1-based index of the parameter which is the dependency in the lifetime relationship to be established. If used to wrap a member function, parameter 1 is the target object (*this). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the C++ object being wrapped is called.
ward A positive compile-time constant of type std::size_t. The 1-based index of the parameter which is the dependent in the lifetime relationship to be established. If used to wrap a member function, parameter 1 is the target object (*this).
Base A model of CallPolicies Used for policy composition. default_call_policies

Class template with_custodian_and_ward synopsis

namespace boost { namespace python
{
   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
   struct with_custodian_and_ward : Base
   {
      static bool precall(PyObject* args);
   };
}}

Class with_custodian_and_ward static functions

bool precall(PyObject* args);
Requires: PyTuple_Check(args) != 0
Effects: Makes the lifetime of the argument indicated by ward dependent on the lifetime of the argument indicated by custodian.
Returns: false and PyErr_Occurred() != 0 upon failure, true otherwise.

Class template with_custodian_and_ward_postcall

with_custodian_and_ward_postcall template parameters
Parameter Requirements Description Default
custodian A compile-time constant of type std::size_t. The index of the parameter which is the dependency in the lifetime relationship to be established. Zero indicates the result object; 1 indicates the first argument. If used to wrap a member function, parameter 1 is the target object (*this). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the C++ object being wrapped is called.
ward A compile-time constant of type std::size_t. The index of the parameter which is the dependent in the lifetime relationship to be established. Zero indicates the result object; 1 indicates the first argument. If used to wrap a member function, parameter 1 is the target object (*this).
Base A model of CallPolicies Used for policy composition. default_call_policies

Class template with_custodian_and_ward_postcall synopsis

namespace boost { namespace python
{
   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
   struct with_custodian_and_ward_postcall : Base
   {
      static PyObject* postcall(PyObject* args, PyObject* result);
   };
}}

Class with_custodian_and_ward_postcall static functions

PyObject* postcall(PyObject* args, PyObject* result);
Requires: PyTuple_Check(args) != 0, result != 0.
Effects: Makes the lifetime of the object indicated by ward dependent on the lifetime of the object indicated by custodian.
Returns: 0 and PyErr_Occurred() != 0 upon failure, true otherwise.

Example

The following example shows how with_custodian_and_ward_postcall is used by the library to implement return_internal_reference
template <std::size_t owner_arg = 1, class Base = default_call_policies>
struct return_internal_reference
    : with_custodian_and_ward_postcall<0, owner_arg, Base>
{
   typedef reference_existing_object result_converter;
};

Revised 13 November, 2002

© Copyright Dave Abrahams 2002. All Rights Reserved.