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