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