return_internal_reference.qbk 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. [section boost/python/return_internal_reference.hpp]
  2. [section Introduction]
  3. `return_internal_reference` instantiations are models of [link concepts.callpolicies `CallPolicies`] which allow pointers and references to objects held internally by a free or member function argument or from the target of a member function to be returned safely without making a copy of the referent. The default for its first template argument handles the common case where the containing object is the target (`*this`) of a wrapped member function.
  4. [endsect]
  5. [section Class template `return_internal_reference`]
  6. [table
  7. [[Parameter][Requirements][Description][Default]]
  8. [[owner_arg][A positive compile-time constant of type `std::size_t`.][The index of the parameter which contains the object to which the reference or pointer is being returned. 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 function being wrapped is called.][]]
  9. [[Base][A model of [link concepts.callpolicies `CallPolicies`]][Used for policy composition. Any `result_converter` it supplies will be overridden by `return_internal_reference`, but its `precall` and `postcall` policies are composed as described here [link concepts.callpolicies `CallPolicies`].][default_call_policies]]
  10. ]
  11. ``
  12. namespace boost { namespace python
  13. {
  14. template <std::size_t owner_arg = 1, class Base = default_call_policies>
  15. struct return_internal_reference : Base
  16. {
  17. static PyObject* postcall(PyObject*, PyObject* result);
  18. typedef reference_existing_object result_converter;
  19. };
  20. }}
  21. ``
  22. [endsect]
  23. [section Class `return_internal_reference` static functions]
  24. ``PyObject* postcall(PyObject* args, PyObject* result);``
  25. [variablelist
  26. [[Requires][`PyTuple_Check(args) != 0`]]
  27. [[Returns][[link function_invocation_and_creation.models_of_callpolicies.boost_python_with_custodian_and_.class_with_custodian_and_ward_st `with_custodian_and_ward_postcall::postcall(args, result)`]]]
  28. ]
  29. [endsect]
  30. [section Example]
  31. C++ module definition:
  32. ``
  33. #include <boost/python/module.hpp>
  34. #include <boost/python/class.hpp>
  35. #include <boost/python/return_internal_reference.hpp>
  36. class Bar
  37. {
  38. public:
  39. Bar(int x) : x(x) {}
  40. int get_x() const { return x; }
  41. void set_x(int x) { this->x = x; }
  42. private:
  43. int x;
  44. };
  45. class Foo
  46. {
  47. public:
  48. Foo(int x) : b(x) {}
  49. // Returns an internal reference
  50. Bar const& get_bar() const { return b; }
  51. private:
  52. Bar b;
  53. };
  54. using namespace boost::python;
  55. BOOST_PYTHON_MODULE(internal_refs)
  56. {
  57. class_<Bar>("Bar", init<int>())
  58. .def("get_x", &Bar::get_x)
  59. .def("set_x", &Bar::set_x)
  60. ;
  61. class_<Foo>("Foo", init<int>())
  62. .def("get_bar", &Foo::get_bar
  63. , return_internal_reference<>())
  64. ;
  65. }
  66. ``
  67. Python code:
  68. ``
  69. >>> from internal_refs import *
  70. >>> f = Foo(3)
  71. >>> b1 = f.get_bar()
  72. >>> b2 = f.get_bar()
  73. >>> b1.get_x()
  74. 3
  75. >>> b2.get_x()
  76. 3
  77. >>> b1.set_x(42)
  78. >>> b2.get_x()
  79. 42
  80. ``
  81. [endsect]
  82. [endsect]