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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "List.H"
30 #include "ListLoopM.H"
31 #include "FixedList.H"
32 #include "PtrList.H"
33 #include "SLList.H"
34 #include "contiguous.H"
35 #include <utility>
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 template<class T>
40 void Foam::List<T>::doResize(const label len)
41 {
42  if (len == this->size_)
43  {
44  return;
45  }
46 
47  if (len > 0)
48  {
49  // With sign-check to avoid spurious -Walloc-size-larger-than
50  T* nv = new T[len];
51 
52  const label overlap = min(this->size_, len);
53 
54  if (overlap)
55  {
56  #ifdef USEMEMCPY
57  if (is_contiguous<T>::value)
58  {
59  std::memcpy
60  (
61  static_cast<void*>(nv), this->v_, overlap*sizeof(T)
62  );
63  }
64  else
65  #endif
66  {
67  List_ACCESS(T, *this, vp);
68  for (label i = 0; i < overlap; ++i)
69  {
70  nv[i] = std::move(vp[i]);
71  }
72  }
73  }
74 
75  clear();
76  this->size_ = len;
77  this->v_ = nv;
78  }
79  else
80  {
81  // Or only #ifdef FULLDEBUG
82  if (len < 0)
83  {
85  << "bad size " << len
86  << abort(FatalError);
87  }
88  // #endif
89 
90  clear();
91  }
92 }
93 
94 
95 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
96 
97 template<class T>
98 Foam::List<T>::List(const label len)
99 :
100  UList<T>(nullptr, len)
101 {
102  if (len < 0)
103  {
105  << "bad size " << len
106  << abort(FatalError);
107  }
108 
109  doAlloc();
110 }
111 
112 
113 template<class T>
114 Foam::List<T>::List(const label len, const T& val)
115 :
116  UList<T>(nullptr, len)
117 {
118  if (len < 0)
119  {
121  << "bad size " << len
122  << abort(FatalError);
123  }
124 
125  if (len)
126  {
127  doAlloc();
128 
129  List_ACCESS(T, (*this), vp);
130  for (label i=0; i < len; ++i)
131  {
132  vp[i] = val;
133  }
134  }
135 }
136 
137 
138 template<class T>
139 Foam::List<T>::List(const label len, const Foam::zero)
140 :
141  UList<T>(nullptr, len)
142 {
143  if (len < 0)
144  {
146  << "bad size " << len
147  << abort(FatalError);
148  }
149 
150  if (len)
151  {
152  doAlloc();
153 
154  List_ACCESS(T, (*this), vp);
155  for (label i=0; i < len; ++i)
156  {
157  vp[i] = Zero;
158  }
159  }
160 }
161 
162 
163 template<class T>
164 Foam::List<T>::List(const Foam::one, const T& val)
165 :
166  UList<T>(new T[1], 1)
167 {
168  this->v_[0] = val;
169 }
170 
171 
172 template<class T>
174 :
175  UList<T>(new T[1], 1)
176 {
177  this->v_[0] = std::move(val);
178 }
179 
180 
181 template<class T>
183 :
184  UList<T>(new T[1], 1)
185 {
186  this->v_[0] = Zero;
187 }
188 
189 
190 template<class T>
192 :
193  UList<T>(nullptr, a.size_)
194 {
195  const label len = this->size_;
196 
197  if (len)
198  {
199  doAlloc();
200 
201  #ifdef USEMEMCPY
203  {
204  std::memcpy
205  (
206  static_cast<void*>(this->v_), a.v_, this->size_bytes()
207  );
208  }
209  else
210  #endif
211  {
212  List_ACCESS(T, (*this), vp);
213  List_CONST_ACCESS(T, a, ap);
214  for (label i = 0; i < len; ++i)
215  {
216  vp[i] = ap[i];
217  }
218  }
219  }
220 }
221 
222 
223 template<class T>
225 :
226  UList<T>(nullptr, a.size_)
227 {
228  const label len = this->size_;
229 
230  if (len)
231  {
232  doAlloc();
233 
234  #ifdef USEMEMCPY
236  {
237  std::memcpy
238  (
239  static_cast<void*>(this->v_), a.v_, this->size_bytes()
240  );
241  }
242  else
243  #endif
244  {
245  List_ACCESS(T, (*this), vp);
246  List_CONST_ACCESS(T, a, ap);
247  for (label i = 0; i < len; ++i)
248  {
249  vp[i] = ap[i];
250  }
251  }
252  }
253 }
254 
255 
256 template<class T>
258 :
259  UList<T>(nullptr, a.size_)
260 {
261  if (reuse)
262  {
263  // Steal content
264  this->v_ = a.v_;
265  a.v_ = nullptr;
266  a.size_ = 0;
267  return;
268  }
269 
270  const label len = this->size_;
271 
272  if (len)
273  {
274  doAlloc();
275 
276  #ifdef USEMEMCPY
278  {
279  std::memcpy
280  (
281  static_cast<void*>(this->v_), a.v_, this->size_bytes()
282  );
283  }
284  else
285  #endif
286  {
287  List_ACCESS(T, (*this), vp);
288  List_CONST_ACCESS(T, a, ap);
289  for (label i = 0; i < len; ++i)
290  {
291  vp[i] = ap[i];
292  }
293  }
294  }
295 }
296 
297 
298 template<class T>
299 Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
300 :
301  UList<T>(nullptr, indices.size())
302 {
303  const label len = indices.size();
304 
305  if (len)
306  {
307  doAlloc();
308 
309  List_ACCESS(T, (*this), vp);
310 
311  for (label i=0; i < len; ++i)
312  {
313  vp[i] = list[indices[i]];
314  }
315  }
316 }
317 
318 
319 template<class T>
320 template<unsigned N>
322 (
323  const UList<T>& list,
324  const FixedList<label,N>& indices
325 )
326 :
327  UList<T>(nullptr, label(N))
328 {
329  const label len = label(N);
330 
331  doAlloc();
332 
333  List_ACCESS(T, (*this), vp);
334 
335  for (label i=0; i < len; ++i)
336  {
337  vp[i] = list[indices[i]];
338  }
339 }
340 
341 
342 template<class T>
343 template<unsigned N>
345 :
346  UList<T>(nullptr, label(N))
347 {
348  doAlloc();
349  copyList(list);
350 }
351 
352 
353 template<class T>
355 :
356  UList<T>(nullptr, list.size())
357 {
358  doAlloc();
359  copyList(list);
360 }
361 
362 
363 template<class T>
365 :
366  List<T>(list.begin(), list.end(), list.size())
367 {}
368 
369 
370 template<class T>
371 template<class Addr>
373 :
374  UList<T>(nullptr, list.size())
375 {
376  doAlloc();
377  copyList(list);
378 }
379 
380 
381 template<class T>
382 Foam::List<T>::List(std::initializer_list<T> list)
383 :
384  List<T>(list.begin(), list.end(), list.size())
385 {}
386 
387 
388 template<class T>
390 :
391  UList<T>()
392 {
393  // Can use transfer or swap to manage content
394  transfer(list);
395 }
396 
397 
398 template<class T>
399 template<int SizeMin>
401 :
402  UList<T>()
403 {
404  transfer(list);
405 }
406 
407 
408 template<class T>
410 :
411  UList<T>()
412 {
413  transfer(list);
414 }
415 
416 
417 template<class T>
419 :
420  UList<T>()
421 {
422  operator=(std::move(list));
423 }
424 
425 
426 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
427 
428 template<class T>
430 {
431  if (this->v_)
432  {
433  delete[] this->v_;
434  }
435 }
436 
437 
438 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
439 
440 template<class T>
441 void Foam::List<T>::resize(const label len, const T& val)
442 {
443  label idx = this->size_;
444  this->doResize(len);
445 
446  List_ACCESS(T, *this, vp);
447  while (idx < len)
448  {
449  vp[idx] = val;
450  ++idx;
451  }
452 }
453 
454 
455 template<class T>
457 {
458  if (this == &list)
459  {
460  return; // Self-assignment is a no-op
461  }
462 
463  // Clear and swap - could also check for self assignment
464  clear();
465  this->size_ = list.size_;
466  this->v_ = list.v_;
467 
468  list.size_ = 0;
469  list.v_ = nullptr;
470 }
471 
472 
473 template<class T>
474 template<int SizeMin>
476 {
477  // Shrink the allocated space to the number of elements used
478  list.shrink();
479  transfer(static_cast<List<T>&>(list));
480 
481  // Ensure DynamicList has proper capacity=0 too
482  list.clearStorage();
483 }
484 
485 
486 template<class T>
488 {
489  // Shrink away the sort indices
490  list.shrink();
491  transfer(static_cast<List<T>&>(list));
492 }
493 
494 
495 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
496 
497 template<class T>
499 {
500  if (this == &a)
501  {
502  return; // Self-assignment is a no-op
503  }
504 
505  reAlloc(a.size_);
506 
507  const label len = this->size_;
508 
509  if (len)
510  {
511  #ifdef USEMEMCPY
513  {
514  std::memcpy
515  (
516  static_cast<void*>(this->v_), a.v_, this->size_bytes()
517  );
518  }
519  else
520  #endif
521  {
522  List_ACCESS(T, (*this), vp);
523  List_CONST_ACCESS(T, a, ap);
524  for (label i = 0; i < len; ++i)
525  {
526  vp[i] = ap[i];
527  }
528  }
529  }
530 }
531 
532 
533 template<class T>
535 {
536  if (this == &list)
537  {
538  return; // Self-assignment is a no-op
539  }
540 
541  operator=(static_cast<const UList<T>&>(list));
542 }
543 
544 
545 template<class T>
547 {
548  const label len = list.size();
549 
550  reAlloc(len);
551 
552  if (len)
553  {
554  T* iter = this->begin();
555 
556  for (const T& val : list)
557  {
558  *iter = val;
559  ++iter;
560  }
561  }
562 }
563 
564 
565 template<class T>
566 template<unsigned N>
568 {
569  reAlloc(static_cast<label>(N));
570 
571  T* iter = this->begin();
572 
573  for (const T& val : list)
574  {
575  *iter = val;
576  ++iter;
577  }
578 }
579 
580 
581 template<class T>
582 template<class Addr>
584 {
585  const label len = list.size();
586 
587  reAlloc(len);
588 
589  if (len)
590  {
591  List_ACCESS(T, (*this), vp);
592 
593  for (label i=0; i < len; ++i)
594  {
595  vp[i] = list[i];
596  }
597  }
598 }
599 
600 
601 template<class T>
602 void Foam::List<T>::operator=(std::initializer_list<T> list)
603 {
604  const label len = list.size();
605 
606  reAlloc(len);
607 
608  if (len)
609  {
610  T* iter = this->begin();
611 
612  for (const T& val : list)
613  {
614  *iter = val;
615  ++iter;
616  }
617  }
618 }
619 
620 
621 template<class T>
623 {
624  if (this == &list)
625  {
626  return; // Self-assignment is a no-op
627  }
628 
629  transfer(list);
630 }
631 
632 
633 template<class T>
634 template<int SizeMin>
636 {
637  transfer(list);
638 }
639 
640 
641 template<class T>
643 {
644  transfer(list);
645 }
646 
647 
648 template<class T>
650 {
651  label len = list.size();
652 
653  reAlloc(len);
654 
655  T* iter = this->begin();
656 
657  while (len--)
658  {
659  *iter = std::move(list.removeHead());
660  ++iter;
661  }
662 
663  list.clear();
664 }
665 
666 
667 // ************************************************************************* //
List.H
stdFoam::begin
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:97
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::one
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:61
Foam::DynamicList::shrink
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:434
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::LList
Template class for non-intrusive linked lists.
Definition: LList.H:54
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:456
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::List::operator=
void operator=(const UList< T > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:498
Foam::SortableList::shrink
List< T > & shrink()
Clear the indices and return a reference to the underlying List.
Definition: SortableList.C:116
Foam::FatalError
error FatalError
Foam::SortableList
A list that is sorted upon construction or when explicitly requested with the sort() method.
Definition: List.H:60
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::IndirectListBase::size
label size() const noexcept
The number of elements in the list.
Definition: IndirectListBase.H:125
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::List::List
constexpr List() noexcept
Default construct.
Definition: ListI.H:95
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
List_CONST_ACCESS
#define List_CONST_ACCESS(type, f, fp)
Definition: ListLoopM.H:43
clear
patchWriters clear()
SLList.H
Non-intrusive singly-linked list.
contiguous.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::FixedList
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:104
Foam::List::~List
~List()
Destructor.
Definition: List.C:429
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::DynamicList::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:398
PtrList.H
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:56
overlap
const cellCellStencilObject & overlap
Definition: correctPhi.H:57
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
N
const Vector< label > N(dict.get< Vector< label >>("N"))
FixedList.H
List_ACCESS
#define List_ACCESS(type, f, fp)
Definition: ListLoopM.H:39
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75
ListLoopM.H
Macros for accessing List elements.
Foam::zero
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:62