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