Fix a bug with clang on C++
[scilab.git] / scilab / modules / external_objects / includes / ScilabAbstractMemoryAllocator.hxx
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifndef __SCILABABSTRACTMEMORYALLOCATOR_H__
14 #define __SCILABABSTRACTMEMORYALLOCATOR_H__
15
16 #include "ScilabAbstractEnvironmentWrapper.hxx"
17 #include "ScilabAbstractEnvironmentException.hxx"
18
19 extern "C" {
20 #include "api_scilab.h"
21 }
22
23 namespace org_modules_external_objects
24 {
25
26 class ComplexDataPointers
27 {
28 public:
29
30     ComplexDataPointers(double * _realPtr, double * _imagPtr) : realPtr(_realPtr), imagPtr(_imagPtr) { }
31     ComplexDataPointers() : realPtr(0), imagPtr(0) { }
32     ~ComplexDataPointers() { }
33
34     double * const realPtr;
35     double * const imagPtr;
36 };
37
38 class ScilabStackAllocator
39 {
40
41 public:
42
43     ScilabStackAllocator(void * _pvApiCtx, int _position) : pvApiCtx(_pvApiCtx), position(_position) { }
44
45     ~ScilabStackAllocator() { }
46
47 protected:
48
49     int position;
50     void * pvApiCtx;
51
52     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, double * ptr)
53     {
54         SciErr err = createMatrixOfDouble(pvApiCtx, position, rows, cols, ptr);
55         checkError(err);
56     }
57
58     inline static double * alloc(void * pvApiCtx, const int position, const int rows, const int cols, double * ptr)
59     {
60         double * _ptr = 0;
61         SciErr err = allocMatrixOfDouble(pvApiCtx, position, rows, cols, &_ptr);
62         checkError(err);
63
64         return _ptr;
65     }
66
67     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, float * ptr)
68     {
69         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Invalid operation: cannot create a matrix of floats");
70     }
71
72     inline static float * alloc(void * pvApiCtx, const int position, const int rows, const int cols, float * ptr)
73     {
74         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Invalid operation: cannot allocate a matrix of floats");
75     }
76
77     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, double * re, double * im)
78     {
79         SciErr err = createComplexMatrixOfDouble(pvApiCtx, position, rows, cols, re, im);
80         checkError(err);
81     }
82
83     inline static ComplexDataPointers alloc(void * pvApiCtx, const int position, const int rows, const int cols, double * re, double * im)
84     {
85         double * _re = 0, * _im = 0;
86         SciErr err = allocComplexMatrixOfDouble(pvApiCtx, position, rows, cols, &_re, &_im);
87         checkError(err);
88
89         return ComplexDataPointers(_re, _im);
90     }
91
92     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, char * ptr)
93     {
94         SciErr err = createMatrixOfInteger8(pvApiCtx, position, rows, cols, ptr);
95         checkError(err);
96     }
97
98     inline static char * alloc(void * pvApiCtx, const int position, const int rows, const int cols, char * ptr)
99     {
100         char * _ptr = 0;
101         SciErr err = allocMatrixOfInteger8(pvApiCtx, position, rows, cols, &_ptr);
102         checkError(err);
103
104         return _ptr;
105     }
106
107     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, unsigned char * ptr)
108     {
109         SciErr err = createMatrixOfUnsignedInteger8(pvApiCtx, position, rows, cols, ptr);
110         checkError(err);
111     }
112
113     inline static unsigned char * alloc(void * pvApiCtx, const int position, const int rows, const int cols, unsigned char * ptr)
114     {
115         unsigned char * _ptr = 0;
116         SciErr err = allocMatrixOfUnsignedInteger8(pvApiCtx, position, rows, cols, &_ptr);
117         checkError(err);
118
119         return _ptr;
120     }
121
122     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, short * ptr)
123     {
124         SciErr err = createMatrixOfInteger16(pvApiCtx, position, rows, cols, ptr);
125         checkError(err);
126     }
127
128     inline static short * alloc(void * pvApiCtx, const int position, const int rows, const int cols, short * ptr)
129     {
130         short * _ptr = 0;
131         SciErr err = allocMatrixOfInteger16(pvApiCtx, position, rows, cols, &_ptr);
132         checkError(err);
133
134         return _ptr;
135     }
136
137     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, unsigned short * ptr)
138     {
139         SciErr err = createMatrixOfUnsignedInteger16(pvApiCtx, position, rows, cols, ptr);
140         checkError(err);
141     }
142
143     inline static unsigned short * alloc(void * pvApiCtx, const int position, const int rows, const int cols, unsigned short * ptr)
144     {
145         unsigned short * _ptr = 0;
146         SciErr err = allocMatrixOfUnsignedInteger16(pvApiCtx, position, rows, cols, &_ptr);
147         checkError(err);
148
149         return _ptr;
150     }
151
152     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, int * ptr)
153     {
154         SciErr err = createMatrixOfInteger32(pvApiCtx, position, rows, cols, ptr);
155         checkError(err);
156     }
157
158     inline static int * alloc(void * pvApiCtx, const int position, const int rows, const int cols, int * ptr)
159     {
160         int * _ptr = 0;
161         SciErr err = allocMatrixOfInteger32(pvApiCtx, position, rows, cols, &_ptr);
162         checkError(err);
163
164         return _ptr;
165     }
166
167     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, unsigned int * ptr)
168     {
169         SciErr err = createMatrixOfUnsignedInteger32(pvApiCtx, position, rows, cols, ptr);
170         checkError(err);
171     }
172
173     inline static unsigned int * alloc(void * pvApiCtx, const int position, const int rows, const int cols, unsigned int * ptr)
174     {
175         unsigned int * _ptr = 0;
176         SciErr err = allocMatrixOfUnsignedInteger32(pvApiCtx, position, rows, cols, &_ptr);
177         checkError(err);
178
179         return _ptr;
180     }
181
182 #ifdef __SCILAB_INT64__
183
184     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, long long * ptr)
185     {
186         SciErr err = createMatrixOfInteger64(pvApiCtx, position, rows, cols, ptr);
187         checkError(err);
188     }
189
190     inline static long long * alloc(void * pvApiCtx, const int position, const int rows, const int cols, long long * ptr)
191     {
192         long long * _ptr = 0;
193         SciErr err = allocMatrixOfInteger64(pvApiCtx, position, rows, cols, &_ptr);
194         checkError(err);
195
196         return _ptr;
197     }
198
199     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
200     {
201         SciErr err = createMatrixOfUnsignedIntege64(pvApiCtx, position, rows, cols, ptr);
202         checkError(err);
203     }
204
205     inline static unsigned long long * alloc(void * pvApiCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
206     {
207         unsigned long long * _ptr = 0;
208         SciErr err = allocMatrixOfUnsignedInteger64(pvApiCtx, position, rows, cols, &_ptr);
209         checkError(err);
210
211         return_ ptr;
212     }
213
214 #else
215
216     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, long long * ptr)
217     {
218         int * dataPtr = 0;
219         alloc(pvApiCtx, position, rows, cols, dataPtr);
220         for (int i = 0; i < rows * cols; i++)
221         {
222             dataPtr[i] = static_cast<int>(ptr[i]);
223         }
224     }
225
226     inline static long long * alloc(void * pvApiCtx, const int position, const int rows, const int cols, long long * ptr)
227     {
228         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Invalid operation: cannot allocate a matrix of Integer64");
229     }
230
231     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
232     {
233         unsigned int * dataPtr = 0;
234         alloc(pvApiCtx, position, rows, cols, dataPtr);
235         for (int i = 0; i < rows * cols; i++)
236         {
237             dataPtr[i] = static_cast<unsigned int>(ptr[i]);
238         }
239     }
240
241     inline static unsigned long long * alloc(void * pvApiCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
242     {
243         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Invalid operation: cannot allocate a matrix of UInteger64");
244     }
245
246 #endif
247
248     inline static void create(void * pvApiCtx, const int position, const int rows, const int cols, char ** ptr)
249     {
250         SciErr err = createMatrixOfString(pvApiCtx, position, rows, cols, const_cast<const char * const *>(ptr));
251         checkError(err);
252     }
253
254     inline static char ** alloc(void * pvApiCtx, const int position, const int rows, const int cols, char ** ptr)
255     {
256         throw ScilabAbstractEnvironmentException("Invalid operation: cannot allocate a matrix of String");
257     }
258
259     inline static void createBool(void * pvApiCtx, const int position, const int rows, const int cols, int * ptr)
260     {
261         SciErr err = createMatrixOfBoolean(pvApiCtx, position, rows, cols, ptr);
262         checkError(err);
263     }
264
265     inline static int * allocBool(void * pvApiCtx, const int position, const int rows, const int cols, int * ptr)
266     {
267         int * _ptr = 0;
268         SciErr err = allocMatrixOfBoolean(pvApiCtx, position, rows, cols, &_ptr);
269         checkError(err);
270
271         return _ptr;
272     }
273
274
275 private:
276
277     inline static void checkError(const SciErr & err)
278     {
279         if (err.iErr)
280         {
281             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Cannot allocate memory");
282         }
283     }
284
285 };
286
287 template <typename T>
288 class ScilabSingleTypeStackAllocator : public ScilabStackAllocator
289 {
290
291 public:
292
293     ScilabSingleTypeStackAllocator(void * _pvApiCtx, int _position) : ScilabStackAllocator(_pvApiCtx, _position) { }
294
295     ~ScilabSingleTypeStackAllocator() { }
296
297     virtual T * allocate(const int rows, const int cols, T * dataPtr) const
298     {
299         if (!rows || !cols)
300         {
301             createEmptyMatrix(pvApiCtx, position);
302             return 0;
303         }
304
305         if (dataPtr)
306         {
307             create(pvApiCtx, position, rows, cols, dataPtr);
308             return 0;
309         }
310         else
311         {
312             return alloc(pvApiCtx, position, rows, cols, dataPtr);
313         }
314     }
315 };
316
317 typedef ScilabSingleTypeStackAllocator<double> ScilabDoubleStackAllocator;
318 typedef ScilabSingleTypeStackAllocator<char *> ScilabStringStackAllocator;
319 typedef ScilabSingleTypeStackAllocator<char> ScilabCharStackAllocator;
320 typedef ScilabSingleTypeStackAllocator<unsigned char> ScilabUCharStackAllocator;
321 typedef ScilabSingleTypeStackAllocator<short> ScilabShortStackAllocator;
322 typedef ScilabSingleTypeStackAllocator<unsigned short> ScilabUShortStackAllocator;
323 typedef ScilabSingleTypeStackAllocator<int> ScilabIntStackAllocator;
324 typedef ScilabSingleTypeStackAllocator<unsigned int> ScilabUIntStackAllocator;
325 typedef ScilabSingleTypeStackAllocator<long long> ScilabLongStackAllocator;
326 typedef ScilabSingleTypeStackAllocator<unsigned long long> ScilabULongStackAllocator;
327 typedef ScilabSingleTypeStackAllocator<float> ScilabFloatStackAllocator;
328
329 class ScilabComplexStackAllocator : public ScilabStackAllocator
330 {
331
332 public:
333
334     ScilabComplexStackAllocator(void * _pvApiCtx, int _position) : ScilabStackAllocator(_pvApiCtx, _position) { }
335
336     ~ScilabComplexStackAllocator() { }
337
338     ComplexDataPointers allocate(const int rows, const int cols, double * realPtr, double * imagPtr) const
339     {
340         if (!rows || !cols)
341         {
342             createEmptyMatrix(pvApiCtx, position);
343             return ComplexDataPointers();
344         }
345
346         if (realPtr && imagPtr)
347         {
348             create(pvApiCtx, position, rows, cols, realPtr, imagPtr);
349             return ComplexDataPointers();
350         }
351         else
352         {
353             return alloc(pvApiCtx, position, rows, cols, realPtr, imagPtr);
354         }
355     }
356 };
357
358 class ScilabBooleanStackAllocator : public ScilabSingleTypeStackAllocator<int>
359 {
360
361 public:
362
363     ScilabBooleanStackAllocator(void * _pvApiCtx, int _position) : ScilabSingleTypeStackAllocator<int>(_pvApiCtx, _position) { }
364
365     ~ScilabBooleanStackAllocator() { }
366
367     int * allocate(const int rows, const int cols, int * dataPtr) const
368     {
369         if (!rows || !cols)
370         {
371             createEmptyMatrix(pvApiCtx, position);
372             return 0;
373         }
374
375         if (dataPtr)
376         {
377             createBool(pvApiCtx, position, rows, cols, dataPtr);
378             return 0;
379         }
380         else
381         {
382             return allocBool(pvApiCtx, position, rows, cols, dataPtr);
383         }
384     }
385
386     template <typename T>
387     int * allocate(const int rows, const int cols, T * dataPtr)
388     {
389         if (!rows || !cols)
390         {
391             createEmptyMatrix(pvApiCtx, position);
392             return 0;
393         }
394
395         if (dataPtr)
396         {
397             int * ptr = 0;
398             allocBool(pvApiCtx, position, rows, cols, ptr);
399             for (int i = 0; i < rows * cols; i++)
400             {
401                 ptr[i] = static_cast<int>(dataPtr[i]);
402             }
403
404             return 0;
405         }
406         else
407         {
408             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Invalid operation: cannot allocate a matrix of Boolean");
409         }
410     }
411 };
412
413 }
414
415 #endif // __SCILABABSTRACTMEMORYALLOCATOR_H__