lvalue_from_pytype.qbk 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. [section boost/python/lvalue_from_pytype.hpp]
  2. [section Introduction]
  3. <boost/python/lvalue_from_pytype.hpp> supplies a facility for extracting C++ objects from within Python instances of a given type. This is typically useful for dealing with "traditional" Python extension types.
  4. [endsect]
  5. [section Class template `lvalue_from_pytype`]
  6. Class template lvalue_from_pytype will register from_python converters which, given an object of the given Python type, can extract references and pointers to a particular C++ type. Its template arguments are:
  7. In the table below, x denotes an object of type PythonObject&
  8. [table
  9. [[Parameter][Requirements][Semantics]]
  10. [[Extractor][a model of [link concepts.extractor `Extractor`] whose execute function returns a reference type.][Extracts the lvalue from the Python object once its type has been confirmed]]
  11. [[python_type][A compile-time constant [@http://www.python.org/doc/2.2/ext/dnt-type-methods.html `PyTypeObject*`]][The Python type of instances convertible by this converter. Python subtypes are also convertible.]]
  12. ]
  13. ``
  14. namespace boost { namespace python
  15. {
  16. template <class Extractor, PyTypeObject const* python_type>
  17. struct lvalue_from_pytype
  18. {
  19. lvalue_from_pytype();
  20. };
  21. }}
  22. ``
  23. [section Class template `lvalue_from_pytype` constructor]
  24. ``lvalue_from_pytype();``
  25. [variablelist
  26. [[Effects][Registers converters which can convert Python objects of the given type to lvalues of the type returned by Extractor::execute.]]
  27. ]
  28. [endsect]
  29. [endsect]
  30. [section Class template `extract_identity`]
  31. extract_identity is a model of [link concepts.extractor `Extractor`] which can be used in the common case where the C++ type to be extracted is the same as the Python object type.
  32. ``
  33. namespace boost { namespace python
  34. {
  35. template <class InstanceType>
  36. struct extract_identity
  37. {
  38. static InstanceType& execute(InstanceType& c);
  39. };
  40. }}
  41. ``
  42. [section Class template `extract_identity` static functions]
  43. ``InstanceType& execute(InstanceType& c);``
  44. [variablelist
  45. [[Returns][c]]
  46. ]
  47. [endsect]
  48. [endsect]
  49. [section Class template `extract_member`]
  50. `extract_member` is a model of [link concepts.extractor `Extractor`] which can be used in the common case in the common case where the C++ type to be extracted is a member of the Python object.
  51. ``
  52. namespace boost { namespace python
  53. {
  54. template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
  55. struct extract_member
  56. {
  57. static MemberType& execute(InstanceType& c);
  58. };
  59. }}
  60. ``
  61. [section Class template `extract_member` static functions]
  62. ``static MemberType& execute(InstanceType& c);``
  63. [variablelist
  64. [[Returns][`c.*member`]]
  65. ]
  66. [endsect]
  67. [endsect]
  68. [section Example]
  69. This example presumes that someone has implemented the standard noddy example module from the Python documentation, and we want to build a module which manipulates Noddys. Since noddy_NoddyObject is so simple that it carries no interesting information, the example is a bit contrived: it assumes you want to keep track of one particular object for some reason. This module would have to be dynamically linked to the module which defines noddy_NoddyType.
  70. In C++:
  71. ``
  72. #include <boost/python/module.hpp>
  73. #include <boost/python/handle.hpp>
  74. #include <boost/python/borrowed.hpp>
  75. #include <boost/python/lvalue_from_pytype.hpp>
  76. // definition lifted from the Python docs
  77. typedef struct {
  78. PyObject_HEAD
  79. } noddy_NoddyObject;
  80. using namespace boost::python;
  81. static handle<noddy_NoddyObject> cache;
  82. bool is_cached(noddy_NoddyObject* x)
  83. {
  84. return x == cache.get();
  85. }
  86. void set_cache(noddy_NoddyObject* x)
  87. {
  88. cache = handle<noddy_NoddyObject>(borrowed(x));
  89. }
  90. BOOST_PYTHON_MODULE(noddy_cache)
  91. {
  92. def("is_cached", is_cached);
  93. def("set_cache", set_cache);
  94. // register Noddy lvalue converter
  95. lvalue_from_pytype<extract_identity<noddy_NoddyObject>,&noddy_NoddyType>();
  96. }
  97. ``
  98. In Python:
  99. ``
  100. >>> import noddy
  101. >>> n = noddy.new_noddy()
  102. >>> import noddy_cache
  103. >>> noddy_cache.is_cached(n)
  104. 0
  105. >>> noddy_cache.set_cache(n)
  106. >>> noddy_cache.is_cached(n)
  107. 1
  108. >>> noddy_cache.is_cached(noddy.new_noddy())
  109. 0
  110. ``
  111. [endsect]
  112. [endsect]