PolyBoRi
embed.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 //*****************************************************************************
15 //*****************************************************************************
16 
17 #ifndef polybori_embed_h_
18 #define polybori_embed_h_
19 
20 // include basic definitions
21 #include <polybori/polybori.h>
22 
23 #include <boost/python.hpp>
24 #include <boost/python/stl_iterator.hpp>
25 
26 #include <string>
27 #include <iostream>
28 #include <vector>
29 #include <list>
30 #include <set>
31 
32 
33 #ifndef PBORI_PYTHONPATH
34 #define PBORI_PYTHONPATH "."
35 #endif
36 
38 
40 using boost::python::str;
41 using boost::python::import;
42 using boost::python::handle;
43 using boost::python::borrowed;
44 using boost::python::extract;
45 using boost::python::stl_input_iterator;
46 using boost::python::error_already_set;
47 
48 
54 
62 };
63 
71 class Interpreter {
72 public:
73 
75  ~Interpreter() { if(m_owns_python) Py_Finalize(); }
76 
79  static void init() { instance(); }
80 
82  static boost::python::object& globals() { return instance().m_globals; }
83 
84 private:
86  Interpreter():
87  m_owns_python(false), m_globals() {
88  if (!Py_IsInitialized()) init_python();
89  set_python_defaults();
90  }
91 
94  static Interpreter& instance() {
95  static Interpreter init_interpreter;
96  return init_interpreter;
97  }
98 
100  void init_python() {
101  Py_Initialize();
102  m_owns_python = true;
103  }
104 
106  void set_python_defaults() {
107  // Sone python modules needs argc, argv set for some reason
108  const char* argv = "";
109  PySys_SetArgv(1, (char**)&argv);
110  import("sys").attr("path").attr("insert")(0, PBORI_PYTHONPATH);
111  PyRun_SimpleString("from polybori.frontend import *");
112 
113  m_globals = import("__main__").attr("__dict__");
114  boost::python::object start = boost::python::eval("polybori_start", m_globals, m_globals);
115  start(m_globals);
116  }
117 
119  bool m_owns_python;
120 
122  boost::python::object m_globals;
123 };
124 
125 template <class Type>
126 class DerefProxy {
127  typedef DerefProxy self;
128 public:
129 
130  DerefProxy(const Type& val): m_val(val) {}
131 
133  return *this;
134  }
135  const Type& get() const{ return m_val; }
136 
137 private:
138  const Type& m_val;
139 };
140 
144 class dict:
145  public boost::python::dict {
146  typedef dict self;
147  typedef boost::python::dict base;
148 
149 public:
151  template <class Type>
152  dict(const Type& obj): base(obj) {}
153 
155  dict(): base() {}
156 
159  return *this;
160  }
161 };
162 
166 class tuple:
167  public boost::python::tuple {
168  typedef tuple self;
169  typedef boost::python::tuple base;
170 
171 public:
173  template <class Type>
174  tuple(const Type& obj): base(obj) {}
175 
177  tuple(): base() {}
178 
181  return *this;
182  }
183 };
184 
188 class object:
189  public boost::python::object {
190 
191  typedef object self;
192  typedef boost::python::object base;
193 
194 public:
196  template <class Type>
197  object(const Type& obj): base(obj) {}
198 
200  object(): base() {}
201 
203  self
204  operator()(const DerefProxy<tuple>& args,
205  const DerefProxy<DerefProxy<dict> >& kwds) const {
206  return object(handle<>(borrowed(PyObject_Call(base::ptr(), args.get().ptr(),
207  kwds.get().get().ptr()))));
208  }
210 
211  template <class Type>
212  self operator()(const Type& arg) const {
213  return static_cast<const boost::python::object&>(*this)(arg);
214  }
215  template <class Type1, class Type2>
216  self operator()(const Type1& arg1, const Type2& arg2) const {
217  return static_cast<const boost::python::object&>(*this)(arg1, arg2);
218  }
219  template <class Type1, class Type2, class Type3>
220  self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3) const {
221  return static_cast<const boost::python::object&>(*this)(arg1, arg2, arg3);
222  }
223  template <class Type1, class Type2, class Type3, class Type4>
224  self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3,
225  const Type4& arg4) const {
226  return static_cast<const boost::python::object&>(*this)(arg1, arg2, arg3,
227  arg4);
228  }
230 
232 
233  template <class Type>
234  self operator()(const DerefProxy<DerefProxy<dict> >& kwds) const {
235  return self::operator()(DerefProxy<tuple>(boost::python::make_tuple()), kwds);
236  }
237  template <class Type>
238  self operator()(const Type& arg,
239  const DerefProxy<DerefProxy<dict> >& kwds) const {
240  return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg)), kwds);
241  }
242  template <class Type1, class Type2>
243  self operator()(const Type1& arg1, const Type2& arg2,
244  const DerefProxy<DerefProxy<dict> >& kwds) const {
245  return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg1, arg2)), kwds);
246  }
247  template <class Type1, class Type2, class Type3>
248  self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3,
249  const DerefProxy<DerefProxy<dict> >& kwds) const {
250  return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg1, arg2, arg3)), kwds);
251  }
252  template <class Type1, class Type2, class Type3, class Type4>
253  self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3,
254  const Type4& arg4, const DerefProxy<DerefProxy<dict> >& kwds) const {
255  return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg1, arg2, arg3,
256  arg4)), kwds);
257  }
259 
261 
262  operator bool() const {
263  return extract<bool>(*this);
264  }
265  operator int() const {
266  return extract<int>(*this);
267  }
268  operator long() const {
269  return extract<long>(*this);
270  }
271  operator std::string() const {
272  return extract<std::string>(*this);
273  }
274 
275  operator const Ring&() const {
276  return extract<const Ring&>(*this);
277  }
278  operator Polynomial() const {
279  return extract<Polynomial>(*this);
280  }
281  operator Monomial() const {
282  return extract<Monomial>(*this);
283  }
284  operator const Variable&() const {
285  return extract<const Variable&>(*this);
286  }
287  operator BooleSet() const {
288  return extract<BooleSet>(*this);
289  }
290  template <class Type>
291  operator std::vector<Type>() const {
292  stl_input_iterator<self> begin(*this), end;
293  return std::vector<Type>(begin, end);
294  }
295  template <class Type>
296  operator std::list<Type>() const {
297  stl_input_iterator<self> begin(*this), end;
298  return std::list<Type>(begin, end);
299  }
300  template <class Type>
301  operator std::set<Type>() const {
302  stl_input_iterator<self> begin(*this), end;
303  return std::set<Type>(begin, end);
304  }
306 };
307 
308 
309 inline object
310 eval(str expression) {
311 
312 try {
313  return boost::python::eval(expression,
314  Interpreter::globals(),
315  Interpreter::globals());
316  }
317  catch( error_already_set ) {
318  PyErr_Print();
319  }
320  return object();
321 }
322 
323 inline object
324 exec(str code) {
325  try {
326  return boost::python::exec(code,
327  Interpreter::globals(),
328  Interpreter::globals());
329  }
330  catch( error_already_set ) {
331  PyErr_Print();
332  }
333  return object();
334 }
335 
336 inline object
337 exec_file(str filename) {
338  try {
339  return boost::python::exec_file(filename,
340  Interpreter::globals(),
341  Interpreter::globals());
342  }
343  catch( error_already_set ) {
344  PyErr_Print();
345  }
346  return object();
347 }
348 
349 
350 inline void
351 run (const char* code) {
352  PyRun_SimpleString(code);
353 }
354 
355 
357 
358 
359 namespace boost { namespace python { namespace converter {
360  template <>
361  struct object_manager_traits<PBORI::dict>:
362  object_manager_traits<boost::python::dict> {};
363 
364  template <>
365  struct object_manager_traits<PBORI::tuple>:
366  object_manager_traits<boost::python::tuple> {};
367 
368  template <>
369  struct object_manager_traits<PBORI::object>:
370  object_manager_traits<boost::python::object> {};
371 
372 }}}
373 
374 #define BEGIN_PBORI_EMBED() try { USING_NAMESPACE_PBORI; while(0)
375 #define END_PBORI_EMBED() } catch(PBORI::error_already_set) { PyErr_Print(); } while(0)
376 
377 #endif /* polybori_embed_h_ */
378