initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / containers / Lists / DynamicList / DynamicListI.H
blob4e0ffbd1fdeaa30382a39c1e260d8cbf7a8da86b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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 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
19     for more details.
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()
32     List<T>(SizeInc),
33     capacity_(SizeInc)
35     List<T>::size(0);
39 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
40 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
42     const label nElem
45     List<T>(nElem),
46     capacity_(nElem)
48     // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
49     List<T>::size(0);
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
59     List<T>(lst),
60     capacity_(lst.size())
64 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
65 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
67     const UList<T>& lst
70     List<T>(lst),
71     capacity_(lst.size())
75 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
76 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
78     const UIndirectList<T>& lst
81     List<T>(lst),
82     capacity_(lst.size())
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
92     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()
102 const
104     return capacity_;
108 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
109 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity
111     const label nElem
114     label nextFree = List<T>::size();
115     capacity_ = nElem;
117     if (nextFree > capacity_)
118     {
119         // truncate addressed sizes too
120         nextFree = capacity_;
121     }
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
132     const label nElem
135     // allocate more capacity?
136     if (nElem > capacity_)
137     {
138 // TODO: convince the compiler that division by zero does not occur
139 //        if (SizeInc && (!SizeMult || !SizeDiv))
140 //        {
141 //            // resize with SizeInc as the granularity
142 //            capacity_ = nElem;
143 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
144 //            if (pad != SizeInc)
145 //            {
146 //                capacity_ += pad;
147 //            }
148 //        }
149 //        else
150         {
151             capacity_ = max
152             (
153                 nElem,
154                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
155             );
156         }
158         // adjust allocated size, leave addressed size untouched
159         label nextFree = List<T>::size();
160         List<T>::setSize(capacity_);
161         List<T>::size(nextFree);
162     }
166 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
167 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
169     const label nElem
172     // allocate more capacity?
173     if (nElem > capacity_)
174     {
175 // TODO: convince the compiler that division by zero does not occur
176 //        if (SizeInc && (!SizeMult || !SizeDiv))
177 //        {
178 //            // resize with SizeInc as the granularity
179 //            capacity_ = nElem;
180 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
181 //            if (pad != SizeInc)
182 //            {
183 //                capacity_ += pad;
184 //            }
185 //        }
186 //        else
187         {
188             capacity_ = max
189             (
190                 nElem,
191                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
192             );
193         }
195         List<T>::setSize(capacity_);
196     }
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
206     const label nElem,
207     const T& t
210     label nextFree = List<T>::size();
211     setSize(nElem);
213     // set new elements to constant value
214     while (nextFree < nElem)
215     {
216         this->operator[](nextFree++) = t;
217     }
221 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
222 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
224     const label nElem
227     this->setSize(nElem);
231 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
232 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
234     const label nElem,
235     const T& t
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()
245     List<T>::size(0);
249 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
250 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
252     List<T>::clear();
253     capacity_ = 0;
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)
263     {
264         // use the full list when resizing
265         List<T>::size(capacity_);
267         // the new size
268         capacity_ = nextFree;
269         List<T>::setSize(capacity_);
270         List<T>::size(nextFree);
271     }
272     return *this;
276 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
277 inline void
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>
286 inline void
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_;
294     lst.capacity_ = 0;
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
311     const T& t
314     label elemI = List<T>::size();
315     setSize(elemI + 1);
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
324     const UList<T>& lst
327     if (this == &lst)
328     {
329         FatalErrorIn
330         (
331             "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
332             "(const UList<T>&)"
333         )   << "attempted appending to self" << abort(FatalError);
334     }
336     label nextFree = List<T>::size();
337     setSize(nextFree + lst.size());
339     forAll(lst, elemI)
340     {
341         this->operator[](nextFree++) = lst[elemI];
342     }
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());
355     forAll(lst, elemI)
356     {
357         this->operator[](nextFree++) = lst[elemI];
358     }
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;
367     if (elemI < 0)
368     {
369         FatalErrorIn
370         (
371             "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
372         )   << "List is empty" << abort(FatalError);
373     }
375     const T& val = List<T>::operator[](elemI);
377     List<T>::size(elemI);
379     return val;
383 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
385 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
386 inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator()
388     const label elemI
391     if (elemI >= List<T>::size())
392     {
393         setSize(elemI + 1);
394     }
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=
403     const T& t
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=
413     const UList<T>& lst
416     if (capacity_ >= lst.size())
417     {
418         // can copy w/o reallocating, match initial size to avoid reallocation
419         List<T>::size(lst.size());
420         List<T>::operator=(lst);
421     }
422     else
423     {
424         // make everything available for the copy operation
425         List<T>::size(capacity_);
427         List<T>::operator=(lst);
428         capacity_ = List<T>::size();
429     }
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
439     if (this == &lst)
440     {
441         FatalErrorIn
442         (
443             "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
444             "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
445         )   << "attempted assignment to self" << abort(FatalError);
446     }
448     if (capacity_ >= lst.size())
449     {
450         // can copy w/o reallocating, match initial size to avoid reallocation
451         List<T>::size(lst.size());
452         List<T>::operator=(lst);
453     }
454     else
455     {
456         // make everything available for the copy operation
457         List<T>::size(capacity_);
459         List<T>::operator=(lst);
460         capacity_ = List<T>::size();
461     }
465 // ************************************************************************* //