[differential_equations] bugs and tests 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
776     if (bTooMuchNotEntire == true)
777     {
778         //free pArg content
779         cleanIndexesArguments(_pArgs, &pArg);
780         return NULL;
781     }
782
783     delete[] pbFull;
784
785     //find index to keep
786     int iNotEntireSize = pArg[iNotEntire]->getAs<GenericType>()->getSize();
787     double* piNotEntireIndex = getDoubleArrayFromDouble(pArg[iNotEntire]);
788     int iKeepSize = getVarMaxDim(iNotEntire, iDims);
789     bool* pbKeep = new bool[iKeepSize];
790
791     //fill pbKeep with true value
792     for (int i = 0; i < iKeepSize; i++)
793     {
794         pbKeep[i] = true;
795     }
796
797     for (int i = 0; i < iNotEntireSize; i++)
798     {
799         int idx = (int)piNotEntireIndex[i] - 1;
800
801         //don't care of value out of bounds
802         if (idx < iKeepSize)
803         {
804             pbKeep[idx] = false;
805         }
806     }
807
808     int iNewDimSize = 0;
809     for (int i = 0; i < iKeepSize; i++)
810     {
811         if (pbKeep[i] == true)
812         {
813             iNewDimSize++;
814         }
815     }
816     delete[] pbKeep;
817
818     int* piNewDims = new int[iDims];
819     for (int i = 0; i < iDims; i++)
820     {
821         if (i == iNotEntire)
822         {
823             piNewDims[i] = iNewDimSize;
824         }
825         else
826         {
827             piNewDims[i] = getVarMaxDim(i, iDims);
828         }
829     }
830
831     //remove last dimension if are == 1
832     int iOrigDims = iDims;
833     for (int i = (iDims - 1); i >= 2; i--)
834     {
835         if (piNewDims[i] == 1)
836         {
837             iDims--;
838         }
839         else
840         {
841             break;
842         }
843     }
844
845     if (iNewDimSize == 0)
846     {
847         //free pArg content
848         cleanIndexesArguments(_pArgs, &pArg);
849         delete[] piNewDims;
850         return createEmpty();
851     }
852
853     if (iDims == 1)
854     {
855         //two cases, depends of original matrix/vector
856         if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
857         {
858             //special case for row vector
859             int piRealDim[2] = {1, iNewDimSize};
860             pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
861             //in this case we have to care of 2nd dimension
862             //iNotEntire = 1;
863         }
864         else
865         {
866             int piRealDim[2] = {iNewDimSize, 1};
867             pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
868         }
869
870         {
871             int iNewPos = 0;
872             int size = getSize();
873
874             //try to sort piNotEntireIndex
875             std::sort(piNotEntireIndex, piNotEntireIndex + iNotEntireSize);
876
877             int last = 0;
878             for (int i = 0; i < iNotEntireSize; ++i)
879             {
880                 int ii = piNotEntireIndex[i] - 1;
881                 for (int j = last; j < ii; ++j)
882                 {
883                     pOut->set(iNewPos, get(j));
884                     if (m_pImgData != NULL)
885                     {
886                         pOut->setImg(iNewPos, getImg(j));
887                     }
888                     iNewPos++;
889                 }
890
891                 last = ii + 1;
892             }
893
894             for (int i = last; i < size; ++i)
895             {
896                 pOut->set(iNewPos, get(i));
897                 if (m_pImgData != NULL)
898                 {
899                     pOut->setImg(iNewPos, getImg(i));
900                 }
901                 iNewPos++;
902             }
903         }
904     }
905     else
906     {
907         pOut = createEmpty(iDims, piNewDims, m_pImgData != NULL);
908
909         //find a way to copy existing data to new variable ...
910         int iNewPos = 0;
911         int* piIndexes = new int[iOrigDims];
912         int* piViewDims = new int[iOrigDims];
913         for (int i = 0; i < iOrigDims; i++)
914         {
915             piViewDims[i] = getVarMaxDim(i, iOrigDims);
916         }
917
918         for (int i = 0; i < getSize(); i++)
919         {
920             bool bByPass = false;
921             getIndexesWithDims(i, piIndexes, piViewDims, iOrigDims);
922
923             //check if piIndexes use removed indexes
924             for (int j = 0; j < iNotEntireSize; j++)
925             {
926                 if ((piNotEntireIndex[j] - 1) == piIndexes[iNotEntire])
927                 {
928                     //by pass this value
929                     bByPass = true;
930                     break;
931                 }
932             }
933
934             if (bByPass == false)
935             {
936                 //compute new index
937                 pOut->set(iNewPos, get(i));
938                 if (m_pImgData != NULL)
939                 {
940                     pOut->setImg(iNewPos, getImg(i));
941                 }
942                 iNewPos++;
943             }
944         }
945
946         delete[] piIndexes;
947         delete[] piViewDims;
948     }
949
950     delete[] piNewDims;
951
952     //free pArg content
953     cleanIndexesArguments(_pArgs, &pArg);
954
955     return pOut;
956 }
957
958 template <typename T>
959 GenericType* ArrayOf<T>::extract(typed_list* _pArgs)
960 {
961     ArrayOf<T>* pOut = NULL;
962     int iDims = (int)_pArgs->size();
963     typed_list pArg;
964
965     int index;
966     if (getScalarIndex(this, _pArgs, &index))
967     {
968         if (index < 0)
969         {
970             return NULL;
971         }
972
973         if (getSize() == 0)
974         {
975             return createEmpty();
976         }
977
978         if (index >= getSize())
979         {
980             return NULL;
981         }
982
983         int dims[2] = {1, 1};
984         pOut = createEmpty(2, dims, isComplex());;
985         pOut->set(0, get(index));
986         if (isComplex())
987         {
988             pOut->setImg(0, getImg(index));
989         }
990
991         return pOut;
992     }
993
994     std::vector<double> il;
995     if (getScalarImplicitIndex(this, _pArgs, il))
996     {
997         double start = il[0];
998         double step = il[1];
999         double end = il[2];
1000         //index are ":"
1001         bool isForceColVector = il.size() == 4;
1002
1003         //std::cout << start << ":" << step << ":" << end << std::endl;
1004         int size = static_cast<int>((end - start) / step + 1);
1005         if (size <= 0 || m_iSize == 0)
1006         {
1007             return createEmpty();
1008         }
1009
1010         if (step > 0 && (size - 1) * step + start > m_iSize ||
1011                 step < 0 && start > m_iSize)
1012         {
1013             return NULL;
1014         }
1015
1016         bool isRowVector = m_iRows == 1;
1017         isRowVector = isRowVector && !isForceColVector;
1018         int dims[2] = {isRowVector ? 1 : size, isRowVector ? size : 1};
1019         pOut = createEmpty(2, dims, isComplex());
1020         double idx = start;
1021
1022         if (isComplex())
1023         {
1024             for (int i = 0; i < size; ++i)
1025             {
1026                 int index = static_cast<int>(idx) - 1;
1027                 pOut->set(i, get(index));
1028                 pOut->setImg(i, getImg(index));
1029                 idx += step;
1030             }
1031         }
1032         else
1033         {
1034             for (int i = 0; i < size; ++i)
1035             {
1036                 pOut->set(i, get(static_cast<int>(idx) - 1));
1037                 idx += step;
1038             }
1039         }
1040         return pOut;
1041     }
1042
1043     std::vector<int> indexes;
1044     std::vector<int> dims;
1045     if (getImplicitIndex(this, _pArgs, indexes, dims))
1046     {
1047         if (indexes.size() == 0)
1048         {
1049             return createEmpty();
1050         }
1051
1052         if (dims.size() == 1)
1053         {
1054             int d[2] = {1, dims[0]};
1055             pOut = createEmpty(2, d, isComplex());
1056         }
1057         else
1058         {
1059             pOut = createEmpty(static_cast<int>(dims.size()), dims.data(), isComplex());
1060         }
1061
1062         int size = getSize();
1063         if (isComplex())
1064         {
1065             int idx = 0;
1066             for (int & i : indexes)
1067             {
1068                 if (i < 0 || i >= size)
1069                 {
1070                     pOut->killMe();
1071                     return NULL;
1072                 }
1073
1074                 pOut->set(idx, get(i));
1075                 pOut->setImg(idx, getImg(i));
1076                 ++idx;
1077             }
1078         }
1079         else
1080         {
1081             int idx = 0;
1082             for (int & i : indexes)
1083             {
1084                 pOut->set(idx, get(i));
1085                 ++idx;
1086             }
1087         }
1088
1089         return pOut;
1090     }
1091
1092
1093     int* piMaxDim = new int[iDims];
1094     int* piCountDim = new int[iDims];
1095
1096     //evaluate each argument and replace by appropriate value and compute the count of combinations
1097     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1098     if (iSeqCount == 0)
1099     {
1100         delete[] piMaxDim;
1101         delete[] piCountDim;
1102         //free pArg content
1103         cleanIndexesArguments(_pArgs, &pArg);
1104         return createEmpty();
1105     }
1106
1107     if (iSeqCount < 0)
1108     {
1109         delete[] piMaxDim;
1110         delete[] piCountDim;
1111         //free pArg content
1112         cleanIndexesArguments(_pArgs, &pArg);
1113         return NULL;
1114     }
1115
1116     //a = {};a(1:2, 1:2) -> {}
1117     if (getSize() == 0)
1118     {
1119         delete[] piMaxDim;
1120         delete[] piCountDim;
1121         //free pArg content
1122         cleanIndexesArguments(_pArgs, &pArg);
1123         return createEmpty();
1124     }
1125
1126     if (iDims < m_iDims)
1127     {
1128         for (int i = 0; i < iDims; i++)
1129         {
1130             int iDimToCheck = 0;
1131             if (i == (iDims - 1))
1132             {
1133                 iDimToCheck = getVarMaxDim(i, iDims);
1134             }
1135             else
1136             {
1137                 iDimToCheck = m_piDims[i];
1138             }
1139
1140             if (piMaxDim[i] > iDimToCheck)
1141             {
1142                 delete[] piMaxDim;
1143                 delete[] piCountDim;
1144                 //free pArg content
1145                 cleanIndexesArguments(_pArgs, &pArg);
1146                 return NULL;
1147             }
1148         }
1149     }
1150     else
1151     {
1152         if (iDims > m_iDims)
1153         {
1154             for (int i = m_iDims; i < iDims; i++)
1155             {
1156                 if (piMaxDim[i] > 1)
1157                 {
1158                     delete[] piMaxDim;
1159                     delete[] piCountDim;
1160                     //free pArg content
1161                     cleanIndexesArguments(_pArgs, &pArg);
1162                     return NULL;
1163                 }
1164             }
1165         }
1166
1167         //check MaxDim
1168         for (int i = 0; i < m_iDims; i++)
1169         {
1170             if (piMaxDim[i] > m_piDims[i])
1171             {
1172                 delete[] piMaxDim;
1173                 delete[] piCountDim;
1174                 //free pArg content
1175                 cleanIndexesArguments(_pArgs, &pArg);
1176                 //exrtact must be in dimension limits
1177                 return NULL;
1178             }
1179         }
1180     }
1181
1182     //remove last dimension if are == 1
1183     for (int i = (iDims - 1); i >= 2; i--)
1184     {
1185         if (piCountDim[i] == 1)
1186         {
1187             (iDims)--;
1188         }
1189         else
1190         {
1191             break;
1192         }
1193     }
1194
1195     //vector
1196     if (iDims == 1)
1197     {
1198         if (piCountDim[0] == 0)
1199         {
1200             delete[] piMaxDim;
1201             delete[] piCountDim;
1202             //free pArg content
1203             cleanIndexesArguments(_pArgs, &pArg);
1204             return createEmpty();
1205         }
1206         else
1207         {
1208             //two cases, depends of original matrix/vector
1209             if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[1] != 1 && m_piDims[0] == 1)
1210             {
1211                 //special case for row vector
1212                 int piRealDim[2] = {1, piCountDim[0]};
1213                 pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
1214             }
1215             else
1216             {
1217                 if (getSize() == 1)
1218                 {
1219                     //for extraction on scalar
1220                     pOut = createEmpty(pArg[0]->getAs<GenericType>()->getDims(), pArg[0]->getAs<GenericType>()->getDimsArray(), m_pImgData != NULL);
1221                 }
1222                 else
1223                 {
1224                     int piRealDim[2] = {piCountDim[0], 1};
1225                     pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
1226                 }
1227             }
1228         }
1229     }
1230     else
1231     {
1232         //matrix
1233         pOut = createEmpty(iDims, piCountDim, m_pImgData != NULL);
1234     }
1235
1236     int* piIndex = new int[_pArgs->size()];
1237     int* piCoord = new int[_pArgs->size()];
1238     int* piViewDims = new int[iDims];
1239     memset(piIndex, 0x00, sizeof(int) * _pArgs->size());
1240
1241     for (int i = 0; i < iDims; i++)
1242     {
1243         piViewDims[i] = getVarMaxDim(i, iDims);
1244     }
1245
1246     for (int i = 0; i < iSeqCount; i++)
1247     {
1248         //increment last dimension
1249         computeTuples(piCountDim, (int)_pArgs->size(), (int)_pArgs->size() - 1, piIndex);
1250
1251         //std::cout << "[";
1252         for (int j = 0; j < (int)_pArgs->size(); j++)
1253         {
1254             piCoord[j] = getIntValueFromDouble(pArg[j], piIndex[j]) - 1;
1255             //InternalType* pVar = pArg[i];
1256             //piCoord[j] = static_cast<int>(pVar->getAs<Double>()->get(piIndex[j]) - 1);
1257             //std::cout << piCoord[j] << " ";
1258
1259             // try to access somewhere wrong.
1260             if (piCoord[j] < 0)
1261             {
1262                 delete[] piIndex;
1263                 delete[] piCoord;
1264                 delete[] piViewDims;
1265                 delete[] piMaxDim;
1266                 delete[] piCountDim;
1267
1268                 //free pArg content
1269                 cleanIndexesArguments(_pArgs, &pArg);
1270                 return NULL;
1271             }
1272         }
1273
1274         //std::cout << "]" << std::endl;
1275
1276         int iPos = 0;
1277         //put vlaue in the new matrix
1278         if ((int)_pArgs->size() < m_iDims)
1279         {
1280             //compute index based on viewed matrix
1281             iPos = getIndexWithDims(piCoord, piViewDims, iDims);
1282         }
1283         else
1284         {
1285             //compute vector index
1286             iPos = getIndex(piCoord);
1287         }
1288
1289         //convert flat dimension to 0
1290         for (int j = 0; j < iDims; j++)
1291         {
1292             if (piCountDim[j] == 1)
1293             {
1294                 piCoord[j] = 0;
1295             }
1296         }
1297
1298         pOut->set(i, get(iPos));
1299         if (m_pImgData != NULL)
1300         {
1301             pOut->setImg(i, getImg(iPos));
1302         }
1303
1304
1305         piIndex[0]++;
1306     }
1307
1308     //free pArg content
1309     cleanIndexesArguments(_pArgs, &pArg);
1310
1311     delete[] piIndex;
1312     delete[] piCoord;
1313     delete[] piViewDims;
1314     delete[] piMaxDim;
1315     delete[] piCountDim;
1316
1317     return pOut;
1318 }
1319
1320 template <typename T>
1321 ArrayOf<T>* ArrayOf<T>::reshape(int* _piDims, int _iDims)
1322 {
1323     typedef ArrayOf<T>* (ArrayOf<T>::*reshape_t)(int*, int);
1324     ArrayOf<T>* pIT = checkRef(this, (reshape_t)&ArrayOf<T>::reshape, _piDims, _iDims);
1325     if (pIT != this)
1326     {
1327         return pIT;
1328     }
1329
1330     int iNewSize = get_max_size(_piDims, _iDims);
1331     if (iNewSize != m_iSize)
1332     {
1333         return NULL;
1334     }
1335
1336     for (int i = 0 ; i < _iDims ; i++)
1337     {
1338         m_piDims[i] = _piDims[i];
1339     }
1340
1341     if (_iDims == 1)
1342     {
1343         m_piDims[1] = 1;
1344         _iDims++;
1345     }
1346
1347     int iDims = _iDims;
1348     for (int i = iDims - 1; i >= 2; --i)
1349     {
1350         if (m_piDims[i] == 1)
1351         {
1352             _iDims--;
1353         }
1354         else
1355         {
1356             break;
1357         }
1358     }
1359
1360     m_iRows = m_piDims[0];
1361     m_iCols = m_piDims[1];
1362     m_iSize = iNewSize;
1363     m_iDims = _iDims;
1364
1365     return this;
1366 }
1367
1368 template <typename T>
1369 ArrayOf<T>* ArrayOf<T>::resize(int* _piDims, int _iDims)
1370 {
1371     typedef ArrayOf<T>* (ArrayOf<T>::*resize_t)(int*, int);
1372     ArrayOf<T>* pIT = checkRef(this, (resize_t)&ArrayOf::resize, _piDims, _iDims);
1373     if (pIT != this)
1374     {
1375         return pIT;
1376     }
1377
1378     if (_iDims == m_iDims)
1379     {
1380         bool bChange = false;
1381         for (int i = 0; i < _iDims; i++)
1382         {
1383             if (m_piDims[i] != _piDims[i])
1384             {
1385                 bChange = true;
1386                 break;
1387             }
1388         }
1389
1390         if (bChange == false)
1391         {
1392             //nothing to do
1393             return this;
1394         }
1395     }
1396
1397     //alloc new data array
1398     T* pRealData = NULL;
1399     T* pImgData = NULL;
1400
1401     int iNewSize = 0;
1402     if (m_pImgData != NULL)
1403     {
1404         iNewSize = get_max_size(_piDims, _iDims);
1405         if (m_iSizeMax < iNewSize)
1406         {
1407             //alloc 10% bigger than asked to prevent future resize
1408             int iOldSizeMax = m_iSizeMax;
1409             m_iSizeMax = static_cast<int>(iNewSize * 1.1);
1410             pRealData = allocData(m_iSizeMax);
1411             pImgData = allocData(m_iSizeMax);
1412
1413             //copy values into new one
1414             int* piIndexes = new int[std::max(m_iDims, _iDims)];
1415             memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1416             for (int i = 0; i < _iDims; i++)
1417             {
1418                 piIndexes[i] = 0;
1419             }
1420
1421             int iPreviousNewIdx = 0;
1422             for (int i = 0; i < m_iSize; i++)
1423             {
1424                 getIndexes(i, piIndexes);
1425                 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1426                 pRealData[iNewIdx] = m_pRealData[i];
1427                 pImgData[iNewIdx] = m_pImgData[i];
1428                 for (int j = iPreviousNewIdx; j < iNewIdx; ++j)
1429                 {
1430                     T pTemp = getNullValue();
1431                     pRealData[j] = copyValue(pTemp);
1432                     pImgData[j] = copyValue(pTemp);
1433                     if (pTemp != pRealData[j])
1434                     {
1435                         deleteData(pTemp);
1436                     }
1437                 }
1438
1439                 iPreviousNewIdx = iNewIdx + 1;
1440             }
1441
1442             // if it's not the first resize,
1443             // fill new data with element of last allocation
1444             if (iPreviousNewIdx < iOldSizeMax)
1445             {
1446                 for (int i = iPreviousNewIdx; i < iOldSizeMax; ++i)
1447                 {
1448                     pRealData[i] = m_pRealData[i];
1449                     pImgData[i] = m_pImgData[i];
1450                 }
1451             }
1452             else
1453             {
1454                 // first resize, iOldSizeMax don't contain the 10%
1455                 iOldSizeMax = iPreviousNewIdx;
1456             }
1457
1458             for (int i = iOldSizeMax; i < m_iSizeMax; ++i)
1459             {
1460                 T pTemp = getNullValue();
1461                 pRealData[i] = copyValue(pTemp);
1462                 pImgData[i] = copyValue(pTemp);
1463                 if (pTemp != pRealData[i])
1464                 {
1465                     deleteData(pTemp);
1466                 }
1467             }
1468
1469             delete[] piIndexes;
1470             //delete all array
1471             delete[] m_pRealData;
1472             delete[] m_pImgData;
1473             //replace old array by new one
1474             m_pRealData = pRealData;
1475             m_pImgData = pImgData;
1476         }
1477         else
1478         {
1479             //check if only the last dims change
1480             bool bNonLastDimChange = false;
1481             for (int i = 0; i < (m_iDims - 1); i++)
1482             {
1483                 if (m_piDims[i] != _piDims[i])
1484                 {
1485                     bNonLastDimChange = true;
1486                     break;
1487                 }
1488             }
1489
1490             //if vector or if row dimension not change, we don't need to shift data
1491             if (m_iDims != _iDims || (!isVector() && bNonLastDimChange))
1492             {
1493                 //copy values into new one
1494                 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1495                 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1496                 for (int i = m_iSize - 1; i >= 0; i--)
1497                 {
1498                     getIndexes(i, piIndexes);
1499                     int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1500                     if (iNewIdx != i)
1501                     {
1502                         T pTemp = m_pRealData[iNewIdx];
1503                         m_pRealData[iNewIdx] = m_pRealData[i];
1504                         m_pRealData[i] = pTemp;
1505
1506                         pTemp = m_pImgData[iNewIdx];
1507                         m_pImgData[iNewIdx] = m_pImgData[i];
1508                         m_pImgData[i] = pTemp;
1509                     }
1510                 }
1511                 delete[] piIndexes;
1512             }
1513         }
1514     }
1515     else
1516     {
1517         iNewSize = get_max_size(_piDims, _iDims);
1518         if (iNewSize > m_iSizeMax)
1519         {
1520             //alloc 10% bigger than asked to prevent future resize
1521             int iOldSizeMax = m_iSizeMax;
1522             m_iSizeMax = static_cast<int>(iNewSize * 1.1);
1523             pRealData = allocData(m_iSizeMax);
1524
1525             //copy values into new one
1526             int* piIndexes = new int[std::max(m_iDims, _iDims)];
1527             memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1528             for (int i = 0; i < _iDims; i++)
1529             {
1530                 piIndexes[i] = 0;
1531             }
1532
1533             int iPreviousNewIdx = 0;
1534             for (int i = 0; i < m_iSize; i++)
1535             {
1536                 getIndexes(i, piIndexes);
1537                 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1538                 pRealData[iNewIdx] = m_pRealData[i];
1539                 m_pRealData[i] = NULL;
1540                 for (int j = iPreviousNewIdx; j < iNewIdx; ++j)
1541                 {
1542                     T pTemp = getNullValue();
1543                     T pTemp2 = copyValue(pTemp);
1544                     pRealData[j] = pTemp2;
1545                     if (pTemp != pTemp2)
1546                     {
1547                         deleteData(pTemp);
1548                     }
1549                 }
1550
1551                 iPreviousNewIdx = iNewIdx + 1;
1552             }
1553
1554             //clean section between m_iSize and iOldSizeMax
1555             for (int i = m_iSize; i < iOldSizeMax; ++i)
1556             {
1557                 deleteData(m_pRealData[i]);
1558                 m_pRealData[i] = NULL;
1559             }
1560
1561             //if (iPreviousNewIdx < iOldSizeMax)
1562             //{
1563             //    for (int i = iPreviousNewIdx; i < iOldSizeMax; ++i)
1564             //    {
1565             //        pRealData[i] = m_pRealData[i];
1566             //        m_pRealData[i] = NULL;
1567             //    }
1568             //}
1569             //else
1570             //{
1571             //    iOldSizeMax = iPreviousNewIdx;
1572             //}
1573
1574             //fill exceeded with NullValue
1575             for (int i = iPreviousNewIdx; i < m_iSizeMax; ++i)
1576             {
1577                 T pTemp = getNullValue();
1578                 T pTemp2 = copyValue(pTemp);
1579                 pRealData[i] = pTemp2;
1580                 if (pTemp != pTemp2)
1581                 {
1582                     deleteData(pTemp);
1583                 }
1584             }
1585
1586             delete[] piIndexes;
1587             //delete all array
1588             delete[] m_pRealData;
1589             //replace old array by new one
1590             m_pRealData = pRealData;
1591         }
1592         else
1593         {
1594             //check if only the last dims change
1595             bool bNonLastDimChange = false;
1596             for (int i = 0; i < (m_iDims - 1); i++)
1597             {
1598                 if (m_piDims[i] != _piDims[i])
1599                 {
1600                     bNonLastDimChange = true;
1601                     break;
1602                 }
1603             }
1604
1605             //if vector or if row dimension not change, we don't need to shift data
1606             if (m_iDims != _iDims || (!isVector() && bNonLastDimChange))
1607             {
1608                 //copy values into new one
1609                 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1610                 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1611                 for (int i = m_iSize - 1; i >= 0; i--)
1612                 {
1613                     getIndexes(i, piIndexes);
1614                     int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1615                     if (iNewIdx != i)
1616                     {
1617                         T pTemp = m_pRealData[iNewIdx];
1618                         m_pRealData[iNewIdx] = m_pRealData[i];
1619                         m_pRealData[i] = pTemp;
1620                     }
1621                 }
1622                 delete[] piIndexes;
1623             }
1624         }
1625     }
1626
1627     if (_iDims != m_iDims)
1628     {
1629         //int* piDims = new int[_iDims];
1630         for (int i = 0; i < _iDims; i++)
1631         {
1632             m_piDims[i] = _piDims[i];
1633         }
1634         //delete[] m_piDims;
1635         //m_piDims = piDims;
1636         m_iDims = _iDims;
1637     }
1638     else
1639     {
1640         for (int i = 0; i < m_iDims; i++)
1641         {
1642             m_piDims[i] = _piDims[i];
1643         }
1644     }
1645     m_iRows = m_piDims[0];
1646     m_iCols = m_piDims[1];
1647     m_iSize = iNewSize;
1648     return this;
1649 }
1650
1651 template <typename T>
1652 bool ArrayOf<T>::isTrue()
1653 {
1654     return type_traits::isTrue<T>(m_iSize, m_pRealData);
1655 }
1656
1657 template<typename T>
1658 bool ArrayOf<T>::neg(InternalType *& out)
1659 {
1660     out = new Bool(this->m_iDims, this->m_piDims);
1661     type_traits::neg<T, int>(this->m_iSize, this->m_pRealData, static_cast<Bool *>(out)->get());
1662
1663     return true;
1664 }
1665
1666 template<typename T>
1667 bool ArrayOf<T>::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
1668 {
1669     if (in.size() == 0)
1670     {
1671         out.push_back(this);
1672     }
1673     else
1674     {
1675         InternalType * _out = extract(&in);
1676         if (!_out)
1677         {
1678             std::wostringstream os;
1679             os << _W("Invalid index.") << std::endl;
1680             throw ast::InternalError(os.str(), 999, e.getLocation());
1681         }
1682         out.push_back(_out);
1683     }
1684
1685     return true;
1686 }
1687
1688 template<typename T>
1689 bool ArrayOf<T>::isInvokable() const
1690 {
1691     return true;
1692 }
1693
1694 template<typename T>
1695 bool ArrayOf<T>::hasInvokeOption() const
1696 {
1697     return false;
1698 }
1699
1700 template<typename T>
1701 int ArrayOf<T>::getInvokeNbIn()
1702 {
1703     return -1;
1704 }
1705
1706 template<typename T>
1707 int ArrayOf<T>::getInvokeNbOut()
1708 {
1709     return 1;
1710 }
1711
1712
1713 // used to allow definition of ArrayOf methode in this cpp file.
1714 template class EXTERN_AST ArrayOf < char >;
1715 template class EXTERN_AST ArrayOf < unsigned char >;
1716 template class EXTERN_AST ArrayOf < short >;
1717 template class EXTERN_AST ArrayOf < unsigned short >;
1718 template class EXTERN_AST ArrayOf < int >;
1719 template class EXTERN_AST ArrayOf < unsigned int >;
1720 template class EXTERN_AST ArrayOf < long long >;
1721 template class EXTERN_AST ArrayOf < unsigned long long >;
1722 template class EXTERN_AST ArrayOf < double >;
1723 template class EXTERN_AST ArrayOf < wchar_t* >;
1724 template class EXTERN_AST ArrayOf < SinglePoly* >;
1725 template class EXTERN_AST ArrayOf < SingleStruct* >;
1726 template class EXTERN_AST ArrayOf < InternalType* >; // Cell
1727 }