4 #include <boost/any.hpp>
10 #include "pybind11/pybind11.h"
11 #include "pybind11/eigen.h"
13 namespace pybind11 {
namespace detail {
15 template <>
struct type_caster<boost::any> {
18 PYBIND11_TYPE_CASTER(boost::any, _(
"boost::any"));
20 bool load(handle src,
bool) {
22 PyObject *source = src.ptr();
24 char thisStr[] =
"this";
27 if (!PyObject_HasAttrString(source, thisStr))
29 std::string typeStr = source->ob_type->tp_name;
30 auto it = fromPythonMap.find(typeStr);
31 if( it != fromPythonMap.end()){
32 value = it->second(source);
35 value = boost::any(src.cast<pybind11::object>());
41 PyObject* thisAttr = PyObject_GetAttrString(source, thisStr);
44 std::cerr <<
"\nERROR: Could not get the this attr.\n\n";
47 std::cerr <<
"ERROR: Don't have a good way to deal with generic classes yet...." << std::endl;
54 static handle cast(boost::any src, return_value_policy , handle ) {
56 auto it = toPythonMap.find(src.type());
57 if(it != toPythonMap.end()){
58 return it->second(src);
60 std::cerr <<
"WARNING: Could not convert type " <<
demangle_typename(src.type().name()) <<
" directly to Python type. Trying to cast as pybind11::object." << std::endl;
61 return boost::any_cast<pybind11::object>(src);
67 using EigenRowType = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
68 using EigenColType = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
70 using EigenVectorType = Eigen::Matrix<double, Eigen::Dynamic,1>;
71 using EigenRowVectorType = Eigen::Matrix<double, 1, Eigen::Dynamic>;
74 static std::map<std::type_index, std::function<handle(boost::any
const&)>> toPythonMap;
75 static std::map<std::string, std::function<boost::any(PyObject*)>> fromPythonMap;
77 static std::map<std::type_index, std::function<handle(boost::any
const&)>> createToPythonMap()
79 std::map<std::type_index, std::function<handle(boost::any
const&)>> m;
80 m[
typeid(long)] = [](boost::any
const& x) {
return PyLong_FromLong(boost::any_cast<long>(x));};
81 m[
typeid(int)] = [](boost::any
const& x) {
return PyLong_FromLong(boost::any_cast<int>(x));};
82 m[
typeid(unsigned)] = [](boost::any
const& x) {
return PyLong_FromLong(boost::any_cast<unsigned>(x));};
83 m[
typeid(
unsigned long)] = [](boost::any
const& x) {
return PyLong_FromLong(boost::any_cast<unsigned long>(x));};
84 m[
typeid(double)] = [](boost::any
const& x) {
return PyFloat_FromDouble(boost::any_cast<double>(x));};
85 m[
typeid(float)] = [](boost::any
const& x) {
return PyFloat_FromDouble(
static_cast<double>(boost::any_cast<float>(x)));};
86 m[
typeid(std::string)] = [](boost::any
const& x) {
return PyBytes_FromString(boost::any_cast<std::string>(x).c_str());};
88 m[
typeid(Eigen::Ref<EigenRowType>)] = [](boost::any
const& x){
89 return eigen_array_cast<EigenProps<Eigen::Ref<EigenRowType>>>(boost::any_cast<Eigen::Ref<EigenRowType>>(x));
92 m[
typeid(Eigen::Ref<EigenColType>)] = [](boost::any
const& x){
93 return eigen_array_cast<EigenProps<Eigen::Ref<EigenColType>>>(boost::any_cast<Eigen::Ref<EigenColType>>(x));
96 m[
typeid(EigenRowType)] = [](boost::any
const& x){
97 return eigen_array_cast<EigenProps<EigenRowType>>(boost::any_cast<EigenRowType>(x));
100 m[
typeid(EigenColType)] = [](boost::any
const& x){
101 return eigen_array_cast<EigenProps<EigenColType>>(boost::any_cast<EigenColType>(x));
104 m[
typeid(EigenVectorType)] = [](boost::any
const& x){
105 return eigen_array_cast<EigenProps<EigenVectorType>>(boost::any_cast<EigenVectorType>(x));
108 m[
typeid(EigenRowVectorType)] = [](boost::any
const& x){
109 return eigen_array_cast<EigenProps<EigenRowVectorType>>(boost::any_cast<EigenRowVectorType>(x));
116 static std::map<std::string, std::function<boost::any(PyObject*)>> createFromPythonMap()
118 std::map<std::string, std::function<boost::any(PyObject*)>> m;
119 m[
"float"] = [](PyObject* obj) {
return boost::any(PyFloat_AsDouble(obj));};
120 m[
"int"] = [](PyObject* obj) {
return boost::any(PyLong_AsLong(obj));};
121 m[
"str"] = [](PyObject* obj){
122 PyObject* str_exc_type = PyObject_Repr(obj);
124 PyObject* pyStr = PyUnicode_AsEncodedString(str_exc_type,
"utf-8",
"Error ~");
125 const char *strExcType = PyBytes_AS_STRING(pyStr);
127 boost::any output = std::string(strExcType);
129 Py_XDECREF(str_exc_type);
135 m[
"numpy.ndarray"] = [](PyObject* obj){
137 type_caster<Eigen::Ref<EigenRowType>> rowCaster;
138 bool res = rowCaster.load(obj,
false);
140 Eigen::Ref<EigenRowType> *ref = rowCaster;
141 return boost::any(*ref);
143 type_caster<Eigen::Ref<EigenColType>> colCaster;
144 bool res = colCaster.load(obj,
false);
147 std::cerr <<
"ERROR: Could not convert numpy array to Eigen::Ref. Current support is only for row-major and col-major arrays of doubles. Is the numpy array full of doubles?";
151 Eigen::Ref<EigenColType> *ref = colCaster;
152 return boost::any(*ref);
166 std::unique_ptr<char, void(*)(
void*)> res {
167 abi::__cxa_demangle(name, NULL, NULL, &status),
171 return (status==0) ? res.get() : name ;
176 std::map<std::type_index, std::function<handle(boost::any
const&)>>
177 type_caster<boost::any>::toPythonMap = type_caster<boost::any>::createToPythonMap();
180 std::map<std::string, std::function<boost::any(PyObject*)>>
181 type_caster<boost::any>::fromPythonMap = type_caster<boost::any>::createFromPythonMap();
std::string demangle_typename(const char *name)
void load(Archive &ar, boost::any &obj)