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