1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #ifndef __MEDCOUPLINGDATAARRAYTRAITS_HXX__
22 #define __MEDCOUPLINGDATAARRAYTRAITS_HXX__
24 #include "MEDCouplingMemArray.hxx"
29 #include <numpy/arrayobject.h>
30 #if NPY_API_VERSION <= 0x00000006
31 # define MED_NUMPY_OWNDATA NPY_OWNDATA
33 # define MED_NUMPY_OWNDATA NPY_ARRAY_OWNDATA
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)
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]);
50 PyArrayObject *objC=reinterpret_cast<PyArrayObject *>(obj);
51 objC->flags|=MED_NUMPY_OWNDATA;
52 Py_XDECREF(weakRefOnOwner);
57 typedef void (*MyDeallocator)(void *,void *);
58 MyDeallocator deall=(MyDeallocator)wronc[1];
60 Py_XDECREF(weakRefOnOwner);
67 template<class MCData>
68 struct PyCallBackDataArraySt {
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;
80 static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; }
82 static PyObject *callbackmcdataarraychar___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
84 PyCallBackDataArrayChar *self = (PyCallBackDataArrayChar *) ( type->tp_alloc(type, 0) );
85 return (PyObject *)self;
88 static PyObject *callbackmcdataarrayint___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
90 PyCallBackDataArrayInt *self = (PyCallBackDataArrayInt *) ( type->tp_alloc(type, 0) );
91 return (PyObject *)self;
94 static PyObject *callbackmcdataarrayfloat___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
96 PyCallBackDataArrayFloat *self = (PyCallBackDataArrayFloat *) ( type->tp_alloc(type, 0) );
97 return (PyObject *)self;
100 static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
102 PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) );
103 return (PyObject *)self;
106 static void callbackmcdataarray_dealloc(PyObject *self)
108 Py_TYPE(self)->tp_free(self);
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)
118 MEDCoupling::MemArray<char>& mma=self->_pt_mc->accessToMemArray();
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)
131 MEDCoupling::MemArray<int>& mma=self->_pt_mc->accessToMemArray();
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)
144 MEDCoupling::MemArray<float>& mma=self->_pt_mc->accessToMemArray();
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)
157 MEDCoupling::MemArray<double>& mma=self->_pt_mc->accessToMemArray();
165 PyTypeObject PyCallBackDataArrayChar_RefType = {
166 PyVarObject_HEAD_INIT(&PyType_Type, 0)
167 "callbackmcdataarraychar",
168 sizeof(PyCallBackDataArrayChar),
170 callbackmcdataarray_dealloc, /*tp_dealloc*/
177 0, /*tp_as_sequence*/
180 (ternaryfunc)callbackmcdataarraychar_call, /*tp_call*/
185 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
189 0, /*tp_richcompare*/
190 0, /*tp_weaklistoffset*/
201 callbackmcdataarray___init__, /*tp_init*/
202 PyType_GenericAlloc, /*tp_alloc*/
203 callbackmcdataarraychar___new__, /*tp_new*/
204 PyObject_GC_Del, /*tp_free*/
208 PyTypeObject PyCallBackDataArrayInt_RefType = {
209 PyVarObject_HEAD_INIT(&PyType_Type, 0)
210 "callbackmcdataarrayint",
211 sizeof(PyCallBackDataArrayInt),
213 callbackmcdataarray_dealloc, /*tp_dealloc*/
220 0, /*tp_as_sequence*/
223 (ternaryfunc)callbackmcdataarrayint_call, /*tp_call*/
228 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
232 0, /*tp_richcompare*/
233 0, /*tp_weaklistoffset*/
244 callbackmcdataarray___init__, /*tp_init*/
245 PyType_GenericAlloc, /*tp_alloc*/
246 callbackmcdataarrayint___new__, /*tp_new*/
247 PyObject_GC_Del, /*tp_free*/
250 PyTypeObject PyCallBackDataArrayFloat_RefType = {
251 PyVarObject_HEAD_INIT(&PyType_Type, 0)
252 "callbackmcdataarraydouble",
253 sizeof(PyCallBackDataArrayFloat),
255 callbackmcdataarray_dealloc, /*tp_dealloc*/
262 0, /*tp_as_sequence*/
265 (ternaryfunc)callbackmcdataarraydouble_call, /*tp_call*/
270 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
274 0, /*tp_richcompare*/
275 0, /*tp_weaklistoffset*/
286 callbackmcdataarray___init__, /*tp_init*/
287 PyType_GenericAlloc, /*tp_alloc*/
288 callbackmcdataarrayfloat___new__, /*tp_new*/
289 PyObject_GC_Del, /*tp_free*/
292 PyTypeObject PyCallBackDataArrayDouble_RefType = {
293 PyVarObject_HEAD_INIT(&PyType_Type, 0)
294 "callbackmcdataarraydouble",
295 sizeof(PyCallBackDataArrayDouble),
297 callbackmcdataarray_dealloc, /*tp_dealloc*/
304 0, /*tp_as_sequence*/
307 (ternaryfunc)callbackmcdataarraydouble_call, /*tp_call*/
312 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/
316 0, /*tp_richcompare*/
317 0, /*tp_weaklistoffset*/
328 callbackmcdataarray___init__, /*tp_init*/
329 PyType_GenericAlloc, /*tp_alloc*/
330 callbackmcdataarraydouble___new__, /*tp_new*/
331 PyObject_GC_Del, /*tp_free*/
341 struct NPYTraits<double>
343 static const int NPYObjectType=NPY_DOUBLE;
344 static PyTypeObject *NPYFunc;
345 static PyObject *Array_SWIGTYPE;
349 struct NPYTraits<float>
351 static const int NPYObjectType=NPY_FLOAT;
352 static PyTypeObject *NPYFunc;
353 static PyObject *Array_SWIGTYPE;