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