24 #ifndef NDARRAY_SWIG_PyConverter_h_INCLUDED
25 #define NDARRAY_SWIG_PyConverter_h_INCLUDED
33 #include <boost/intrusive_ptr.hpp>
38 inline void intrusive_ptr_add_ref(PyObject * obj) { Py_INCREF(obj); }
39 inline void intrusive_ptr_release(PyObject * obj) { Py_DECREF(obj); }
48 typedef boost::intrusive_ptr<PyObject>
PyPtr;
118 template <
typename T>
119 struct PyConverter :
public detail::PyConverterBase<T> {
169 struct PyConverter<bool> :
public detail::PyConverterBase<bool> {
172 if (!PyBool_Check(input.get())) {
173 PyPtr s(PyObject_Repr(input.get()));
174 if (!s)
return false;
175 char * cs = PyString_AsString(s.get());
176 if (!cs)
return false;
177 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ bool value.",cs);
184 output = (input.get() == Py_True);
188 static PyObject *
toPython(
bool input) {
189 if (input) Py_RETURN_TRUE;
193 static PyTypeObject
const *
getPyType() {
return &PyBool_Type; }
197 struct PyConverter<int> :
public detail::PyConverterBase<int> {
200 if (!PyInt_Check(input.get()) && !PyLong_Check(input.get())) {
201 PyPtr s(PyObject_Repr(input.get()));
202 if (!s)
return false;
203 char * cs = PyString_AsString(s.get());
204 if (!cs)
return false;
205 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ int value.",cs);
212 output = PyInt_AsLong(input.get());
216 static PyObject *
toPython(
int input) {
217 return PyInt_FromLong(input);
220 static PyTypeObject
const *
getPyType() {
return &PyInt_Type; }
224 struct PyConverter<long> :
public detail::PyConverterBase<long> {
227 if (!PyInt_Check(input.get()) && !PyLong_Check(input.get())) {
228 PyPtr s(PyObject_Repr(input.get()));
229 if (!s)
return false;
230 char * cs = PyString_AsString(s.get());
231 if (!cs)
return false;
232 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ long value.",cs);
239 output = PyLong_AsLong(input.get());
243 static PyObject *
toPython(
long input) {
244 return PyLong_FromLong(input);
247 static PyTypeObject
const *
getPyType() {
return &PyLong_Type; }
251 struct PyConverter<float> :
public detail::PyConverterBase<float> {
254 if (!PyFloat_Check(input.get())) {
255 PyPtr s(PyObject_Repr(input.get()));
256 if (!s)
return false;
257 char * cs = PyString_AsString(s.get());
258 if (!cs)
return false;
259 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ float value.",cs);
266 output = PyFloat_AsDouble(input.get());
270 static PyObject *
toPython(
float input) {
271 return PyFloat_FromDouble(input);
274 static PyTypeObject
const *
getPyType() {
return &PyFloat_Type; }
278 struct PyConverter<double> :
public detail::PyConverterBase<double> {
281 if (!PyFloat_Check(input.get())) {
282 PyPtr s(PyObject_Repr(input.get()));
283 if (!s)
return false;
284 char * cs = PyString_AsString(s.get());
285 if (!cs)
return false;
286 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ double value.",cs);
293 output = PyFloat_AsDouble(input.get());
297 static PyObject *
toPython(
double input) {
298 return PyFloat_FromDouble(input);
301 static PyTypeObject
const *
getPyType() {
return &PyFloat_Type; }
304 template <
typename U>
305 struct PyConverter< std::complex<U> > :
public detail::PyConverterBase< std::complex<U> > {
308 if (!PyComplex_Check(input.get())) {
309 PyPtr s(PyObject_Repr(input.get()));
310 if (!s)
return false;
311 char * cs = PyString_AsString(s.get());
312 if (!cs)
return false;
313 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ complex value.",cs);
320 output.real() = PyComplex_RealAsDouble(input.get());
321 output.imag() = PyComplex_ImagAsDouble(input.get());
325 static PyObject *
toPython(std::complex<U>
const & input) {
326 return PyComplex_FromDoubles(input.real(),input.imag());
329 static PyTypeObject
const *
getPyType() {
return &PyComplex_Type; }
333 struct PyConverter< std::string > :
public detail::PyConverterBase<std::string> {
336 if (!PyString_Check(input.get())) {
337 PyPtr s(PyObject_Repr(input.get()));
338 if (!s)
return false;
339 char * cs = PyString_AsString(s.get());
340 if (!cs)
return false;
341 PyErr_Format(PyExc_TypeError,
"'%s' is not a valid C++ string value.",cs);
350 if (PyString_AsStringAndSize(input.get(),&buf,&size) == -1)
return false;
351 output = std::string(buf,size);
355 static PyObject *
toPython(std::string
const & input) {
356 return PyString_FromStringAndSize(input.data(),input.size());
359 static PyTypeObject
const *
getPyType() {
return &PyString_Type; }
366 #endif // !NDARRAY_SWIG_PyConverter_h_INCLUDED
static int fromPython(PyObject *arg, T *output)
Convert a Python object to a C++ object.
static bool fromPythonStage2(PyPtr const &p, T &output)
Complete a Python to C++ conversion begun with fromPythonStage1().
boost::intrusive_ptr< PyObject > PyPtr
A reference-counting smart pointer for PyObject.
static PyObject * toPython(T const &input)
Convert a C++ object to a new Python object.
static bool matches(PyObject *arg)
Check if a Python object might be convertible to T.
#define NDARRAY_ASSERT(ARG)
A class providing Python conversion functions for T.
static bool fromPythonStage1(PyPtr &p)
Check if a Python object is convertible to T and optionally begin the conversion by replacing the inp...
static PyTypeObject const * getPyType()
Return the Python TypeObject that corresponds to the object the toPython() function returns...