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-2020 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 newSize)
41 {
42  if (newSize < 0)
43  {
45  << "bad size " << newSize
46  << abort(FatalError);
47  }
48 
49  if (newSize != this->size_)
50  {
51  if (newSize > 0)
52  {
53  T* nv = new T[newSize];
54 
55  const label overlap = min(this->size_, newSize);
56 
57  if (overlap)
58  {
59  #ifdef USEMEMCPY
60  if (is_contiguous<T>::value)
61  {
62  std::memcpy
63  (
64  static_cast<void*>(nv), this->v_, overlap*sizeof(T)
65  );
66  }
67  else
68  #endif
69  {
70  // No speedup observed for copy assignment on simple types
71  List_ACCESS(T, *this, vp);
72  for (label i = 0; i < overlap; ++i)
73  {
74  nv[i] = std::move(vp[i]);
75  }
76  }
77  }
78 
79  clear();
80  this->size_ = newSize;
81  this->v_ = nv;
82  }
83  else
84  {
85  clear();
86  }
87  }
88 }
89 
90 
91 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
92 
93 template<class T>
94 Foam::List<T>::List(const label len)
95 :
96  UList<T>(nullptr, len)
97 {
98  if (len < 0)
99  {
101  << "bad size " << len
102  << abort(FatalError);
103  }
104 
105  doAlloc();
106 }
107 
108 
109 template<class T>
110 Foam::List<T>::List(const label len, const T& val)
111 :
112  UList<T>(nullptr, len)
113 {
114  if (len < 0)
115  {
117  << "bad size " << len
118  << abort(FatalError);
119  }
120 
121  if (len)
122  {
123  doAlloc();
124 
125  List_ACCESS(T, (*this), vp);
126  for (label i=0; i < len; ++i)
127  {
128  vp[i] = val;
129  }
130  }
131 }
132 
133 
134 template<class T>
135 Foam::List<T>::List(const label len, const Foam::zero)
136 :
137  UList<T>(nullptr, len)
138 {
139  if (len < 0)
140  {
142  << "bad size " << len
143  << abort(FatalError);
144  }
145 
146  if (len)
147  {
148  doAlloc();
149 
150  List_ACCESS(T, (*this), vp);
151  for (label i=0; i < len; ++i)
152  {
153  vp[i] = Zero;
154  }
155  }
156 }
157 
158 
159 template<class T>
160 Foam::List<T>::List(const Foam::one, const T& val)
161 :
162  UList<T>(new T[1], 1)
163 {
164  this->v_[0] = val;
165 }
166 
167 
168 template<class T>
170 :
171  UList<T>(new T[1], 1)
172 {
173  this->v_[0] = std::move(val);
174 }
175 
176 
177 template<class T>
179 :
180  UList<T>(new T[1], 1)
181 {
182  this->v_[0] = Zero;
183 }
184 
185 
186 template<class T>
188 :
189  UList<T>(nullptr, a.size_)
190 {
191  const label len = this->size_;
192 
193  if (len)
194  {
195  doAlloc();
196 
197  #ifdef USEMEMCPY
199  {
200  std::memcpy
201  (
202  static_cast<void*>(this->v_), a.v_, this->byteSize()
203  );
204  }
205  else
206  #endif
207  {
208  List_ACCESS(T, (*this), vp);
209  List_CONST_ACCESS(T, a, ap);
210  for (label i = 0; i < len; ++i)
211  {
212  vp[i] = ap[i];
213  }
214  }
215  }
216 }
217 
218 
219 template<class T>
221 :
222  UList<T>(nullptr, a.size_)
223 {
224  const label len = this->size_;
225 
226  if (len)
227  {
228  doAlloc();
229 
230  #ifdef USEMEMCPY
232  {
233  std::memcpy
234  (
235  static_cast<void*>(this->v_), a.v_, this->byteSize()
236  );
237  }
238  else
239  #endif
240  {
241  List_ACCESS(T, (*this), vp);
242  List_CONST_ACCESS(T, a, ap);
243  for (label i = 0; i < len; ++i)
244  {
245  vp[i] = ap[i];
246  }
247  }
248  }
249 }
250 
251 
252 template<class T>
254 :
255  UList<T>(nullptr, a.size_)
256 {
257  if (reuse)
258  {
259  // swap content
260  this->v_ = a.v_;
261  a.v_ = nullptr;
262  a.size_ = 0;
263  return;
264  }
265 
266  const label len = this->size_;
267 
268  if (len)
269  {
270  doAlloc();
271 
272  #ifdef USEMEMCPY
274  {
275  std::memcpy
276  (
277  static_cast<void*>(this->v_), a.v_, this->byteSize()
278  );
279  }
280  else
281  #endif
282  {
283  List_ACCESS(T, (*this), vp);
284  List_CONST_ACCESS(T, a, ap);
285  for (label i = 0; i < len; ++i)
286  {
287  vp[i] = ap[i];
288  }
289  }
290  }
291 }
292 
293 
294 template<class T>
295 Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
296 :
297  UList<T>(nullptr, indices.size())
298 {
299  const label len = indices.size();
300 
301  if (len)
302  {
303  doAlloc();
304 
305  List_ACCESS(T, (*this), vp);
306 
307  for (label i=0; i < len; ++i)
308  {
309  vp[i] = list[indices[i]];
310  }
311  }
312 }
313 
314 
315 template<class T>
316 template<unsigned N>
318 (
319  const UList<T>& list,
320  const FixedList<label,N>& indices
321 )
322 :
323  UList<T>(nullptr, label(N))
324 {
325  const label len = label(N);
326 
327  doAlloc();
328 
329  List_ACCESS(T, (*this), vp);
330 
331  for (label i=0; i < len; ++i)
332  {
333  vp[i] = list[indices[i]];
334  }
335 }
336 
337 
338 template<class T>
339 template<class InputIterator>
340 Foam::List<T>::List(InputIterator begIter, InputIterator endIter)
341 :
342  List<T>(begIter, endIter, std::distance(begIter, endIter))
343 {}
344 
345 
346 template<class T>
347 template<unsigned N>
349 :
350  UList<T>(nullptr, label(N))
351 {
352  doAlloc();
353  copyList(list);
354 }
355 
356 
357 template<class T>
359 :
360  UList<T>(nullptr, list.size())
361 {
362  doAlloc();
363  copyList(list);
364 }
365 
366 
367 template<class T>
369 :
370  List<T>(list.begin(), list.end(), list.size())
371 {}
372 
373 
374 template<class T>
375 template<class Addr>
377 :
378  UList<T>(nullptr, list.size())
379 {
380  doAlloc();
381  copyList(list);
382 }
383 
384 
385 template<class T>
386 Foam::List<T>::List(std::initializer_list<T> list)
387 :
388  List<T>(list.begin(), list.end(), list.size())
389 {}
390 
391 
392 template<class T>
394 :
395  UList<T>()
396 {
397  // Can use transfer or swap to manage content
398  transfer(list);
399 }
400 
401 
402 template<class T>
403 template<int SizeMin>
405 :
406  UList<T>()
407 {
408  transfer(list);
409 }
410 
411 
412 template<class T>
414 :
415  UList<T>()
416 {
417  transfer(list);
418 }
419 
420 
421 template<class T>
423 :
424  UList<T>()
425 {
426  operator=(std::move(list));
427 }
428 
429 
430 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
431 
432 template<class T>
434 {
435  if (this->v_)
436  {
437  delete[] this->v_;
438  }
439 }
440 
441 
442 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
443 
444 template<class T>
445 void Foam::List<T>::resize(const label newSize, const T& val)
446 {
447  const label oldSize = this->size_;
448  this->doResize(newSize);
449 
450  List_ACCESS(T, *this, vp);
451  for (label i = oldSize; i < newSize; ++i)
452  {
453  vp[i] = val;
454  }
455 }
456 
457 
458 template<class T>
460 {
461  if (this == &list)
462  {
463  return; // Self-assignment is a no-op
464  }
465 
466  // Clear and swap - could also check for self assignment
467  clear();
468  this->size_ = list.size_;
469  this->v_ = list.v_;
470 
471  list.size_ = 0;
472  list.v_ = nullptr;
473 }
474 
475 
476 template<class T>
477 template<int SizeMin>
479 {
480  // Shrink the allocated space to the number of elements used
481  list.shrink();
482  transfer(static_cast<List<T>&>(list));
483 
484  // Ensure DynamicList has proper capacity=0 too
485  list.clearStorage();
486 }
487 
488 
489 template<class T>
491 {
492  // Shrink away the sort indices
493  list.shrink();
494  transfer(static_cast<List<T>&>(list));
495 }
496 
497 
498 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
499 
500 template<class T>
502 {
503  if (this == &a)
504  {
505  return; // Self-assignment is a no-op
506  }
507 
508  reAlloc(a.size_);
509 
510  const label len = this->size_;
511 
512  if (len)
513  {
514  #ifdef USEMEMCPY
516  {
517  std::memcpy
518  (
519  static_cast<void*>(this->v_), a.v_, this->byteSize()
520  );
521  }
522  else
523  #endif
524  {
525  List_ACCESS(T, (*this), vp);
526  List_CONST_ACCESS(T, a, ap);
527  for (label i = 0; i < len; ++i)
528  {
529  vp[i] = ap[i];
530  }
531  }
532  }
533 }
534 
535 
536 template<class T>
538 {
539  if (this == &list)
540  {
541  return; // Self-assignment is a no-op
542  }
543 
544  operator=(static_cast<const UList<T>&>(list));
545 }
546 
547 
548 template<class T>
550 {
551  const label len = list.size();
552 
553  reAlloc(len);
554 
555  if (len)
556  {
557  T* iter = this->begin();
558 
559  for (const T& val : list)
560  {
561  *iter = val;
562  ++iter;
563  }
564  }
565 }
566 
567 
568 template<class T>
569 template<unsigned N>
571 {
572  reAlloc(label(N));
573 
574  T* iter = this->begin();
575 
576  for (const T& val : list)
577  {
578  *iter = val;
579  ++iter;
580  }
581 }
582 
583 
584 template<class T>
585 template<class Addr>
587 {
588  const label len = list.size();
589 
590  reAlloc(len);
591 
592  if (len)
593  {
594  List_ACCESS(T, (*this), vp);
595 
596  for (label i=0; i < len; ++i)
597  {
598  vp[i] = list[i];
599  }
600  }
601 }
602 
603 
604 template<class T>
605 void Foam::List<T>::operator=(std::initializer_list<T> list)
606 {
607  const label len = list.size();
608 
609  reAlloc(len);
610 
611  if (len)
612  {
613  T* iter = this->begin();
614 
615  for (const T& val : list)
616  {
617  *iter = val;
618  ++iter;
619  }
620  }
621 }
622 
623 
624 template<class T>
626 {
627  if (this == &list)
628  {
629  return; // Self-assignment is a no-op
630  }
631 
632  transfer(list);
633 }
634 
635 
636 template<class T>
637 template<int SizeMin>
639 {
640  transfer(list);
641 }
642 
643 
644 template<class T>
646 {
647  transfer(list);
648 }
649 
650 
651 template<class T>
653 {
654  label len = list.size();
655 
656  reAlloc(len);
657 
658  T* iter = this->begin();
659 
660  while (len--)
661  {
662  *iter = std::move(list.removeHead());
663  ++iter;
664  }
665 
666  list.clear();
667 }
668 
669 
670 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
671 
672 #include "ListIO.C"
673 
674 // ************************************************************************* //
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::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:376
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:459
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:62
Foam::List::operator=
void operator=(const UList< T > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:501
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
ListIO.C
Foam::SortableList::shrink
List< T > & shrink()
Clear the indices and return a reference to the underlying List.
Definition: SortableList.C:130
Foam::FatalError
error FatalError
Foam::SortableList
A list that is sorted upon construction or when explicitly requested with the sort() method.
Definition: List.H:63
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
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
Null constructor.
Definition: ListI.H:94
Foam::distance
scalar distance(const vector &p1, const vector &p2)
Definition: curveTools.C:12
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
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:433
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:355
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
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
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::IndirectListBase::size
label size() const
The number of elements in the list.
Definition: IndirectListBase.H:125
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