FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

DynamicListI.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00027 
00028 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00029 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
00030 :
00031     List<T>(SizeInc),
00032     capacity_(SizeInc)
00033 {
00034     List<T>::size(0);
00035 }
00036 
00037 
00038 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00039 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
00040 (
00041     const label nElem
00042 )
00043 :
00044     List<T>(nElem),
00045     capacity_(nElem)
00046 {
00047     // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
00048     List<T>::size(0);
00049 }
00050 
00051 
00052 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00053 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
00054 (
00055     const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
00056 )
00057 :
00058     List<T>(lst),
00059     capacity_(lst.size())
00060 {}
00061 
00062 
00063 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00064 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
00065 (
00066     const UList<T>& lst
00067 )
00068 :
00069     List<T>(lst),
00070     capacity_(lst.size())
00071 {}
00072 
00073 
00074 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00075 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
00076 (
00077     const UIndirectList<T>& lst
00078 )
00079 :
00080     List<T>(lst),
00081     capacity_(lst.size())
00082 {}
00083 
00084 
00085 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00086 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
00087 (
00088     const Xfer<List<T> >& lst
00089 )
00090 :
00091     List<T>(lst),
00092     capacity_(List<T>::size())
00093 {}
00094 
00095 
00096 
00097 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00098 
00099 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00100 inline Foam::label Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::capacity()
00101 const
00102 {
00103     return capacity_;
00104 }
00105 
00106 
00107 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00108 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity
00109 (
00110     const label nElem
00111 )
00112 {
00113     label nextFree = List<T>::size();
00114     capacity_ = nElem;
00115 
00116     if (nextFree > capacity_)
00117     {
00118         // truncate addressed sizes too
00119         nextFree = capacity_;
00120     }
00121     // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
00122 
00123     List<T>::setSize(capacity_);
00124     List<T>::size(nextFree);
00125 }
00126 
00127 
00128 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00129 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::reserve
00130 (
00131     const label nElem
00132 )
00133 {
00134     // allocate more capacity?
00135     if (nElem > capacity_)
00136     {
00137 // TODO: convince the compiler that division by zero does not occur
00138 //        if (SizeInc && (!SizeMult || !SizeDiv))
00139 //        {
00140 //            // resize with SizeInc as the granularity
00141 //            capacity_ = nElem;
00142 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
00143 //            if (pad != SizeInc)
00144 //            {
00145 //                capacity_ += pad;
00146 //            }
00147 //        }
00148 //        else
00149         {
00150             capacity_ = max
00151             (
00152                 nElem,
00153                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
00154             );
00155         }
00156 
00157         // adjust allocated size, leave addressed size untouched
00158         label nextFree = List<T>::size();
00159         List<T>::setSize(capacity_);
00160         List<T>::size(nextFree);
00161     }
00162 }
00163 
00164 
00165 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00166 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
00167 (
00168     const label nElem
00169 )
00170 {
00171     // allocate more capacity?
00172     if (nElem > capacity_)
00173     {
00174 // TODO: convince the compiler that division by zero does not occur
00175 //        if (SizeInc && (!SizeMult || !SizeDiv))
00176 //        {
00177 //            // resize with SizeInc as the granularity
00178 //            capacity_ = nElem;
00179 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
00180 //            if (pad != SizeInc)
00181 //            {
00182 //                capacity_ += pad;
00183 //            }
00184 //        }
00185 //        else
00186         {
00187             capacity_ = max
00188             (
00189                 nElem,
00190                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
00191             );
00192         }
00193 
00194         List<T>::setSize(capacity_);
00195     }
00196 
00197     // adjust addressed size
00198     List<T>::size(nElem);
00199 }
00200 
00201 
00202 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00203 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
00204 (
00205     const label nElem,
00206     const T& t
00207 )
00208 {
00209     label nextFree = List<T>::size();
00210     setSize(nElem);
00211 
00212     // set new elements to constant value
00213     while (nextFree < nElem)
00214     {
00215         this->operator[](nextFree++) = t;
00216     }
00217 }
00218 
00219 
00220 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00221 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
00222 (
00223     const label nElem
00224 )
00225 {
00226     this->setSize(nElem);
00227 }
00228 
00229 
00230 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00231 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize
00232 (
00233     const label nElem,
00234     const T& t
00235 )
00236 {
00237     this->setSize(nElem, t);
00238 }
00239 
00240 
00241 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00242 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clear()
00243 {
00244     List<T>::size(0);
00245 }
00246 
00247 
00248 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00249 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
00250 {
00251     List<T>::clear();
00252     capacity_ = 0;
00253 }
00254 
00255 
00256 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00257 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
00258 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink()
00259 {
00260     label nextFree = List<T>::size();
00261     if (capacity_ > nextFree)
00262     {
00263         // use the full list when resizing
00264         List<T>::size(capacity_);
00265 
00266         // the new size
00267         capacity_ = nextFree;
00268         List<T>::setSize(capacity_);
00269         List<T>::size(nextFree);
00270     }
00271     return *this;
00272 }
00273 
00274 
00275 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00276 inline void
00277 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst)
00278 {
00279     capacity_ = lst.size();
00280     List<T>::transfer(lst);   // take over storage, clear addressing for lst.
00281 }
00282 
00283 
00284 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00285 inline void
00286 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer
00287 (
00288     DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
00289 )
00290 {
00291     // take over storage as-is (without shrink), clear addressing for lst.
00292     capacity_ = lst.capacity_;
00293     lst.capacity_ = 0;
00294 
00295     List<T>::transfer(static_cast<List<T>&>(lst));
00296 }
00297 
00298 
00299 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00300 inline Foam::Xfer< Foam::List<T> >
00301 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::xfer()
00302 {
00303     return xferMoveTo< List<T> >(*this);
00304 }
00305 
00306 
00307 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00308 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
00309 (
00310     const T& t
00311 )
00312 {
00313     label elemI = List<T>::size();
00314     setSize(elemI + 1);
00315 
00316     this->operator[](elemI) = t;
00317 }
00318 
00319 
00320 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00321 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
00322 (
00323     const UList<T>& lst
00324 )
00325 {
00326     if (this == &lst)
00327     {
00328         FatalErrorIn
00329         (
00330             "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
00331             "(const UList<T>&)"
00332         )   << "attempted appending to self" << abort(FatalError);
00333     }
00334 
00335     label nextFree = List<T>::size();
00336     setSize(nextFree + lst.size());
00337 
00338     forAll(lst, elemI)
00339     {
00340         this->operator[](nextFree++) = lst[elemI];
00341     }
00342 }
00343 
00344 
00345 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00346 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
00347 (
00348     const UIndirectList<T>& lst
00349 )
00350 {
00351     label nextFree = List<T>::size();
00352     setSize(nextFree + lst.size());
00353 
00354     forAll(lst, elemI)
00355     {
00356         this->operator[](nextFree++) = lst[elemI];
00357     }
00358 }
00359 
00360 
00361 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00362 inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()
00363 {
00364     label elemI = List<T>::size() - 1;
00365 
00366     if (elemI < 0)
00367     {
00368         FatalErrorIn
00369         (
00370             "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
00371         )   << "List is empty" << abort(FatalError);
00372     }
00373 
00374     const T& val = List<T>::operator[](elemI);
00375 
00376     List<T>::size(elemI);
00377 
00378     return val;
00379 }
00380 
00381 
00382 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00383 
00384 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00385 inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator()
00386 (
00387     const label elemI
00388 )
00389 {
00390     if (elemI >= List<T>::size())
00391     {
00392         setSize(elemI + 1);
00393     }
00394 
00395     return this->operator[](elemI);
00396 }
00397 
00398 
00399 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00400 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
00401 (
00402     const T& t
00403 )
00404 {
00405     UList<T>::operator=(t);
00406 }
00407 
00408 
00409 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00410 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
00411 (
00412     const UList<T>& lst
00413 )
00414 {
00415     if (capacity_ >= lst.size())
00416     {
00417         // can copy w/o reallocating, match initial size to avoid reallocation
00418         List<T>::size(lst.size());
00419         List<T>::operator=(lst);
00420     }
00421     else
00422     {
00423         // make everything available for the copy operation
00424         List<T>::size(capacity_);
00425 
00426         List<T>::operator=(lst);
00427         capacity_ = List<T>::size();
00428     }
00429 }
00430 
00431 
00432 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00433 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
00434 (
00435     const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
00436 )
00437 {
00438     if (this == &lst)
00439     {
00440         FatalErrorIn
00441         (
00442             "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
00443             "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
00444         )   << "attempted assignment to self" << abort(FatalError);
00445     }
00446 
00447     if (capacity_ >= lst.size())
00448     {
00449         // can copy w/o reallocating, match initial size to avoid reallocation
00450         List<T>::size(lst.size());
00451         List<T>::operator=(lst);
00452     }
00453     else
00454     {
00455         // make everything available for the copy operation
00456         List<T>::size(capacity_);
00457 
00458         List<T>::operator=(lst);
00459         capacity_ = List<T>::size();
00460     }
00461 }
00462 
00463 
00464 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines