]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [section boost/python/with_custodian_and_ward.hpp] |
2 | [section Introduction] | |
3 | This header provides facilities 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 [@http://www.python.org/doc/current/lib/module-weakref.html 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. | |
4 | ||
5 | 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. | |
6 | ||
7 | 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. | |
8 | [endsect] | |
9 | [section Class `with_custodian_and_ward`] | |
10 | [table | |
11 | [[Parameter][Requirements][Description][Default]] | |
12 | [[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. ][]] | |
13 | [[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`). ][]] | |
14 | [[Base][ A model of [link concepts.callpolicies `CallPolicies`]][ Used for policy [link concepts.callpolicies.callpolicies_composition composition]. ][default_call_policies]] | |
15 | ] | |
16 | `` | |
17 | namespace boost { namespace python | |
18 | { | |
19 | template <std::size_t custodian, std::size_t ward, class Base = default_call_policies> | |
20 | struct with_custodian_and_ward : Base | |
21 | { | |
22 | static bool precall(PyObject* args); | |
23 | }; | |
24 | }}`` | |
25 | [endsect] | |
26 | [section Class `with_custodian_and_ward` static functions] | |
27 | ``bool precall(PyObject* args);`` | |
28 | [variablelist | |
29 | [[Requires][`PyTuple_Check(args) != 0`]] | |
30 | [[Effects][Makes the lifetime of the argument indicated by ward dependent on the lifetime of the argument indicated by custodian. ]] | |
31 | [[Returns][false and PyErr_Occurred() != 0 upon failure, true otherwise.]] | |
32 | ] | |
33 | [endsect] | |
34 | ||
35 | [section Class `with_custodian_and_ward_postcall`] | |
36 | [table | |
37 | [[Parameter][Requirements][Description][Default]] | |
38 | [[custodian][ A positive 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. ][]] | |
39 | [[ward][ A positive 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`). ][]] | |
40 | [[Base][ A model of [link concepts.callpolicies `CallPolicies`]][ Used for policy [link concepts.callpolicies.callpolicies_composition composition]. ][default_call_policies]] | |
41 | ] | |
42 | `` | |
43 | namespace boost { namespace python | |
44 | { | |
45 | template <std::size_t custodian, std::size_t ward, class Base = default_call_policies> | |
46 | struct with_custodian_and_ward_postcall : Base | |
47 | { | |
48 | static PyObject* postcall(PyObject* args, PyObject* result); | |
49 | }; | |
50 | }} | |
51 | `` | |
52 | [endsect] | |
53 | [section Class `with_custodian_and_ward_postcall` static functions] | |
54 | ``PyObject *postcall(PyObject* args, PyObject* result);`` | |
55 | [variablelist | |
56 | [[Requires][`PyTuple_Check(args) != 0`, `result != 0`]] | |
57 | [[Effects][Makes the lifetime of the object indicated by ward dependent on the lifetime of the object indicated by custodian. ]] | |
58 | [[Returns][`0` and `PyErr_Occurred() != 0` upon failure, `true` otherwise. ]] | |
59 | ] | |
60 | [endsect] | |
61 | [section Example] | |
62 | The following example shows how `with_custodian_and_ward_postcall` is used by the library to implement `return_internal_reference` | |
63 | `` | |
64 | template <std::size_t owner_arg = 1, class Base = default_call_policies> | |
65 | struct return_internal_reference | |
66 | : with_custodian_and_ward_postcall<0, owner_arg, Base> | |
67 | { | |
68 | typedef reference_existing_object result_converter; | |
69 | }; | |
70 | `` | |
71 | [endsect] | |
72 | [endsect] |