MUQ  0.4.3
SwigExtract.h
Go to the documentation of this file.
1 #ifndef SWIGEXTRACT_H_
2 #define SWIGEXTRACT_H_
3 
4 #include <pybind11/pybind11.h>
5 
6 struct PySwigObject {
7  PyObject_HEAD
8  void * ptr;
9  const char * desc;
10 };
11 
12 
13 namespace muq{
14 namespace Modeling{
15 
36  {
37 
38  public:
39  SwigExtract(pybind11::object const& objIn) : obj(objIn){};
40 
41  template<typename T>
42  operator T()
43  {
44  return Cast<T>();
45  }
46 
47  template<typename T>
48  T Cast()
49  {
50  // This functions performs some magic performed by the boost.python folks and described here:
51  // https://wiki.python.org/moin/boost.python/HowTo#SWIG_exposed_C.2B-.2B-_object_from_Python
52 
53  PyObject* objPtr = pybind11::handle(obj).ptr();
54 
55  char thisStr[] = "this";
56 
57  //first we need to get the this attribute from the Python Object
58  if (!PyObject_HasAttrString(objPtr, thisStr))
59  ConversionError<T>();
60 
61  PyObject* thisAttr = PyObject_GetAttrString(objPtr, thisStr);
62  if (thisAttr == NULL)
63  ConversionError<T>();
64 
65  T* pointer = (T*) ((PySwigObject*)thisAttr)->ptr;
66  Py_DECREF(thisAttr);
67 
68  return *pointer;
69  }
70 
71  private:
72 
73  pybind11::object const& obj;
74 
75  template<typename T>
77  {
78  throw std::invalid_argument("Unable to convert Python type of " + std::string(pybind11::str(obj.attr("__repr__"))) + " to c++ type of " + std::string(typeid(T).name()));
79  }
80  };
81 
82 
83 } // namepsace Modeling
84 } // namespace muq
85 
86 #endif
Class to extract a c++ class that was exposed to python with Swig. @detials This class is used to unw...
Definition: SwigExtract.h:36
pybind11::object const & obj
Definition: SwigExtract.h:73
SwigExtract(pybind11::object const &objIn)
Definition: SwigExtract.h:39
const char * desc
Definition: SwigExtract.h:9
PyObject_HEAD void * ptr
Definition: SwigExtract.h:8