Salome HOME
f6910ba2116f6e2fb572f591611de69578918aca
[tools/medcoupling.git] / src / MEDCoupling_Swig / MEDCouplingDataArrayTraits.hxx
1 // Copyright (C) 2007-2020  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   int64_t *offset=reinterpret_cast<int64_t*>(wronc[2]);
47   if(obj!=Py_None)
48     {
49       Py_XINCREF(obj);
50       PyArrayObject *objC=reinterpret_cast<PyArrayObject *>(obj);
51       objC->flags|=MED_NUMPY_OWNDATA;
52       Py_XDECREF(weakRefOnOwner);
53       Py_XDECREF(obj);
54     }
55   else
56     {
57       typedef void (*MyDeallocator)(void *,void *);
58       MyDeallocator deall=(MyDeallocator)wronc[1];
59       deall(pt,offset);
60       Py_XDECREF(weakRefOnOwner);
61     }
62   delete offset;
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::DataArrayInt32> PyCallBackDataArrayInt32;
75 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayInt64> PyCallBackDataArrayInt64;
76 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayFloat> PyCallBackDataArrayFloat;
77 typedef struct PyCallBackDataArraySt<MEDCoupling::DataArrayDouble> PyCallBackDataArrayDouble;
78
79 extern "C"
80 {
81   static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; }
82   
83   static PyObject *callbackmcdataarraychar___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
84   {
85     PyCallBackDataArrayChar *self = (PyCallBackDataArrayChar *) ( type->tp_alloc(type, 0) );
86     return (PyObject *)self;
87   }
88
89   static PyObject *callbackmcdataarrayint32___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
90   {
91     PyCallBackDataArrayInt32 *self = (PyCallBackDataArrayInt32 *) ( type->tp_alloc(type, 0) );
92     return (PyObject *)self;
93   }
94   
95   static PyObject *callbackmcdataarrayint64___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
96   {
97     PyCallBackDataArrayInt64 *self = (PyCallBackDataArrayInt64 *) ( type->tp_alloc(type, 0) );
98     return (PyObject *)self;
99   }
100   
101   static PyObject *callbackmcdataarrayfloat___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
102   {
103     PyCallBackDataArrayFloat *self = (PyCallBackDataArrayFloat *) ( type->tp_alloc(type, 0) );
104     return (PyObject *)self;
105   }
106   
107   static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
108   {
109     PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) );
110     return (PyObject *)self;
111   }
112   
113   static void callbackmcdataarray_dealloc(PyObject *self)
114   {
115     Py_TYPE(self)->tp_free(self);
116   }
117
118   
119   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
120   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
121   static PyObject *callbackmcdataarraychar_call(PyCallBackDataArrayChar *self, PyObject *args, PyObject *kw)
122   {
123     if(self->_pt_mc)
124       {
125         MEDCoupling::MemArray<char>& mma=self->_pt_mc->accessToMemArray();
126         mma.destroy();
127       }
128     Py_XINCREF(Py_None);
129     return Py_None;
130   }
131
132   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
133   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
134   static PyObject *callbackmcdataarrayint32_call(PyCallBackDataArrayInt32 *self, PyObject *args, PyObject *kw)
135   {
136     if(self->_pt_mc)
137       {
138         MEDCoupling::MemArray<int>& mma=self->_pt_mc->accessToMemArray();
139         mma.destroy();
140       }
141     Py_XINCREF(Py_None);
142     return Py_None;
143   }
144
145   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
146   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
147   static PyObject *callbackmcdataarrayint64_call(PyCallBackDataArrayInt64 *self, PyObject *args, PyObject *kw)
148   {
149     if(self->_pt_mc)
150       { 
151         MEDCoupling::MemArray<MEDCoupling::Int64>& mma=self->_pt_mc->accessToMemArray();
152         mma.destroy();
153       }
154     Py_XINCREF(Py_None);
155     return Py_None;
156   }
157
158   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
159   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
160   static PyObject *callbackmcdataarrayfloat_call(PyCallBackDataArrayFloat *self, PyObject *args, PyObject *kw)
161   {
162     if(self->_pt_mc)
163       {
164         MEDCoupling::MemArray<float>& mma=self->_pt_mc->accessToMemArray();
165         mma.destroy();
166       }
167     Py_XINCREF(Py_None);
168     return Py_None;
169   }
170   
171   // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed.
172   // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients.
173   static PyObject *callbackmcdataarraydouble_call(PyCallBackDataArrayDouble *self, PyObject *args, PyObject *kw)
174   {
175     if(self->_pt_mc)
176       {
177         MEDCoupling::MemArray<double>& mma=self->_pt_mc->accessToMemArray();
178         mma.destroy();
179       }
180     Py_XINCREF(Py_None);
181     return Py_None;
182   }
183 }
184
185 PyTypeObject PyCallBackDataArrayChar_RefType = {
186   PyVarObject_HEAD_INIT(&PyType_Type, 0)
187   "callbackmcdataarraychar",
188   sizeof(PyCallBackDataArrayChar),
189   0,
190   callbackmcdataarray_dealloc,            /*tp_dealloc*/
191   0,                          /*tp_print*/
192   0,                          /*tp_getattr*/
193   0,                          /*tp_setattr*/
194   0,                          /*tp_compare*/
195   0,                          /*tp_repr*/
196   0,                          /*tp_as_number*/
197   0,                          /*tp_as_sequence*/
198   0,                          /*tp_as_mapping*/
199   0,                          /*tp_hash*/
200   (ternaryfunc)callbackmcdataarraychar_call,  /*tp_call*/
201   0,                          /*tp_str*/
202   0,                          /*tp_getattro*/
203   0,                          /*tp_setattro*/
204   0,                          /*tp_as_buffer*/
205   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
206   0,                          /*tp_doc*/
207   0,                          /*tp_traverse*/
208   0,                          /*tp_clear*/
209   0,                          /*tp_richcompare*/
210   0,                          /*tp_weaklistoffset*/
211   0,                          /*tp_iter*/
212   0,                          /*tp_iternext*/
213   0,                          /*tp_methods*/
214   0,                          /*tp_members*/
215   0,                          /*tp_getset*/
216   0,                          /*tp_base*/
217   0,                          /*tp_dict*/
218   0,                          /*tp_descr_get*/
219   0,                          /*tp_descr_set*/
220   0,                          /*tp_dictoffset*/
221   callbackmcdataarray___init__,           /*tp_init*/
222   PyType_GenericAlloc,        /*tp_alloc*/
223   callbackmcdataarraychar___new__,            /*tp_new*/
224   PyObject_GC_Del,            /*tp_free*/
225 };
226
227
228 PyTypeObject PyCallBackDataArrayInt32_RefType = {
229   PyVarObject_HEAD_INIT(&PyType_Type, 0)
230   "callbackmcdataarrayint32",
231   sizeof(PyCallBackDataArrayInt32),
232   0,
233   callbackmcdataarray_dealloc,            /*tp_dealloc*/
234   0,                          /*tp_print*/
235   0,                          /*tp_getattr*/
236   0,                          /*tp_setattr*/
237   0,                          /*tp_compare*/
238   0,                          /*tp_repr*/
239   0,                          /*tp_as_number*/
240   0,                          /*tp_as_sequence*/
241   0,                          /*tp_as_mapping*/
242   0,                          /*tp_hash*/
243   (ternaryfunc)callbackmcdataarrayint32_call,  /*tp_call*/
244   0,                          /*tp_str*/
245   0,                          /*tp_getattro*/
246   0,                          /*tp_setattro*/
247   0,                          /*tp_as_buffer*/
248   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
249   0,                          /*tp_doc*/
250   0,                          /*tp_traverse*/
251   0,                          /*tp_clear*/
252   0,                          /*tp_richcompare*/
253   0,                          /*tp_weaklistoffset*/
254   0,                          /*tp_iter*/
255   0,                          /*tp_iternext*/
256   0,                          /*tp_methods*/
257   0,                          /*tp_members*/
258   0,                          /*tp_getset*/
259   0,                          /*tp_base*/
260   0,                          /*tp_dict*/
261   0,                          /*tp_descr_get*/
262   0,                          /*tp_descr_set*/
263   0,                          /*tp_dictoffset*/
264   callbackmcdataarray___init__,           /*tp_init*/
265   PyType_GenericAlloc,        /*tp_alloc*/
266   callbackmcdataarrayint32___new__,            /*tp_new*/
267   PyObject_GC_Del,            /*tp_free*/
268 };
269
270
271 PyTypeObject PyCallBackDataArrayInt64_RefType = {
272   PyVarObject_HEAD_INIT(&PyType_Type, 0)
273   "callbackmcdataarrayint64",
274   sizeof(PyCallBackDataArrayInt64),
275   0,
276   callbackmcdataarray_dealloc,            /*tp_dealloc*/
277   0,                          /*tp_print*/
278   0,                          /*tp_getattr*/
279   0,                          /*tp_setattr*/
280   0,                          /*tp_compare*/
281   0,                          /*tp_repr*/
282   0,                          /*tp_as_number*/
283   0,                          /*tp_as_sequence*/
284   0,                          /*tp_as_mapping*/
285   0,                          /*tp_hash*/
286   (ternaryfunc)callbackmcdataarrayint64_call,  /*tp_call*/
287   0,                          /*tp_str*/
288   0,                          /*tp_getattro*/
289   0,                          /*tp_setattro*/
290   0,                          /*tp_as_buffer*/
291   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
292   0,                          /*tp_doc*/
293   0,                          /*tp_traverse*/
294   0,                          /*tp_clear*/
295   0,                          /*tp_richcompare*/
296   0,                          /*tp_weaklistoffset*/
297   0,                          /*tp_iter*/
298   0,                          /*tp_iternext*/
299   0,                          /*tp_methods*/
300   0,                          /*tp_members*/
301   0,                          /*tp_getset*/
302   0,                          /*tp_base*/
303   0,                          /*tp_dict*/
304   0,                          /*tp_descr_get*/
305   0,                          /*tp_descr_set*/
306   0,                          /*tp_dictoffset*/
307   callbackmcdataarray___init__,           /*tp_init*/
308   PyType_GenericAlloc,        /*tp_alloc*/
309   callbackmcdataarrayint64___new__,            /*tp_new*/
310   PyObject_GC_Del,            /*tp_free*/
311 };
312
313 PyTypeObject PyCallBackDataArrayFloat_RefType = {
314   PyVarObject_HEAD_INIT(&PyType_Type, 0)
315   "callbackmcdataarraydouble",
316   sizeof(PyCallBackDataArrayFloat),
317   0,
318   callbackmcdataarray_dealloc,            /*tp_dealloc*/
319   0,                          /*tp_print*/
320   0,                          /*tp_getattr*/
321   0,                          /*tp_setattr*/
322   0,                          /*tp_compare*/
323   0,                          /*tp_repr*/
324   0,                          /*tp_as_number*/
325   0,                          /*tp_as_sequence*/
326   0,                          /*tp_as_mapping*/
327   0,                          /*tp_hash*/
328   (ternaryfunc)callbackmcdataarraydouble_call,  /*tp_call*/
329   0,                          /*tp_str*/
330   0,                          /*tp_getattro*/
331   0,                          /*tp_setattro*/
332   0,                          /*tp_as_buffer*/
333   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
334   0,                          /*tp_doc*/
335   0,                          /*tp_traverse*/
336   0,                          /*tp_clear*/
337   0,                          /*tp_richcompare*/
338   0,                          /*tp_weaklistoffset*/
339   0,                          /*tp_iter*/
340   0,                          /*tp_iternext*/
341   0,                          /*tp_methods*/
342   0,                          /*tp_members*/
343   0,                          /*tp_getset*/
344   0,                          /*tp_base*/
345   0,                          /*tp_dict*/
346   0,                          /*tp_descr_get*/
347   0,                          /*tp_descr_set*/
348   0,                          /*tp_dictoffset*/
349   callbackmcdataarray___init__,           /*tp_init*/
350   PyType_GenericAlloc,        /*tp_alloc*/
351   callbackmcdataarrayfloat___new__,            /*tp_new*/
352   PyObject_GC_Del,            /*tp_free*/
353 };
354
355 PyTypeObject PyCallBackDataArrayDouble_RefType = {
356   PyVarObject_HEAD_INIT(&PyType_Type, 0)
357   "callbackmcdataarraydouble",
358   sizeof(PyCallBackDataArrayDouble),
359   0,
360   callbackmcdataarray_dealloc,            /*tp_dealloc*/
361   0,                          /*tp_print*/
362   0,                          /*tp_getattr*/
363   0,                          /*tp_setattr*/
364   0,                          /*tp_compare*/
365   0,                          /*tp_repr*/
366   0,                          /*tp_as_number*/
367   0,                          /*tp_as_sequence*/
368   0,                          /*tp_as_mapping*/
369   0,                          /*tp_hash*/
370   (ternaryfunc)callbackmcdataarraydouble_call,  /*tp_call*/
371   0,                          /*tp_str*/
372   0,                          /*tp_getattro*/
373   0,                          /*tp_setattro*/
374   0,                          /*tp_as_buffer*/
375   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
376   0,                          /*tp_doc*/
377   0,                          /*tp_traverse*/
378   0,                          /*tp_clear*/
379   0,                          /*tp_richcompare*/
380   0,                          /*tp_weaklistoffset*/
381   0,                          /*tp_iter*/
382   0,                          /*tp_iternext*/
383   0,                          /*tp_methods*/
384   0,                          /*tp_members*/
385   0,                          /*tp_getset*/
386   0,                          /*tp_base*/
387   0,                          /*tp_dict*/
388   0,                          /*tp_descr_get*/
389   0,                          /*tp_descr_set*/
390   0,                          /*tp_dictoffset*/
391   callbackmcdataarray___init__,           /*tp_init*/
392   PyType_GenericAlloc,        /*tp_alloc*/
393   callbackmcdataarraydouble___new__,            /*tp_new*/
394   PyObject_GC_Del,            /*tp_free*/
395 };
396
397 #ifdef WITH_NUMPY
398 template<class T>
399 struct NPYTraits
400 {
401 };
402
403 template<>
404 struct NPYTraits<double>
405 {
406   static const int NPYObjectType=NPY_DOUBLE;
407   static PyTypeObject *NPYFunc;
408   static PyObject *Array_SWIGTYPE;
409 };
410
411 template<>
412 struct NPYTraits<float>
413 {
414   static const int NPYObjectType=NPY_FLOAT;
415   static PyTypeObject *NPYFunc;
416   static PyObject *Array_SWIGTYPE;
417 };
418
419 template<>
420 struct NPYTraits<int>
421 {
422   static const int NPYObjectType=NPY_INT32;
423   static PyTypeObject *NPYFunc;
424   static PyObject *Array_SWIGTYPE;
425 };
426
427 template<>
428 struct NPYTraits<MEDCoupling::Int64>
429 {
430   static const int NPYObjectType=NPY_INT64;
431   static PyTypeObject *NPYFunc;
432   static PyObject *Array_SWIGTYPE;
433 };
434 #endif
435
436 #endif