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