1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
30 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
39 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
40 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
48 // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
53 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
54 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
56 const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
64 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
65 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
75 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
76 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
78 const UIndirectList<T>& lst
86 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
87 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
89 const Xfer<List<T> >& lst
93 capacity_(List<T>::size())
98 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
100 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
101 inline Foam::label Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::capacity()
108 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
109 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity
114 label nextFree = List<T>::size();
117 if (nextFree > capacity_)
119 // truncate addressed sizes too
120 nextFree = capacity_;
122 // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
124 List<T>::setSize(capacity_);
125 List<T>::size(nextFree);
129 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
130 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::reserve
135 // allocate more capacity?
136 if (nElem > capacity_)
138 // TODO: convince the compiler that division by zero does not occur
139 // if (SizeInc && (!SizeMult || !SizeDiv))
141 // // resize with SizeInc as the granularity
142 // capacity_ = nElem;
143 // unsigned pad = SizeInc - (capacity_ % SizeInc);
144 // if (pad != SizeInc)
154 label(SizeInc + capacity_ * SizeMult / SizeDiv)
158 // adjust allocated size, leave addressed size untouched
159 label nextFree = List<T>::size();
160 List<T>::setSize(capacity_);
161 List<T>::size(nextFree);
166 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
167 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
172 // allocate more capacity?
173 if (nElem > capacity_)
175 // TODO: convince the compiler that division by zero does not occur
176 // if (SizeInc && (!SizeMult || !SizeDiv))
178 // // resize with SizeInc as the granularity
179 // capacity_ = nElem;
180 // unsigned pad = SizeInc - (capacity_ % SizeInc);
181 // if (pad != SizeInc)
191 label(SizeInc + capacity_ * SizeMult / SizeDiv)
195 List<T>::setSize(capacity_);
198 // adjust addressed size
199 List<T>::size(nElem);
203 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
204 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
210 label nextFree = List<T>::size();
213 // set new elements to constant value
214 while (nextFree < nElem)
216 this->operator[](nextFree++) = t;
221 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
222 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
227 this->setSize(nElem);
231 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
232 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
238 this->setSize(nElem, t);
242 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
243 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clear()
249 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
250 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
257 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
258 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
259 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink()
261 label nextFree = List<T>::size();
262 if (capacity_ > nextFree)
264 // use the full list when resizing
265 List<T>::size(capacity_);
268 capacity_ = nextFree;
269 List<T>::setSize(capacity_);
270 List<T>::size(nextFree);
276 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
278 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst)
280 capacity_ = lst.size();
281 List<T>::transfer(lst); // take over storage, clear addressing for lst.
285 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
287 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer
289 DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
292 // take over storage as-is (without shrink), clear addressing for lst.
293 capacity_ = lst.capacity_;
296 List<T>::transfer(static_cast<List<T>&>(lst));
300 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
301 inline Foam::Xfer< Foam::List<T> >
302 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::xfer()
304 return xferMoveTo< List<T> >(*this);
308 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
309 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
314 label elemI = List<T>::size();
317 this->operator[](elemI) = t;
321 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
322 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
331 "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
333 ) << "attempted appending to self" << abort(FatalError);
336 label nextFree = List<T>::size();
337 setSize(nextFree + lst.size());
341 this->operator[](nextFree++) = lst[elemI];
346 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
347 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
349 const UIndirectList<T>& lst
352 label nextFree = List<T>::size();
353 setSize(nextFree + lst.size());
357 this->operator[](nextFree++) = lst[elemI];
362 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
363 inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()
365 label elemI = List<T>::size() - 1;
371 "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
372 ) << "List is empty" << abort(FatalError);
375 const T& val = List<T>::operator[](elemI);
377 List<T>::size(elemI);
383 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
385 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
386 inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator()
391 if (elemI >= List<T>::size())
396 return this->operator[](elemI);
400 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
401 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
406 UList<T>::operator=(t);
410 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
411 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
416 if (capacity_ >= lst.size())
418 // can copy w/o reallocating, match initial size to avoid reallocation
419 List<T>::size(lst.size());
420 List<T>::operator=(lst);
424 // make everything available for the copy operation
425 List<T>::size(capacity_);
427 List<T>::operator=(lst);
428 capacity_ = List<T>::size();
433 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
434 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
436 const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
443 "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
444 "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
445 ) << "attempted assignment to self" << abort(FatalError);
448 if (capacity_ >= lst.size())
450 // can copy w/o reallocating, match initial size to avoid reallocation
451 List<T>::size(lst.size());
452 List<T>::operator=(lst);
456 // make everything available for the copy operation
457 List<T>::size(capacity_);
459 List<T>::operator=(lst);
460 capacity_ = List<T>::size();
465 // ************************************************************************* //