Advertisement
Guest User

C++ List/Dict wrapper for Tcl and Python

a guest
Jul 28th, 2017
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.48 KB | None | 0 0
  1. #ifndef SWOBJECT_HPP
  2. #define SWOBJECT_HPP
  3.  
  4. #ifdef SWIGTCL
  5.  
  6. #ifdef SWIG
  7. %typemap(out) SWObject {
  8.     Tcl_SetObjResult(interp, $1.getObj());
  9. }  
  10.  
  11. %typemap(out) SWList {
  12.     Tcl_SetObjResult(interp, $1.getObj());
  13. }  
  14.  
  15. %typemap(out) SWDict {
  16.     Tcl_SetObjResult(interp, $1.getObj());
  17. }  
  18.  
  19.  
  20. %{
  21. #include "SWObject.hpp"
  22. %}
  23.  
  24. #else
  25. // C++-compiler Tcl
  26. #include <tcl.h>
  27. //#include <tclTomMath.h>
  28. #include <string>
  29.  
  30. // create Tcl_Obj by overloaded functions
  31. class SWList;
  32. class SWDict;
  33.  
  34. inline Tcl_Obj* MakeBaseSWObj() {
  35.     // create empty object. Easy in Tcl - Python?
  36.     return Tcl_NewObj();
  37. }
  38.  
  39. inline Tcl_Obj* MakeBaseSWObj(int i) {
  40.     // create integer object
  41.     return Tcl_NewIntObj(i);
  42. }
  43.  
  44. inline Tcl_Obj* MakeBaseSWObj(long i) {
  45.     // create integer object
  46.     return Tcl_NewLongObj(i);
  47. }
  48.  
  49. inline Tcl_Obj* MakeBaseSWObj(long long i) {
  50.     // create integer object
  51.     return Tcl_NewWideIntObj(i);
  52. }
  53.  
  54. inline Tcl_Obj* MakeBaseSWObj(unsigned long long i) {
  55.     // create integer object
  56.     return Tcl_NewWideIntObj(i); /** potential overflow **/
  57. }
  58.  
  59. inline Tcl_Obj* MakeBaseSWObj(float d) {
  60.     // create double object.
  61.     return Tcl_NewDoubleObj(d);
  62. }
  63.  
  64.  
  65. inline Tcl_Obj* MakeBaseSWObj(double d) {
  66.     // create double object.
  67.     return Tcl_NewDoubleObj(d);
  68. }
  69.  
  70. inline Tcl_Obj* MakeBaseSWObj(const std::string &s) {
  71.     // create string object
  72.     return Tcl_NewStringObj(s.c_str(), s.size());
  73. }
  74.  
  75.  
  76. Tcl_Obj* MakeBaseSWObj(const SWList &o);
  77.  
  78. Tcl_Obj* MakeBaseSWObj(const SWDict &o);
  79.    
  80. class SWObject {
  81. protected:
  82.     mutable Tcl_Obj *ptr;
  83. public:
  84.     SWObject() : ptr(NULL) { }
  85.  
  86.     template <typename TObject>
  87.     SWObject(const TObject& obj) : ptr(obj.getObj()) {
  88.         if (ptr) Tcl_IncrRefCount(ptr);
  89.     }
  90.  
  91.     ~SWObject() {
  92.         if (ptr) Tcl_DecrRefCount(ptr);
  93.     }
  94.    
  95.     SWObject(const SWObject& obj) : ptr(obj.ptr) {
  96.         if (ptr) Tcl_IncrRefCount(ptr);
  97.     }
  98.  
  99.     SWObject& operator = (const SWObject& obj) {
  100.         if (ptr) Tcl_DecrRefCount(ptr);
  101.         ptr = obj.ptr;
  102.         if (ptr) Tcl_IncrRefCount(ptr);
  103.         return *this;
  104.     }
  105.  
  106.     template <typename T>
  107.     SWObject& MakeBasic(const T& what) {
  108.         if (ptr) Tcl_DecrRefCount(ptr);
  109.         ptr = MakeBaseSWObj(what);
  110.         Tcl_IncrRefCount(ptr);
  111.         return *this;
  112.     }
  113.  
  114.     Tcl_Obj* getObj() const {
  115.         ensure_exists();
  116.         return ptr;
  117.     }
  118.  
  119.     void ensure_exists() const {
  120.         if (!ptr) {
  121.             ptr = MakeBaseSWObj();
  122.             Tcl_IncrRefCount(ptr);
  123.         }
  124.  
  125.     }
  126. };
  127.  
  128. class SWList : public SWObject {
  129. public:
  130.     SWList() : SWObject() { }
  131.     SWList(const SWList& l) : SWObject(l) { }
  132.     SWList& operator = (const SWList& obj) {
  133.         SWObject::operator = (obj);
  134.         return *this;
  135.     }
  136.    
  137.     template <typename T>
  138.     SWList(const std::vector<T> & vec) : SWObject() {
  139.         for (size_t i=0; i<vec.size(); i++) {
  140.             push_back(vec[i]);
  141.         }
  142.     }
  143.  
  144.     void ensure_exists() const {
  145.         if (!ptr) {
  146.             ptr = Tcl_NewListObj(0, NULL);
  147.             Tcl_IncrRefCount(ptr);
  148.         }
  149.     }
  150.  
  151.     template <typename TPOD>
  152.     void push_back(const TPOD& what) {
  153.         ensure_exists();
  154.         Tcl_ListObjAppendElement(NULL, ptr, MakeBaseSWObj(what));
  155.     }
  156.  
  157.     //template <>
  158.     void push_back(const SWObject& what) {
  159.         ensure_exists();
  160.         Tcl_ListObjAppendElement(NULL, ptr, what.getObj());
  161.     }
  162.  
  163.     Tcl_Obj* getObj() const {
  164.         ensure_exists();
  165.         return ptr;
  166.     }
  167. };
  168.  
  169. inline Tcl_Obj* MakeBaseSWObj(const SWList &l) {
  170.     // create string object
  171.     return l.getObj();
  172. }
  173.  
  174.  
  175. class SWDict : public SWObject {
  176. public:
  177.     SWDict() : SWObject() { }
  178.     SWDict(const SWDict& l) : SWObject(l) { }
  179.     SWDict& operator = (const SWDict& obj) {
  180.         SWObject::operator = (obj);
  181.         return *this;
  182.     }
  183.  
  184.     void ensure_exists() const {
  185.         if (!ptr) {
  186.             ptr = Tcl_NewDictObj();
  187.             Tcl_IncrRefCount(ptr);
  188.         }
  189.     }
  190.    
  191.     template <typename TKey, typename TValue>
  192.     void insert(const TKey &key, const TValue &value) {
  193.         ensure_exists();
  194.         Tcl_DictObjPut(NULL, ptr, MakeBaseSWObj(key), MakeBaseSWObj(value));
  195.     }
  196.  
  197.     template <typename TKey>
  198.     void insert(const TKey &key, const SWObject& value) {
  199.         ensure_exists();
  200.         Tcl_DictObjPut(NULL, ptr, MakeBaseSWObj(key), value.getObj());
  201.     }
  202.  
  203.     Tcl_Obj* getObj() const {
  204.         ensure_exists();
  205.         return ptr;
  206.     }
  207. };
  208.  
  209. inline Tcl_Obj* MakeBaseSWObj(const SWDict &d) {
  210.     // create string object
  211.     return d.getObj();
  212. }
  213.  
  214. #endif
  215. #endif // SWIGTCL
  216.  
  217. #ifdef SWIGPYTHON
  218.  
  219. #ifdef SWIG
  220. %typemap(out) SWObject {
  221.     $result =  $1.getObj();
  222. }  
  223.  
  224. %typemap(out) SWList {
  225.     $result =  $1.getObj();
  226. }  
  227.  
  228. %typemap(out) SWDict {
  229.     $result =  $1.getObj();
  230. }  
  231.  
  232.  
  233. %{
  234. #include "SWObject.hpp"
  235. %}
  236.  
  237. #else
  238. // C++-compiler - Python version
  239. #include <Python.h>
  240. #include <string>
  241.  
  242. // create PyObject by overloaded functions
  243. class SWList;
  244. class SWDict;
  245.  
  246. inline PyObject* MakeBaseSWObj() {
  247.     // create empty object. Easy in Tcl - Python? Refcounting?
  248.     return Py_None;
  249. }
  250.  
  251. inline PyObject* MakeBaseSWObj(int i) {
  252.     // create integer object
  253.     return PyLong_FromLong(i);
  254. }
  255.  
  256. inline PyObject* MakeBaseSWObj(long l) {
  257.     // create integer object
  258.     return PyLong_FromLong(l);
  259. }
  260.  
  261. inline PyObject* MakeBaseSWObj(long long l) {
  262.     // create integer object
  263.     return PyLong_FromLongLong(l);
  264. }
  265.  
  266. inline PyObject* MakeBaseSWObj(unsigned long long l) {
  267.     // create integer object
  268.     return PyLong_FromUnsignedLongLong(l);
  269. }
  270.  
  271. inline PyObject* MakeBaseSWObj(double d) {
  272.     // create double object.
  273.     return PyFloat_FromDouble(d);
  274. }
  275.  
  276. inline PyObject* MakeBaseSWObj(float f) {
  277.     // create double object.
  278.     return PyFloat_FromDouble(f);
  279. }
  280.  
  281. inline PyObject* MakeBaseSWObj(const std::string &s) {
  282.     // create string object
  283.     return PyString_FromStringAndSize(s.c_str(), s.size());
  284. }
  285.  
  286.  
  287. PyObject* MakeBaseSWObj(const SWList &o);
  288.  
  289. PyObject* MakeBaseSWObj(const SWDict &o);
  290.    
  291. class SWObject {
  292. protected:
  293.     mutable PyObject *ptr;
  294. public:
  295.     SWObject() : ptr(NULL) { }
  296.  
  297.     template <typename TObject>
  298.     SWObject(const TObject& obj) : ptr(obj.getObj()) {
  299.         if (ptr) Py_INCREF(ptr);
  300.     }
  301.  
  302.     ~SWObject() {
  303.         if (ptr) Py_DECREF(ptr);
  304.     }
  305.    
  306.     SWObject(const SWObject& obj) : ptr(obj.ptr) {
  307.         if (ptr) Py_INCREF(ptr);
  308.     }
  309.  
  310.     SWObject& operator = (const SWObject& obj) {
  311.         if (ptr) Py_DECREF(ptr);
  312.         ptr = obj.ptr;
  313.         if (ptr) Py_INCREF(ptr);
  314.         return *this;
  315.     }
  316.    
  317.     template <typename T>
  318.     SWObject& MakeBasic(const T& what) {
  319.         if (ptr) Py_DECREF(ptr);
  320.         ptr = MakeBaseSWObj(what);
  321.         Py_INCREF(ptr);
  322.         return *this;
  323.     }
  324.  
  325.     PyObject* getObj() const {
  326.         ensure_exists();
  327.         return ptr;
  328.     }
  329.  
  330.     void ensure_exists() const {
  331.         if (!ptr) {
  332.             ptr = MakeBaseSWObj();
  333.             Py_INCREF(ptr);
  334.         }
  335.  
  336.     }
  337. };
  338.  
  339. class SWList : public SWObject {
  340. public:
  341.     SWList() : SWObject() { }
  342.     SWList(const SWList& l) : SWObject(l) { }
  343.     SWList& operator = (const SWList& obj) {
  344.         SWObject::operator = (obj);
  345.         return *this;
  346.     }
  347.    
  348.     template <typename T>
  349.     SWList(const std::vector<T> & vec) : SWObject() {
  350.         for (size_t i=0; i<vec.size(); i++) {
  351.             push_back(vec[i]);
  352.         }
  353.     }
  354.  
  355.     void ensure_exists() const {
  356.         if (!ptr) {
  357.             ptr = PyList_New(0);
  358.             Py_INCREF(ptr);
  359.         }
  360.     }
  361.  
  362.     template <typename TPOD>
  363.     void push_back(const TPOD& what) {
  364.         ensure_exists();
  365.         PyList_Append(ptr, MakeBaseSWObj(what));
  366.     }
  367.    
  368.     void push_back(const SWObject& what) {
  369.         ensure_exists();
  370.         PyList_Append(ptr, what.getObj());
  371.     }
  372.  
  373.     PyObject* getObj() const {
  374.         ensure_exists();
  375.         return ptr;
  376.     }
  377. };
  378.  
  379. inline PyObject* MakeBaseSWObj(const SWList &l) {
  380.     // create string object
  381.     return l.getObj();
  382. }
  383.  
  384.  
  385. class SWDict : public SWObject {
  386. public:
  387.     SWDict() : SWObject() { }
  388.     SWDict(const SWDict& l) : SWObject(l) { }
  389.     SWDict& operator = (const SWDict& obj) {
  390.         SWObject::operator = (obj);
  391.         return *this;
  392.     }
  393.  
  394.     void ensure_exists() const {
  395.         if (!ptr) {
  396.             ptr = PyDict_New();
  397.             Py_INCREF(ptr);
  398.         }
  399.     }
  400.  
  401.     template <typename TKey, typename TValue>
  402.     void insert(const TKey &key, const TValue &value) {
  403.         ensure_exists();
  404.         PyDict_SetItem(ptr, MakeBaseSWObj(key), MakeBaseSWObj(value));
  405.     }
  406.    
  407.     template <typename TKey>
  408.     void insert(const TKey &key, const SWObject &value) {
  409.         ensure_exists();
  410.         PyDict_SetItem(ptr, MakeBaseSWObj(key), value.getObj());
  411.     }
  412.  
  413.     PyObject* getObj() const {
  414.         ensure_exists();
  415.         return ptr;
  416.     }
  417. };
  418.  
  419. inline PyObject* MakeBaseSWObj(const SWDict &d) {
  420.     // create string object
  421.     return d.getObj();
  422. }
  423.  
  424.  
  425. #endif // C++
  426. #endif //SWIGPYTHON
  427.  
  428. #endif // SWOBJECT_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement