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-2019 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>
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 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 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& mapAddressing)
296 :
297  UList<T>(nullptr, mapAddressing.size())
298 {
299  const label len = mapAddressing.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[mapAddressing[i]];
310  }
311  }
312 }
313 
314 
315 template<class T>
316 template<class InputIterator>
317 Foam::List<T>::List(InputIterator begIter, InputIterator endIter)
318 :
319  List<T>(begIter, endIter, std::distance(begIter, endIter))
320 {}
321 
322 
323 template<class T>
324 template<unsigned N>
326 :
327  UList<T>(nullptr, label(N))
328 {
329  doAlloc();
330  copyList(list);
331 }
332 
333 
334 template<class T>
336 :
337  UList<T>(nullptr, list.size())
338 {
339  doAlloc();
340  copyList(list);
341 }
342 
343 
344 template<class T>
346 :
347  List<T>(list.begin(), list.end(), list.size())
348 {}
349 
350 
351 template<class T>
352 template<class Addr>
354 :
355  UList<T>(nullptr, list.size())
356 {
357  doAlloc();
358  copyList(list);
359 }
360 
361 
362 template<class T>
363 Foam::List<T>::List(std::initializer_list<T> list)
364 :
365  List<T>(list.begin(), list.end(), list.size())
366 {}
367 
368 
369 template<class T>
371 :
372  UList<T>(nullptr, 0)
373 {
374  // Can use transfer or swap to manage content
375  transfer(list);
376 }
377 
378 
379 template<class T>
380 template<int SizeMin>
382 :
383  UList<T>(nullptr, 0)
384 {
385  transfer(list);
386 }
387 
388 
389 template<class T>
391 :
392  UList<T>(nullptr, 0)
393 {
394  transfer(list);
395 }
396 
397 
398 template<class T>
400 :
401  UList<T>(nullptr, 0)
402 {
403  operator=(std::move(list));
404 }
405 
406 
407 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
408 
409 template<class T>
411 {
412  if (this->v_)
413  {
414  delete[] this->v_;
415  }
416 }
417 
418 
419 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
420 
421 template<class T>
422 void Foam::List<T>::resize(const label newSize, const T& val)
423 {
424  const label oldSize = this->size_;
425  this->doResize(newSize);
426 
427  List_ACCESS(T, *this, vp);
428  for (label i = oldSize; i < newSize; ++i)
429  {
430  vp[i] = val;
431  }
432 }
433 
434 
435 template<class T>
437 {
438  if (this == &list)
439  {
440  return; // Self-assignment is a no-op
441  }
442 
443  // Clear and swap - could also check for self assignment
444  clear();
445  this->size_ = list.size_;
446  this->v_ = list.v_;
447 
448  list.size_ = 0;
449  list.v_ = nullptr;
450 }
451 
452 
453 template<class T>
454 template<int SizeMin>
456 {
457  // Shrink the allocated space to the number of elements used
458  list.shrink();
459  transfer(static_cast<List<T>&>(list));
460 
461  // Ensure DynamicList has proper capacity=0 too
462  list.clearStorage();
463 }
464 
465 
466 template<class T>
468 {
469  // Shrink away the sort indices
470  list.shrink();
471  transfer(static_cast<List<T>&>(list));
472 }
473 
474 
475 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
476 
477 template<class T>
479 {
480  if (this == &a)
481  {
482  return; // Self-assignment is a no-op
483  }
484 
485  reAlloc(a.size_);
486 
487  const label len = this->size_;
488 
489  if (len)
490  {
491  #ifdef USEMEMCPY
493  {
494  std::memcpy
495  (
496  static_cast<void*>(this->v_), a.v_, this->byteSize()
497  );
498  }
499  else
500  #endif
501  {
502  List_ACCESS(T, (*this), vp);
503  List_CONST_ACCESS(T, a, ap);
504  for (label i = 0; i < len; ++i)
505  {
506  vp[i] = ap[i];
507  }
508  }
509  }
510 }
511 
512 
513 template<class T>
515 {
516  if (this == &list)
517  {
518  return; // Self-assignment is a no-op
519  }
520 
521  operator=(static_cast<const UList<T>&>(list));
522 }
523 
524 
525 template<class T>
527 {
528  const label len = list.size();
529 
530  reAlloc(len);
531 
532  if (len)
533  {
534  List_ACCESS(T, (*this), vp);
535 
536  label i = 0;
537  for (auto iter = list.cbegin(); iter != list.cend(); ++iter)
538  {
539  vp[i] = *iter;
540  ++i;
541  }
542  }
543 }
544 
545 
546 template<class T>
547 template<class Addr>
549 {
550  const label len = list.size();
551 
552  reAlloc(len);
553 
554  if (len)
555  {
556  List_ACCESS(T, (*this), vp);
557 
558  for (label i=0; i < len; ++i)
559  {
560  vp[i] = list[i];
561  }
562  }
563 }
564 
565 
566 template<class T>
567 void Foam::List<T>::operator=(std::initializer_list<T> list)
568 {
569  const label len = list.size();
570 
571  reAlloc(len);
572 
573  if (len)
574  {
575  List_ACCESS(T, (*this), vp);
576 
577  label i = 0;
578  for (const T& val : list)
579  {
580  vp[i] = val;
581  ++i;
582  }
583  }
584 }
585 
586 
587 template<class T>
589 {
590  if (this == &list)
591  {
592  return; // Self-assignment is a no-op
593  }
594 
595  transfer(list);
596 }
597 
598 
599 template<class T>
600 template<int SizeMin>
602 {
603  transfer(list);
604 }
605 
606 
607 template<class T>
609 {
610  transfer(list);
611 }
612 
613 
614 template<class T>
616 {
617  const label len = list.size();
618 
619  reAlloc(len);
620 
621  if (len)
622  {
623  List_ACCESS(T, (*this), vp);
624 
625  for (label i = 0; i < len; ++i)
626  {
627  vp[i] = std::move(list.removeHead());
628  }
629  }
630 
631  list.clear();
632 }
633 
634 
635 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
636 
637 #include "ListIO.C"
638 
639 // ************************************************************************* //
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
List.H
stdFoam::begin
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:91
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:57
Foam::one
A class representing the concept of 1 (one), which can be used to avoid manipulating objects that are...
Definition: one.H:60
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::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:436
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:65
Foam::List::operator=
void operator=(const UList< T > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:478
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:66
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:115
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
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:355
List_CONST_ACCESS
#define List_CONST_ACCESS(type, f, fp)
Definition: ListLoopM.H:43
clear
patchWriters clear()
SLList.H
Non-intrusive singly-linked list.
Foam::LList::cend
const const_iterator & cend() const
End of list for forward iterators.
Definition: LList.H:537
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: HashTable.H:102
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:410
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::LList::cbegin
const_iterator cbegin() const
Iterator to first item in list with const access.
Definition: LList.H:500
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:57
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:126
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), which can be used to avoid manipulating objects that ar...
Definition: zero.H:61