Tulip  4.2.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
PythonCppTypesConverter.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef PYTHONCPPTYPESCONVERTERS_H
21 #define PYTHONCPPTYPESCONVERTERS_H
22 
23 #include <tulip/Coord.h>
24 #include <tulip/Color.h>
25 #include <tulip/ColorScale.h>
26 #include <tulip/StringCollection.h>
27 #include <tulip/Size.h>
28 #include <tulip/Node.h>
29 #include <tulip/Edge.h>
30 #include <tulip/BooleanProperty.h>
31 #include <tulip/ColorProperty.h>
32 #include <tulip/DoubleProperty.h>
33 #include <tulip/IntegerProperty.h>
34 #include <tulip/LayoutProperty.h>
35 #include <tulip/SizeProperty.h>
36 #include <tulip/StringProperty.h>
37 
38 #if defined(__GNUC__)
39 #include <cxxabi.h>
40 static std::string demangleClassName(const char* className) {
41  static char demangleBuffer[256];
42  int status;
43  size_t length = 256;
44  abi::__cxa_demangle((char *) className, (char *) demangleBuffer,
45  &length, &status);
46  return std::string(demangleBuffer);
47 }
48 #elif defined(_MSC_VER)
49 static std::string demangleClassName(const char* className) {
50  std::string s(className);
51 
52  if (s.find("class ") == 0) {
53  return std::string(className + 6);
54  }
55  else {
56  return s;
57  }
58 }
59 #endif
60 
61 TLP_PYTHON_SCOPE void *convertSipWrapperToCppType(PyObject *sipWrapper, const std::string &cppTypename, const bool transferTo=false);
62 TLP_PYTHON_SCOPE PyObject *convertCppTypeToSipWrapper(void *cppObj, const std::string &cppTypename, bool fromNew=false);
63 
64 TLP_PYTHON_SCOPE bool convertPyObjectToBool(PyObject *pyObject, bool &cppObject);
65 TLP_PYTHON_SCOPE PyObject *convertBoolToPyObject(bool cppObject);
66 
67 TLP_PYTHON_SCOPE bool convertPyObjectToDouble(PyObject *pyObject, double &cppObject);
68 TLP_PYTHON_SCOPE PyObject *convertDoubleToPyObject(double cppObject);
69 
70 TLP_PYTHON_SCOPE bool convertPyObjectToLong(PyObject *pyObject, long &cppObject);
71 TLP_PYTHON_SCOPE PyObject *convertLongToPyObject(long cppObject);
72 
73 TLP_PYTHON_SCOPE bool convertPyObjectToUnsignedLong(PyObject *pyObject, unsigned long &cppObject);
74 TLP_PYTHON_SCOPE PyObject *convertUnsignedLongToPyObject(unsigned long cppObject);
75 
76 class TLP_PYTHON_SCOPE ValueSetter {
77 
78 public:
79 
80  ValueSetter(tlp::DataSet *dataSet, std::string key) :
81  dataSet(dataSet), graph(NULL), key(key) {}
82 
83  ValueSetter(tlp::Graph *graph, std::string key) :
84  dataSet(NULL), graph(graph), key(key) {}
85 
86  template <typename T>
87  void setValue(const T &value) {
88  if (dataSet) {
89  dataSet->set(key, value);
90  }
91  else if (graph) {
92  graph->setAttribute(key, value);
93  }
94  }
95 
96 private :
97 
98  tlp::DataSet *dataSet;
99  tlp::Graph *graph;
100  std::string key;
101 };
102 
103 TLP_PYTHON_SCOPE PyObject *getPyObjectFromDataType(const tlp::DataType *dataType, bool noCopy=false);
104 
105 TLP_PYTHON_SCOPE bool setCppValueFromPyObject(PyObject *pyObj, ValueSetter &valSetter, tlp::DataType *dataType=NULL);
106 
107 template <typename T>
108 class PyObjectToCppObjectConvertor {
109 
110 public:
111 
112  bool convert(PyObject *pyObject, T &cppObject) {
113  std::string className = demangleClassName(typeid(T).name());
114 
115  void *cppObjPointer = convertSipWrapperToCppType(pyObject, className);
116 
117  if (cppObjPointer) {
118  cppObject = *reinterpret_cast<T*>(cppObjPointer);
119  return true;
120  }
121 
122  return false;
123  }
124 
125 };
126 
127 template <typename T>
128 class PyObjectToCppObjectConvertor<T*> {
129 
130 public:
131 
132  bool convert(PyObject *pyObject, T *&cppObject) {
133  std::string className = demangleClassName(typeid(T).name());
134 
135  void *cppObjPointer = convertSipWrapperToCppType(pyObject, className, true);
136 
137  if (cppObjPointer) {
138  cppObject = reinterpret_cast<T*>(cppObjPointer);
139  return true;
140  }
141 
142  return false;
143  }
144 };
145 
146 template <>
147 class PyObjectToCppObjectConvertor<bool> {
148 public:
149  bool convert(PyObject *pyObject, bool &cppObject) {
150  return convertPyObjectToBool(pyObject, cppObject);
151  }
152 };
153 
154 template <>
155 class PyObjectToCppObjectConvertor<double> {
156 public:
157  bool convert(PyObject *pyObject, double &cppObject) {
158  return convertPyObjectToDouble(pyObject, cppObject);
159  }
160 };
161 
162 template <>
163 class PyObjectToCppObjectConvertor<float> {
164 public:
165  bool convert(PyObject *pyObject, float &cppObject) {
166  double val=0;
167  PyObjectToCppObjectConvertor<double> convertor;
168  bool ok = convertor.convert(pyObject, val);
169  cppObject = val;
170  return ok;
171  }
172 };
173 
174 template <>
175 class PyObjectToCppObjectConvertor<long> {
176 
177 public:
178  bool convert(PyObject *pyObject, long &cppObject) {
179  return convertPyObjectToLong(pyObject, cppObject);
180  }
181 };
182 
183 template <>
184 class PyObjectToCppObjectConvertor<int> {
185 public:
186  bool convert(PyObject *pyObject, int &cppObject) {
187  long val=0;
188  PyObjectToCppObjectConvertor<long> convertor;
189  bool ok = convertor.convert(pyObject, val);
190  cppObject = val;
191  return ok;
192  }
193 };
194 
195 template <>
196 class PyObjectToCppObjectConvertor<unsigned long> {
197 public:
198  bool convert(PyObject *pyObject, unsigned long &cppObject) {
199  return convertPyObjectToUnsignedLong(pyObject, cppObject);
200  }
201 };
202 
203 template <>
204 class PyObjectToCppObjectConvertor<unsigned int> {
205 public:
206  bool convert(PyObject *pyObject, unsigned int &cppObject) {
207  unsigned long val=0;
208  PyObjectToCppObjectConvertor<unsigned long> convertor;
209  bool ok = convertor.convert(pyObject, val);
210  cppObject = val;
211  return ok;
212  }
213 };
214 
215 template <typename T>
216 class CppObjectToPyObjectConvertor {
217 
218 public:
219 
220  bool convert(const T &cppObject, PyObject *&pyObject) {
221  std::string className = demangleClassName(typeid(T).name());
222 
223  T *objCopy = new T(cppObject);
224  PyObject *pyObj = convertCppTypeToSipWrapper(objCopy, className, true);
225 
226  if (pyObj) {
227  pyObject = pyObj;
228  return true;
229  }
230  else {
231  delete objCopy;
232  }
233 
234  return false;
235  }
236 };
237 
238 template <typename T>
239 class CppObjectToPyObjectConvertor<T*> {
240 
241 public:
242 
243  bool convert(T *cppObject, PyObject *&pyObject) {
244  std::string className = demangleClassName(typeid(T).name());
245 
246  PyObject *pyObj = convertCppTypeToSipWrapper(cppObject, className);
247 
248  if (pyObj) {
249  pyObject = pyObj;
250  return true;
251  }
252 
253  return false;
254  }
255 
256 };
257 
258 template <>
259 class CppObjectToPyObjectConvertor<bool> {
260 public:
261  bool convert(const bool &cppObject, PyObject *&pyObject) {
262  pyObject = convertBoolToPyObject(cppObject);
263  return true;
264  }
265 };
266 
267 template <>
268 class CppObjectToPyObjectConvertor<long> {
269 public:
270  bool convert(const long &cppObject, PyObject *&pyObject) {
271  pyObject = convertLongToPyObject(cppObject);
272  return true;
273  }
274 };
275 
276 template <>
277 class CppObjectToPyObjectConvertor<int> {
278 public:
279  bool convert(const int &cppObject, PyObject *&pyObject) {
280  pyObject = convertLongToPyObject(cppObject);
281  return true;
282  }
283 };
284 
285 template <>
286 class CppObjectToPyObjectConvertor<unsigned int> {
287 public:
288  bool convert(const unsigned int &cppObject, PyObject *&pyObject) {
289  pyObject = convertUnsignedLongToPyObject(cppObject);
290  return true;
291  }
292 };
293 
294 template <>
295 class CppObjectToPyObjectConvertor<unsigned long> {
296 public:
297  bool convert(const unsigned long &cppObject, PyObject *&pyObject) {
298  pyObject = convertUnsignedLongToPyObject(cppObject);
299  return true;
300  }
301 };
302 
303 template <>
304 class CppObjectToPyObjectConvertor<double> {
305 public:
306  bool convert(const double &cppObject, PyObject *&pyObject) {
307  pyObject = convertDoubleToPyObject(cppObject);
308  return true;
309  }
310 };
311 
312 template <>
313 class CppObjectToPyObjectConvertor<float> {
314 public:
315  bool convert(const float &cppObject, PyObject *&pyObject) {
316  pyObject = convertDoubleToPyObject(cppObject);
317  return true;
318  }
319 };
320 
321 
322 
323 #endif // PYTHONCPPTYPESCONVERTERS_H