reference_existing_object.qbk 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. [section boost/python/reference_existing_object.hpp]
  2. [section Class `reference_existing_object`]
  3. `reference_existing_object` is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions which return a reference or pointer to a C++ object. When the wrapped function is called, the value referenced by its return value is not copied. A new Python object is created which contains a pointer to the referent, and no attempt is made to ensure that the lifetime of the referent is at least as long as that of the corresponding Python object. Thus, it can be *highly dangerous* to use `reference_existing_object` without additional lifetime management from such models of [link concepts.callpolicies CallPolicies] as [link function_invocation_and_creation.models_of_callpolicies.boost_python_with_custodian_and_.class_with_custodian_and_ward `with_custodian_and_ward`]. This class is used in the implementation of [link function_invocation_and_creation.models_of_callpolicies.boost_python_return_internal_ref.class_template_return_internal_r `return_internal_reference`].
  4. ``
  5. namespace boost { namespace python
  6. {
  7. struct reference_existing_object
  8. {
  9. template <class T> struct apply;
  10. };
  11. }}
  12. ``
  13. [endsect]
  14. [section Class `reference_existing_object` metafunctions]
  15. ``template <class T> struct apply``
  16. [variablelist
  17. [[Requires][`T` is `U&` or `U*` for some `U`.]]
  18. [[Returns][`typedef to_python_indirect<T, V> type;`, where V is a class whose static execute function constructs an instance holder containing an unowned `U*` pointing to the referent of the wrapped function's return value.]]
  19. ]
  20. [endsect]
  21. [section Example]
  22. In C++:
  23. ``
  24. #include <boost/python/module.hpp>
  25. #include <boost/python/class.hpp>
  26. #include <boost/python/reference_existing_object.hpp>
  27. #include <boost/python/return_value_policy.hpp>
  28. #include <utility>
  29. // classes to wrap
  30. struct Singleton
  31. {
  32. Singleton() : x(0) {}
  33. int exchange(int n) // set x and return the old value
  34. {
  35. std::swap(n, x);
  36. return n;
  37. }
  38. int x;
  39. };
  40. Singleton& get_it()
  41. {
  42. static Singleton just_one;
  43. return just_one;
  44. }
  45. // Wrapper code
  46. using namespace boost::python;
  47. BOOST_PYTHON_MODULE(singleton)
  48. {
  49. def("get_it", get_it,
  50. return_value_policy<reference_existing_object>());
  51. class_<Singleton>("Singleton")
  52. .def("exchange", &Singleton::exchange)
  53. ;
  54. }
  55. ``
  56. Python code:
  57. ``
  58. >>> import singleton
  59. >>> s1 = singleton.get_it()
  60. >>> s2 = singleton.get_it()
  61. >>> id(s1) == id(s2) # s1 and s2 are not the same object
  62. 0
  63. >>> s1.exchange(42) # but they reference the same C++ Singleton
  64. 0
  65. >>> s2.exchange(99)
  66. 42
  67. ``
  68. [endsect]
  69. [endsect]