Replace Min, Max and Abs by std::min, std::max and std::abs
[scilab.git] / scilab / modules / ast / src / cpp / types / cell.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
4 *  Copyright (C) 2011 - DIGITEO - Antoine ELIAS
5 *
6 *  This file must be used under the terms of the CeCILL.
7 *  This source file is licensed as described in the file COPYING, which
8 *  you should have received as part of this distribution.  The terms
9 *  are also available at
10 *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11 *
12 */
13
14 #include <sstream>
15 #include <math.h>
16 #include "symbol.hxx"
17 #include "cell.hxx"
18 #include "double.hxx"
19 #include "list.hxx"
20 #include "colon.hxx"
21 #include "tostring_common.hxx"
22 #include "core_math.h"
23 #include "list.hxx"
24 #include "configvariable.hxx"
25
26 namespace types
27 {
28 /**
29 ** Constructor & Destructor (public)
30 */
31 Cell::Cell()
32 {
33     InternalType** pIT  = NULL;
34     int piDims[2] = {0, 0};
35     create(piDims, 2, &pIT, NULL);
36 }
37
38 Cell::Cell(int _iRows, int _iCols)
39 {
40     InternalType** pIT  = NULL;
41     int piDims[2] = {_iRows, _iCols};
42     create(piDims, 2, &pIT, NULL);
43     Double* pEmpty = Double::Empty();
44     for (int i = 0 ; i < getSize() ; i++)
45     {
46         pEmpty->IncreaseRef();
47         m_pRealData[i] = pEmpty;
48     }
49 }
50
51 Cell::Cell(int _iDims, int* _piDims)
52 {
53     InternalType** pIT  = NULL;
54     create(_piDims, _iDims, &pIT, NULL);
55     Double* pEmpty = Double::Empty();
56     for (int i = 0 ; i < getSize() ; i++)
57     {
58         pEmpty->IncreaseRef();
59         m_pRealData[i] = pEmpty;
60     }
61 }
62
63 Cell::~Cell()
64 {
65     if (isDeletable() == true)
66     {
67         for (int i = 0 ; i < getSize() ; i++)
68         {
69             m_pRealData[i]->DecreaseRef();
70             if (m_pRealData[i]->isDeletable())
71             {
72                 delete m_pRealData[i];
73             }
74         }
75     }
76 #ifndef NDEBUG
77     //Inspector::removeItem(this);
78 #endif
79 }
80
81 /**
82 ** Private Copy Constructor and data Access
83 */
84 Cell::Cell(Cell *_oCellCopyMe)
85 {
86     InternalType** pIT = NULL;
87     create(_oCellCopyMe->getDimsArray(), _oCellCopyMe->getDims(), &pIT, NULL);
88     for (int i = 0 ; i < getSize() ; i++)
89     {
90         m_pRealData[i] = NULL;
91     }
92
93     for (int i = 0 ; i < getSize() ; i++)
94     {
95         set(i, _oCellCopyMe->get(i)->clone());
96     }
97 #ifndef NDEBUG
98     //Inspector::addItem(this);
99 #endif
100 }
101
102 bool Cell::transpose(InternalType *& out)
103 {
104     if (isScalar())
105     {
106         out = clone();
107         return true;
108     }
109
110     if (m_iDims == 2)
111     {
112         Cell * pC = new Cell();
113         out = pC;
114         InternalType** pIT = NULL;
115         int piDims[2] = {getCols(), getRows()};
116         pC->create(piDims, 2, &pIT, NULL);
117
118         Transposition::transpose_clone(getRows(), getCols(), m_pRealData, pC->m_pRealData);
119
120         return true;
121     }
122
123     return false;
124 }
125
126 bool Cell::set(int _iRows, int _iCols, InternalType* _pIT)
127 {
128     if (_iRows < getRows() && _iCols < getCols())
129     {
130         return set(_iCols * getRows() + _iRows, _pIT);
131     }
132     return false;
133 }
134
135 bool Cell::set(int _iRows, int _iCols, const InternalType* _pIT)
136 {
137     if (_iRows < getRows() && _iCols < getCols())
138     {
139         return set(_iCols * getRows() + _iRows, _pIT);
140     }
141     return false;
142 }
143
144 bool Cell::set(int _iIndex, InternalType* _pIT)
145 {
146     if (m_pRealData[_iIndex] == _pIT)
147     {
148         return true;
149     }
150
151     if (_iIndex < getSize())
152     {
153         if (m_pRealData[_iIndex] != NULL)
154         {
155             m_pRealData[_iIndex]->DecreaseRef();
156             if (m_pRealData[_iIndex]->isDeletable())
157             {
158                 delete m_pRealData[_iIndex];
159             }
160         }
161
162         _pIT->IncreaseRef();
163         m_pRealData[_iIndex] = _pIT;
164         return true;
165     }
166     return false;
167 }
168
169 bool Cell::set(int _iIndex, const InternalType* _pIT)
170 {
171     if (_iIndex < getSize())
172     {
173         if (m_pRealData[_iIndex] != NULL)
174         {
175             m_pRealData[_iIndex]->DecreaseRef();
176             if (m_pRealData[_iIndex]->isDeletable())
177             {
178                 delete m_pRealData[_iIndex];
179             }
180         }
181
182         const_cast<InternalType*>(_pIT)->IncreaseRef();
183         m_pRealData[_iIndex] = const_cast<InternalType*>(_pIT);
184         return true;
185     }
186     return false;
187 }
188
189 bool Cell::set(InternalType** _pIT)
190 {
191     for (int i = 0 ; i < getSize() ; i++)
192     {
193         if (set(i, _pIT[i]) == false)
194         {
195             return false;
196         }
197     }
198     return true;
199 }
200
201 /**
202 ** Clone
203 ** Create a new Struct and Copy all values.
204 */
205 InternalType* Cell::clone()
206 {
207     return new Cell(this);
208 }
209
210 InternalType* Cell::getNullValue()
211 {
212     return Double::Empty();
213 }
214
215 Cell* Cell::createEmpty(int _iDims, int* _piDims, bool _bComplex)
216 {
217     return new Cell(_iDims, _piDims);
218 }
219
220 InternalType* Cell::copyValue(InternalType* _pData)
221 {
222     _pData->IncreaseRef();
223     return _pData;
224 }
225
226 void Cell::deleteAll()
227 {
228     for (int i = 0 ; i < getSize() ; i++)
229     {
230         m_pRealData[i]->DecreaseRef();
231         if (m_pRealData[i]->isDeletable())
232         {
233             delete m_pRealData[i];
234         }
235     }
236     delete[] m_pRealData;
237     m_pRealData = NULL;
238 }
239
240 void Cell::deleteImg()
241 {
242     return;
243 }
244
245 bool Cell::isEmpty()
246 {
247     if (getDims() == 2 && getRows() == 0 && getCols() == 0)
248     {
249         return true;
250     }
251     return false;
252 }
253
254 /**
255 ** toString to display Structs
256 ** FIXME : Find a better indentation process
257 */
258 bool Cell::subMatrixToString(std::wostringstream& ostr, int* _piDims, int _iDims)
259 {
260     int iPrecision = ConfigVariable::getFormatSize();
261
262     if (isEmpty())
263     {
264         ostr << L"   {}";
265     }
266     else
267     {
268         //max len for each column
269         int *piTypeLen = new int[getCols()];
270         int *piSizeLen = new int[getCols()];
271
272         memset(piTypeLen, 0x00, getCols() * sizeof(int));
273         memset(piSizeLen, 0x00, getCols() * sizeof(int));
274
275         for (int j = 0 ; j < getCols() ; j++)
276         {
277             for (int i = 0 ; i < getRows() ; i++)
278             {
279                 _piDims[0] = i;
280                 _piDims[1] = j;
281
282                 int iPos = getIndex(_piDims);
283                 InternalType* pIT = get(iPos);
284
285                 if (pIT->isAssignable())
286                 {
287                     //compute number of digits to write dimensions
288                     int iTypeLen = 0;
289                     if (pIT->getAs<GenericType>())
290                     {
291                         GenericType* pGT = pIT->getAs<GenericType>();
292                         for (int k = 0 ; k < pGT->getDims() ; k++)
293                         {
294                             iTypeLen += static_cast<int>(log10(static_cast<double>(pGT->getDimsArray()[k])) + 1);
295                         }
296                         piSizeLen[j] = std::max(piSizeLen[j], iTypeLen + (pGT->getDims() - 1));//add number of "x"
297                     }
298                     else
299                     {
300                         //types non derived from ArrayOf.
301                         int iSize = static_cast<int>(log10(static_cast<double>(pIT->getAs<GenericType>()->getRows())) + 1);
302                         piSizeLen[j] = std::max(piSizeLen[j], iSize);
303                     }
304                 }
305                 else
306                 {
307                     //no size so let a white space, size == 1
308                     piSizeLen[j] = std::max(piSizeLen[j], 1);
309                 }
310
311                 piTypeLen[j] = std::max(piTypeLen[j], static_cast<int>(pIT->getTypeStr().size()));
312             }
313         }
314
315         for (int i = 0 ; i < getRows() ; i++)
316         {
317             for (int j = 0 ; j < getCols() ; j++)
318             {
319                 _piDims[0] = i;
320                 _piDims[1] = j;
321                 int iPos = getIndex(_piDims);
322                 InternalType* pIT = get(iPos);
323
324                 ostr << L"  [";
325                 if (pIT->isAssignable())
326                 {
327                     if (pIT->isGenericType())
328                     {
329                         //"  ixjxkxl type   "
330                         GenericType* pGT = pIT->getAs<GenericType>();
331                         std::wostringstream ostemp;
332                         for (int k = 0 ; k < pGT->getDims() ; k++)
333                         {
334                             if (k != 0)
335                             {
336                                 ostemp << L"x";
337                             }
338                             ostemp << pGT->getDimsArray()[k];
339                         }
340                         configureStream(&ostr, piSizeLen[j], iPrecision, ' ');
341                         ostr << std::right << ostemp.str();
342                     }
343                     else
344                     {
345                         //" i   "
346                         configureStream(&ostr, piSizeLen[j], iPrecision, ' ');
347                         if (pIT->isList())
348                         {
349                             ostr << std::right << pIT->getAs<List>()->getSize();
350                         }
351                         else
352                         {
353                             ostr << std::right << 1;
354                         }
355                     }
356                 }
357                 else
358                 {
359                     configureStream(&ostr, piSizeLen[j], iPrecision, ' ');
360                     ostr << L"";//fill with space
361                 }
362                 ostr << L" ";
363                 configureStream(&ostr, piTypeLen[j], iPrecision, ' ');
364                 ostr << std::left << pIT->getTypeStr();
365                 ostr << L"]";
366             }
367             ostr << std::endl;
368         }
369
370         delete[] piSizeLen;
371         delete[] piTypeLen;
372     }
373     ostr << std::endl;
374     return true;
375 }
376
377 //bool Cell::append(int _iRows, int _iCols, Cell *_poSource)
378 //{
379 //    return true;
380 //}
381
382 bool Cell::operator==(const InternalType& it)
383 {
384     if (const_cast<InternalType &>(it).isCell())
385     {
386         return false;
387     }
388
389     Cell* pC = const_cast<InternalType &>(it).getAs<Cell>();
390
391     for (int i = 0 ; i < getDims() ; i++)
392     {
393         if (pC->getDimsArray()[i] != getDimsArray()[i])
394         {
395             return false;
396         }
397     }
398
399     for (int i = 0 ; i < getSize() ; i++)
400     {
401         if (get(i) != pC->get(i))
402         {
403             return false;
404         }
405     }
406     return true;
407 }
408
409 bool Cell::operator!=(const InternalType& it)
410 {
411     return !(*this == it);
412 }
413
414 List* Cell::extractCell(typed_list* _pArgs)
415 {
416     InternalType* pIT = extract(_pArgs);
417     if (pIT->isCell() == false)
418     {
419         return NULL;
420     }
421
422     List* pList = new List();
423
424     Cell* pCell = pIT->getAs<Cell>();
425     for (int i = 0 ; i < pCell->getSize() ; i++)
426     {
427         pList->append(pCell->get(i));
428     }
429     delete pCell;
430     return pList;
431 }
432
433 Cell* Cell::insertCell(typed_list* _pArgs, InternalType* _pSource)
434 {
435     Cell* pCell = new Cell(1, 1);
436     pCell->set(0, _pSource);
437     Cell* pOut = insert(_pArgs, pCell)->getAs<Cell>();
438     return pOut;
439 }
440
441 Cell* Cell::insertNewCell(typed_list* _pArgs, InternalType* _pSource)
442 {
443     Cell* pCell = new Cell(1, 1);
444     pCell->set(0, _pSource);
445     Cell* pOut = Cell::insertNew(_pArgs, pCell)->getAs<Cell>();
446     return pOut;
447 }
448
449 InternalType** Cell::allocData(int _iSize)
450 {
451     InternalType** pData = new InternalType*[_iSize];
452     Double* pEmpty = Double::Empty();
453     for (int i = 0 ; i < _iSize ; i++)
454     {
455         pEmpty->IncreaseRef();
456         pData[i] = pEmpty;
457     }
458     return pData;
459 }
460 }