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

List.C

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 #include <OpenFOAM/List.H>
00027 #include <OpenFOAM/ListLoopM.H>
00028 
00029 #include <OpenFOAM/FixedList.H>
00030 #include <OpenFOAM/PtrList.H>
00031 #include <OpenFOAM/SLList.H>
00032 #include <OpenFOAM/IndirectList.H>
00033 #include <OpenFOAM/UIndirectList.H>
00034 #include <OpenFOAM/BiIndirectList.H>
00035 #include <OpenFOAM/contiguous.H>
00036 
00037 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00038 
00039 // * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * //
00040 
00041 // Construct with length specified
00042 template<class T>
00043 Foam::List<T>::List(const label s)
00044 :
00045     UList<T>(NULL, s)
00046 {
00047     if (this->size_ < 0)
00048     {
00049         FatalErrorIn("List<T>::List(const label size)")
00050             << "bad size " << this->size_
00051             << abort(FatalError);
00052     }
00053 
00054     if (this->size_)
00055     {
00056         this->v_ = new T[this->size_];
00057     }
00058 }
00059 
00060 
00061 // Construct with length and single value specified
00062 template<class T>
00063 Foam::List<T>::List(const label s, const T& a)
00064 :
00065     UList<T>(NULL, s)
00066 {
00067     if (this->size_ < 0)
00068     {
00069         FatalErrorIn("List<T>::List(const label size, const T&)")
00070             << "bad size " << this->size_
00071             << abort(FatalError);
00072     }
00073 
00074     if (this->size_)
00075     {
00076         this->v_ = new T[this->size_];
00077 
00078         List_ACCESS(T, (*this), vp);
00079         List_FOR_ALL((*this), i)
00080             List_ELEM((*this), vp, i) = a;
00081         List_END_FOR_ALL
00082     }
00083 }
00084 
00085 
00086 // Construct as copy
00087 template<class T>
00088 Foam::List<T>::List(const List<T>& a)
00089 :
00090     UList<T>(NULL, a.size_)
00091 {
00092     if (this->size_)
00093     {
00094         this->v_ = new T[this->size_];
00095 
00096 #       ifdef USEMEMCPY
00097         if (contiguous<T>())
00098         {
00099             memcpy(this->v_, a.v_, this->byteSize());
00100         }
00101         else
00102 #       endif
00103         {
00104             List_ACCESS(T, (*this), vp);
00105             List_CONST_ACCESS(T, a, ap);
00106             List_FOR_ALL((*this), i)
00107                 List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
00108             List_END_FOR_ALL
00109         }
00110     }
00111 }
00112 
00113 
00114 // Construct by transferring the parameter contents
00115 template<class T>
00116 Foam::List<T>::List(const Xfer< List<T> >& lst)
00117 {
00118     transfer(lst());
00119 }
00120 
00121 
00122 // Construct as copy or re-use as specified.
00123 template<class T>
00124 Foam::List<T>::List(List<T>& a, bool reUse)
00125 :
00126     UList<T>(NULL, a.size_)
00127 {
00128     if (reUse)
00129     {
00130         this->v_ = a.v_;
00131         a.v_ = 0;
00132         a.size_ = 0;
00133     }
00134     else if (this->size_)
00135     {
00136         this->v_ = new T[this->size_];
00137 
00138 #       ifdef USEMEMCPY
00139         if (contiguous<T>())
00140         {
00141             memcpy(this->v_, a.v_, this->byteSize());
00142         }
00143         else
00144 #       endif
00145         {
00146             List_ACCESS(T, (*this), vp);
00147             List_CONST_ACCESS(T, a, ap);
00148             List_FOR_ALL((*this), i)
00149                 List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
00150             List_END_FOR_ALL
00151         }
00152     }
00153 }
00154 
00155 
00156 // Construct as subset
00157 template<class T>
00158 Foam::List<T>::List(const UList<T>& a, const unallocLabelList& map)
00159 :
00160     UList<T>(NULL, map.size())
00161 {
00162     if (this->size_)
00163     {
00164         // Note:cannot use List_ELEM since third argument has to be index.
00165 
00166         this->v_ = new T[this->size_];
00167 
00168         forAll(*this, i)
00169         {
00170             this->v_[i] = a[map[i]];
00171         }
00172     }
00173 }
00174 
00175 
00176 // Construct given start and end iterators.
00177 template<class T>
00178 template<class InputIterator>
00179 Foam::List<T>::List(InputIterator first, InputIterator last)
00180 {
00181     label s = 0;
00182     for
00183     (
00184         InputIterator iter = first;
00185         iter != last;
00186         ++iter
00187     )
00188     {
00189         s++;
00190     }
00191 
00192     setSize(s);
00193 
00194     s = 0;
00195 
00196     for
00197     (
00198         InputIterator iter = first;
00199         iter != last;
00200         ++iter
00201     )
00202     {
00203         this->operator[](s++) = iter();
00204     }
00205 }
00206 
00207 
00208 // Construct as copy of FixedList<T, Size>
00209 template<class T>
00210 template<unsigned Size>
00211 Foam::List<T>::List(const FixedList<T, Size>& lst)
00212 :
00213     UList<T>(NULL, Size)
00214 {
00215     if (this->size_)
00216     {
00217         this->v_ = new T[this->size_];
00218 
00219         forAll(*this, i)
00220         {
00221             this->operator[](i) = lst[i];
00222         }
00223     }
00224 }
00225 
00226 
00227 // Construct as copy of PtrList<T>
00228 template<class T>
00229 Foam::List<T>::List(const PtrList<T>& lst)
00230 :
00231     UList<T>(NULL, lst.size())
00232 {
00233     if (this->size_)
00234     {
00235         this->v_ = new T[this->size_];
00236 
00237         forAll(*this, i)
00238         {
00239             this->operator[](i) = lst[i];
00240         }
00241     }
00242 }
00243 
00244 
00245 // Construct as copy of SLList<T>
00246 template<class T>
00247 Foam::List<T>::List(const SLList<T>& lst)
00248 :
00249     UList<T>(NULL, lst.size())
00250 {
00251     if (this->size_)
00252     {
00253         this->v_ = new T[this->size_];
00254 
00255         label i = 0;
00256         for
00257         (
00258             typename SLList<T>::const_iterator iter = lst.begin();
00259             iter != lst.end();
00260             ++iter
00261         )
00262         {
00263             this->operator[](i++) = iter();
00264         }
00265     }
00266 }
00267 
00268 
00269 // Construct as copy of IndirectList<T>
00270 template<class T>
00271 Foam::List<T>::List(const IndirectList<T>& lst)
00272 :
00273     UList<T>(NULL, lst.size())
00274 {
00275     if (this->size_)
00276     {
00277         this->v_ = new T[this->size_];
00278 
00279         forAll(*this, i)
00280         {
00281             this->operator[](i) = lst[i];
00282         }
00283     }
00284 }
00285 
00286 
00287 // Construct as copy of UIndirectList<T>
00288 template<class T>
00289 Foam::List<T>::List(const UIndirectList<T>& lst)
00290 :
00291     UList<T>(NULL, lst.size())
00292 {
00293     if (this->size_)
00294     {
00295         this->v_ = new T[this->size_];
00296 
00297         forAll(*this, i)
00298         {
00299             this->operator[](i) = lst[i];
00300         }
00301     }
00302 }
00303 
00304 
00305 // Construct as copy of BiIndirectList<T>
00306 template<class T>
00307 Foam::List<T>::List(const BiIndirectList<T>& lst)
00308 :
00309     UList<T>(NULL, lst.size())
00310 {
00311     if (this->size_)
00312     {
00313         this->v_ = new T[this->size_];
00314 
00315         forAll(*this, i)
00316         {
00317             this->operator[](i) = lst[i];
00318         }
00319     }
00320 }
00321 
00322 
00323 // * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * * //
00324 
00325 // Destroy list elements
00326 template<class T>
00327 Foam::List<T>::~List()
00328 {
00329     if (this->v_) delete[] this->v_;
00330 }
00331 
00332 
00333 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00334 
00335 template<class T>
00336 void Foam::List<T>::setSize(const label newSize)
00337 {
00338     if (newSize < 0)
00339     {
00340         FatalErrorIn("List<T>::setSize(const label)")
00341             << "bad set size " << newSize
00342             << abort(FatalError);
00343     }
00344 
00345     if (newSize != this->size_)
00346     {
00347         if (newSize > 0)
00348         {
00349             T* nv = new T[label(newSize)];
00350 
00351             if (this->size_)
00352             {
00353                 register label i = min(this->size_, newSize);
00354 
00355 #               ifdef USEMEMCPY
00356                 if (contiguous<T>())
00357                 {
00358                     memcpy(nv, this->v_, i*sizeof(T));
00359                 }
00360                 else
00361 #               endif
00362                 {
00363                     register T* vv = &this->v_[i];
00364                     register T* av = &nv[i];
00365                     while (i--) *--av = *--vv;
00366                 }
00367             }
00368             if (this->v_) delete[] this->v_;
00369 
00370             this->size_ = newSize;
00371             this->v_ = nv;
00372         }
00373         else
00374         {
00375             clear();
00376         }
00377     }
00378 }
00379 
00380 
00381 template<class T>
00382 void Foam::List<T>::setSize(const label newSize, const T& a)
00383 {
00384     label oldSize = this->size_;
00385     this->setSize(newSize);
00386 
00387     if (newSize > oldSize)
00388     {
00389         register label i = newSize - oldSize;
00390         register T* vv = &this->v_[newSize];
00391         while (i--) *--vv = a;
00392     }
00393 }
00394 
00395 
00396 template<class T>
00397 void Foam::List<T>::clear()
00398 {
00399     if (this->v_) delete[] this->v_;
00400     this->size_ = 0;
00401     this->v_ = 0;
00402 }
00403 
00404 
00405 // Transfer the contents of the argument List into this List
00406 // and anull the argument list
00407 template<class T>
00408 void Foam::List<T>::transfer(List<T>& a)
00409 {
00410     if (this->v_) delete[] this->v_;
00411     this->size_ = a.size_;
00412     this->v_ = a.v_;
00413 
00414     a.size_ = 0;
00415     a.v_ = 0;
00416 }
00417 
00418 
00419 // Transfer the contents of the argument DynamicList into this List
00420 // and anull the argument list
00421 template<class T>
00422 template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00423 void Foam::List<T>::transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a)
00424 {
00425     // shrink the allocated space to the number of elements used
00426     a.shrink();
00427     transfer(static_cast<List<T>&>(a));
00428     a.clearStorage();
00429 }
00430 
00431 
00432 // Transfer the contents of the argument SortableList into this List
00433 // and anull the argument list
00434 template<class T>
00435 void Foam::List<T>::transfer(SortableList<T>& a)
00436 {
00437     // shrink away the sort indices
00438     a.shrink();
00439     transfer(static_cast<List<T>&>(a));
00440 }
00441 
00442 
00443 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00444 
00445 // Assignment to UList operator. Takes linear time.
00446 template<class T>
00447 void Foam::List<T>::operator=(const UList<T>& a)
00448 {
00449     if (a.size_ != this->size_)
00450     {
00451         if (this->v_) delete[] this->v_;
00452         this->v_ = 0;
00453         this->size_ = a.size_;
00454         if (this->size_) this->v_ = new T[this->size_];
00455     }
00456 
00457     if (this->size_)
00458     {
00459 #       ifdef USEMEMCPY
00460         if (contiguous<T>())
00461         {
00462             memcpy(this->v_, a.v_, this->byteSize());
00463         }
00464         else
00465 #       endif
00466         {
00467             List_ACCESS(T, (*this), vp);
00468             List_CONST_ACCESS(T, a, ap);
00469             List_FOR_ALL((*this), i)
00470                 List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
00471             List_END_FOR_ALL
00472         }
00473     }
00474 }
00475 
00476 
00477 // Assignment operator. Takes linear time.
00478 template<class T>
00479 void Foam::List<T>::operator=(const List<T>& a)
00480 {
00481     if (this == &a)
00482     {
00483         FatalErrorIn("List<T>::operator=(const List<T>&)")
00484             << "attempted assignment to self"
00485             << abort(FatalError);
00486     }
00487 
00488     operator=(static_cast<const UList<T>&>(a));
00489 }
00490 
00491 
00492 // Assignment operator. Takes linear time.
00493 template<class T>
00494 void Foam::List<T>::operator=(const SLList<T>& lst)
00495 {
00496     if (lst.size() != this->size_)
00497     {
00498         if (this->v_) delete[] this->v_;
00499         this->v_ = 0;
00500         this->size_ = lst.size();
00501         if (this->size_) this->v_ = new T[this->size_];
00502     }
00503 
00504     if (this->size_)
00505     {
00506         label i = 0;
00507         for
00508         (
00509             typename SLList<T>::const_iterator iter = lst.begin();
00510             iter != lst.end();
00511             ++iter
00512         )
00513         {
00514             this->operator[](i++) = iter();
00515         }
00516     }
00517 }
00518 
00519 
00520 // Assignment operator. Takes linear time.
00521 template<class T>
00522 void Foam::List<T>::operator=(const IndirectList<T>& lst)
00523 {
00524     if (lst.size() != this->size_)
00525     {
00526         if (this->v_) delete[] this->v_;
00527         this->v_ = 0;
00528         this->size_ = lst.size();
00529         if (this->size_) this->v_ = new T[this->size_];
00530     }
00531 
00532     forAll(*this, i)
00533     {
00534         this->operator[](i) = lst[i];
00535     }
00536 }
00537 
00538 
00539 // Assignment operator. Takes linear time.
00540 template<class T>
00541 void Foam::List<T>::operator=(const UIndirectList<T>& lst)
00542 {
00543     if (lst.size() != this->size_)
00544     {
00545         if (this->v_) delete[] this->v_;
00546         this->v_ = 0;
00547         this->size_ = lst.size();
00548         if (this->size_) this->v_ = new T[this->size_];
00549     }
00550 
00551     forAll(*this, i)
00552     {
00553         this->operator[](i) = lst[i];
00554     }
00555 }
00556 
00557 
00558 // Assignment operator. Takes linear time.
00559 template<class T>
00560 void Foam::List<T>::operator=(const BiIndirectList<T>& lst)
00561 {
00562     if (lst.size() != this->size_)
00563     {
00564         if (this->v_) delete[] this->v_;
00565         this->v_ = 0;
00566         this->size_ = lst.size();
00567         if (this->size_) this->v_ = new T[this->size_];
00568     }
00569 
00570     forAll(*this, i)
00571     {
00572         this->operator[](i) = lst[i];
00573     }
00574 }
00575 
00576 // * * * * * * * * * * * * * * * *  IOStream operators * * * * * * * * * * * //
00577 
00578 #include <OpenFOAM/ListIO.C>
00579 
00580 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines