From 51d60a603590d559647283bbf3d9c33ebf866002 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 3 Mar 2001 11:48:52 +0000 Subject: [PATCH] added: converters for [plain] char and std::complex [SVN r9397] --- include/boost/python/conversions.hpp | 39 ++++++++++++++++++++++++++++ src/conversions.cpp | 21 +++++++++++++++ test/comprehensive.cpp | 34 ++++++++++++++++++++++++ test/comprehensive.py | 33 +++++++++++++++++++++++ 4 files changed, 127 insertions(+) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index d11f7f14..b633c0ee 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 03 01 added: converters for [plain] char and std::complex (Ralf W. Grosse-Kunstleve) #ifndef METHOD_DWA122899_H_ # define METHOD_DWA122899_H_ @@ -16,6 +19,7 @@ # include # include # include +# include BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround @@ -100,6 +104,10 @@ PyObject* to_python(unsigned short); unsigned short from_python(PyObject*, boost::python::type); unsigned short from_python(PyObject*, boost::python::type); +PyObject* to_python(char); +char from_python(PyObject*, boost::python::type); +char from_python(PyObject*, boost::python::type); + PyObject* to_python(signed char); signed char from_python(PyObject*, boost::python::type); signed char from_python(PyObject*, boost::python::type); @@ -130,6 +138,32 @@ PyObject* to_python(const std::string& s); std::string from_python(PyObject*, boost::python::type); std::string from_python(PyObject*, boost::python::type); +template +PyObject* to_python(const std::complex& sc) { + Py_complex pcc; + pcc.real = sc.real(); + pcc.imag = sc.imag(); + return PyComplex_FromCComplex(pcc); +} + +template +std::complex from_python(PyObject* p, + boost::python::type&>) { + if (! PyComplex_Check(p)) { + PyErr_SetString(PyExc_TypeError, "expected a complex number"); + throw boost::python::argument_error(); + } + return std::complex( + static_cast(PyComplex_RealAsDouble(p)), + static_cast(PyComplex_ImagAsDouble(p))); +} + +template +inline std::complex from_python(PyObject* p, + boost::python::type >) { + return from_python(p, boost::python::type&>()); +} + // For when your C++ function really wants to pass/return a PyObject* PyObject* to_python(PyObject*); PyObject* from_python(PyObject*, boost::python::type); @@ -304,6 +338,11 @@ inline unsigned short from_python(PyObject* p, boost::python::type()); } +inline char from_python(PyObject* p, boost::python::type) +{ + return from_python(p, boost::python::type()); +} + inline signed char from_python(PyObject* p, boost::python::type) { return from_python(p, boost::python::type()); diff --git a/src/conversions.cpp b/src/conversions.cpp index ded01e0e..369f197a 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -5,6 +5,9 @@ // // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +// +// Revision History: +// Mar 03 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) #include #include @@ -160,6 +163,24 @@ unsigned short from_python(PyObject* p, boost::python::type type return integer_from_python(p, type); } +PyObject* to_python(char c) +{ + if (c == '\0') return PyString_FromString(""); + return PyString_FromStringAndSize(&c, 1); +} + +char from_python(PyObject* p, boost::python::type) +{ + int l = -1; + if (PyString_Check(p)) l = PyString_Size(p); + if (l < 0 || l > 1) { + PyErr_SetString(PyExc_TypeError, "expected string of length 0 or 1"); + throw boost::python::argument_error(); + } + if (l == 0) return '\0'; + return PyString_AsString(p)[0]; +} + PyObject* to_python(unsigned char i) { return integer_to_python(i); diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 7fad74bb..592b0ebd 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -815,6 +815,25 @@ namespace bpl_test { w.set_secret_number(number); } + // Test plain char converters. + char get_plain_char() { return 'x'; } + std::string use_plain_char(char c) { return std::string(3, c); } + std::string use_const_plain_char(const char c) { return std::string(5, c); } + + // Test std::complex converters. + std::complex dpolar(double rho, double theta) { + return std::polar(rho, theta); + } + double dreal(const std::complex& c) { return c.real(); } + double dimag(std::complex c) { return c.imag(); } + + // Test std::complex converters. + std::complex fpolar(float rho, float theta) { + return std::polar(rho, theta); + } + double freal(const std::complex& c) { return c.real(); } + double fimag(std::complex c) { return c.imag(); } + /************************************************************/ /* */ /* init the module */ @@ -1036,6 +1055,21 @@ void init_module(boost::python::module_builder& m) world_class.def(world_getinitargs, "__getinitargs__"); world_class.def(world_getstate, "__getstate__"); world_class.def(world_setstate, "__setstate__"); + + // Test plain char converters. + m.def(get_plain_char, "get_plain_char"); + m.def(use_plain_char, "use_plain_char"); + m.def(use_const_plain_char, "use_const_plain_char"); + + // Test std::complex converters. + m.def(dpolar, "dpolar"); + m.def(dreal, "dreal"); + m.def(dimag, "dimag"); + + // Test std::complex converters. + m.def(fpolar, "fpolar"); + m.def(freal, "freal"); + m.def(fimag, "fimag"); } PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& keywords) diff --git a/test/comprehensive.py b/test/comprehensive.py index a8e181d2..8bc8021c 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -1070,6 +1070,39 @@ test methodologies for wrapping functions that return a pointer 3 >>> eo.second 1 + +======== test [plain] char converters ============== + >>> get_plain_char() + 'x' + >>> use_plain_char('a') + 'aaa' + >>> use_const_plain_char('b') + 'bbbbb' + +======== test std::complex converters ============== + >>> c = dpolar(3, 5) + >>> type(c) + + >>> '%.3g' % (dreal(c)) + '0.851' + >>> '%.3g' % (dimag(c)) + '-2.88' + >>> '%.3g' % (freal(c)) + '0.851' + >>> '%.3g' % (fimag(c)) + '-2.88' + >>> c = fpolar(7, 13) + >>> type(c) + + >>> '%.3g' % (fimag(c)) + '2.94' + >>> '%.3g' % (freal(c)) + '6.35' + >>> '%.3g' % (dimag(c)) + '2.94' + >>> '%.3g' % (dreal(c)) + '6.35' + ''' from test import *