Coverity: ast module resource leaks fixed
[scilab.git] / scilab / modules / ast / src / cpp / types / arrayof.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2010 - DIGITEO - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 *
14 */
15
16 #include "arrayof.hxx"
17 #include "double.hxx"
18 #include "bool.hxx"
19 #include "singlepoly.hxx"
20 #include "singlestruct.hxx"
21 #include "type_traits.hxx"
22 #include "exp.hxx"
23 #include "types_tools.hxx"
24
25 extern "C"
26 {
27 #include "dynlib_ast.h"
28 }
29
30 namespace types
31 {
32
33 static int get_max_size(int* _piDims, int _iDims)
34 {
35     if (_iDims == 0)
36     {
37         return 0;
38     }
39
40     int iMax = 1;
41     for (int i = 0 ; i < _iDims ; i++)
42     {
43         iMax *= _piDims[i];
44     }
45     return iMax;
46 }
47
48 template <typename T>
49 GenericType* ArrayOf<T>::createEmpty()
50 {
51     return createEmptyDouble();
52 }
53
54 template <typename T>
55 void ArrayOf<T>::getIndexes(int _iIndex, int* _piIndexes)
56 {
57     getIndexesWithDims(_iIndex, _piIndexes, m_piDims, m_iDims);
58 }
59
60 template <typename T>
61 ArrayOf<T>* ArrayOf<T>::insert(typed_list* _pArgs, InternalType* _pSource)
62 {
63     ArrayOf<T>* pIT = checkRef(this, &ArrayOf::insert, _pArgs, _pSource);
64     if (pIT != this)
65     {
66         return pIT;
67     }
68
69     int index;
70     if (getScalarIndex(this, _pArgs, &index))
71     {
72         ArrayOf* pIns = _pSource->getAs<ArrayOf>();
73         int sizeIn = pIns->getSize();
74         //only scalar can be used to ".=" operation
75         if (sizeIn != 1)
76         {
77             return NULL;
78         }
79
80         T* pRealData = pIns->get();
81         T* pImgData = pIns->getImg();
82
83         if (isComplex() == false && pIns->isComplex() == false)
84         {
85             if (set(index, *pRealData) != NULL)
86             {
87                 return this;
88             }
89         }
90
91         //if complex continue
92     }
93
94     std::vector<int> indexes;
95     std::vector<int> dims;
96     if (getImplicitIndex(this, _pArgs, indexes, dims))
97     {
98         if (indexes.size() == 0)
99         {
100             return this;
101         }
102
103         ArrayOf* pIns = _pSource->getAs<ArrayOf>();
104         int sizeIn = pIns->getSize();
105         int count = static_cast<int>(indexes.size());
106         //only scalar can be used to ".=" operation
107         if (sizeIn != 1 && count != sizeIn)
108         {
109             return NULL;
110         }
111
112         T* pRealData = pIns->get();
113         T* pImgData = pIns->getImg();
114
115         bool status = true;
116         if (isComplex() == false && pIns->isComplex() == false)
117         {
118             if (sizeIn == 1)
119             {
120                 for (int & i : indexes)
121                 {
122                     if (set(i, *pRealData) == NULL)
123                     {
124                         status = false;
125                         break;
126                     }
127                 }
128             }
129             else
130             {
131                 for (int & i : indexes)
132                 {
133                     if (set(i, *pRealData) == NULL)
134                     {
135                         status = false;
136                         break;
137                     }
138                     ++pRealData;
139                 }
140             }
141
142             if (status)
143             {
144                 return this;
145             }
146
147             //if status is false, continue to entire process
148         }
149     }
150
151     bool bNeedToResize = false;
152     int iDims = (int)_pArgs->size();
153     int iDimsOrigine = m_iDims;
154     typed_list pArg;
155
156     int* piMaxDim = new int[iDims];
157     int* piCountDim = new int[iDims];
158
159     //on case of resize
160     int* piNewDims = NULL;
161     int iNewDims = 0;
162     ArrayOf* pSource = _pSource->getAs<ArrayOf>();
163
164     bool bIsColon = false;
165
166     //evaluate each argument and replace by appropriate value and compute the count of combinations
167     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
168     if (iSeqCount == 0)
169     {
170         //free pArg content
171         delete[] piCountDim;
172         delete[] piMaxDim;
173         cleanIndexesArguments(_pArgs, &pArg);
174         return this;
175     }
176
177     //only scalar can be used to ".=" operation
178     if (iSeqCount != pSource->getSize() && pSource->isScalar() == false)
179     {
180         return NULL;
181     }
182
183     //remove last dimension at size 1
184     //remove last dimension if are == 1
185     for (int i = (iDims - 1); i >= m_iDims; i--)
186     {
187         if (piMaxDim[i] == 1)
188         {
189             iDims--;
190             pArg.back()->killMe();
191             pArg.pop_back();
192         }
193         else
194         {
195             break;
196         }
197     }
198
199
200     if (iDims >= m_iDims)
201     {
202         //all case are good, we can do almost everything
203         //check if resize is needed
204         if (iDims > m_iDims)
205         {
206             bNeedToResize = true;
207         }
208         else //_iDims == m_iDims
209         {
210             for (int i = 0; i < m_iDims; i++)
211             {
212                 if (m_piDims[i] < piMaxDim[i])
213                 {
214                     bNeedToResize = true;
215                     break;
216                 }
217             }
218         }
219
220         //determine new dimension of the matrix
221         if (bNeedToResize == true)
222         {
223             iNewDims = iDims;
224             piNewDims = new int[iNewDims];
225             for (int i = 0; i < m_iDims; i++)
226             {
227                 piNewDims[i] = std::max(piMaxDim[i], m_piDims[i]);
228             }
229
230             int iSource = (pSource->getDims() - 1);
231             bool bPassed = false;
232             int *piSourceDims = pSource->getDimsArray();
233
234             for (int i = m_iDims; i < iNewDims; ++i)
235             {
236                 piNewDims[i] = piMaxDim[i];
237             }
238         }
239     }
240     else // _iDims < m_iDims
241     {
242         if (isVector() || isScalar() || getSize() == 0) //getSize() == 0, only for [] and {}
243         {
244             if (getSize() < piMaxDim[0])
245             {
246                 bNeedToResize = true;
247                 iNewDims = 2;
248                 piNewDims = new int[2];
249
250                 if (getCols() == 1 || getSize() == 0)
251                 {
252                     //column vector
253                     piNewDims[0] = piMaxDim[0];
254                     piNewDims[1] = 1;
255                 }
256                 else if (getRows() == 1)
257                 {
258                     //row vector
259                     piNewDims[0] = 1;
260                     piNewDims[1] = piMaxDim[0];
261                 }
262             }
263         }
264         else
265         {
266             //each index before last index must be in range of his dimension
267             //and last given dimension can not be > prod(last dimensions)
268             for (int i = 0; i < iDims - 1; i++)
269             {
270                 //indexes are always doubles
271                 double* pIdx = getDoubleArrayFromDouble(pArg[i]);
272                 //InternalType* pVar = pArg[i];
273                 //double* pIdx = static_cast<double*>(pVar->getAs<Double>()->get());
274                 int iSize = pArg[i]->getAs<ArrayOf>()->getSize();
275                 for (int j = 0; j < iSize; j++)
276                 {
277                     if (pIdx[j] > m_piDims[i])
278                     {
279                         delete[] piCountDim;
280                         delete[] piMaxDim;
281                         //free pArg content
282                         cleanIndexesArguments(_pArgs, &pArg);
283                         return NULL;
284                     }
285                 }
286             }
287
288             //check last dim
289             int iMaxLastDim = getVarMaxDim(iDims - 1, iDims);
290             double* pIdx = getDoubleArrayFromDouble(pArg[pArg.size() - 1]);
291             //InternalType* pVar = pArg[pArg.size() - 1];
292             //double* pIdx = static_cast<double*>(pVar->getAs<Double>()->get());
293             int iSize = pArg[pArg.size() - 1]->getAs<GenericType>()->getSize();
294             for (int i = 0; i < iSize; i++)
295             {
296                 if (pIdx[i] > iMaxLastDim)
297                 {
298                     delete[] piCountDim;
299                     delete[] piMaxDim;
300                     //free pArg content
301                     cleanIndexesArguments(_pArgs, &pArg);
302                     return NULL;
303                 }
304             }
305         }
306     }
307
308     //before resize, check input dimension
309     if (bNeedToResize)
310     {
311         ArrayOf<T>* pTemp = resize(piNewDims, iNewDims);
312         if (pTemp == NULL)
313         {
314             delete[] piCountDim;
315             delete[] piMaxDim;
316             //free pArg content
317             cleanIndexesArguments(_pArgs, &pArg);
318             return NULL;
319         }
320     }
321     else
322     {
323         piNewDims = m_piDims;
324         iNewDims = m_iDims;
325     }
326
327     //update complexity
328     if (pSource->isComplex() && m_pImgData == NULL)
329     {
330         setComplex(true);
331     }
332
333     int argSize = static_cast<int>(pArg.size());
334     int* piIndex = new int[argSize];
335     int* piCoord = new int[argSize];
336     int* piViewDims = new int[iDims];
337     memset(piIndex, 0x00, sizeof(int) * argSize);
338
339     //convert  current dimension to view dimension
340     for (int i = 0; i < iDims; i++)
341     {
342         piViewDims[i] = getVarMaxDim(i, iDims);
343     }
344
345     T* pRealData = pSource->get();
346     T* pImgData = pSource->getImg();
347     bool bComplex = pSource->isComplex();
348
349     for (int i = 0; i < iSeqCount; i++)
350     {
351         computeTuples(piCountDim, argSize, argSize - 1, piIndex);
352
353         //std::cout << "[";
354         for (int j = 0; j < argSize; j++)
355         {
356             piCoord[j] = getIntValueFromDouble(pArg[j], piIndex[j]) - 1;
357             //InternalType* pVar = pArg[j];
358             //piCoord[j] = static_cast<int>(pVar->getAs<Double>()->get(piIndex[j]) - 1);
359             //std::cout << piCoord[j] << " ";
360         }
361
362         //std::cout << "]" << std::endl;
363
364         int iPos = getIndexWithDims(piCoord, piViewDims, iDims);
365         if (iPos < 0)
366         {
367             if (bNeedToResize)
368             {
369                 delete[] piNewDims;
370             }
371
372             delete[] piMaxDim;
373             delete[] piCountDim;
374             delete[] piIndex;
375             delete[] piCoord;
376             delete[] piViewDims;
377
378             //free pArg content
379             cleanIndexesArguments(_pArgs, &pArg);
380
381             wchar_t szError[bsiz];
382             os_swprintf(szError, bsiz, _W("Invalid index.\n").c_str());
383             throw ast::InternalError(szError);
384         }
385
386         if (pSource->isScalar())
387         {
388             //element-wise insertion
389             set(iPos, pRealData[0]);
390             if (pImgData != NULL && bComplex)
391             {
392                 setImg(iPos, pImgData[0]);
393             }
394         }
395         else
396         {
397             if (bIsColon)
398             {
399                 int iPas = 1;
400                 for (int j = 0; j < iDimsOrigine; j++)
401                 {
402                     iPas = iPas * m_piDims[j];
403                 }
404
405                 for (int iPost = iPos; iPost < this->getSize(); iPost += iPas)
406                 {
407                     set(iPost, pRealData[i]);
408                     if (pImgData != NULL && bComplex)
409                     {
410                         setImg(iPost, pImgData[i]);
411                     }
412                     i++;
413                 }
414             }
415             else
416             {
417                 set(iPos, pRealData[i]);
418                 if (pImgData != NULL && bComplex)
419                 {
420                     setImg(iPos, pImgData[i]);
421                 }
422             }
423         }
424
425         // reset imaginary part
426         if (m_pImgData != NULL && bComplex == false)
427         {
428             setImg(iPos, 0);
429         }
430
431         //update index
432         piIndex[0]++;
433     }
434
435     if (bNeedToResize)
436     {
437         delete[] piNewDims;
438     }
439
440     delete[] piMaxDim;
441     delete[] piCountDim;
442     delete[] piIndex;
443     delete[] piCoord;
444     delete[] piViewDims;
445
446     //free pArg content
447     cleanIndexesArguments(_pArgs, &pArg);
448
449     return this;
450 }
451
452 template <typename T>
453 GenericType* ArrayOf<T>::insertNew(typed_list* _pArgs)
454 {
455     typed_list pArg;
456     InternalType *pOut = NULL;
457
458     int iDims = (int)_pArgs->size();
459     int* piMaxDim = new int[iDims];
460     int* piCountDim = new int[iDims];
461     bool bComplex = getImg() != NULL;
462     bool bUndefine = false;
463     bool bIsImpli = false;
464
465     //evaluate each argument and replace by appropriate value and compute the count of combinations
466     int iSeqCount = checkIndexesArguments(NULL, _pArgs, &pArg, piMaxDim, piCountDim);
467
468     if (iSeqCount == 0)
469     {
470         delete[] piMaxDim;
471         delete[] piCountDim;
472         //free pArg content
473         cleanIndexesArguments(_pArgs, &pArg);
474         return createEmptyDouble();
475     }
476
477     if (iSeqCount < 0)
478     {
479         iSeqCount = -iSeqCount;
480         bUndefine = true;
481     }
482
483     if (bUndefine)
484     {
485         //manage : and $ in creation by insertion
486         int *piSourceDims = getDimsArray();
487         int iSourceDims = getDims();
488         int iCompteurNull = 0;
489         int iLastNull = 0;
490         for (int i = 0; i < iDims; i++)
491         {
492             if (pArg[i] == NULL)
493             {
494                 iCompteurNull++;
495                 iLastNull = i;
496             }
497             else
498             {
499                 if ((*_pArgs)[i]->isImplicitList())
500                 {
501                     bIsImpli = true;
502                 }
503             }
504         }
505
506         //if all index are : -> a = x
507         if (iCompteurNull == pArg.size())
508         {
509             delete[] piMaxDim;
510             delete[] piCountDim;
511             //free pArg content
512             cleanIndexesArguments(_pArgs, &pArg);
513             return this;
514         }
515
516         //vector case
517         if (isVector() && iCompteurNull == 1)
518         {
519             piMaxDim[iLastNull] = getSize();
520             pArg[iLastNull] = createDoubleVector(piMaxDim[iLastNull]);
521         }
522         else
523         {
524             //matrix and hypermatrix case
525             if (iCompteurNull < getDims())
526             {
527                 delete[] piMaxDim;
528                 delete[] piCountDim;
529                 //free pArg content
530                 cleanIndexesArguments(_pArgs, &pArg);
531                 //contain bad index, like <= 0, ...
532                 return NULL;
533             }
534
535             //replace ":" by know source dimensions
536             int iSource = 0;
537             for (int i = 0; i < iDims; ++i)
538             {
539                 if (pArg[i] == NULL)
540                 {
541                     if (iSource < iSourceDims)
542                     {
543                         piMaxDim[i] = piSourceDims[iSource];
544                         pArg[i] = createDoubleVector(piMaxDim[i]);
545                         ++iSource;
546                     }
547                     else
548                     {
549                         //fill dimensions after getDimes() with 1
550                         piMaxDim[i] = 1;
551                         pArg[i] = createDoubleVector(piMaxDim[i]);
552                     }
553                 }
554             }
555         }
556     }
557
558     //remove last dimension at size 1
559     //remove last dimension if are == 1
560     for (int i = (iDims - 1); i >= 2; i--)
561     {
562         if (piMaxDim[i] == 1)
563         {
564             iDims--;
565             pArg.back()->killMe();
566             pArg.pop_back();
567         }
568         else
569         {
570             break;
571         }
572     }
573
574     if (checkArgValidity(pArg) == false)
575     {
576         delete[] piMaxDim;
577         delete[] piCountDim;
578         //free pArg content
579         cleanIndexesArguments(_pArgs, &pArg);
580         //contain bad index, like <= 0, ...
581         return NULL;
582     }
583
584     if (iDims == 1)
585     {
586         if (getCols() == 1)
587         {
588             int piRealDim[2] = {piMaxDim[0], 1};
589             pOut = createEmpty(2, piRealDim, bComplex);
590         }
591         else
592         {
593             //rows == 1
594             int piRealDim[2] = {1, piMaxDim[0]};
595             pOut = createEmpty(2, piRealDim, bComplex);
596         }
597     }
598     else
599     {
600         pOut = createEmpty(iDims, piMaxDim, bComplex);
601     }
602
603     //fill with null item
604     ArrayOf* pArrayOut = pOut->getAs<ArrayOf>();
605     T* pRealData = pArrayOut->get();
606     if (bComplex)
607     {
608         T* pImgData = pArrayOut->getImg();
609         for (int i = 0; i < pArrayOut->getSize(); i++)
610         {
611             pArrayOut->deleteData(pRealData[i]);
612             pRealData[i] = getNullValue();
613             pArrayOut->deleteData(pImgData[i]);
614             pImgData[i] = getNullValue();
615         }
616     }
617     else
618     {
619         for (int i = 0; i < pArrayOut->getSize(); i++)
620         {
621             pArrayOut->deleteData(pRealData[i]);
622             pRealData[i] = getNullValue();
623         }
624     }
625
626     if (bIsImpli && (pArrayOut->getSize() != getSize()))
627     {
628         delete[] piMaxDim;
629         delete[] piCountDim;
630         //free pArg content
631         cleanIndexesArguments(_pArgs, &pArg);
632         return NULL;
633     }
634     //insert values in new matrix
635     ArrayOf* pOut2 = pArrayOut->insert(&pArg, this);
636     if (pOut != pOut2)
637     {
638         delete pOut;
639     }
640
641     delete[] piMaxDim;
642     delete[] piCountDim;
643     //free pArg content
644     cleanIndexesArguments(_pArgs, &pArg);
645
646     return pOut2;
647 }
648
649 template <typename T>
650 ArrayOf<T>* ArrayOf<T>::append(int _iRows, int _iCols, InternalType* _poSource)
651 {
652     ArrayOf<T>* pIT = checkRef(this, &ArrayOf::append, _iRows, _iCols, _poSource);
653     if (pIT != this)
654     {
655         return pIT;
656     }
657
658     ArrayOf * pGT = _poSource->getAs<ArrayOf>();
659     int iRows = pGT->getRows();
660     int iCols = pGT->getCols();
661
662     //insert without resize
663     if (iRows + _iRows > m_iRows || iCols + _iCols > m_iCols)
664     {
665         return NULL;
666     }
667
668     //Update complexity if necessary
669     if (pGT->isComplex())
670     {
671         setComplex(true);
672     }
673     else if (isComplex())
674     {
675         pGT->setComplex(true);
676     }
677
678     if (pGT->isComplex())
679     {
680         for (int i = 0; i < iRows; i++)
681         {
682             for (int j = 0; j < iCols; j++)
683             {
684                 set(_iRows + i, _iCols + j, pGT->get(i, j));
685                 setImg(_iRows + i, _iCols + j, pGT->getImg(i, j));
686             }
687         }
688     }
689     else
690     {
691         for (int i = 0; i < iRows; i++)
692         {
693             for (int j = 0; j < iCols; j++)
694             {
695                 set(_iRows + i, _iCols + j, pGT->get(i, j));
696             }
697         }
698     }
699
700     return this;
701 }
702
703 template <typename T>
704 GenericType* ArrayOf<T>::remove(typed_list* _pArgs)
705 {
706     ArrayOf<T>* pOut = NULL;
707     int iDims = (int)_pArgs->size();
708     typed_list pArg;
709
710     int* piMaxDim = new int[iDims];
711     int* piCountDim = new int[iDims];
712
713     //evaluate each argument and replace by appropriate value and compute the count of combinations
714     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
715     delete[] piMaxDim;
716     delete[] piCountDim;
717     if (iSeqCount == 0)
718     {
719         //free pArg content
720         cleanIndexesArguments(_pArgs, &pArg);
721         //no Seq, no change but no error.
722         return this;
723     }
724
725     bool* pbFull = new bool[iDims];
726     //coord must represent all values on a dimension
727     for (int i = 0; i < iDims; i++)
728     {
729         pbFull[i] = false;
730         int iDimToCheck = getVarMaxDim(i, iDims);
731         int iIndexSize = pArg[i]->getAs<GenericType>()->getSize();
732
733         //we can have index more than once
734         if (iIndexSize >= iDimToCheck)
735         {
736             //size is good, now check datas
737             double* pIndexes = getDoubleArrayFromDouble(pArg[i]);
738             for (int j = 0; j < iDimToCheck; j++)
739             {
740                 bool bFind = false;
741                 for (int k = 0; k < iIndexSize; k++)
742                 {
743                     if ((int)pIndexes[k] == j + 1)
744                     {
745                         bFind = true;
746                         break;
747                     }
748                 }
749                 pbFull[i] = bFind;
750             }
751         }
752     }
753
754     //only one dims can be not full/entire
755     bool bNotEntire = false;
756     int iNotEntire = 0;
757     bool bTooMuchNotEntire = false;
758     for (int i = 0; i < iDims; i++)
759     {
760         if (pbFull[i] == false)
761         {
762             if (bNotEntire == false)
763             {
764                 bNotEntire = true;
765                 iNotEntire = i;
766             }
767             else
768             {
769                 bTooMuchNotEntire = true;
770                 break;
771             }
772         }
773     }
774
775     delete[] pbFull;
776
777     if (bTooMuchNotEntire == true)
778     {
779         //free pArg content
780         cleanIndexesArguments(_pArgs, &pArg);
781         return NULL;
782     }
783
784     //find index to keep
785     int iNotEntireSize = pArg[iNotEntire]->getAs<GenericType>()->getSize();
786     double* piNotEntireIndex = getDoubleArrayFromDouble(pArg[iNotEntire]);
787     int iKeepSize = getVarMaxDim(iNotEntire, iDims);
788     bool* pbKeep = new bool[iKeepSize];
789
790     //fill pbKeep with true value
791     for (int i = 0; i < iKeepSize; i++)
792     {
793         pbKeep[i] = true;
794     }
795
796     for (int i = 0; i < iNotEntireSize; i++)
797     {
798         int idx = (int)piNotEntireIndex[i] - 1;
799
800         //don't care of value out of bounds
801         if (idx < iKeepSize)
802         {
803             pbKeep[idx] = false;
804         }
805     }
806
807     int iNewDimSize = 0;
808     for (int i = 0; i < iKeepSize; i++)
809     {
810         if (pbKeep[i] == true)
811         {
812             iNewDimSize++;
813         }
814     }
815     delete[] pbKeep;
816
817     int* piNewDims = new int[iDims];
818     for (int i = 0; i < iDims; i++)
819     {
820         if (i == iNotEntire)
821         {
822             piNewDims[i] = iNewDimSize;
823         }
824         else
825         {
826             piNewDims[i] = getVarMaxDim(i, iDims);
827         }
828     }
829
830     //remove last dimension if are == 1
831     int iOrigDims = iDims;
832     for (int i = (iDims - 1); i >= 2; i--)
833     {
834         if (piNewDims[i] == 1)
835         {
836             iDims--;
837         }
838         else
839         {
840             break;
841         }
842     }
843
844     if (iNewDimSize == 0)
845     {
846         //free pArg content
847         cleanIndexesArguments(_pArgs, &pArg);
848         delete[] piNewDims;
849         return createEmpty();
850     }
851
852     if (iDims == 1)
853     {
854         //two cases, depends of original matrix/vector
855         if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
856         {
857             //special case for row vector
858             int piRealDim[2] = {1, iNewDimSize};
859             pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
860             //in this case we have to care of 2nd dimension
861             //iNotEntire = 1;
862         }
863         else
864         {
865             int piRealDim[2] = {iNewDimSize, 1};
866             pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
867         }
868
869         {
870             int iNewPos = 0;
871             int size = getSize();
872
873             //try to sort piNotEntireIndex
874             std::sort(piNotEntireIndex, piNotEntireIndex + iNotEntireSize);
875
876             int last = 0;
877             for (int i = 0; i < iNotEntireSize; ++i)
878             {
879                 int ii = piNotEntireIndex[i] - 1;
880                 for (int j = last; j < ii; ++j)
881                 {
882                     pOut->set(iNewPos, get(j));
883                     if (m_pImgData != NULL)
884                     {
885                         pOut->setImg(iNewPos, getImg(j));
886                     }
887                     iNewPos++;
888                 }
889
890                 last = ii + 1;
891             }
892
893             for (int i = last; i < size; ++i)
894             {
895                 pOut->set(iNewPos, get(i));
896                 if (m_pImgData != NULL)
897                 {
898                     pOut->setImg(iNewPos, getImg(i));
899                 }
900                 iNewPos++;
901             }
902         }
903     }
904     else
905     {
906         pOut = createEmpty(iDims, piNewDims, m_pImgData != NULL);
907
908         //find a way to copy existing data to new variable ...
909         int iNewPos = 0;
910         int* piIndexes = new int[iOrigDims];
911         int* piViewDims = new int[iOrigDims];
912         for (int i = 0; i < iOrigDims; i++)
913         {
914             piViewDims[i] = getVarMaxDim(i, iOrigDims);
915         }
916
917         for (int i = 0; i < getSize(); i++)
918         {
919             bool bByPass = false;
920             getIndexesWithDims(i, piIndexes, piViewDims, iOrigDims);
921
922             //check if piIndexes use removed indexes
923             for (int j = 0; j < iNotEntireSize; j++)
924             {
925                 if ((piNotEntireIndex[j] - 1) == piIndexes[iNotEntire])
926                 {
927                     //by pass this value
928                     bByPass = true;
929                     break;
930                 }
931             }
932
933             if (bByPass == false)
934             {
935                 //compute new index
936                 pOut->set(iNewPos, get(i));
937                 if (m_pImgData != NULL)
938                 {
939                     pOut->setImg(iNewPos, getImg(i));
940                 }
941                 iNewPos++;
942             }
943         }
944
945         delete[] piIndexes;
946         delete[] piViewDims;
947     }
948
949     delete[] piNewDims;
950
951     //free pArg content
952     cleanIndexesArguments(_pArgs, &pArg);
953
954     return pOut;
955 }
956
957 template <typename T>
958 GenericType* ArrayOf<T>::extract(typed_list* _pArgs)
959 {
960     ArrayOf<T>* pOut = NULL;
961     int iDims = (int)_pArgs->size();
962     typed_list pArg;
963
964     int index;
965     if (getScalarIndex(this, _pArgs, &index))
966     {
967         if (index < 0)
968         {
969             return NULL;
970         }
971
972         if (getSize() == 0)
973         {
974             return createEmpty();
975         }
976
977         if (index >= getSize())
978         {
979             return NULL;
980         }
981
982         int dims[2] = {1, 1};
983         pOut = createEmpty(2, dims, isComplex());;
984         pOut->set(0, get(index));
985         if (isComplex())
986         {
987             pOut->setImg(0, getImg(index));
988         }
989
990         return pOut;
991     }
992
993     std::vector<double> il;
994     if (getScalarImplicitIndex(this, _pArgs, il))
995     {
996         double start = il[0];
997         double step = il[1];
998         double end = il[2];
999         //index are ":"
1000         bool isForceColVector = il.size() == 4;
1001
1002         //std::cout << start << ":" << step << ":" << end << std::endl;
1003         int size = static_cast<int>((end - start) / step + 1);
1004         if (size <= 0 || m_iSize == 0)
1005         {
1006             return createEmpty();
1007         }
1008
1009         if (step > 0 && (size - 1) * step + start > m_iSize ||
1010                 step < 0 && start > m_iSize)
1011         {
1012             return NULL;
1013         }
1014
1015         bool isRowVector = m_iRows == 1;
1016         isRowVector = isRowVector && !isForceColVector;
1017         int dims[2] = {isRowVector ? 1 : size, isRowVector ? size : 1};
1018         pOut = createEmpty(2, dims, isComplex());
1019         double idx = start;
1020
1021         if (isComplex())
1022         {
1023             for (int i = 0; i < size; ++i)
1024             {
1025                 int index = static_cast<int>(idx) - 1;
1026                 pOut->set(i, get(index));
1027                 pOut->setImg(i, getImg(index));
1028                 idx += step;
1029             }
1030         }
1031         else
1032         {
1033             for (int i = 0; i < size; ++i)
1034             {
1035                 pOut->set(i, get(static_cast<int>(idx) - 1));
1036                 idx += step;
1037             }
1038         }
1039         return pOut;
1040     }
1041
1042     std::vector<int> indexes;
1043     std::vector<int> dims;
1044     if (getImplicitIndex(this, _pArgs, indexes, dims))
1045     {
1046         if (indexes.size() == 0)
1047         {
1048             return createEmpty();
1049         }
1050
1051         if (dims.size() == 1)
1052         {
1053             int d[2] = {1, dims[0]};
1054             pOut = createEmpty(2, d, isComplex());
1055         }
1056         else
1057         {
1058             pOut = createEmpty(static_cast<int>(dims.size()), dims.data(), isComplex());
1059         }
1060
1061         int size = getSize();
1062         if (isComplex())
1063         {
1064             int idx = 0;
1065             for (int & i : indexes)
1066             {
1067                 if (i < 0 || i >= size)
1068                 {
1069                     pOut->killMe();
1070                     return NULL;
1071                 }
1072
1073                 pOut->set(idx, get(i));
1074                 pOut->setImg(idx, getImg(i));
1075                 ++idx;
1076             }
1077         }
1078         else
1079         {
1080             int idx = 0;
1081             for (int & i : indexes)
1082             {
1083                 pOut->set(idx, get(i));
1084                 ++idx;
1085             }
1086         }
1087
1088         return pOut;
1089     }
1090
1091
1092     int* piMaxDim = new int[iDims];
1093     int* piCountDim = new int[iDims];
1094
1095     //evaluate each argument and replace by appropriate value and compute the count of combinations
1096     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1097     if (iSeqCount == 0)
1098     {
1099         delete[] piMaxDim;
1100         delete[] piCountDim;
1101         //free pArg content
1102         cleanIndexesArguments(_pArgs, &pArg);
1103         return createEmpty();
1104     }
1105
1106     if (iSeqCount < 0)
1107     {
1108         delete[] piMaxDim;
1109         delete[] piCountDim;
1110         //free pArg content
1111         cleanIndexesArguments(_pArgs, &pArg);
1112         return NULL;
1113     }
1114
1115     //a = {};a(1:2, 1:2) -> {}
1116     if (getSize() == 0)
1117     {
1118         delete[] piMaxDim;
1119         delete[] piCountDim;
1120         //free pArg content
1121         cleanIndexesArguments(_pArgs, &pArg);
1122         return createEmpty();
1123     }
1124
1125     if (iDims < m_iDims)
1126     {
1127         for (int i = 0; i < iDims; i++)
1128         {
1129             int iDimToCheck = 0;
1130             if (i == (iDims - 1))
1131             {
1132                 iDimToCheck = getVarMaxDim(i, iDims);
1133             }
1134             else
1135             {
1136                 iDimToCheck = m_piDims[i];
1137             }
1138
1139             if (piMaxDim[i] > iDimToCheck)
1140             {
1141                 delete[] piMaxDim;
1142                 delete[] piCountDim;
1143                 //free pArg content
1144                 cleanIndexesArguments(_pArgs, &pArg);
1145                 return NULL;
1146             }
1147         }
1148     }
1149     else
1150     {
1151         if (iDims > m_iDims)
1152         {
1153             for (int i = m_iDims; i < iDims; i++)
1154             {
1155                 if (piMaxDim[i] > 1)
1156                 {
1157                     delete[] piMaxDim;
1158                     delete[] piCountDim;
1159                     //free pArg content
1160                     cleanIndexesArguments(_pArgs, &pArg);
1161                     return NULL;
1162                 }
1163             }
1164         }
1165
1166         //check MaxDim
1167         for (int i = 0; i < m_iDims; i++)
1168         {
1169             if (piMaxDim[i] > m_piDims[i])
1170             {
1171                 delete[] piMaxDim;
1172                 delete[] piCountDim;
1173                 //free pArg content
1174                 cleanIndexesArguments(_pArgs, &pArg);
1175                 //exrtact must be in dimension limits
1176                 return NULL;
1177             }
1178         }
1179     }
1180
1181     //remove last dimension if are == 1
1182     for (int i = (iDims - 1); i >= 2; i--)
1183     {
1184         if (piCountDim[i] == 1)
1185         {
1186             (iDims)--;
1187         }
1188         else
1189         {
1190             break;
1191         }
1192     }
1193
1194     //vector
1195     if (iDims == 1)
1196     {
1197         if (piCountDim[0] == 0)
1198         {
1199             delete[] piMaxDim;
1200             delete[] piCountDim;
1201             //free pArg content
1202             cleanIndexesArguments(_pArgs, &pArg);
1203             return createEmpty();
1204         }
1205         else
1206         {
1207             //two cases, depends of original matrix/vector
1208             if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[1] != 1 && m_piDims[0] == 1)
1209             {
1210                 //special case for row vector
1211                 int piRealDim[2] = {1, piCountDim[0]};
1212                 pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
1213             }
1214             else
1215             {
1216                 if (getSize() == 1)
1217                 {
1218                     //for extraction on scalar
1219                     pOut = createEmpty(pArg[0]->getAs<GenericType>()->getDims(), pArg[0]->getAs<GenericType>()->getDimsArray(), m_pImgData != NULL);
1220                 }
1221                 else
1222                 {
1223                     int piRealDim[2] = {piCountDim[0], 1};
1224                     pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
1225                 }
1226             }
1227         }
1228     }
1229     else
1230     {
1231         //matrix
1232         pOut = createEmpty(iDims, piCountDim, m_pImgData != NULL);
1233     }
1234
1235     int* piIndex = new int[_pArgs->size()];
1236     int* piCoord = new int[_pArgs->size()];
1237     int* piViewDims = new int[iDims];
1238     memset(piIndex, 0x00, sizeof(int) * _pArgs->size());
1239
1240     for (int i = 0; i < iDims; i++)
1241     {
1242         piViewDims[i] = getVarMaxDim(i, iDims);
1243     }
1244
1245     for (int i = 0; i < iSeqCount; i++)
1246     {
1247         //increment last dimension
1248         computeTuples(piCountDim, (int)_pArgs->size(), (int)_pArgs->size() - 1, piIndex);
1249
1250         //std::cout << "[";
1251         for (int j = 0; j < (int)_pArgs->size(); j++)
1252         {
1253             piCoord[j] = getIntValueFromDouble(pArg[j], piIndex[j]) - 1;
1254             //InternalType* pVar = pArg[i];
1255             //piCoord[j] = static_cast<int>(pVar->getAs<Double>()->get(piIndex[j]) - 1);
1256             //std::cout << piCoord[j] << " ";
1257
1258             // try to access somewhere wrong.
1259             if (piCoord[j] < 0)
1260             {
1261                 delete[] piIndex;
1262                 delete[] piCoord;
1263                 delete[] piViewDims;
1264                 delete[] piMaxDim;
1265                 delete[] piCountDim;
1266
1267                 //free pArg content
1268                 cleanIndexesArguments(_pArgs, &pArg);
1269                 return NULL;
1270             }
1271         }
1272
1273         //std::cout << "]" << std::endl;
1274
1275         int iPos = 0;
1276         //put vlaue in the new matrix
1277         if ((int)_pArgs->size() < m_iDims)
1278         {
1279             //compute index based on viewed matrix
1280             iPos = getIndexWithDims(piCoord, piViewDims, iDims);
1281         }
1282         else
1283         {
1284             //compute vector index
1285             iPos = getIndex(piCoord);
1286         }
1287
1288         //convert flat dimension to 0
1289         for (int j = 0; j < iDims; j++)
1290         {
1291             if (piCountDim[j] == 1)
1292             {
1293                 piCoord[j] = 0;
1294             }
1295         }
1296
1297         pOut->set(i, get(iPos));
1298         if (m_pImgData != NULL)
1299         {
1300             pOut->setImg(i, getImg(iPos));
1301         }
1302
1303
1304         piIndex[0]++;
1305     }
1306
1307     //free pArg content
1308     cleanIndexesArguments(_pArgs, &pArg);
1309
1310     delete[] piIndex;
1311     delete[] piCoord;
1312     delete[] piViewDims;
1313     delete[] piMaxDim;
1314     delete[] piCountDim;
1315
1316     return pOut;
1317 }
1318
1319 template <typename T>
1320 ArrayOf<T>* ArrayOf<T>::reshape(int* _piDims, int _iDims)
1321 {
1322     typedef ArrayOf<T>* (ArrayOf<T>::*reshape_t)(int*, int);
1323     ArrayOf<T>* pIT = checkRef(this, (reshape_t)&ArrayOf<T>::reshape, _piDims, _iDims);
1324     if (pIT != this)
1325     {
1326         return pIT;
1327     }
1328
1329     int iNewSize = get_max_size(_piDims, _iDims);
1330     if (iNewSize != m_iSize)
1331     {
1332         return NULL;
1333     }
1334
1335     for (int i = 0 ; i < _iDims ; i++)
1336     {
1337         m_piDims[i] = _piDims[i];
1338     }
1339
1340     if (_iDims == 1)
1341     {
1342         m_piDims[1] = 1;
1343         _iDims++;
1344     }
1345
1346     int iDims = _iDims;
1347     for (int i = iDims - 1; i >= 2; --i)
1348     {
1349         if (m_piDims[i] == 1)
1350         {
1351             _iDims--;
1352         }
1353         else
1354         {
1355             break;
1356         }
1357     }
1358
1359     m_iRows = m_piDims[0];
1360     m_iCols = m_piDims[1];
1361     m_iSize = iNewSize;
1362     m_iDims = _iDims;
1363
1364     return this;
1365 }
1366
1367 template <typename T>
1368 ArrayOf<T>* ArrayOf<T>::resize(int* _piDims, int _iDims)
1369 {
1370     typedef ArrayOf<T>* (ArrayOf<T>::*resize_t)(int*, int);
1371     ArrayOf<T>* pIT = checkRef(this, (resize_t)&ArrayOf::resize, _piDims, _iDims);
1372     if (pIT != this)
1373     {
1374         return pIT;
1375     }
1376
1377     if (_iDims == m_iDims)
1378     {
1379         bool bChange = false;
1380         for (int i = 0; i < _iDims; i++)
1381         {
1382             if (m_piDims[i] != _piDims[i])
1383             {
1384                 bChange = true;
1385                 break;
1386             }
1387         }
1388
1389         if (bChange == false)
1390         {
1391             //nothing to do
1392             return this;
1393         }
1394     }
1395
1396     //alloc new data array
1397     T* pRealData = NULL;
1398     T* pImgData = NULL;
1399
1400     int iNewSize = 0;
1401     if (m_pImgData != NULL)
1402     {
1403         iNewSize = get_max_size(_piDims, _iDims);
1404         if (m_iSizeMax < iNewSize)
1405         {
1406             //alloc 10% bigger than asked to prevent future resize
1407             int iOldSizeMax = m_iSizeMax;
1408             m_iSizeMax = static_cast<int>(iNewSize * 1.1);
1409             pRealData = allocData(m_iSizeMax);
1410             pImgData = allocData(m_iSizeMax);
1411
1412             //copy values into new one
1413             int* piIndexes = new int[std::max(m_iDims, _iDims)];
1414             memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1415             for (int i = 0; i < _iDims; i++)
1416             {
1417                 piIndexes[i] = 0;
1418             }
1419
1420             int iPreviousNewIdx = 0;
1421             for (int i = 0; i < m_iSize; i++)
1422             {
1423                 getIndexes(i, piIndexes);
1424                 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1425                 pRealData[iNewIdx] = m_pRealData[i];
1426                 pImgData[iNewIdx] = m_pImgData[i];
1427                 for (int j = iPreviousNewIdx; j < iNewIdx; ++j)
1428                 {
1429                     T pTemp = getNullValue();
1430                     pRealData[j] = copyValue(pTemp);
1431                     pImgData[j] = copyValue(pTemp);
1432                     if (pTemp != pRealData[j])
1433                     {
1434                         deleteData(pTemp);
1435                     }
1436                 }
1437
1438                 iPreviousNewIdx = iNewIdx + 1;
1439             }
1440
1441             // if it's not the first resize,
1442             // fill new data with element of last allocation
1443             if (iPreviousNewIdx < iOldSizeMax)
1444             {
1445                 for (int i = iPreviousNewIdx; i < iOldSizeMax; ++i)
1446                 {
1447                     pRealData[i] = m_pRealData[i];
1448                     pImgData[i] = m_pImgData[i];
1449                 }
1450             }
1451             else
1452             {
1453                 // first resize, iOldSizeMax don't contain the 10%
1454                 iOldSizeMax = iPreviousNewIdx;
1455             }
1456
1457             for (int i = iOldSizeMax; i < m_iSizeMax; ++i)
1458             {
1459                 T pTemp = getNullValue();
1460                 pRealData[i] = copyValue(pTemp);
1461                 pImgData[i] = copyValue(pTemp);
1462                 if (pTemp != pRealData[i])
1463                 {
1464                     deleteData(pTemp);
1465                 }
1466             }
1467
1468             delete[] piIndexes;
1469             //delete all array
1470             delete[] m_pRealData;
1471             delete[] m_pImgData;
1472             //replace old array by new one
1473             m_pRealData = pRealData;
1474             m_pImgData = pImgData;
1475         }
1476         else
1477         {
1478             //check if only the last dims change
1479             bool bNonLastDimChange = false;
1480             for (int i = 0; i < (m_iDims - 1); i++)
1481             {
1482                 if (m_piDims[i] != _piDims[i])
1483                 {
1484                     bNonLastDimChange = true;
1485                     break;
1486                 }
1487             }
1488
1489             //if vector or if row dimension not change, we don't need to shift data
1490             if (m_iDims != _iDims || (!isVector() && bNonLastDimChange))
1491             {
1492                 //copy values into new one
1493                 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1494                 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1495                 for (int i = m_iSize - 1; i >= 0; i--)
1496                 {
1497                     getIndexes(i, piIndexes);
1498                     int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1499                     if (iNewIdx != i)
1500                     {
1501                         T pTemp = m_pRealData[iNewIdx];
1502                         m_pRealData[iNewIdx] = m_pRealData[i];
1503                         m_pRealData[i] = pTemp;
1504
1505                         pTemp = m_pImgData[iNewIdx];
1506                         m_pImgData[iNewIdx] = m_pImgData[i];
1507                         m_pImgData[i] = pTemp;
1508                     }
1509                 }
1510                 delete[] piIndexes;
1511             }
1512         }
1513     }
1514     else
1515     {
1516         iNewSize = get_max_size(_piDims, _iDims);
1517         if (iNewSize > m_iSizeMax)
1518         {
1519             //alloc 10% bigger than asked to prevent future resize
1520             int iOldSizeMax = m_iSizeMax;
1521             m_iSizeMax = static_cast<int>(iNewSize * 1.1);
1522             pRealData = allocData(m_iSizeMax);
1523
1524             //copy values into new one
1525             int* piIndexes = new int[std::max(m_iDims, _iDims)];
1526             memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1527             for (int i = 0; i < _iDims; i++)
1528             {
1529                 piIndexes[i] = 0;
1530             }
1531
1532             int iPreviousNewIdx = 0;
1533             for (int i = 0; i < m_iSize; i++)
1534             {
1535                 getIndexes(i, piIndexes);
1536                 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1537                 pRealData[iNewIdx] = m_pRealData[i];
1538                 m_pRealData[i] = NULL;
1539                 for (int j = iPreviousNewIdx; j < iNewIdx; ++j)
1540                 {
1541                     T pTemp = getNullValue();
1542                     T pTemp2 = copyValue(pTemp);
1543                     pRealData[j] = pTemp2;
1544                     if (pTemp != pTemp2)
1545                     {
1546                         deleteData(pTemp);
1547                     }
1548                 }
1549
1550                 iPreviousNewIdx = iNewIdx + 1;
1551             }
1552
1553             //clean section between m_iSize and iOldSizeMax
1554             for (int i = m_iSize; i < iOldSizeMax; ++i)
1555             {
1556                 deleteData(m_pRealData[i]);
1557                 m_pRealData[i] = NULL;
1558             }
1559
1560             //if (iPreviousNewIdx < iOldSizeMax)
1561             //{
1562             //    for (int i = iPreviousNewIdx; i < iOldSizeMax; ++i)
1563             //    {
1564             //        pRealData[i] = m_pRealData[i];
1565             //        m_pRealData[i] = NULL;
1566             //    }
1567             //}
1568             //else
1569             //{
1570             //    iOldSizeMax = iPreviousNewIdx;
1571             //}
1572
1573             //fill exceeded with NullValue
1574             for (int i = iPreviousNewIdx; i < m_iSizeMax; ++i)
1575             {
1576                 T pTemp = getNullValue();
1577                 T pTemp2 = copyValue(pTemp);
1578                 pRealData[i] = pTemp2;
1579                 if (pTemp != pTemp2)
1580                 {
1581                     deleteData(pTemp);
1582                 }
1583             }
1584
1585             delete[] piIndexes;
1586             //delete all array
1587             delete[] m_pRealData;
1588             //replace old array by new one
1589             m_pRealData = pRealData;
1590         }
1591         else
1592         {
1593             //check if only the last dims change
1594             bool bNonLastDimChange = false;
1595             for (int i = 0; i < (m_iDims - 1); i++)
1596             {
1597                 if (m_piDims[i] != _piDims[i])
1598                 {
1599                     bNonLastDimChange = true;
1600                     break;
1601                 }
1602             }
1603
1604             //if vector or if row dimension not change, we don't need to shift data
1605             if (m_iDims != _iDims || (!isVector() && bNonLastDimChange))
1606             {
1607                 //copy values into new one
1608                 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1609                 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1610                 for (int i = m_iSize - 1; i >= 0; i--)
1611                 {
1612                     getIndexes(i, piIndexes);
1613                     int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1614                     if (iNewIdx != i)
1615                     {
1616                         T pTemp = m_pRealData[iNewIdx];
1617                         m_pRealData[iNewIdx] = m_pRealData[i];
1618                         m_pRealData[i] = pTemp;
1619                     }
1620                 }
1621                 delete[] piIndexes;
1622             }
1623         }
1624     }
1625
1626     if (_iDims != m_iDims)
1627     {
1628         //int* piDims = new int[_iDims];
1629         for (int i = 0; i < _iDims; i++)
1630         {
1631             m_piDims[i] = _piDims[i];
1632         }
1633         //delete[] m_piDims;
1634         //m_piDims = piDims;
1635         m_iDims = _iDims;
1636     }
1637     else
1638     {
1639         for (int i = 0; i < m_iDims; i++)
1640         {
1641             m_piDims[i] = _piDims[i];
1642         }
1643     }
1644     m_iRows = m_piDims[0];
1645     m_iCols = m_piDims[1];
1646     m_iSize = iNewSize;
1647     return this;
1648 }
1649
1650 template <typename T>
1651 bool ArrayOf<T>::isTrue()
1652 {
1653     return type_traits::isTrue<T>(m_iSize, m_pRealData);
1654 }
1655
1656 template<typename T>
1657 bool ArrayOf<T>::neg(InternalType *& out)
1658 {
1659     out = new Bool(this->m_iDims, this->m_piDims);
1660     type_traits::neg<T, int>(this->m_iSize, this->m_pRealData, static_cast<Bool *>(out)->get());
1661
1662     return true;
1663 }
1664
1665 template<typename T>
1666 bool ArrayOf<T>::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
1667 {
1668     if (in.size() == 0)
1669     {
1670         out.push_back(this);
1671     }
1672     else
1673     {
1674         InternalType * _out = extract(&in);
1675         if (!_out)
1676         {
1677             std::wostringstream os;
1678             os << _W("Invalid index.") << std::endl;
1679             throw ast::InternalError(os.str(), 999, e.getLocation());
1680         }
1681         out.push_back(_out);
1682     }
1683
1684     return true;
1685 }
1686
1687 template<typename T>
1688 bool ArrayOf<T>::isInvokable() const
1689 {
1690     return true;
1691 }
1692
1693 template<typename T>
1694 bool ArrayOf<T>::hasInvokeOption() const
1695 {
1696     return false;
1697 }
1698
1699 template<typename T>
1700 int ArrayOf<T>::getInvokeNbIn()
1701 {
1702     return -1;
1703 }
1704
1705 template<typename T>
1706 int ArrayOf<T>::getInvokeNbOut()
1707 {
1708     return 1;
1709 }
1710
1711
1712 // used to allow definition of ArrayOf methode in this cpp file.
1713 template class EXTERN_AST ArrayOf < char >;
1714 template class EXTERN_AST ArrayOf < unsigned char >;
1715 template class EXTERN_AST ArrayOf < short >;
1716 template class EXTERN_AST ArrayOf < unsigned short >;
1717 template class EXTERN_AST ArrayOf < int >;
1718 template class EXTERN_AST ArrayOf < unsigned int >;
1719 template class EXTERN_AST ArrayOf < long long >;
1720 template class EXTERN_AST ArrayOf < unsigned long long >;
1721 template class EXTERN_AST ArrayOf < double >;
1722 template class EXTERN_AST ArrayOf < wchar_t* >;
1723 template class EXTERN_AST ArrayOf < SinglePoly* >;
1724 template class EXTERN_AST ArrayOf < SingleStruct* >;
1725 template class EXTERN_AST ArrayOf < InternalType* >; // Cell
1726 }