FreeFOAM The Cross-Platform CFD Toolkit
List.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include <OpenFOAM/List.H>
27 #include <OpenFOAM/ListLoopM.H>
28 
29 #include <OpenFOAM/FixedList.H>
30 #include <OpenFOAM/PtrList.H>
31 #include <OpenFOAM/SLList.H>
32 #include <OpenFOAM/IndirectList.H>
33 #include <OpenFOAM/UIndirectList.H>
35 #include <OpenFOAM/contiguous.H>
36 
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 
39 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
40 
41 // Construct with length specified
42 template<class T>
43 Foam::List<T>::List(const label s)
44 :
45  UList<T>(NULL, s)
46 {
47  if (this->size_ < 0)
48  {
49  FatalErrorIn("List<T>::List(const label size)")
50  << "bad size " << this->size_
51  << abort(FatalError);
52  }
53 
54  if (this->size_)
55  {
56  this->v_ = new T[this->size_];
57  }
58 }
59 
60 
61 // Construct with length and single value specified
62 template<class T>
63 Foam::List<T>::List(const label s, const T& a)
64 :
65  UList<T>(NULL, s)
66 {
67  if (this->size_ < 0)
68  {
69  FatalErrorIn("List<T>::List(const label size, const T&)")
70  << "bad size " << this->size_
71  << abort(FatalError);
72  }
73 
74  if (this->size_)
75  {
76  this->v_ = new T[this->size_];
77 
78  List_ACCESS(T, (*this), vp);
79  List_FOR_ALL((*this), i)
80  List_ELEM((*this), vp, i) = a;
82  }
83 }
84 
85 
86 // Construct as copy
87 template<class T>
89 :
90  UList<T>(NULL, a.size_)
91 {
92  if (this->size_)
93  {
94  this->v_ = new T[this->size_];
95 
96 # ifdef USEMEMCPY
97  if (contiguous<T>())
98  {
99  memcpy(this->v_, a.v_, this->byteSize());
100  }
101  else
102 # endif
103  {
104  List_ACCESS(T, (*this), vp);
105  List_CONST_ACCESS(T, a, ap);
106  List_FOR_ALL((*this), i)
107  List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
109  }
110  }
111 }
112 
113 
114 // Construct by transferring the parameter contents
115 template<class T>
117 {
118  transfer(lst());
119 }
120 
121 
122 // Construct as copy or re-use as specified.
123 template<class T>
125 :
126  UList<T>(NULL, a.size_)
127 {
128  if (reUse)
129  {
130  this->v_ = a.v_;
131  a.v_ = 0;
132  a.size_ = 0;
133  }
134  else if (this->size_)
135  {
136  this->v_ = new T[this->size_];
137 
138 # ifdef USEMEMCPY
139  if (contiguous<T>())
140  {
141  memcpy(this->v_, a.v_, this->byteSize());
142  }
143  else
144 # endif
145  {
146  List_ACCESS(T, (*this), vp);
147  List_CONST_ACCESS(T, a, ap);
148  List_FOR_ALL((*this), i)
149  List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
151  }
152  }
153 }
154 
155 
156 // Construct as subset
157 template<class T>
159 :
160  UList<T>(NULL, map.size())
161 {
162  if (this->size_)
163  {
164  // Note:cannot use List_ELEM since third argument has to be index.
165 
166  this->v_ = new T[this->size_];
167 
168  forAll(*this, i)
169  {
170  this->v_[i] = a[map[i]];
171  }
172  }
173 }
174 
175 
176 // Construct given start and end iterators.
177 template<class T>
178 template<class InputIterator>
179 Foam::List<T>::List(InputIterator first, InputIterator last)
180 {
181  label s = 0;
182  for
183  (
184  InputIterator iter = first;
185  iter != last;
186  ++iter
187  )
188  {
189  s++;
190  }
191 
192  setSize(s);
193 
194  s = 0;
195 
196  for
197  (
198  InputIterator iter = first;
199  iter != last;
200  ++iter
201  )
202  {
203  this->operator[](s++) = iter();
204  }
205 }
206 
207 
208 // Construct as copy of FixedList<T, Size>
209 template<class T>
210 template<unsigned Size>
212 :
213  UList<T>(NULL, Size)
214 {
215  if (this->size_)
216  {
217  this->v_ = new T[this->size_];
218 
219  forAll(*this, i)
220  {
221  this->operator[](i) = lst[i];
222  }
223  }
224 }
225 
226 
227 // Construct as copy of PtrList<T>
228 template<class T>
230 :
231  UList<T>(NULL, lst.size())
232 {
233  if (this->size_)
234  {
235  this->v_ = new T[this->size_];
236 
237  forAll(*this, i)
238  {
239  this->operator[](i) = lst[i];
240  }
241  }
242 }
243 
244 
245 // Construct as copy of SLList<T>
246 template<class T>
248 :
249  UList<T>(NULL, lst.size())
250 {
251  if (this->size_)
252  {
253  this->v_ = new T[this->size_];
254 
255  label i = 0;
256  for
257  (
258  typename SLList<T>::const_iterator iter = lst.begin();
259  iter != lst.end();
260  ++iter
261  )
262  {
263  this->operator[](i++) = iter();
264  }
265  }
266 }
267 
268 
269 // Construct as copy of IndirectList<T>
270 template<class T>
272 :
273  UList<T>(NULL, lst.size())
274 {
275  if (this->size_)
276  {
277  this->v_ = new T[this->size_];
278 
279  forAll(*this, i)
280  {
281  this->operator[](i) = lst[i];
282  }
283  }
284 }
285 
286 
287 // Construct as copy of UIndirectList<T>
288 template<class T>
290 :
291  UList<T>(NULL, lst.size())
292 {
293  if (this->size_)
294  {
295  this->v_ = new T[this->size_];
296 
297  forAll(*this, i)
298  {
299  this->operator[](i) = lst[i];
300  }
301  }
302 }
303 
304 
305 // Construct as copy of BiIndirectList<T>
306 template<class T>
308 :
309  UList<T>(NULL, lst.size())
310 {
311  if (this->size_)
312  {
313  this->v_ = new T[this->size_];
314 
315  forAll(*this, i)
316  {
317  this->operator[](i) = lst[i];
318  }
319  }
320 }
321 
322 
323 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
324 
325 // Destroy list elements
326 template<class T>
328 {
329  if (this->v_) delete[] this->v_;
330 }
331 
332 
333 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
334 
335 template<class T>
336 void Foam::List<T>::setSize(const label newSize)
337 {
338  if (newSize < 0)
339  {
340  FatalErrorIn("List<T>::setSize(const label)")
341  << "bad set size " << newSize
342  << abort(FatalError);
343  }
344 
345  if (newSize != this->size_)
346  {
347  if (newSize > 0)
348  {
349  T* nv = new T[label(newSize)];
350 
351  if (this->size_)
352  {
353  register label i = min(this->size_, newSize);
354 
355 # ifdef USEMEMCPY
356  if (contiguous<T>())
357  {
358  memcpy(nv, this->v_, i*sizeof(T));
359  }
360  else
361 # endif
362  {
363  register T* vv = &this->v_[i];
364  register T* av = &nv[i];
365  while (i--) *--av = *--vv;
366  }
367  }
368  if (this->v_) delete[] this->v_;
369 
370  this->size_ = newSize;
371  this->v_ = nv;
372  }
373  else
374  {
375  clear();
376  }
377  }
378 }
379 
380 
381 template<class T>
382 void Foam::List<T>::setSize(const label newSize, const T& a)
383 {
384  label oldSize = this->size_;
385  this->setSize(newSize);
386 
387  if (newSize > oldSize)
388  {
389  register label i = newSize - oldSize;
390  register T* vv = &this->v_[newSize];
391  while (i--) *--vv = a;
392  }
393 }
394 
395 
396 template<class T>
398 {
399  if (this->v_) delete[] this->v_;
400  this->size_ = 0;
401  this->v_ = 0;
402 }
403 
404 
405 // Transfer the contents of the argument List into this List
406 // and anull the argument list
407 template<class T>
409 {
410  if (this->v_) delete[] this->v_;
411  this->size_ = a.size_;
412  this->v_ = a.v_;
413 
414  a.size_ = 0;
415  a.v_ = 0;
416 }
417 
418 
419 // Transfer the contents of the argument DynamicList into this List
420 // and anull the argument list
421 template<class T>
422 template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
424 {
425  // shrink the allocated space to the number of elements used
426  a.shrink();
427  transfer(static_cast<List<T>&>(a));
428  a.clearStorage();
429 }
430 
431 
432 // Transfer the contents of the argument SortableList into this List
433 // and anull the argument list
434 template<class T>
436 {
437  // shrink away the sort indices
438  a.shrink();
439  transfer(static_cast<List<T>&>(a));
440 }
441 
442 
443 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
444 
445 // Assignment to UList operator. Takes linear time.
446 template<class T>
448 {
449  if (a.size_ != this->size_)
450  {
451  if (this->v_) delete[] this->v_;
452  this->v_ = 0;
453  this->size_ = a.size_;
454  if (this->size_) this->v_ = new T[this->size_];
455  }
456 
457  if (this->size_)
458  {
459 # ifdef USEMEMCPY
460  if (contiguous<T>())
461  {
462  memcpy(this->v_, a.v_, this->byteSize());
463  }
464  else
465 # endif
466  {
467  List_ACCESS(T, (*this), vp);
468  List_CONST_ACCESS(T, a, ap);
469  List_FOR_ALL((*this), i)
470  List_ELEM((*this), vp, i) = List_ELEM(a, ap, i);
472  }
473  }
474 }
475 
476 
477 // Assignment operator. Takes linear time.
478 template<class T>
480 {
481  if (this == &a)
482  {
483  FatalErrorIn("List<T>::operator=(const List<T>&)")
484  << "attempted assignment to self"
485  << abort(FatalError);
486  }
487 
488  operator=(static_cast<const UList<T>&>(a));
489 }
490 
491 
492 // Assignment operator. Takes linear time.
493 template<class T>
495 {
496  if (lst.size() != this->size_)
497  {
498  if (this->v_) delete[] this->v_;
499  this->v_ = 0;
500  this->size_ = lst.size();
501  if (this->size_) this->v_ = new T[this->size_];
502  }
503 
504  if (this->size_)
505  {
506  label i = 0;
507  for
508  (
509  typename SLList<T>::const_iterator iter = lst.begin();
510  iter != lst.end();
511  ++iter
512  )
513  {
514  this->operator[](i++) = iter();
515  }
516  }
517 }
518 
519 
520 // Assignment operator. Takes linear time.
521 template<class T>
523 {
524  if (lst.size() != this->size_)
525  {
526  if (this->v_) delete[] this->v_;
527  this->v_ = 0;
528  this->size_ = lst.size();
529  if (this->size_) this->v_ = new T[this->size_];
530  }
531 
532  forAll(*this, i)
533  {
534  this->operator[](i) = lst[i];
535  }
536 }
537 
538 
539 // Assignment operator. Takes linear time.
540 template<class T>
542 {
543  if (lst.size() != this->size_)
544  {
545  if (this->v_) delete[] this->v_;
546  this->v_ = 0;
547  this->size_ = lst.size();
548  if (this->size_) this->v_ = new T[this->size_];
549  }
550 
551  forAll(*this, i)
552  {
553  this->operator[](i) = lst[i];
554  }
555 }
556 
557 
558 // Assignment operator. Takes linear time.
559 template<class T>
561 {
562  if (lst.size() != this->size_)
563  {
564  if (this->v_) delete[] this->v_;
565  this->v_ = 0;
566  this->size_ = lst.size();
567  if (this->size_) this->v_ = new T[this->size_];
568  }
569 
570  forAll(*this, i)
571  {
572  this->operator[](i) = lst[i];
573  }
574 }
575 
576 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
577 
578 #include <OpenFOAM/ListIO.C>
579 
580 // ************************ vim: set sw=4 sts=4 et: ************************ //