Salome HOME
50b0f9b41a500464c61bfa2f157cd7fee15b11fc
[tools/medcoupling.git] / src / MEDCoupling_Swig / MEDCouplingDataArrayTraits.hxx
1 // Copyright (C) 2007-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #ifndef __MEDCOUPLINGDATAARRAYTRAITS_HXX__
22 #define __MEDCOUPLINGDATAARRAYTRAITS_HXX__
23
24 #include "MEDCouplingMemArray.hxx"
25
26 #include <Python.h>
27
28 #ifdef WITH_NUMPY
29 #include <numpy/arrayobject.h>
30 #if NPY_API_VERSION <= 0x00000006
31 #  define MED_NUMPY_OWNDATA NPY_OWNDATA
32 #else
33 #  define MED_NUMPY_OWNDATA NPY_ARRAY_OWNDATA
34 #endif
35 #endif
36
37 #ifdef WITH_NUMPY
38 // specific DataArray deallocator callback. This deallocator is used both in the constructor of DataArray and in the toNumPyArr
39 // method. This dellocator uses weakref to determine if the linked numArr is still alive or not. If alive the ownership is given to it.
40 // if no more alive the "standard" DataArray deallocator is called.
41 void numarrdeal(void *pt, void *wron)
42 {
43   void **wronc=(void **)wron;
44   PyObject *weakRefOnOwner=reinterpret_cast<PyObject *>(wronc[0]);
45   PyObject *obj=PyWeakref_GetObject(weakRefOnOwner);
46   if(obj!=Py_None)
47     {
48       Py_XINCREF(obj);
49       PyArrayObject *objC=reinterpret_cast<PyArrayObject *>(obj);
50       objC->flags|=MED_NUMPY_OWNDATA;
51       Py_XDECREF(weakRefOnOwner);
52       Py_XDECREF(obj);
53     }
54   else
55     {
56       typedef void (*MyDeallocator)(void *,void *);
57       MyDeallocator deall=(MyDeallocator)wronc[1];
58       int64_t *offset=reinterpret_cast<int64_t*>(wronc[2]);
59       deall(pt,offset);
60       delete offset;
61       Py_XDECREF(weakRefOnOwner);
62     }
63   delete [] wronc;
64 }
65 #endif
66
67 template<class MCData>
68 struct PyCallBackDataArraySt {
69     PyObject_HEAD
70     MCData *_pt_mc;
71 };
72
73 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayByte> PyCallBackDataArrayChar;
74 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayInt> PyCallBackDataArrayInt;
75 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayFloat> PyCallBackDataArrayFloat;
76 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayDouble> PyCallBackDataArrayDouble;
77
78 extern "C"
79 {
80   static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; }
81   
82   static PyObject *callbackmcdataarraychar___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
83   {
84     PyCallBackDataArrayChar *self = (PyCallBackDataArrayChar *) ( type->tp_alloc(type, 0) );
85     return (PyObject *)self;
86   }
87
88   static PyObject *callbackmcdataarrayint___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
89   {
90     PyCallBackDataArrayInt *self = (PyCallBackDataArrayInt *) ( type->tp_alloc(type, 0) );
91     return (PyObject *)self;
92   }
93   
94   static PyObject *callbackmcdataarrayfloat___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
95   {
96     PyCallBackDataArrayFloat *self = (PyCallBackDataArrayFloat *) ( type->tp_alloc(type, 0) );
97     return (PyObject *)self;
98   }
99   
100   static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
101   {
102     PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) );
103     return (PyObject *)self;
104   }
105   
106   static void callbackmcdataarray_dealloc(PyObject *self)
107   {
108     Py_TYPE(self)->tp_free(self);
109   }
110
111   
112   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
113   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
114   static PyObject *callbackmcdataarraychar_call(PyCallBackDataArrayChar *self, PyObject *args, PyObject *kw)
115   {
116     if(self->_pt_mc)
117       {
118         MEDCoupling::MemArray<char>& mma=self->_pt_mc->accessToMemArray();
119         mma.destroy();
120       }
121     Py_XINCREF(Py_None);
122     return Py_None;
123   }
124
125   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
126   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
127   static PyObject *callbackmcdataarrayint_call(PyCallBackDataArrayInt *self, PyObject *args, PyObject *kw)
128   {
129     if(self->_pt_mc)
130       {
131         MEDCoupling::MemArray<int>& mma=self->_pt_mc->accessToMemArray();
132         mma.destroy();
133       }
134     Py_XINCREF(Py_None);
135     return Py_None;
136   }
137
138   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
139   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
140   static PyObject *callbackmcdataarrayfloat_call(PyCallBackDataArrayFloat *self, PyObject *args, PyObject *kw)
141   {
142     if(self->_pt_mc)
143       {
144         MEDCoupling::MemArray<float>& mma=self->_pt_mc->accessToMemArray();
145         mma.destroy();
146       }
147     Py_XINCREF(Py_None);
148     return Py_None;
149   }
150   
151   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
152   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
153   static PyObject *callbackmcdataarraydouble_call(PyCallBackDataArrayDouble *self, PyObject *args, PyObject *kw)
154   {
155     if(self->_pt_mc)
156       {
157         MEDCoupling::MemArray<double>& mma=self->_pt_mc->accessToMemArray();
158         mma.destroy();
159       }
160     Py_XINCREF(Py_None);
161     return Py_None;
162   }
163 }
164
165 PyTypeObject PyCallBackDataArrayChar_RefType = {
166   PyVarObject_HEAD_INIT(&PyType_Type, 0)
167   "callbackmcdataarraychar",
168   sizeof(PyCallBackDataArrayChar),
169   0,
170   callbackmcdataarray_dealloc,            /*tp_dealloc*/
171   0,                          /*tp_print*/
172   0,                          /*tp_getattr*/
173   0,                          /*tp_setattr*/
174   0,                          /*tp_compare*/
175   0,                          /*tp_repr*/
176   0,                          /*tp_as_number*/
177   0,                          /*tp_as_sequence*/
178   0,                          /*tp_as_mapping*/
179   0,                          /*tp_hash*/
180   (ternaryfunc)callbackmcdataarraychar_call,  /*tp_call*/
181   0,                          /*tp_str*/
182   0,                          /*tp_getattro*/
183   0,                          /*tp_setattro*/
184   0,                          /*tp_as_buffer*/
185   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
186   0,                          /*tp_doc*/
187   0,                          /*tp_traverse*/
188   0,                          /*tp_clear*/
189   0,                          /*tp_richcompare*/
190   0,                          /*tp_weaklistoffset*/
191   0,                          /*tp_iter*/
192   0,                          /*tp_iternext*/
193   0,                          /*tp_methods*/
194   0,                          /*tp_members*/
195   0,                          /*tp_getset*/
196   0,                          /*tp_base*/
197   0,                          /*tp_dict*/
198   0,                          /*tp_descr_get*/
199   0,                          /*tp_descr_set*/
200   0,                          /*tp_dictoffset*/
201   callbackmcdataarray___init__,           /*tp_init*/
202   PyType_GenericAlloc,        /*tp_alloc*/
203   callbackmcdataarraychar___new__,            /*tp_new*/
204   PyObject_GC_Del,            /*tp_free*/
205 };
206
207
208 PyTypeObject PyCallBackDataArrayInt_RefType = {
209   PyVarObject_HEAD_INIT(&PyType_Type, 0)
210   "callbackmcdataarrayint",
211   sizeof(PyCallBackDataArrayInt),
212   0,
213   callbackmcdataarray_dealloc,            /*tp_dealloc*/
214   0,                          /*tp_print*/
215   0,                          /*tp_getattr*/
216   0,                          /*tp_setattr*/
217   0,                          /*tp_compare*/
218   0,                          /*tp_repr*/
219   0,                          /*tp_as_number*/
220   0,                          /*tp_as_sequence*/
221   0,                          /*tp_as_mapping*/
222   0,                          /*tp_hash*/
223   (ternaryfunc)callbackmcdataarrayint_call,  /*tp_call*/
224   0,                          /*tp_str*/
225   0,                          /*tp_getattro*/
226   0,                          /*tp_setattro*/
227   0,                          /*tp_as_buffer*/
228   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
229   0,                          /*tp_doc*/
230   0,                          /*tp_traverse*/
231   0,                          /*tp_clear*/
232   0,                          /*tp_richcompare*/
233   0,                          /*tp_weaklistoffset*/
234   0,                          /*tp_iter*/
235   0,                          /*tp_iternext*/
236   0,                          /*tp_methods*/
237   0,                          /*tp_members*/
238   0,                          /*tp_getset*/
239   0,                          /*tp_base*/
240   0,                          /*tp_dict*/
241   0,                          /*tp_descr_get*/
242   0,                          /*tp_descr_set*/
243   0,                          /*tp_dictoffset*/
244   callbackmcdataarray___init__,           /*tp_init*/
245   PyType_GenericAlloc,        /*tp_alloc*/
246   callbackmcdataarrayint___new__,            /*tp_new*/
247   PyObject_GC_Del,            /*tp_free*/
248 };
249
250 PyTypeObject PyCallBackDataArrayFloat_RefType = {
251   PyVarObject_HEAD_INIT(&PyType_Type, 0)
252   "callbackmcdataarraydouble",
253   sizeof(PyCallBackDataArrayFloat),
254   0,
255   callbackmcdataarray_dealloc,            /*tp_dealloc*/
256   0,                          /*tp_print*/
257   0,                          /*tp_getattr*/
258   0,                          /*tp_setattr*/
259   0,                          /*tp_compare*/
260   0,                          /*tp_repr*/
261   0,                          /*tp_as_number*/
262   0,                          /*tp_as_sequence*/
263   0,                          /*tp_as_mapping*/
264   0,                          /*tp_hash*/
265   (ternaryfunc)callbackmcdataarraydouble_call,  /*tp_call*/
266   0,                          /*tp_str*/
267   0,                          /*tp_getattro*/
268   0,                          /*tp_setattro*/
269   0,                          /*tp_as_buffer*/
270   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
271   0,                          /*tp_doc*/
272   0,                          /*tp_traverse*/
273   0,                          /*tp_clear*/
274   0,                          /*tp_richcompare*/
275   0,                          /*tp_weaklistoffset*/
276   0,                          /*tp_iter*/
277   0,                          /*tp_iternext*/
278   0,                          /*tp_methods*/
279   0,                          /*tp_members*/
280   0,                          /*tp_getset*/
281   0,                          /*tp_base*/
282   0,                          /*tp_dict*/
283   0,                          /*tp_descr_get*/
284   0,                          /*tp_descr_set*/
285   0,                          /*tp_dictoffset*/
286   callbackmcdataarray___init__,           /*tp_init*/
287   PyType_GenericAlloc,        /*tp_alloc*/
288   callbackmcdataarrayfloat___new__,            /*tp_new*/
289   PyObject_GC_Del,            /*tp_free*/
290 };
291
292 PyTypeObject PyCallBackDataArrayDouble_RefType = {
293   PyVarObject_HEAD_INIT(&PyType_Type, 0)
294   "callbackmcdataarraydouble",
295   sizeof(PyCallBackDataArrayDouble),
296   0,
297   callbackmcdataarray_dealloc,            /*tp_dealloc*/
298   0,                          /*tp_print*/
299   0,                          /*tp_getattr*/
300   0,                          /*tp_setattr*/
301   0,                          /*tp_compare*/
302   0,                          /*tp_repr*/
303   0,                          /*tp_as_number*/
304   0,                          /*tp_as_sequence*/
305   0,                          /*tp_as_mapping*/
306   0,                          /*tp_hash*/
307   (ternaryfunc)callbackmcdataarraydouble_call,  /*tp_call*/
308   0,                          /*tp_str*/
309   0,                          /*tp_getattro*/
310   0,                          /*tp_setattro*/
311   0,                          /*tp_as_buffer*/
312   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
313   0,                          /*tp_doc*/
314   0,                          /*tp_traverse*/
315   0,                          /*tp_clear*/
316   0,                          /*tp_richcompare*/
317   0,                          /*tp_weaklistoffset*/
318   0,                          /*tp_iter*/
319   0,                          /*tp_iternext*/
320   0,                          /*tp_methods*/
321   0,                          /*tp_members*/
322   0,                          /*tp_getset*/
323   0,                          /*tp_base*/
324   0,                          /*tp_dict*/
325   0,                          /*tp_descr_get*/
326   0,                          /*tp_descr_set*/
327   0,                          /*tp_dictoffset*/
328   callbackmcdataarray___init__,           /*tp_init*/
329   PyType_GenericAlloc,        /*tp_alloc*/
330   callbackmcdataarraydouble___new__,            /*tp_new*/
331   PyObject_GC_Del,            /*tp_free*/
332 };
333
334 #ifdef WITH_NUMPY
335 template<class T>
336 struct NPYTraits
337 {
338 };
339
340 template<>
341 struct NPYTraits<double>
342 {
343   static const int NPYObjectType=NPY_DOUBLE;
344   static PyTypeObject *NPYFunc;
345   static PyObject *Array_SWIGTYPE;
346 };
347
348 template<>
349 struct NPYTraits<float>
350 {
351   static const int NPYObjectType=NPY_FLOAT;
352   static PyTypeObject *NPYFunc;
353   static PyObject *Array_SWIGTYPE;
354 };
355 #endif
356
357 #endif