7 #ifndef MDS_UTILS_PYTHON_CONVERSION_HPP_INCLUDED 8 #define MDS_UTILS_PYTHON_CONVERSION_HPP_INCLUDED 14 #include <boost/preprocessor/seq/for_each.hpp> 15 #include <boost/preprocessor/tuple/elem.hpp> 16 #include <boost/preprocessor/stringize.hpp> 17 #include <boost/numeric/conversion/cast.hpp> 76 inline PyObject* get<PyObject*>(PyObject *po) {
80 inline PyObject*
to_python(PyObject *po) {
86 #define SEQ_TYPE_PY_TYPE_FUN_AS \ 87 ((long,PyInt_AsLong,PyInt_FromLong)) \ 88 ((double,PyFloat_AsDouble,PyFloat_FromDouble)) 90 #define SEQ_TYPE_PY_TYPE_FUN_AS_CAST \ 91 ((short,PyInt_AsLong,PyInt_FromLong,long)) \ 92 ((unsigned short,PyInt_AsLong,PyInt_FromLong,long)) \ 93 ((int,PyInt_AsLong,PyInt_FromLong,long)) \ 94 ((unsigned int,PyInt_AsLong,PyInt_FromLong,long)) \ 95 ((unsigned long,PyInt_AsLong,PyInt_FromLong,long)) \ 96 ((long long,PyInt_AsLong,PyInt_FromLong,long)) \ 97 ((unsigned long long,PyInt_AsLong,PyInt_FromLong,long)) \ 98 ((float,PyFloat_AsDouble,PyFloat_FromDouble,double)) 100 #define GET_SPEC_GEN(r,data,elem) \ 102 inline BOOST_PP_TUPLE_ELEM(3,0,elem) get< BOOST_PP_TUPLE_ELEM(3,0,elem) >(PyObject *po) { \ 103 BOOST_PP_TUPLE_ELEM(3,0,elem) retval(BOOST_PP_TUPLE_ELEM(3,1,elem)(po)); \ 105 if (PyErr_Occurred() != NULL) { \ 106 throw std::invalid_argument("Cannot get a " BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(3,0,elem)) " value"); \ 112 inline PyObject* to_python(BOOST_PP_TUPLE_ELEM(3,0,elem) val) { \ 113 PyObject* retval(BOOST_PP_TUPLE_ELEM(3,2,elem)(val)); \ 115 if (retval == NULL) throw std::invalid_argument("Cannot convert " BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(3,0,elem)) " to Python"); \ 121 #define GET_SPEC_GEN_CAST(r,data,elem) \ 123 inline BOOST_PP_TUPLE_ELEM(4,0,elem) get< BOOST_PP_TUPLE_ELEM(4,0,elem) >(PyObject *po) { \ 124 BOOST_PP_TUPLE_ELEM(4,0,elem) retval(boost::numeric_cast< BOOST_PP_TUPLE_ELEM(4,0,elem) >(BOOST_PP_TUPLE_ELEM(4,1,elem)(po))); \ 126 if (PyErr_Occurred() != NULL) { \ 127 throw std::invalid_argument("Cannot get a " BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(4,0,elem)) " value"); \ 133 inline PyObject* to_python(const BOOST_PP_TUPLE_ELEM(4,0,elem) val) { \ 134 PyObject* retval(BOOST_PP_TUPLE_ELEM(4,2,elem)(boost::numeric_cast< BOOST_PP_TUPLE_ELEM(4,3,elem) >(val))); \ 136 if (retval == NULL) throw std::invalid_argument("Cannot convert " BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(4,0,elem)) " to Python"); \ 141 BOOST_PP_SEQ_FOR_EACH(GET_SPEC_GEN,~,SEQ_TYPE_PY_TYPE_FUN_AS)
142 BOOST_PP_SEQ_FOR_EACH(GET_SPEC_GEN_CAST,~,SEQ_TYPE_PY_TYPE_FUN_AS_CAST)
146 inline const
char*
get<const
char*>(PyObject *po) {
148 const char *retval(const_cast<const char*>(PyString_AsString(po)));
150 if (PyErr_Occurred() != NULL) {
151 throw std::invalid_argument(
"Cannot get a const char* value"); \
159 inline std::string get<std::string>(PyObject *po) {
160 std::string retval(get<char*>(po));
162 if (PyErr_Occurred() != NULL) {
163 throw std::invalid_argument(
"Cannot get a std::string value");
171 inline PyObject*
to_python(
const char* str) {
172 PyObject *retval(PyString_FromString(str));
174 if (retval == NULL)
throw std::invalid_argument(
"Cannot convert a const char* to Python");
180 inline PyObject*
to_python(
const std::string& str) {
182 PyObject* retval(PyString_FromString(str.c_str()));
184 if (retval == NULL)
throw std::invalid_argument(
"Cannot convert a std::string to Python");
191 inline std::complex<double> get< std::complex<double> >(PyObject *po) {
193 std::complex<double> retval(
194 PyComplex_RealAsDouble(po),
195 PyComplex_ImagAsDouble(po)
198 if (PyErr_Occurred() != NULL) {
199 throw std::invalid_argument(
"Cannot get a std::complex<double> value"); \
206 inline PyObject*
to_python(
const std::complex<double>& val) {
208 PyObject* retval(PyComplex_FromDoubles(val.real(),val.imag()));
210 if (retval == NULL) {
211 throw std::invalid_argument(
"Cannot convert a std::complex<double> to Python");
T get(PyObject *po)
Primary template for extracting a value from a Python object.
PyObject * to_python(void)
Converts a value into a Python object.
Main namespace of all Michele De Stefano's C++ utilities.