Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / containers / Lists / DynamicList / DynamicListI.H
blob66da090c32b9fa99d0b0563cb5f5a9233223bb6a
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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()
31     List<T>(0),
32     capacity_(0)
34     List<T>::size(0);
38 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
39 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
41     const label nElem
44     List<T>(nElem),
45     capacity_(nElem)
47     // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
48     List<T>::size(0);
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
58     List<T>(lst),
59     capacity_(lst.size())
63 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
64 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
66     const UList<T>& lst
69     List<T>(lst),
70     capacity_(lst.size())
74 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
75 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
77     const UIndirectList<T>& lst
80     List<T>(lst),
81     capacity_(lst.size())
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
91     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()
101 const
103     return capacity_;
107 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
108 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity
110     const label nElem
113     label nextFree = List<T>::size();
114     capacity_ = nElem;
116     if (nextFree > capacity_)
117     {
118         // truncate addressed sizes too
119         nextFree = capacity_;
120     }
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
131     const label nElem
134     // allocate more capacity?
135     if (nElem > capacity_)
136     {
137 // TODO: convince the compiler that division by zero does not occur
138 //        if (SizeInc && (!SizeMult || !SizeDiv))
139 //        {
140 //            // resize with SizeInc as the granularity
141 //            capacity_ = nElem;
142 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
143 //            if (pad != SizeInc)
144 //            {
145 //                capacity_ += pad;
146 //            }
147 //        }
148 //        else
149         {
150             capacity_ = max
151             (
152                 nElem,
153                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
154             );
155         }
157         // adjust allocated size, leave addressed size untouched
158         label nextFree = List<T>::size();
159         List<T>::setSize(capacity_);
160         List<T>::size(nextFree);
161     }
165 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
166 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
168     const label nElem
171     // allocate more capacity?
172     if (nElem > capacity_)
173     {
174 // TODO: convince the compiler that division by zero does not occur
175 //        if (SizeInc && (!SizeMult || !SizeDiv))
176 //        {
177 //            // resize with SizeInc as the granularity
178 //            capacity_ = nElem;
179 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
180 //            if (pad != SizeInc)
181 //            {
182 //                capacity_ += pad;
183 //            }
184 //        }
185 //        else
186         {
187             capacity_ = max
188             (
189                 nElem,
190                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
191             );
192         }
194         List<T>::setSize(capacity_);
195     }
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
205     const label nElem,
206     const T& t
209     label nextFree = List<T>::size();
210     setSize(nElem);
212     // set new elements to constant value
213     while (nextFree < nElem)
214     {
215         this->operator[](nextFree++) = t;
216     }
220 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
221 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
223     const label nElem
226     this->setSize(nElem);
230 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
231 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
233     const label nElem,
234     const T& t
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()
244     List<T>::size(0);
248 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
249 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
251     List<T>::clear();
252     capacity_ = 0;
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)
262     {
263         // use the full list when resizing
264         List<T>::size(capacity_);
266         // the new size
267         capacity_ = nextFree;
268         List<T>::setSize(capacity_);
269         List<T>::size(nextFree);
270     }
271     return *this;
275 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
276 inline void
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>
285 inline void
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_;
293     lst.capacity_ = 0;
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
311     const T& t
314     const label elemI = List<T>::size();
315     setSize(elemI + 1);
317     this->operator[](elemI) = t;
318     return *this;
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
326     const UList<T>& lst
329     if (this == &lst)
330     {
331         FatalErrorIn
332         (
333             "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
334             "(const UList<T>&)"
335         )   << "attempted appending to self" << abort(FatalError);
336     }
338     label nextFree = List<T>::size();
339     setSize(nextFree + lst.size());
341     forAll(lst, elemI)
342     {
343         this->operator[](nextFree++) = lst[elemI];
344     }
345     return *this;
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());
359     forAll(lst, elemI)
360     {
361         this->operator[](nextFree++) = lst[elemI];
362     }
363     return *this;
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;
372     if (elemI < 0)
373     {
374         FatalErrorIn
375         (
376             "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
377         )   << "List is empty" << abort(FatalError);
378     }
380     const T& val = List<T>::operator[](elemI);
382     List<T>::size(elemI);
384     return val;
388 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
390 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
391 inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator()
393     const label elemI
396     if (elemI >= List<T>::size())
397     {
398         setSize(elemI + 1);
399     }
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=
408     const T& t
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
421     if (this == &lst)
422     {
423         FatalErrorIn
424         (
425             "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
426             "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
427         )   << "attempted assignment to self" << abort(FatalError);
428     }
430     if (capacity_ >= lst.size())
431     {
432         // can copy w/o reallocating, match initial size to avoid reallocation
433         List<T>::size(lst.size());
434         List<T>::operator=(lst);
435     }
436     else
437     {
438         // make everything available for the copy operation
439         List<T>::size(capacity_);
441         List<T>::operator=(lst);
442         capacity_ = List<T>::size();
443     }
447 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
448 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
450     const UList<T>& lst
453     if (capacity_ >= lst.size())
454     {
455         // can copy w/o reallocating, match initial size to avoid reallocation
456         List<T>::size(lst.size());
457         List<T>::operator=(lst);
458     }
459     else
460     {
461         // make everything available for the copy operation
462         List<T>::size(capacity_);
464         List<T>::operator=(lst);
465         capacity_ = List<T>::size();
466     }
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())
477     {
478         // can copy w/o reallocating, match initial size to avoid reallocation
479         List<T>::size(lst.size());
480         List<T>::operator=(lst);
481     }
482     else
483     {
484         // make everything available for the copy operation
485         List<T>::size(capacity_);
487         List<T>::operator=(lst);
488         capacity_ = List<T>::size();
489     }
492 // ************************************************************************* //