Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
NodeConverter.h
Go to the documentation of this file.
1
19#ifndef PYSTON_NODECONVERTER_H
20#define PYSTON_NODECONVERTER_H
21
23#include <boost/python.hpp>
24
25namespace Pyston {
26
38template <typename To, typename From>
39static bool createCastNode(boost::python::object& object, void* storage) {
40 using boost::python::extract;
41
42 extract<std::shared_ptr<Node<From>>> extractor(object);
43 if (!extractor.check())
44 return false;
45
46 new (storage) std::shared_ptr<Node<To>>(new Cast<To, From>(extractor));
47
48 return true;
49}
50
56template <typename T>
57struct NodeCast {
62 static bool isUpcast(PyObject*) {
63 return false;
64 }
65
71 static bool cast(PyObject*, void*) {
72 return false;
73 }
74};
75
80template <>
81struct NodeCast<double> {
82
86 static bool isUpcast(PyObject* obj_ptr) {
87 using boost::python::borrowed;
88 using boost::python::extract;
89 using boost::python::handle;
90 using boost::python::object;
91
92 object object(handle<>(borrowed(obj_ptr)));
93 extract<Node<bool>> bool_extract(object);
94 extract<Node<int64_t>> int_extract(object);
95
96 if (bool_extract.check() || int_extract.check()) {
97 return true;
98 }
99
100 return false;
101 }
102
106 static bool cast(PyObject* obj_ptr, void* storage) {
107 using boost::python::borrowed;
108 using boost::python::handle;
109 using boost::python::object;
110
111 object object(handle<>(borrowed(obj_ptr)));
112
113 return createCastNode<double, bool>(object, storage) || createCastNode<double, int64_t>(object, storage);
114 }
115};
116
121template <>
122struct NodeCast<int64_t> {
123
127 static bool isUpcast(PyObject* obj_ptr) {
128 using boost::python::borrowed;
129 using boost::python::extract;
130 using boost::python::handle;
131 using boost::python::object;
132
133 object object(handle<>(borrowed(obj_ptr)));
134 extract<Node<bool>> bool_extract(object);
135
136 return bool_extract.check();
137 }
138
142 static bool cast(PyObject* obj_ptr, void* storage) {
143 using boost::python::borrowed;
144 using boost::python::handle;
145 using boost::python::object;
146
147 object object(handle<>(borrowed(obj_ptr)));
148
149 return createCastNode<int64_t, bool>(object, storage);
150 }
151};
152
158template <typename T>
167 static void* isConvertible(PyObject* obj_ptr) {
168 using boost::python::borrowed;
169 using boost::python::extract;
170 using boost::python::handle;
171 using boost::python::object;
172 using boost::python::converter::registry::query;
173
174 // Primitive numeric types are ok
175#if PY_MAJOR_VERSION >= 3
176 if (PyFloat_Check(obj_ptr) || PyLong_Check(obj_ptr) || PyBool_Check(obj_ptr)) {
177 return obj_ptr;
178 }
179#else
180 if (PyFloat_Check(obj_ptr) || PyLong_Check(obj_ptr) || PyBool_Check(obj_ptr) || PyInt_Check(obj_ptr)) {
181 return obj_ptr;
182 }
183#endif
184
185 // Upcasting one type of node to another is too
186 if (NodeCast<T>::isUpcast(obj_ptr)) {
187 return obj_ptr;
188 }
189
190 // Can't
191 return nullptr;
192 }
193
203 static bool fromPrimitive(PyObject* obj_ptr, void* storage) {
204 // Rely on the casting done by C++
205 T value = 0;
206 if (PyFloat_Check(obj_ptr)) {
207 value = PyFloat_AsDouble(obj_ptr);
208 } else if (PyLong_Check(obj_ptr)) {
209 value = PyLong_AsLong(obj_ptr);
210 } else if (PyBool_Check(obj_ptr)) {
211 value = (obj_ptr == Py_True);
212#if PY_MAJOR_VERSION < 3
213 } else if (PyInt_Check(obj_ptr)) {
214 value = PyInt_AsLong(obj_ptr);
215#endif
216 } else {
217 return false;
218 }
219
220 new (storage) std::shared_ptr<Node<T>>(new Constant<T>(value));
221 return true;
222 }
223
231 static void construct(PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data) {
232 // Memory area where to store the new type
233 void* storage =
234 ((boost::python::converter::rvalue_from_python_storage<std::shared_ptr<Node<T>>>*)data)->storage.bytes;
235
236 // Abort if can not convert, because isConvertible hasn't done its job
237 if (!fromPrimitive(obj_ptr, storage) && !NodeCast<T>::cast(obj_ptr, storage))
238 abort();
239
240 data->convertible = storage;
241 }
242};
243
244} // end of namespace Pyston
245
246#endif // PYSTON_NODECONVERTER_H
static bool createCastNode(boost::python::object &object, void *storage)
static bool isUpcast(PyObject *obj_ptr)
static bool cast(PyObject *obj_ptr, void *storage)
static bool cast(PyObject *obj_ptr, void *storage)
static bool isUpcast(PyObject *obj_ptr)
static bool isUpcast(PyObject *)
static bool cast(PyObject *, void *)
static bool fromPrimitive(PyObject *obj_ptr, void *storage)
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
static void * isConvertible(PyObject *obj_ptr)