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-2023 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 "FixedList.H"
31 #include "PtrList.H"
32 #include "contiguous.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 template<class T>
37 void Foam::List<T>::doResize(const label len)
38 {
39  if (len == this->size_)
40  {
41  return;
42  }
43 
44  if (len > 0)
45  {
46  // With sign-check to avoid spurious -Walloc-size-larger-than
47  const label overlap = min(this->size_, len);
48 
49  if (overlap > 0)
50  {
51  // Recover overlapping content when resizing
52  T* old = this->v_;
53  this->size_ = len;
54  this->v_ = new T[len];
55 
56  // Can dispatch with
57  // - std::execution::parallel_unsequenced_policy
58  // - std::execution::unsequenced_policy
59  std::move(old, (old + overlap), this->v_);
60 
61  delete[] old;
62  }
63  else
64  {
65  // No overlapping content
66  delete[] this->v_;
67  this->size_ = len;
68  this->v_ = new T[len];
69  }
70  }
71  else
72  {
73  // Or only #ifdef FULLDEBUG
74  if (len < 0)
75  {
77  << "bad size " << len
78  << abort(FatalError);
79  }
80  // #endif
81 
82  clear();
83  }
84 }
85 
86 
87 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
88 
89 template<class T>
90 Foam::List<T>::List(const label len)
91 :
92  UList<T>(nullptr, len)
93 {
94  if (len < 0)
95  {
97  << "bad size " << len
98  << abort(FatalError);
99  }
100 
101  doAlloc();
102 }
103 
104 
105 template<class T>
106 Foam::List<T>::List(const label len, const T& val)
107 :
108  UList<T>(nullptr, len)
109 {
110  if (len < 0)
111  {
113  << "bad size " << len
114  << abort(FatalError);
115  }
116 
117  if (len)
118  {
119  doAlloc();
120  UList<T>::operator=(val);
121  }
122 }
123 
124 
125 template<class T>
126 Foam::List<T>::List(const label len, const Foam::zero)
127 :
128  UList<T>(nullptr, len)
129 {
130  if (len < 0)
131  {
133  << "bad size " << len
134  << abort(FatalError);
135  }
136 
137  if (len)
138  {
139  doAlloc();
141  }
142 }
143 
144 
145 template<class T>
146 Foam::List<T>::List(const Foam::one, const T& val)
147 :
148  UList<T>(new T[1], 1)
149 {
150  this->v_[0] = val;
151 }
152 
153 
154 template<class T>
155 Foam::List<T>::List(const Foam::one, T&& val)
156 :
157  UList<T>(new T[1], 1)
158 {
159  this->v_[0] = std::move(val);
160 }
161 
162 
163 template<class T>
165 :
166  UList<T>(new T[1], 1)
167 {
168  this->v_[0] = Zero;
169 }
170 
171 
172 template<class T>
173 Foam::List<T>::List(const UList<T>& list)
174 :
175  UList<T>(nullptr, list.size_)
176 {
177  if (this->size_ > 0)
178  {
179  doAlloc();
180  UList<T>::deepCopy(list);
181  }
182 }
183 
184 
185 template<class T>
186 Foam::List<T>::List(const List<T>& list)
187 :
188  UList<T>(nullptr, list.size_)
189 {
190  if (this->size_ > 0)
191  {
192  doAlloc();
193  UList<T>::deepCopy(list);
194  }
195 }
196 
197 
198 template<class T>
199 Foam::List<T>::List(List<T>& list, bool reuse)
200 :
201  UList<T>(nullptr, list.size_)
202 {
203  if (reuse)
204  {
205  // Steal content
206  this->v_ = list.v_;
207  list.v_ = nullptr;
208  list.size_ = 0;
209  return;
210  }
211 
212  if (this->size_)
213  {
214  doAlloc();
215  UList<T>::deepCopy(list);
216  }
217 }
218 
219 
220 template<class T>
221 Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
222 :
223  UList<T>(nullptr, indices.size())
224 {
225  doAlloc();
226  copyList(list, indices); // <- deepCopy()
227 }
228 
229 
230 template<class T>
231 template<unsigned N>
233 (
234  const UList<T>& list,
235  const FixedList<label,N>& indices
236 )
237 :
238  UList<T>(nullptr, indices.size())
239 {
240  doAlloc();
241  copyList(list, indices); // <- deepCopy()
242 }
243 
244 
245 template<class T>
246 template<unsigned N>
248 :
249  List<T>(list.begin(), list.end(), list.size())
250 {}
251 
252 
253 template<class T>
254 Foam::List<T>::List(const PtrList<T>& list)
255 :
256  UList<T>(nullptr, list.size())
257 {
258  doAlloc();
259  copyList(list);
260 }
261 
262 
263 template<class T>
264 template<class Addr>
266 :
267  UList<T>(nullptr, list.size())
268 {
269  if (this->size_ > 0)
270  {
271  doAlloc();
272  UList<T>::deepCopy(list);
273  }
274 }
275 
276 
277 template<class T>
278 Foam::List<T>::List(std::initializer_list<T> list)
279 :
280  List<T>(list.begin(), list.end(), list.size())
281 {}
282 
283 
284 template<class T>
286 :
287  UList<T>(list.data(), list.size())
288 {
289  list.size_ = 0;
290  list.v_ = nullptr;
291 }
292 
293 
294 template<class T>
295 template<int SizeMin>
297 :
298  UList<T>()
299 {
300  transfer(list);
301 }
302 
303 
304 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
305 
306 template<class T>
308 {
309  delete[] this->v_;
310 }
311 
312 
313 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
314 
315 template<class T>
316 void Foam::List<T>::resize(const label len, const T& val)
317 {
318  const label oldLen = this->size_;
319  this->doResize(len);
320 
321  // Fill trailing part with new values
322  if (oldLen < this->size_)
323  {
324  std::fill
325  (
326  (this->v_ + oldLen), (this->v_ + this->size_), val
327  );
328  }
329 }
330 
331 
332 template<class T>
333 void Foam::List<T>::transfer(List<T>& list)
334 {
335  if (this == &list)
336  {
337  return; // Self-assignment is a no-op
338  }
339 
340  // Clear and swap
341  clear();
342  this->size_ = list.size_;
343  this->v_ = list.v_;
344 
345  list.size_ = 0;
346  list.v_ = nullptr;
347 }
348 
349 
350 template<class T>
351 template<int SizeMin>
353 {
354  // Remove existing contents before anything else.
355  clear();
356 
357  // Shrink the allocated space to the number of elements used
358  list.shrink_to_fit();
359  transfer(static_cast<List<T>&>(list));
360  list.clearStorage(); // Deletion, capacity=0 etc.
361 }
362 
363 
364 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
365 
366 template<class T>
367 void Foam::List<T>::operator=(const UList<T>& list)
368 {
369  if (this == &list)
370  {
371  return; // Self-assignment is a no-op
372  }
373 
374  reAlloc(list.size_);
375 
376  if (this->size_ > 0)
377  {
378  UList<T>::deepCopy(list);
379  }
380 }
381 
382 
383 template<class T>
384 void Foam::List<T>::operator=(const List<T>& list)
385 {
386  if (this == &list)
387  {
388  return; // Self-assignment is a no-op
389  }
390 
391  reAlloc(list.size_);
392 
393  if (this->size_ > 0)
394  {
396  }
397 }
398 
399 
400 template<class T>
401 template<unsigned N>
402 void Foam::List<T>::operator=(const FixedList<T, N>& list)
403 {
404  reAlloc(list.size());
406  std::copy(list.begin(), list.end(), this->v_);
407 }
408 
409 
410 template<class T>
411 template<class Addr>
413 {
414  reAlloc(list.size());
415  UList<T>::deepCopy(list);
416 }
417 
418 
419 template<class T>
420 void Foam::List<T>::operator=(std::initializer_list<T> list)
421 {
422  reAlloc(list.size());
423 
424  std::copy(list.begin(), list.end(), this->v_);
425 }
426 
427 
428 template<class T>
430 {
431  if (this == &list)
432  {
433  return; // Self-assignment is a no-op
434  }
436  transfer(list);
437 }
438 
439 
440 template<class T>
441 template<int SizeMin>
443 {
444  transfer(list);
445 }
446 
447 
448 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
449 
450 template<class T>
452 (
453  const UList<T>& list
454 )
455 {
456  labelList order;
457  Foam::sortedOrder(list, order, typename UList<T>::less(list));
458  return order;
459 }
460 
461 
462 template<class T>
464 (
465  const UList<T>& list,
466  labelList& order
467 )
468 {
469  Foam::sortedOrder(list, order, typename UList<T>::less(list));
470 }
471 
472 
473 template<class T, class ListComparePredicate>
475 (
476  const UList<T>& list,
477  labelList& order,
478  const ListComparePredicate& comp
479 )
480 {
481  // List lengths must be identical. Old content is overwritten
482  order.resize_nocopy(list.size());
483 
484  Foam::identity(order, 0);
485  Foam::stableSort(order, comp);
486 }
488 
489 // * * * * * * * * * * * * * * * Housekeeping * * * * * * * * * * * * * * * //
490 
491 #include "SLList.H"
492 
493 template<class T>
495 :
496  List<T>(list.begin(), list.end(), list.size())
497 {}
498 
499 
500 template<class T>
501 void Foam::List<T>::operator=(const SLList<T>& list)
502 {
503  const label len = list.size();
504 
505  reAlloc(len);
506 
507  // Cannot use std::copy algorithm
508  // - SLList doesn't define iterator category
509 
510  T* iter = this->begin();
511 
512  for (const T& val : list)
513  {
514  *iter = val;
515  ++iter;
516  }
517 }
518 
519 
520 // ************************************************************************* //
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the 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:56
Template class for non-intrusive linked lists.
Definition: LList.H:46
~List()
Destructor.
Definition: List.C:300
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:175
void stableSort(UList< T > &list)
Stable sort the list.
Definition: UList.C:312
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
void shrink_to_fit()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:420
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
void operator=(const UList< T > &list)
Assignment to UList operator. Takes linear time.
Definition: List.C:360
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
const cellCellStencilObject & overlap
Definition: correctPhi.H:57
patchWriters clear()
label size() const noexcept
The number of elements in the list.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
errorManip< error > abort(error &err)
Definition: errorManip.H:139
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:105
const direction noexcept
Definition: Scalar.H:258
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:201
const volScalarField & T
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:412
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
List< label > labelList
A List of labels.
Definition: List.H:62
Non-intrusive singly-linked list.
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:168
constexpr List() noexcept
Default construct.
Definition: ListI.H:116
A list compare binary predicate for normal sort.
Definition: UList.H:240
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:56
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127