with_custodian_and_ward.qbk 5.2 KB

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