Salome HOME
Step1
[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 // specific DataArray deallocator callback. This deallocator is used both in the constructor of DataArray and in the toNumPyArr
38 // method. This dellocator uses weakref to determine if the linked numArr is still alive or not. If alive the ownership is given to it.
39 // if no more alive the "standart" DataArray deallocator is called.
40 void numarrdeal(void *pt, void *wron)
41 {
42   void **wronc=(void **)wron;
43   PyObject *weakRefOnOwner=reinterpret_cast<PyObject *>(wronc[0]);
44   PyObject *obj=PyWeakref_GetObject(weakRefOnOwner);
45   if(obj!=Py_None)
46     {
47       Py_XINCREF(obj);
48       PyArrayObject *objC=reinterpret_cast<PyArrayObject *>(obj);
49       objC->flags|=MED_NUMPY_OWNDATA;
50       Py_XDECREF(weakRefOnOwner);
51       Py_XDECREF(obj);
52     }
53   else
54     {
55       typedef void (*MyDeallocator)(void *,void *);
56       MyDeallocator deall=(MyDeallocator)wronc[1];
57       deall(pt,NULL);
58       Py_XDECREF(weakRefOnOwner);
59     }
60   delete [] wronc;
61 }
62
63 template<class MCData>
64 struct PyCallBackDataArraySt {
65     PyObject_HEAD
66     MCData *_pt_mc;
67 };
68
69 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayByte> PyCallBackDataArrayChar;
70 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayInt> PyCallBackDataArrayInt;
71 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayFloat> PyCallBackDataArrayFloat;
72 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayDouble> PyCallBackDataArrayDouble;
73
74 extern "C"
75 {
76   static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; }
77   
78   static PyObject *callbackmcdataarraychar___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
79   {
80     PyCallBackDataArrayChar *self = (PyCallBackDataArrayChar *) ( type->tp_alloc(type, 0) );
81     return (PyObject *)self;
82   }
83
84   static PyObject *callbackmcdataarrayint___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
85   {
86     PyCallBackDataArrayInt *self = (PyCallBackDataArrayInt *) ( type->tp_alloc(type, 0) );
87     return (PyObject *)self;
88   }
89   
90   static PyObject *callbackmcdataarrayfloat___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
91   {
92     PyCallBackDataArrayFloat *self = (PyCallBackDataArrayFloat *) ( type->tp_alloc(type, 0) );
93     return (PyObject *)self;
94   }
95   
96   static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
97   {
98     PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) );
99     return (PyObject *)self;
100   }
101   
102   static void callbackmcdataarray_dealloc(PyObject *self)
103   {
104     Py_TYPE(self)->tp_free(self);
105   }
106
107   
108   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
109   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
110   static PyObject *callbackmcdataarraychar_call(PyCallBackDataArrayChar *self, PyObject *args, PyObject *kw)
111   {
112     if(self->_pt_mc)
113       {
114         MEDCoupling::MemArray<char>& mma=self->_pt_mc->accessToMemArray();
115         mma.destroy();
116       }
117     Py_XINCREF(Py_None);
118     return Py_None;
119   }
120
121   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
122   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
123   static PyObject *callbackmcdataarrayint_call(PyCallBackDataArrayInt *self, PyObject *args, PyObject *kw)
124   {
125     if(self->_pt_mc)
126       {
127         MEDCoupling::MemArray<int>& mma=self->_pt_mc->accessToMemArray();
128         mma.destroy();
129       }
130     Py_XINCREF(Py_None);
131     return Py_None;
132   }
133
134   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
135   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
136   static PyObject *callbackmcdataarrayfloat_call(PyCallBackDataArrayFloat *self, PyObject *args, PyObject *kw)
137   {
138     if(self->_pt_mc)
139       {
140         MEDCoupling::MemArray<float>& mma=self->_pt_mc->accessToMemArray();
141         mma.destroy();
142       }
143     Py_XINCREF(Py_None);
144     return Py_None;
145   }
146   
147   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
148   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
149   static PyObject *callbackmcdataarraydouble_call(PyCallBackDataArrayDouble *self, PyObject *args, PyObject *kw)
150   {
151     if(self->_pt_mc)
152       {
153         MEDCoupling::MemArray<double>& mma=self->_pt_mc->accessToMemArray();
154         mma.destroy();
155       }
156     Py_XINCREF(Py_None);
157     return Py_None;
158   }
159 }
160
161 PyTypeObject PyCallBackDataArrayChar_RefType = {
162   PyVarObject_HEAD_INIT(&PyType_Type, 0)
163   "callbackmcdataarraychar",
164   sizeof(PyCallBackDataArrayChar),
165   0,
166   callbackmcdataarray_dealloc,            /*tp_dealloc*/
167   0,                          /*tp_print*/
168   0,                          /*tp_getattr*/
169   0,                          /*tp_setattr*/
170   0,                          /*tp_compare*/
171   0,                          /*tp_repr*/
172   0,                          /*tp_as_number*/
173   0,                          /*tp_as_sequence*/
174   0,                          /*tp_as_mapping*/
175   0,                          /*tp_hash*/
176   (ternaryfunc)callbackmcdataarraychar_call,  /*tp_call*/
177   0,                          /*tp_str*/
178   0,                          /*tp_getattro*/
179   0,                          /*tp_setattro*/
180   0,                          /*tp_as_buffer*/
181   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
182   0,                          /*tp_doc*/
183   0,                          /*tp_traverse*/
184   0,                          /*tp_clear*/
185   0,                          /*tp_richcompare*/
186   0,                          /*tp_weaklistoffset*/
187   0,                          /*tp_iter*/
188   0,                          /*tp_iternext*/
189   0,                          /*tp_methods*/
190   0,                          /*tp_members*/
191   0,                          /*tp_getset*/
192   0,                          /*tp_base*/
193   0,                          /*tp_dict*/
194   0,                          /*tp_descr_get*/
195   0,                          /*tp_descr_set*/
196   0,                          /*tp_dictoffset*/
197   callbackmcdataarray___init__,           /*tp_init*/
198   PyType_GenericAlloc,        /*tp_alloc*/
199   callbackmcdataarraychar___new__,            /*tp_new*/
200   PyObject_GC_Del,            /*tp_free*/
201 };
202
203
204 PyTypeObject PyCallBackDataArrayInt_RefType = {
205   PyVarObject_HEAD_INIT(&PyType_Type, 0)
206   "callbackmcdataarrayint",
207   sizeof(PyCallBackDataArrayInt),
208   0,
209   callbackmcdataarray_dealloc,            /*tp_dealloc*/
210   0,                          /*tp_print*/
211   0,                          /*tp_getattr*/
212   0,                          /*tp_setattr*/
213   0,                          /*tp_compare*/
214   0,                          /*tp_repr*/
215   0,                          /*tp_as_number*/
216   0,                          /*tp_as_sequence*/
217   0,                          /*tp_as_mapping*/
218   0,                          /*tp_hash*/
219   (ternaryfunc)callbackmcdataarrayint_call,  /*tp_call*/
220   0,                          /*tp_str*/
221   0,                          /*tp_getattro*/
222   0,                          /*tp_setattro*/
223   0,                          /*tp_as_buffer*/
224   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
225   0,                          /*tp_doc*/
226   0,                          /*tp_traverse*/
227   0,                          /*tp_clear*/
228   0,                          /*tp_richcompare*/
229   0,                          /*tp_weaklistoffset*/
230   0,                          /*tp_iter*/
231   0,                          /*tp_iternext*/
232   0,                          /*tp_methods*/
233   0,                          /*tp_members*/
234   0,                          /*tp_getset*/
235   0,                          /*tp_base*/
236   0,                          /*tp_dict*/
237   0,                          /*tp_descr_get*/
238   0,                          /*tp_descr_set*/
239   0,                          /*tp_dictoffset*/
240   callbackmcdataarray___init__,           /*tp_init*/
241   PyType_GenericAlloc,        /*tp_alloc*/
242   callbackmcdataarrayint___new__,            /*tp_new*/
243   PyObject_GC_Del,            /*tp_free*/
244 };
245
246 PyTypeObject PyCallBackDataArrayFloat_RefType = {
247   PyVarObject_HEAD_INIT(&PyType_Type, 0)
248   "callbackmcdataarraydouble",
249   sizeof(PyCallBackDataArrayFloat),
250   0,
251   callbackmcdataarray_dealloc,            /*tp_dealloc*/
252   0,                          /*tp_print*/
253   0,                          /*tp_getattr*/
254   0,                          /*tp_setattr*/
255   0,                          /*tp_compare*/
256   0,                          /*tp_repr*/
257   0,                          /*tp_as_number*/
258   0,                          /*tp_as_sequence*/
259   0,                          /*tp_as_mapping*/
260   0,                          /*tp_hash*/
261   (ternaryfunc)callbackmcdataarraydouble_call,  /*tp_call*/
262   0,                          /*tp_str*/
263   0,                          /*tp_getattro*/
264   0,                          /*tp_setattro*/
265   0,                          /*tp_as_buffer*/
266   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
267   0,                          /*tp_doc*/
268   0,                          /*tp_traverse*/
269   0,                          /*tp_clear*/
270   0,                          /*tp_richcompare*/
271   0,                          /*tp_weaklistoffset*/
272   0,                          /*tp_iter*/
273   0,                          /*tp_iternext*/
274   0,                          /*tp_methods*/
275   0,                          /*tp_members*/
276   0,                          /*tp_getset*/
277   0,                          /*tp_base*/
278   0,                          /*tp_dict*/
279   0,                          /*tp_descr_get*/
280   0,                          /*tp_descr_set*/
281   0,                          /*tp_dictoffset*/
282   callbackmcdataarray___init__,           /*tp_init*/
283   PyType_GenericAlloc,        /*tp_alloc*/
284   callbackmcdataarrayfloat___new__,            /*tp_new*/
285   PyObject_GC_Del,            /*tp_free*/
286 };
287
288 PyTypeObject PyCallBackDataArrayDouble_RefType = {
289   PyVarObject_HEAD_INIT(&PyType_Type, 0)
290   "callbackmcdataarraydouble",
291   sizeof(PyCallBackDataArrayDouble),
292   0,
293   callbackmcdataarray_dealloc,            /*tp_dealloc*/
294   0,                          /*tp_print*/
295   0,                          /*tp_getattr*/
296   0,                          /*tp_setattr*/
297   0,                          /*tp_compare*/
298   0,                          /*tp_repr*/
299   0,                          /*tp_as_number*/
300   0,                          /*tp_as_sequence*/
301   0,                          /*tp_as_mapping*/
302   0,                          /*tp_hash*/
303   (ternaryfunc)callbackmcdataarraydouble_call,  /*tp_call*/
304   0,                          /*tp_str*/
305   0,                          /*tp_getattro*/
306   0,                          /*tp_setattro*/
307   0,                          /*tp_as_buffer*/
308   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
309   0,                          /*tp_doc*/
310   0,                          /*tp_traverse*/
311   0,                          /*tp_clear*/
312   0,                          /*tp_richcompare*/
313   0,                          /*tp_weaklistoffset*/
314   0,                          /*tp_iter*/
315   0,                          /*tp_iternext*/
316   0,                          /*tp_methods*/
317   0,                          /*tp_members*/
318   0,                          /*tp_getset*/
319   0,                          /*tp_base*/
320   0,                          /*tp_dict*/
321   0,                          /*tp_descr_get*/
322   0,                          /*tp_descr_set*/
323   0,                          /*tp_dictoffset*/
324   callbackmcdataarray___init__,           /*tp_init*/
325   PyType_GenericAlloc,        /*tp_alloc*/
326   callbackmcdataarraydouble___new__,            /*tp_new*/
327   PyObject_GC_Del,            /*tp_free*/
328 };
329
330 template<class T>
331 struct NPYTraits
332 {
333 };
334
335 template<>
336 struct NPYTraits<double>
337 {
338   static const int NPYObjectType=NPY_DOUBLE;
339   static PyTypeObject *NPYFunc;
340   static PyObject *Array_SWIGTYPE;
341 };
342
343 template<>
344 struct NPYTraits<float>
345 {
346   static const int NPYObjectType=NPY_FLOAT;
347   static PyTypeObject *NPYFunc;
348   static PyObject *Array_SWIGTYPE;
349 };
350
351 #endif