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