2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
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.
20 #include "listinsert.hxx"
21 #include "types_tools.hxx"
22 #include "localization.hxx"
23 #include "scilabWrite.hxx"
24 #include "types_tools.hxx"
25 #include "function.hxx"
28 #include "inspector.hxx"
33 #include "os_string.h"
39 ** Constructor & Destructor (public)
41 List::List() : Container()
43 m_plData = new std::vector<InternalType *>();
45 Inspector::addItem(this);
51 if (isDeletable() == true)
53 for (auto data : *m_plData)
61 Inspector::removeItem(this);
66 ** Private Copy Constructor and data Access
68 List::List(List *_oListCopyMe)
70 m_plData = new std::vector<InternalType *>;
71 std::vector<InternalType *>* lData = _oListCopyMe->getData();
72 int size = lData->size();
73 for (int i = 0 ; i < size ; i++)
78 m_iSize = static_cast<int>(size);
80 Inspector::addItem(this);
84 std::vector<InternalType *> *List::getData()
89 bool List::getMemory(long long* _piSize, long long* _piSizePlusType)
93 for (auto pData : *m_plData)
96 if (pData->getMemory(&piS, &piSPT))
99 *_piSizePlusType += piSPT;
103 *_piSizePlusType += sizeof(List);
109 ** Return the number of elements in list
111 int List::getSize() const
113 return static_cast<int>(m_plData->size());
117 ** append(InternalType *_typedValue)
118 ** Append the given value to the end of the List
120 List* List::append(InternalType *_typedValue)
122 List* pIT = checkRef(this, &List::append, _typedValue);
128 _typedValue->IncreaseRef();
129 m_plData->push_back(_typedValue);
130 m_iSize = static_cast<int>(m_plData->size());
136 ** Create a new List and Copy all values.
140 return new List(this);
144 ** toString to display Lists
146 bool List::toString(std::wostringstream& ostr)
151 ostr << L" ()" << std::endl;
155 wchar_t* wcsVarName = os_wcsdup(ostr.str().c_str());
157 for (auto val : *m_plData)
159 std::wostringstream nextVarName;
161 nextVarName << " " << SPACES_LIST << wcsVarName << L"(" << iPosition++ << L")";
162 ostr << std::endl << nextVarName.str() << std::endl << std::endl;
163 scilabForcedWriteW(ostr.str().c_str());
164 if (VariableToString(val, nextVarName.str().c_str()) == types::Function::Error)
179 InternalType* List::extract(typed_list* _pArgs)
181 List* outList = new List();
183 if (_pArgs->size() != 1)
189 int iDims = (int)_pArgs->size();
191 int* piMaxDim = new int[iDims];
192 int* piCountDim = new int[iDims];
194 //evaluate each argument and replace by appropriate value and compute the count of combinations
195 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
199 for (int i = 0 ; i < iSeqCount ; i++)
201 int idx = (int)pArg[0]->getAs<Double>()->get(i);
202 if (idx > getSize() || idx < 1)
208 InternalType* pIT = (*m_plData)[idx - 1];
209 outList->set(i, pIT);
213 cleanIndexesArguments(_pArgs, &pArg);
218 List* List::insert(typed_list* _pArgs, InternalType* _pSource)
221 if (_pArgs->size() != 1)
226 List* pIT = checkRef(this, &List::insert, _pArgs, _pSource);
233 int iDims = (int)_pArgs->size();
235 int* piMaxDim = new int[iDims];
236 int* piCountDim = new int[iDims];
238 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
244 cleanIndexesArguments(_pArgs, &pArg);
248 else if (iSeqCount > 1)
251 cleanIndexesArguments(_pArgs, &pArg);
252 std::wostringstream os;
253 os << _W("Unable to insert multiple item in a list.\n");
254 throw ast::InternalError(os.str());
256 else if (iSeqCount < 0)
259 cleanIndexesArguments(_pArgs, &pArg);
263 int idx = (int)pArg[0]->getAs<Double>()->get(0);
264 if (_pSource->isListDelete())
270 cleanIndexesArguments(_pArgs, &pArg);
274 else if (idx <= (int)m_plData->size())
276 InternalType* pIT = (*m_plData)[idx - 1];
282 m_plData->erase(m_plData->begin() + idx - 1);
285 else if (_pSource->isListInsert())
291 cleanIndexesArguments(_pArgs, &pArg);
292 std::wostringstream os;
293 os << _W("Index out of bounds.\n");
294 throw ast::InternalError(os.str());
297 InternalType* pInsert = _pSource->getAs<ListInsert>()->getInsert();
298 pInsert->IncreaseRef();
299 if (idx > (int)m_plData->size())
301 //try to insert after the last index, increase list size and assign value
302 while ((int)m_plData->size() < idx)
304 //incease list size and fill with Void type object
305 m_plData->push_back(new types::Void());
307 (*m_plData)[idx - 1] = pInsert;
311 m_plData->insert(m_plData->begin() + idx - 1, pInsert);
316 //special case to insert at the first position
317 _pSource->IncreaseRef();
318 m_plData->insert(m_plData->begin(), _pSource);
322 while ((int)m_plData->size() < idx)
324 //incease list size and fill with Void type object
325 InternalType* pLU = new types::Void();
327 m_plData->push_back(pLU);
330 InternalType* pIT = (*m_plData)[idx - 1];
332 (*m_plData)[idx - 1] = _pSource;
333 (*m_plData)[idx - 1]->IncreaseRef();
339 m_iSize = (int)m_plData->size();
342 cleanIndexesArguments(_pArgs, &pArg);
347 InternalType* List::get(const int _iIndex)
349 if (_iIndex >= 0 && _iIndex < (int)m_plData->size())
351 return (*m_plData)[_iIndex];
356 List* List::set(const int _iIndex, InternalType* _pIT)
363 List* pIT = checkRef(this, &List::set, _iIndex, _pIT);
369 while ((int)m_plData->size() < _iIndex)
371 //incease list size and fill with Void type object
372 m_plData->push_back(new types::Void());
373 m_plData->back()->IncreaseRef();
377 if ((int)m_plData->size() == _iIndex)
380 m_plData->push_back(_pIT);
385 InternalType* pOld = (*m_plData)[_iIndex];
388 (*m_plData)[_iIndex] = _pIT;
390 //manage ref on the old value
401 bool List::operator==(const InternalType& it)
403 if (const_cast<InternalType &>(it).isList() == false)
408 List* plst = const_cast<InternalType &>(it).getAs<List>();
410 if (getSize() != plst->getSize())
415 for (int i = 0; i < getSize(); i++)
417 if (*(*m_plData)[i] != *plst->get(i))