FLAME  devel
 All Classes Functions Variables Typedefs Enumerations Pages
pyflame.h
1 #include <stdexcept>
2 
3 #ifndef PYFLAME_H
4 #define PYFLAME_H
5 #define PY_SSIZE_T_CLEAN
6 #include <Python.h>
7 
8 struct Config;
9 struct StateBase;
10 
11 Config* list2conf(PyObject *dict);
12 void List2Config(Config& ret, PyObject *dict, unsigned depth=0);
13 PyObject* conf2dict(const Config *conf);
14 
15 PyObject* wrapstate(StateBase*); // takes ownership of argument from caller
16 StateBase* unwrapstate(PyObject*); // ownership of returned pointer remains with argument
17 
18 PyObject* PyGLPSPrint(PyObject *, PyObject *args);
19 Config* PyGLPSParse2Config(PyObject *, PyObject *args, PyObject *kws);
20 PyObject* PyGLPSParse(PyObject *, PyObject *args, PyObject *kws);
21 
22 int registerModMachine(PyObject *mod);
23 int registerModState(PyObject *mod);
24 
25 #define CATCH2V(CXX, PYEXC) catch(CXX& e) { if(!PyErr_Occurred()) PyErr_SetString(PyExc_##PYEXC, e.what()); return; }
26 #define CATCH3(CXX, PYEXC, RET) catch(CXX& e) { if(!PyErr_Occurred()) PyErr_SetString(PyExc_##PYEXC, e.what()); return RET; }
27 #define CATCH2(CXX, PYEXC) CATCH3(CXX, PYEXC, NULL)
28 #define CATCH1(RET) CATCH3(std::exception, RuntimeError, RET)
29 #define CATCH() CATCH2(std::exception, RuntimeError)
30 
31 #if PY_MAJOR_VERSION >= 3
32 #define PyInt_Type PyLong_Type
33 #define PyInt_Check PyLong_Check
34 #define PyInt_FromLong PyLong_FromLong
35 #define PyInt_FromSize_t PyLong_FromSize_t
36 #define PyInt_AsLong PyLong_AsLong
37 #define PyString_Check PyUnicode_Check
38 #define PyString_FromString PyUnicode_FromString
39 #define MODINIT_RET(VAL) return (VAL)
40 
41 #else
42 #define MODINIT_RET(VAL) return
43 
44 #endif
45 
46 struct borrow {};
47 
48 template<typename T = PyObject>
49 struct PyRef {
50  T* _ptr;
51  PyRef() :_ptr(NULL) {}
53  PyRef(const PyRef& o)
54  :_ptr(o._ptr)
55  {
56  Py_XINCREF(_ptr);
57  }
62  explicit PyRef(PyObject* p) : _ptr((T*)p) {
63  if(!p)
64  throw std::bad_alloc(); // TODO: probably already a python exception
65  }
67  PyRef(T* p, borrow) : _ptr(p) {
68  if(!p)
69  throw std::bad_alloc();
70  Py_INCREF(p);
71  }
72  ~PyRef() {Py_CLEAR(_ptr);}
73  PyRef& operator =(const PyRef& o)
74  {
75  if(&o!=this) {
76  PyObject *tmp = _ptr;
77  _ptr = o._ptr;
78  Py_XINCREF(_ptr);
79  Py_XDECREF(tmp);
80  }
81  return *this;
82  }
83  T* release() {
84  T* ret = _ptr;
85  assert(ret);
86  _ptr = NULL;
87  return ret;
88  }
89  void clear() {
90  Py_CLEAR(_ptr);
91  }
92  void reset(T* p) {
93  if(!p)
94  throw std::bad_alloc(); // TODO: probably already a python exception
95  Py_CLEAR(_ptr);
96  _ptr = p;
97  }
98  void reset(T* p, borrow) {
99  if(!p)
100  throw std::bad_alloc(); // TODO: probably already a python exception
101  PyObject *tmp = _ptr;
102  _ptr = p;
103  Py_INCREF(p);
104  Py_XDECREF(tmp);
105  }
106  struct allow_null {};
107  T* reset(T* p, allow_null) {
108  Py_CLEAR(_ptr);
109  _ptr = p;
110  return p;
111  }
112  T* get() const { return _ptr; }
113  PyObject* releasePy() {
114  return (PyObject*)release();
115  }
116  PyObject* py() const {
117  return (PyObject*)_ptr;
118  }
119  template<typename E>
120  E* as() const {
121  return (E*)_ptr;
122  }
123  T& operator*() const {
124  return *_ptr;
125  }
126  T* operator->() const {
127  return _ptr;
128  }
129 };
130 
131 // Extract C string from python object. py2 str or unicode, py3 str only (aka. unicode)
132 struct PyCString
133 {
134  PyRef<> pystr; // py2 str or py3 bytes
135  PyCString() {}
136  PyCString(const PyRef<>& o) { *this = o; }
137  PyCString& operator=(const PyRef<>& o) { reset(o.py()); return *this; }
138  void reset(PyObject *obj)
139  {
140  if(PY_MAJOR_VERSION>=3 || PyUnicode_Check(obj)) {
141  pystr.reset(PyUnicode_AsUTF8String(obj));
142  } else if(PyBytes_Check(obj)) {
143  pystr.reset(obj, borrow());
144  }
145  }
146  const char *c_str(PyObject *obj) {
147  if(!obj)
148  throw std::bad_alloc();
149  reset(obj);
150  return c_str();
151  }
152  const char *c_str() const {
153  const char *ret = PyBytes_AsString(pystr.py());
154  if(!ret)
155  throw std::invalid_argument("Can't extract string from object");
156  return ret;
157 
158  }
159 private:
160  PyCString(const PyCString&);
161  PyCString& operator=(const PyCString&);
162 };
163 
164 struct PyGetBuf
165 {
166  Py_buffer buf;
167  bool havebuf;
168  PyGetBuf() : havebuf(false) {}
169  ~PyGetBuf() {
170  if(havebuf) PyBuffer_Release(&buf);
171  }
172  bool get(PyObject *obj) {
173  if(havebuf) PyBuffer_Release(&buf);
174  havebuf = PyObject_GetBuffer(obj, &buf, PyBUF_SIMPLE)==0;
175  if(!havebuf) PyErr_Clear();
176  return havebuf;
177  }
178  size_t size() const { return havebuf ? buf.len : 0; }
179  void * data() const { return buf.buf; }
180 };
181 
182 #endif // PYFLAME_H
The abstract base class for all simulation state objects.
Definition: base.h:28
Associative configuration container.
Definition: config.h:66