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