1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
28 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
29 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
38 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
39 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
47 // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
52 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
53 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
55 const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
63 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
64 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
74 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
75 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
77 const UIndirectList<T>& lst
85 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
86 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
88 const Xfer<List<T> >& lst
92 capacity_(List<T>::size())
97 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
99 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
100 inline Foam::label Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::capacity()
107 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
108 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity
113 label nextFree = List<T>::size();
116 if (nextFree > capacity_)
118 // truncate addressed sizes too
119 nextFree = capacity_;
121 // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
123 List<T>::setSize(capacity_);
124 List<T>::size(nextFree);
128 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
129 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::reserve
134 // allocate more capacity?
135 if (nElem > capacity_)
137 // TODO: convince the compiler that division by zero does not occur
138 // if (SizeInc && (!SizeMult || !SizeDiv))
140 // // resize with SizeInc as the granularity
141 // capacity_ = nElem;
142 // unsigned pad = SizeInc - (capacity_ % SizeInc);
143 // if (pad != SizeInc)
153 label(SizeInc + capacity_ * SizeMult / SizeDiv)
157 // adjust allocated size, leave addressed size untouched
158 label nextFree = List<T>::size();
159 List<T>::setSize(capacity_);
160 List<T>::size(nextFree);
165 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
166 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
171 // allocate more capacity?
172 if (nElem > capacity_)
174 // TODO: convince the compiler that division by zero does not occur
175 // if (SizeInc && (!SizeMult || !SizeDiv))
177 // // resize with SizeInc as the granularity
178 // capacity_ = nElem;
179 // unsigned pad = SizeInc - (capacity_ % SizeInc);
180 // if (pad != SizeInc)
190 label(SizeInc + capacity_ * SizeMult / SizeDiv)
194 List<T>::setSize(capacity_);
197 // adjust addressed size
198 List<T>::size(nElem);
202 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
203 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
209 label nextFree = List<T>::size();
212 // set new elements to constant value
213 while (nextFree < nElem)
215 this->operator[](nextFree++) = t;
220 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
221 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
226 this->setSize(nElem);
230 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
231 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
237 this->setSize(nElem, t);
241 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
242 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clear()
248 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
249 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
256 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
257 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
258 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink()
260 label nextFree = List<T>::size();
261 if (capacity_ > nextFree)
263 // use the full list when resizing
264 List<T>::size(capacity_);
267 capacity_ = nextFree;
268 List<T>::setSize(capacity_);
269 List<T>::size(nextFree);
275 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
277 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst)
279 capacity_ = lst.size();
280 List<T>::transfer(lst); // take over storage, clear addressing for lst.
284 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
286 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer
288 DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
291 // take over storage as-is (without shrink), clear addressing for lst.
292 capacity_ = lst.capacity_;
295 List<T>::transfer(static_cast<List<T>&>(lst));
299 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
300 inline Foam::Xfer<Foam::List<T> >
301 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::xfer()
303 return xferMoveTo< List<T> >(*this);
307 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
308 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
309 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
314 const label elemI = List<T>::size();
317 this->operator[](elemI) = t;
322 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
323 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
324 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
333 "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
335 ) << "attempted appending to self" << abort(FatalError);
338 label nextFree = List<T>::size();
339 setSize(nextFree + lst.size());
343 this->operator[](nextFree++) = lst[elemI];
349 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
350 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
351 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
353 const UIndirectList<T>& lst
356 label nextFree = List<T>::size();
357 setSize(nextFree + lst.size());
361 this->operator[](nextFree++) = lst[elemI];
367 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
368 inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()
370 const label elemI = List<T>::size() - 1;
376 "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
377 ) << "List is empty" << abort(FatalError);
380 const T& val = List<T>::operator[](elemI);
382 List<T>::size(elemI);
388 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
390 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
391 inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator()
396 if (elemI >= List<T>::size())
401 return this->operator[](elemI);
405 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
406 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
411 UList<T>::operator=(t);
415 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
416 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
418 const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
425 "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
426 "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
427 ) << "attempted assignment to self" << abort(FatalError);
430 if (capacity_ >= lst.size())
432 // can copy w/o reallocating, match initial size to avoid reallocation
433 List<T>::size(lst.size());
434 List<T>::operator=(lst);
438 // make everything available for the copy operation
439 List<T>::size(capacity_);
441 List<T>::operator=(lst);
442 capacity_ = List<T>::size();
447 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
448 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
453 if (capacity_ >= lst.size())
455 // can copy w/o reallocating, match initial size to avoid reallocation
456 List<T>::size(lst.size());
457 List<T>::operator=(lst);
461 // make everything available for the copy operation
462 List<T>::size(capacity_);
464 List<T>::operator=(lst);
465 capacity_ = List<T>::size();
470 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
471 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
473 const UIndirectList<T>& lst
476 if (capacity_ >= lst.size())
478 // can copy w/o reallocating, match initial size to avoid reallocation
479 List<T>::size(lst.size());
480 List<T>::operator=(lst);
484 // make everything available for the copy operation
485 List<T>::size(capacity_);
487 List<T>::operator=(lst);
488 capacity_ = List<T>::size();
492 // ************************************************************************* //