2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
16 #ifndef __ARRAYOF_HXX__
17 #define __ARRAYOF_HXX__
26 #include "scilabexception.hxx"
27 #include "inspector.hxx"
31 #include "core_math.h"
32 #include "localization.h"
33 #include "os_string.h"
40 class ArrayOf : public GenericType
50 ArrayOf() : GenericType(), m_pRealData(NULL), m_pImgData(NULL) {}
58 /*internal constructor*/
59 void create(const int* _piDims, int _iDims, T** _pRealData, T** _pImgData)
64 //reduce dims if it's possible
65 for (int i = _iDims - 1 ; i > 1 ; i--)
69 //remove dimension equal to 1
78 //m_piDims = new int[m_iDims];
81 if (m_iDims == 2 && _piDims[0] == -1 && _piDims[1] == -1)
90 for (int i = 0 ; i < m_iDims ; i++)
92 // if one of dim is null, create an empty matrix
102 m_piDims[i] = _piDims[i];
105 ** Manage overflow on size
106 ** a = b * c is in overflow if a / b != c
107 ** check b is not 0 (empty matrix case)
109 int iTmpSize = m_iSize * m_piDims[i];
110 if (m_iSize != 0 && iTmpSize / m_iSize != m_piDims[i])
114 humanReadableByteCount(((size_t) m_iSize) * ((size_t) m_piDims[i]) * sizeof(T), byteString);
115 os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
116 throw ast::InternalError(message);
127 os_sprintf(message, _("Can not allocate negative size (%d).\n"), m_iSize);
128 throw ast::InternalError(message);
138 m_pRealData = allocData(m_iSize);
139 *_pRealData = m_pRealData;
148 m_pImgData = allocData(m_iSize);
149 *_pImgData = m_pImgData;
156 catch (std::bad_alloc & /*e*/)
160 humanReadableByteCount(((size_t) m_iSize) * sizeof(T), byteString);
161 os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
162 throw ast::InternalError(message);
165 m_iSizeMax = m_iSize;
166 m_iRows = m_piDims[0];
167 m_iCols = m_piDims[1];
170 virtual T getNullValue() = 0;
171 virtual ArrayOf<T>* createEmpty(int _iDims, int* _piDims, bool _bComplex = false) = 0;
172 virtual GenericType* createEmpty();
174 virtual T copyValue(T _data) = 0;
175 virtual T* allocData(int _iSize) = 0;
176 virtual void deleteAll() = 0;
177 virtual void deleteImg() = 0;
187 // The function is not write here because we needs to create a Bool which inherits from ArrayOf<int>
188 // so it will create a cyclic dependency... so the body of the function is in bool.hxx after the Bool definition.
189 virtual bool neg(InternalType *& out);
191 virtual bool isVector() //only one dim must be != 1
193 bool bFirstChance = false;
195 for (int i = 0 ; i < m_iDims ; i++)
197 if (m_piDims[i] != 1)
199 if (bFirstChance == true)
212 virtual bool isComplex()
214 return m_pImgData != NULL;
217 //type does not need to delete or clone ( int, double, ... )
218 virtual bool isNativeType()
223 virtual void fillDefaultValues()
225 int size = getSize();
226 T tNullVal = getNullValue();
229 for (int i = 0; i < size; ++i)
237 for (int i = 0; i < size; ++i)
243 deleteData(tNullVal);
246 virtual ArrayOf<T>* setComplex(bool _bComplex)
248 typedef ArrayOf<T>* (ArrayOf<T>::*setcplx_t)(bool);
249 ArrayOf<T>* pIT = checkRef(this, (setcplx_t)&ArrayOf<T>::setComplex, _bComplex);
255 if (_bComplex == false)
257 if (m_pImgData != NULL)
262 else // _bComplex == true
264 if (m_pImgData == NULL)
266 m_pImgData = allocData(m_iSize);
267 memset(m_pImgData, 0x00, sizeof(T) * m_iSize);
274 virtual ArrayOf<T>* set(int _iPos, const T _data)
276 if (m_pRealData == NULL || _iPos >= m_iSize)
281 typedef ArrayOf<T>* (ArrayOf<T>::*set_t)(int, T);
282 ArrayOf<T>* pIT = checkRef(this, (set_t)&ArrayOf<T>::set, _iPos, _data);
288 deleteData(m_pRealData[_iPos]);
289 m_pRealData[_iPos] = copyValue(_data);
293 virtual ArrayOf<T>* set(int _iRows, int _iCols, const T _data)
296 // piIndexes[0] = _iRows;
297 // piIndexes[1] = _iCols;
298 // return set(getIndex(piIndexes), _data);
299 return set(_iCols * getRows() + _iRows, _data);
302 virtual ArrayOf<T>* set(T* _pdata)
304 if (m_pRealData == NULL)
309 typedef ArrayOf<T>* (ArrayOf<T>::*set_t)(T*);
310 ArrayOf<T>* pIT = checkRef(this, (set_t)&ArrayOf<T>::set, _pdata);
316 for (int i = 0 ; i < m_iSize ; i++)
318 deleteData(m_pRealData[i]);
319 m_pRealData[i] = copyValue(_pdata[i]);
324 virtual ArrayOf<T>* set(const T* _pdata)
326 if (m_pRealData == NULL)
331 typedef ArrayOf<T>* (ArrayOf<T>::*set_t)(const T*);
332 ArrayOf<T>* pIT = checkRef(this, (set_t)&ArrayOf<T>::set, _pdata);
338 for (int i = 0 ; i < m_iSize ; i++)
340 deleteData(m_pRealData[i]);
341 m_pRealData[i] = copyValue(_pdata[i]);
347 inline T* get() const
352 inline T get(int _iPos)
356 return m_pRealData[_iPos];
361 inline T get(int _iRows, int _iCols)
363 int piIndexes[2] = {_iRows, _iCols};
364 return get(getIndex(piIndexes));
367 /*internal function to manage img part*/
368 ArrayOf<T>* setImg(int _iPos, T _data)
370 if (m_pImgData == NULL || _iPos >= m_iSize)
375 typedef ArrayOf<T>* (ArrayOf<T>::*setimg_t)(int, T);
376 ArrayOf<T>* pIT = checkRef(this, (setimg_t)&ArrayOf<T>::setImg, _iPos, _data);
382 m_pImgData[_iPos] = copyValue(_data);
387 ArrayOf<T>* setImg(int _iRows, int _iCols, T _data)
389 int piIndexes[2] = {_iRows, _iCols};
390 return setImg(getIndex(piIndexes), copyValue(_data));
393 ArrayOf<T>* setImg(T* _pdata)
395 if (m_pImgData == NULL)
400 typedef ArrayOf<T>* (ArrayOf<T>::*setimg_t)(T*);
401 ArrayOf<T>* pIT = checkRef(this, (setimg_t)&ArrayOf<T>::setImg, _pdata);
407 for (int i = 0 ; i < m_iSize ; i++)
409 m_pImgData[i] = copyValue(_pdata[i]);
416 ArrayOf<T>* setImg(const T* _pdata)
418 if (m_pImgData == NULL)
423 typedef ArrayOf<T>* (ArrayOf<T>::*setimg_t)(const T*);
424 ArrayOf<T>* pIT = checkRef(this, (setimg_t)&ArrayOf<T>::setImg, _pdata);
430 for (int i = 0 ; i < m_iSize ; i++)
432 m_pImgData[i] = copyValue(_pdata[i]);
438 inline T* getImg() const
443 inline T getImg(int _iPos)
447 return m_pImgData[_iPos];
452 inline T getImg(int _iRows, int _iCols)
454 int piIndexes[2] = {_iRows, _iCols};
455 return getImg(getIndex(piIndexes));
458 virtual ArrayOf<T>* insert(typed_list* _pArgs, InternalType* _pSource);
459 virtual ArrayOf<T>* append(int _iRows, int _iCols, InternalType* _poSource);
460 virtual ArrayOf<T>* resize(int* _piDims, int _iDims);
462 // return a GenericType because of [] wich is a types::Double (can't be a ArrayOf<char>)
463 virtual GenericType* remove(typed_list* _pArgs);
464 virtual GenericType* extract(typed_list* _pArgs);
465 virtual GenericType* insertNew(typed_list* _pArgs);
467 virtual bool invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e) override;
468 virtual bool isInvokable() const;
469 virtual bool hasInvokeOption() const;
470 virtual int getInvokeNbIn();
471 virtual int getInvokeNbOut();
473 virtual ArrayOf<T>* reshape(int _iNewRows, int _iNewCols)
475 int piDims[2] = {_iNewRows, _iNewCols};
476 return reshape(piDims, 2);
479 virtual ArrayOf<T>* reshape(int* _piDims, int _iDims);
482 virtual ArrayOf<T>* resize(int _iNewRows, int _iNewCols)
484 int piDims[2] = {_iNewRows, _iNewCols};
485 return resize(piDims, 2);
488 virtual void deleteData(T /*data*/)
492 /*dimensions functions*/
493 int getIndex(const int* _piIndexes)
497 for (int i = 0 ; i < m_iDims ; i++)
499 idx += _piIndexes[i] * iMult;
500 iMult *= m_piDims[i];
505 void getIndexes(int _iIndex, int* _piIndexes);
507 virtual bool getMemory(long long* _piSize, long long* _piSizePlusType);
509 void humanReadableByteCount(size_t n, char (&str)[9]);
511 ArrayOf<T>* getColumnValues(int _iPos)
513 ArrayOf<T>* pOut = NULL;
516 int piDims[2] = {m_iRows, 1};
517 pOut = createEmpty(2, piDims, m_pImgData != NULL);
518 T* pReal = pOut->get();
519 T* pImg = pOut->getImg();
520 for (int i = 0 ; i < m_iRows ; i++)
522 pReal[i] = copyValue(get(i, _iPos));
525 if (m_pImgData != NULL)
527 for (int i = 0 ; i < m_iRows ; i++)
529 pImg[i] = copyValue(getImg(i, _iPos));
536 virtual bool toString(std::wostringstream& ostr)
538 int* piDims = new int[m_iDims];
539 bool bFinish = parseSubMatrix(ostr, piDims, m_iDims, m_iDims - 1);
544 bool parseSubMatrix(std::wostringstream& ostr, int* _piDims, int _iDims, int _iDim)
546 bool bFinish = false;
549 //we have reach 2-dim matrix
551 if (m_iDims > 2 && m_bPrintFromStart)
553 //only print for dims > 2
555 for (int i = 2 ; i < _iDims ; i++)
557 ostr << L"," << (_piDims[i] + 1);
559 ostr << L")" << std::endl << std::endl;
562 //reset flag to print dims on next call
563 m_bPrintFromStart = true;
565 bFinish = subMatrixToString(ostr, _piDims, _iDims);
566 if (bFinish == false)
569 m_bPrintFromStart = false;
575 //draw, continue to dig
576 for (int i = m_iSavePrintState ; i < m_piDims[_iDim] ; i++)
579 bFinish = parseSubMatrix(ostr, _piDims, _iDims, _iDim - 1);
580 if (bFinish == false)
583 m_iSavePrintState = i;
588 //reset state to print from state
589 m_iSavePrintState = 0;
590 m_iRows1PrintState = 0;
591 m_iCols1PrintState = 0;
592 m_iRows2PrintState = 0;
593 m_iCols2PrintState = 0;
599 virtual bool subMatrixToString(std::wostringstream& ostr, int* _piDims, int _iDims) = 0;
601 virtual std::wstring toStringInLine()
603 std::wostringstream ostr;
606 for (int i = 0 ; i < m_iDims ; i++)
616 ostr << L" " << getTypeStr() << L"]";
623 #endif /* !__ARRAYOF_HXX__ */