]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
8 | In the table below, x denotes an object of type PythonObject& | |
9 | [table | |
10 | [[Parameter][Requirements][Semantics]] | |
11 | [[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]] | |
12 | [[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.]] | |
13 | ] | |
14 | `` | |
15 | namespace boost { namespace python | |
16 | { | |
17 | template <class Extractor, PyTypeObject const* python_type> | |
18 | struct lvalue_from_pytype | |
19 | { | |
20 | lvalue_from_pytype(); | |
21 | }; | |
22 | }} | |
23 | `` | |
24 | [section Class template `lvalue_from_pytype` constructor] | |
25 | ``lvalue_from_pytype();`` | |
26 | [variablelist | |
27 | [[Effects][Registers converters which can convert Python objects of the given type to lvalues of the type returned by Extractor::execute.]] | |
28 | ] | |
29 | [endsect] | |
30 | [endsect] | |
31 | [section Class template `extract_identity`] | |
32 | 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. | |
33 | `` | |
34 | namespace boost { namespace python | |
35 | { | |
36 | template <class InstanceType> | |
37 | struct extract_identity | |
38 | { | |
39 | static InstanceType& execute(InstanceType& c); | |
40 | }; | |
41 | }} | |
42 | `` | |
43 | [section Class template `extract_identity` static functions] | |
44 | ``InstanceType& execute(InstanceType& c);`` | |
45 | [variablelist | |
46 | [[Returns][c]] | |
47 | ] | |
48 | [endsect] | |
49 | [endsect] | |
50 | [section Class template `extract_member`] | |
51 | `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. | |
52 | `` | |
53 | namespace boost { namespace python | |
54 | { | |
55 | template <class InstanceType, class MemberType, MemberType (InstanceType::*member)> | |
56 | struct extract_member | |
57 | { | |
58 | static MemberType& execute(InstanceType& c); | |
59 | }; | |
60 | }} | |
61 | `` | |
62 | [section Class template `extract_member` static functions] | |
63 | ``static MemberType& execute(InstanceType& c);`` | |
64 | [variablelist | |
65 | [[Returns][`c.*member`]] | |
66 | ] | |
67 | [endsect] | |
68 | [endsect] | |
69 | [section Example] | |
70 | 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. | |
71 | ||
72 | In C++: | |
73 | `` | |
74 | #include <boost/python/module.hpp> | |
75 | #include <boost/python/handle.hpp> | |
76 | #include <boost/python/borrowed.hpp> | |
77 | #include <boost/python/lvalue_from_pytype.hpp> | |
78 | ||
79 | // definition lifted from the Python docs | |
80 | typedef struct { | |
81 | PyObject_HEAD | |
82 | } noddy_NoddyObject; | |
83 | ||
84 | using namespace boost::python; | |
85 | static handle<noddy_NoddyObject> cache; | |
86 | ||
87 | bool is_cached(noddy_NoddyObject* x) | |
88 | { | |
89 | return x == cache.get(); | |
90 | } | |
91 | ||
92 | void set_cache(noddy_NoddyObject* x) | |
93 | { | |
94 | cache = handle<noddy_NoddyObject>(borrowed(x)); | |
95 | } | |
96 | ||
97 | BOOST_PYTHON_MODULE(noddy_cache) | |
98 | { | |
99 | def("is_cached", is_cached); | |
100 | def("set_cache", set_cache); | |
101 | ||
102 | // register Noddy lvalue converter | |
103 | lvalue_from_pytype<extract_identity<noddy_NoddyObject>,&noddy_NoddyType>(); | |
104 | } | |
105 | `` | |
106 | In Python: | |
107 | `` | |
108 | >>> import noddy | |
109 | >>> n = noddy.new_noddy() | |
110 | >>> import noddy_cache | |
111 | >>> noddy_cache.is_cached(n) | |
112 | 0 | |
113 | >>> noddy_cache.set_cache(n) | |
114 | >>> noddy_cache.is_cached(n) | |
115 | 1 | |
116 | >>> noddy_cache.is_cached(noddy.new_noddy()) | |
117 | 0 | |
118 | `` | |
119 | [endsect] | |
120 | [endsect] |