-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathwrap_Attributes.cpp
More file actions
203 lines (168 loc) · 6.55 KB
/
wrap_Attributes.cpp
File metadata and controls
203 lines (168 loc) · 6.55 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*****************************************************************************
*
* diffpy.srreal by DANSE Diffraction group
* Simon J. L. Billinge
* (c) 2010 The Trustees of Columbia University
* in the City of New York. All rights reserved.
*
* File coded by: Pavol Juhas
*
* See AUTHORS.txt for a list of people who contributed.
* See LICENSE_DANSE.txt for license information.
*
******************************************************************************
*
* Bindings to the diffpy::Attributes class.
*
*****************************************************************************/
#include <boost/python/class.hpp>
#include <cassert>
#include <diffpy/Attributes.hpp>
#include "srreal_converters.hpp"
namespace srrealmodule {
namespace nswrap_Attributes {
using std::string;
using namespace boost;
using namespace diffpy::attributes;
// docstrings ----------------------------------------------------------------
const char* doc_Attributes = "\
This class manages named C++ double attributes owned by an instance.\n\
The derived objects own double attributes that can be looked up from C++\n\
by name, without having to know a full C++ interface of their classes.\n\
";
const char* doc_Attributes__getDoubleAttr = "\
Return value of a named C++ double attribute owned by this object.\n\
\n\
name -- string name of a double attribute\n\
\n\
Return double.\n\
Raise AttributeError for invalid name.\n\
";
const char* doc_Attributes__setDoubleAttr = "\
Set named C++ double attribute to the specified value.\n\
\n\
name -- string name of a double attribute\n\
value -- new value of the attribute\n\
\n\
No return value.\n\
Raise AttributeError for invalid name or read-only attribute.\n\
";
const char* doc_Attributes__hasDoubleAttr = "\
Check if named C++ double attribute exists.\n\
\n\
name -- string name of a double attribute\n\
\n\
Return bool.\n\
";
const char* doc_Attributes__namesOfDoubleAttributes = "\
Return set of C++ double attributes owned by this object.\n\
";
const char* doc_Attributes__namesOfWritableDoubleAttributes = "\
Return set of writable C++ double attributes related to this object.\n\
";
const char* doc_Attributes__registerDoubleAttribute = "\
Register a C++ double attribute that is defined in Python.\n\
This must be called from the __init__ method of a Python class\n\
that derives from the Attributes.\n\
\n\
name -- string name of a double attribute, must be a unique\n\
attribute name for this instance\n\
getter -- optional function that returns the attribute value\n\
setter -- optional function that sets the attribute value.\n\
The attribute is read-only when None.\n\
\n\
When both getter and setter are None, register standard Python\n\
attribute access as a C++ double attribute.\n\
";
// wrappers ------------------------------------------------------------------
DECLARE_PYSET_METHOD_WRAPPER(namesOfDoubleAttributes,
namesOfDoubleAttributes_asset)
DECLARE_PYSET_METHOD_WRAPPER(namesOfWritableDoubleAttributes,
namesOfWritableDoubleAttributes_asset)
// Helper class to handle double attributes defined from Python
class PythonDoubleAttribute : public BaseDoubleAttribute
{
public:
// constructor
PythonDoubleAttribute(python::object owner,
python::object getter, python::object setter)
{
// PythonDoubleAttribute needs to know its Python owner, but it
// has to use a borrowed reference otherwise the owner would be
// never freed. We store a pointer to the raw object and create
// a borrowed boost python wrapper as necessary.
mowner = owner.ptr();
mgetter = getter;
msetter = setter;
}
double getValue(const Attributes* obj) const
{
// verify that mowner is indeed the obj wrapper
python::object owner(python::borrowed(mowner));
assert(obj == python::extract<const Attributes*>(owner));
python::object pyrv = mgetter(owner);
double rv = python::extract<double>(pyrv);
return rv;
}
void setValue(Attributes* obj, double value)
{
if (this->isreadonly()) throwDoubleAttributeReadOnly();
// verify that mowner is indeed the obj wrapper
python::object owner(python::borrowed(mowner));
assert(obj == python::extract<Attributes*>(owner));
msetter(owner, value);
}
bool isreadonly() const
{
return (msetter.is_none());
}
private:
// data
PyObject* mowner;
python::object mgetter;
python::object msetter;
}; // class PythonDoubleAttribute
void registerPythonDoubleAttribute(python::object owner,
const string& name, python::object g, python::object s)
{
// when neither getter no setter are specified,
// make it use normal python attribute access
if (g.is_none() && s.is_none())
{
python::object mod = python::import("diffpy.srreal.attributes");
g = mod.attr("_pyattrgetter")(name);
s = mod.attr("_pyattrsetter")(name);
}
Attributes* cowner = python::extract<Attributes*>(owner);
BaseDoubleAttribute* pa = new PythonDoubleAttribute(owner, g, s);
registerBaseDoubleAttribute(cowner, name, pa);
}
} // namespace nswrap_Attributes
// Wrapper definition --------------------------------------------------------
void wrap_Attributes()
{
using namespace nswrap_Attributes;
using namespace boost::python;
const python::object None;
// ready for class definition
class_<Attributes>("Attributes", doc_Attributes)
.def("_getDoubleAttr", &Attributes::getDoubleAttr,
doc_Attributes__getDoubleAttr)
.def("_setDoubleAttr", &Attributes::setDoubleAttr,
doc_Attributes__setDoubleAttr)
.def("_hasDoubleAttr", &Attributes::hasDoubleAttr,
doc_Attributes__hasDoubleAttr)
.def("_namesOfDoubleAttributes",
namesOfDoubleAttributes_asset<Attributes>,
doc_Attributes__namesOfDoubleAttributes)
.def("_namesOfWritableDoubleAttributes",
namesOfWritableDoubleAttributes_asset<Attributes>,
doc_Attributes__namesOfWritableDoubleAttributes)
.def("_registerDoubleAttribute",
registerPythonDoubleAttribute,
(python::arg("getter")=None, python::arg("setter")=None),
doc_Attributes__registerDoubleAttribute)
;
}
} // namespace srrealmodule
// End of file