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