initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / OpenFOAM / containers / Lists / List / List.C
blobed38924cf7f281ceeb80dd6509c0cd1a75299a16
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 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 #include "List.H"
28 #include "ListLoopM.H"
30 #include "FixedList.H"
31 #include "PtrList.H"
32 #include "SLList.H"
33 #include "IndirectList.H"
34 #include "BiIndirectList.H"
35 #include "contiguous.H"
37 #include <algorithm>
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 namespace Foam
44 // * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * //
46 // Construct with length specified
47 template<class T>
48 List<T>::List(const label s)
50     UList<T>(NULL, s)
52     if (this->size_ < 0)
53     {
54         FatalErrorIn("List<T>::List(const label size)")
55             << "bad size " << this->size_
56             << abort(FatalError);
57     }
59     if (this->size_)
60     {
61         this->v_ = new T[this->size_];
62     }
63     else
64     {
65         this->v_ = 0;
66     }
70 // Construct with length and single value specified
71 template<class T>
72 List<T>::List(const label s, const T& a)
74     UList<T>(NULL, s)
76     if (this->size_ < 0)
77     {
78         FatalErrorIn("List<T>::List(const label size, const T a)")
79             << "bad size " << this->size_
80             << abort(FatalError);
81     }
83     if (this->size_)
84     {
85         this->v_ = new T[this->size_];
87         List_ACCESS(T, (*this), vp);
88         List_FOR_ALL((*this), i)
89             List_ELEM((*this), vp, i) = a;
90         List_END_FOR_ALL
91     }
92     else
93     {
94         this->v_ = 0;
95     }
99 // Construct as copy
100 template<class T>
101 List<T>::List(const List<T>& a)
103     UList<T>(NULL, a.size_)
105     if (this->size_)
106     {
107         this->v_ = new T[this->size_];
109 #       ifdef USEMEMCPY
110         if (contiguous<T>())
111         {
112             memcpy(this->v_, a.v_, this->byteSize());
113         }
114         else
115 #       endif
116         {
117             List_ACCESS(T, (*this), vp);
118             List_CONST_ACCESS(T, a, ap);
119             List_FOR_ALL((*this), i)
120                 List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
121             List_END_FOR_ALL
122         }
123     }
124     else
125     {
126         this->v_ = 0;
127     }
131 // Construct as copy or re-use as specified.
132 template<class T>
133 List<T>::List(List<T>& a, bool reUse)
135     UList<T>(NULL, a.size_)
137     if (reUse)
138     {
139         this->v_ = a.v_;
140         a.v_ = 0;
141         a.size_ = 0;
142     }
143     else if (this->size_)
144     {
145         this->v_ = new T[this->size_];
147 #       ifdef USEMEMCPY
148         if (contiguous<T>())
149         {
150             memcpy(this->v_, a.v_, this->byteSize());
151         }
152         else
153 #       endif
154         {
155             List_ACCESS(T, (*this), vp);
156             List_CONST_ACCESS(T, a, ap);
157             List_FOR_ALL((*this), i)
158                 List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
159             List_END_FOR_ALL
160         }
161     }
162     else
163     {
164         this->v_ = 0;
165     }
169 // Construct given size and start and end iterators.
170 template<class T>
171 template<class InputIterator>
172 List<T>::List(InputIterator first, InputIterator last)
174     label s = 0;
175     for
176     (
177         InputIterator iter = first;
178         iter != last;
179         ++iter
180     )
181     {
182         s++;
183     }
185     setSize(s);
187     s = 0;
189     for
190     (
191         InputIterator iter = first;
192         iter != last;
193         ++iter
194     )
195     {
196         this->operator[](s++) = iter();
197     }
201 // Construct as copy of FixedList<T, Size>
202 template<class T>
203 template<label Size>
204 List<T>::List(const FixedList<T, Size>& fl)
206     UList<T>(NULL, Size)
208     if (Size)
209     {
210         this->v_ = new T[this->size_];
212         forAll(*this, i)
213         {
214             this->operator[](i) = fl[i];
215         }
216     }
217     else
218     {
219         this->v_ = 0;
220     }
224 // Construct as copy of PtrList<T>
225 template<class T>
226 List<T>::List(const PtrList<T>& sptrl)
228     UList<T>(NULL, sptrl.size())
230     if (this->size_)
231     {
232         this->v_ = new T[this->size_];
234         forAll(*this, i)
235         {
236             this->operator[](i) = sptrl[i];
237         }
238     }
239     else
240     {
241         this->v_ = 0;
242     }
246 // Construct as copy of SLList<T>
247 template<class T>
248 List<T>::List(const SLList<T>& sll)
250     UList<T>(NULL, sll.size())
252     if (this->size_)
253     {
254         this->v_ = new T[this->size_];
256         label i = 0;
257         for
258         (
259             typename SLList<T>::const_iterator iter = sll.begin();
260             iter != sll.end();
261             ++iter
262         )
263         {
264             this->operator[](i++) = iter();
265         }
266     }
267     else
268     {
269         this->v_ = 0;
270     }
274 // Construct as copy of IndirectList<T>
275 template<class T>
276 List<T>::List(const IndirectList<T>& idl)
278     UList<T>(NULL, idl.size())
280     if (this->size_)
281     {
282         this->v_ = new T[this->size_];
284         forAll(*this, i)
285         {
286             this->operator[](i) = idl[i];
287         }
288     }
289     else
290     {
291         this->v_ = 0;
292     }
296 // Construct as copy of BiIndirectList<T>
297 template<class T>
298 List<T>::List(const BiIndirectList<T>& idl)
300     UList<T>(NULL, idl.size())
302     if (this->size_)
303     {
304         this->v_ = new T[this->size_];
306         forAll(*this, i)
307         {
308             this->operator[](i) = idl[i];
309         }
310     }
311     else
312     {
313         this->v_ = 0;
314     }
318 // * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * * //
320 // Destroy list elements
321 template<class T>
322 List<T>::~List()
324     if (this->size_) delete[] this->v_;
328 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
330 template<class T>
331 const List<T>& List<T>::null()
333     List<T>* nullPtr = reinterpret_cast<List<T>*>(NULL);
334     return *nullPtr;
338 template<class T>
339 void List<T>::setSize(const label newSize)
341     if (newSize < 0)
342     {
343         FatalErrorIn("List<T>::setSize(const label)")
344             << "bad set size " << newSize
345             << abort(FatalError);
346     }
348     if (newSize != this->size_)
349     {
350         if (newSize > 0)
351         {
352             T* nv = new T[label(newSize)];
354             if (this->size_)
355             {
356                 register label i = min(this->size_, newSize);
358 #               ifdef USEMEMCPY
359                 if (contiguous<T>())
360                 {
361                     memcpy(nv, this->v_, i*sizeof(T));
362                 }
363                 else
364 #               endif
365                 {
366                     register T* vv = &this->v_[i];
367                     register T* av = &nv[i];
368                     while (i--) *--av = *--vv;
369                 }
371                 delete[] this->v_;
372             }
374             this->size_ = newSize;
375             this->v_ = nv;
376         }
377         else
378         {
379             clear();
380         }
381     }
385 template<class T>
386 void List<T>::setSize(const label newSize, const T& a)
388     label oldSize = this->size_;
389     this->setSize(newSize);
391     if (newSize > oldSize)
392     {
393         register label i = newSize - oldSize;
394         register T* vv = &this->v_[newSize];
395         while (i--) *--vv = a;
396     }
400 template<class T>
401 void List<T>::clear()
403     if (this->size_) delete[] this->v_;
404     this->size_ = 0;
405     this->v_ = 0;
409 // Transfer the contents of the argument List into this List
410 // and anull the argument list
411 template<class T>
412 void List<T>::transfer(List<T>& a)
414     if (this->size_) delete[] this->v_;
416     this->size_ = a.size_;
417     this->v_ = a.v_;
419     a.size_ = 0;
420     a.v_ = 0;
424 template<class T>
425 void sort(List<T>& a)
427     std::sort(a.begin(), a.end());
431 template<class T, class Cmp>
432 void sort(List<T>& a, const Cmp& cmp)
434     std::sort(a.begin(), a.end(), cmp);
438 template<class T>
439 void stableSort(List<T>& a)
441     std::stable_sort(a.begin(), a.end());
445 template<class T, class Cmp>
446 void stableSort(List<T>& a, const Cmp& cmp)
448     std::stable_sort(a.begin(), a.end(), cmp);
452 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
454 // Assignment to UList operator. Takes linear time.
455 template<class T>
456 void List<T>::operator=(const UList<T>& a)
458     if (a.size_ != this->size_)
459     {
460         if (this->size_) delete[] this->v_;
461         this->size_ = a.size_;
462         if (this->size_) this->v_ = new T[this->size_];
463     }
465     if (this->size_)
466     {
467 #       ifdef USEMEMCPY
468         if (contiguous<T>())
469         {
470             memcpy(this->v_, a.v_, this->byteSize());
471         }
472         else
473 #       endif
474         {
475             List_ACCESS(T, (*this), vp);
476             List_CONST_ACCESS(T, a, ap);
477             List_FOR_ALL((*this), i)
478                 List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
479             List_END_FOR_ALL
480         }
481     }
485 // Assignment operator. Takes linear time.
486 template<class T>
487 void List<T>::operator=(const List<T>& a)
489     if (this == &a)
490     {
491         FatalErrorIn("List<T>::operator=(const List<T>&)")
492             << "attempted assignment to self"
493             << abort(FatalError);
494     }
496     operator=(static_cast<const UList<T>&>(a));
500 // Assignment operator. Takes linear time.
501 template<class T>
502 void List<T>::operator=(const SLList<T>& sll)
504     if (sll.size() != this->size_)
505     {
506         if (this->size_) delete[] this->v_;
507         this->size_ = sll.size();
508         if (this->size_) this->v_ = new T[this->size_];
509     }
511     if (this->size_)
512     {
513         label i = 0;
514         for
515         (
516             typename SLList<T>::const_iterator iter = sll.begin();
517             iter != sll.end();
518             ++iter
519         )
520         {
521             this->operator[](i++) = iter();
522         }
523     }
527 // Assignment operator. Takes linear time.
528 template<class T>
529 void List<T>::operator=(const IndirectList<T>& idl)
531     if (idl.size() != this->size_)
532     {
533         if (this->size_) delete[] this->v_;
534         this->size_ = idl.size();
535         if (this->size_) this->v_ = new T[this->size_];
536     }
538     if (this->size_)
539     {
540         forAll(*this, i)
541         {
542             this->operator[](i) = idl[i];
543         }
544     }
548 // Assignment operator. Takes linear time.
549 template<class T>
550 void List<T>::operator=(const BiIndirectList<T>& idl)
552     if (idl.size() != this->size_)
553     {
554         if (this->size_) delete[] this->v_;
555         this->size_ = idl.size();
556         if (this->size_) this->v_ = new T[this->size_];
557     }
559     if (this->size_)
560     {
561         forAll(*this, i)
562         {
563             this->operator[](i) = idl[i];
564         }
565     }
569 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
571 } // End namespace Foam
573 // * * * * * * * * * * * * * * * *  IOStream operators * * * * * * * * * * * //
575 #include "ListIO.C"
577 // ************************************************************************* //