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