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-2025 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 
33 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
34 
35 template<class T>
36 void Foam::List<T>::resize_copy(const label count, const label len)
37 {
38  // Only a limited number of internal size checks.
39  // Caller knows what they are doing.
40 
41  if (FOAM_LIKELY(len > 0))
42  {
43  // With sign-check to avoid spurious -Walloc-size-larger-than
44  const label oldLen = this->size_;
45  const label overlap = Foam::min(count, len);
46  // Extra safety, not currently necessary:
47  // const label overlap = Foam::min(Foam::min(count, oldLen), len);
48 
49  T* old = this->v_;
50 
51  if (overlap > 0)
52  {
53  // Recover overlapping content when resizing
54 
55  this->size_ = len;
56  this->v_ = ListPolicy::allocate<T>(len);
57 
58  // Can dispatch with
59  // - std::execution::par_unseq
60  // - std::execution::unseq
61  std::move(old, (old + overlap), this->v_);
62 
63  ListPolicy::deallocate(old, oldLen);
64  }
65  else
66  {
67  // No overlapping content
68  ListPolicy::deallocate(old, oldLen);
69 
70  this->size_ = len;
71  this->v_ = ListPolicy::allocate<T>(len);
72  }
73  }
74  else
75  {
76  // Or only #ifdef FULLDEBUG
77  if (FOAM_UNLIKELY(len < 0))
78  {
80  << "bad size " << len
81  << abort(FatalError);
82  }
83  // #endif
84 
85  clear();
86  }
87 }
88 
89 
90 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
91 
92 template<class T>
93 Foam::List<T>::List(const label len)
94 :
95  UList<T>(nullptr, len)
96 {
97  if (FOAM_UNLIKELY(len < 0))
98  {
100  << "bad size " << len
101  << abort(FatalError);
102  }
103 
104  if (len > 0)
105  {
106  doAlloc();
107  }
108 }
109 
110 
111 template<class T>
112 Foam::List<T>::List(const label len, const T& val)
113 :
114  UList<T>(nullptr, len)
115 {
116  if (FOAM_UNLIKELY(len < 0))
117  {
119  << "bad size " << len
120  << abort(FatalError);
121  }
122 
123  if (len > 0)
124  {
125  doAlloc();
126  UList<T>::operator=(val);
127  }
128 }
129 
130 
131 template<class T>
132 Foam::List<T>::List(const label len, Foam::zero)
133 :
134  UList<T>(nullptr, len)
135 {
136  if (FOAM_UNLIKELY(len < 0))
137  {
139  << "bad size " << len
140  << abort(FatalError);
141  }
142 
143  if (len > 0)
144  {
145  doAlloc();
147  }
148 }
149 
150 
151 template<class T>
152 Foam::List<T>::List(Foam::one, const T& val)
153 :
154  UList<T>(ListPolicy::allocate<T>(1), 1)
155 {
156  this->v_[0] = val;
157 }
158 
159 
160 template<class T>
162 :
163  UList<T>(ListPolicy::allocate<T>(1), 1)
164 {
165  this->v_[0] = std::move(val);
166 }
167 
168 
169 template<class T>
171 :
172  UList<T>(ListPolicy::allocate<T>(1), 1)
173 {
174  this->v_[0] = Foam::zero{};
175 }
176 
177 
178 template<class T>
179 Foam::List<T>::List(const UList<T>& list)
180 :
181  UList<T>(nullptr, list.size_)
182 {
183  if (this->size_ > 0)
184  {
185  doAlloc();
186  UList<T>::deepCopy(list);
187  }
188 }
189 
190 
191 template<class T>
192 Foam::List<T>::List(const List<T>& list)
193 :
194  UList<T>(nullptr, list.size_)
195 {
196  if (this->size_ > 0)
197  {
198  doAlloc();
199  UList<T>::deepCopy(list);
200  }
201 }
202 
203 
204 template<class T>
205 Foam::List<T>::List(List<T>& list, bool reuse)
206 :
207  UList<T>(nullptr, list.size_)
208 {
209  if (reuse)
210  {
211  // Steal content
212  this->v_ = list.v_;
213  list.v_ = nullptr;
214  list.size_ = 0;
215  }
216  else if (this->size_ > 0)
217  {
218  doAlloc();
219  UList<T>::deepCopy(list);
220  }
221 }
222 
223 
224 template<class T>
225 Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
226 :
227  UList<T>(nullptr, indices.size())
228 {
229  doAlloc();
230  copyList(list, indices); // <- deepCopy()
231 }
232 
233 
234 template<class T>
235 template<unsigned N>
237 (
238  const UList<T>& list,
239  const FixedList<label,N>& indices
240 )
241 :
242  UList<T>(nullptr, indices.size())
243 {
244  doAlloc();
245  copyList(list, indices); // <- deepCopy()
246 }
247 
248 
249 template<class T>
250 template<unsigned N>
252 :
253  List<T>(list.begin(), list.end(), list.size())
254 {}
255 
256 
257 template<class T>
258 Foam::List<T>::List(const PtrList<T>& list)
259 :
260  UList<T>(nullptr, list.size())
261 {
262  doAlloc();
263  copyList(list);
264 }
265 
266 
267 template<class T>
268 template<class Addr>
270 :
271  UList<T>(nullptr, list.size())
272 {
273  if (this->size_ > 0)
274  {
275  doAlloc();
276  UList<T>::deepCopy(list);
277  }
278 }
279 
280 
281 template<class T>
282 Foam::List<T>::List(std::initializer_list<T> list)
283 :
284  List<T>(list.begin(), list.end(), list.size())
285 {}
286 
287 
288 template<class T>
290 :
291  UList<T>(list.data(), list.size())
292 {
293  list.size_ = 0;
294  list.v_ = nullptr;
295 }
296 
297 
298 template<class T>
299 template<int SizeMin>
301 :
302  UList<T>()
303 {
304  transfer(list);
305 }
306 
307 
308 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
309 
310 template<class T>
312 {
313  //TODO? May need to verify that size is accurate (for correct alignment)
314  ListPolicy::deallocate(this->v_, this->size_);
315 }
316 
317 
318 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
319 
320 template<class T>
321 void Foam::List<T>::resize(const label len, const T& val)
322 {
323  const label oldLen = this->size_;
324 
325  if (oldLen == len)
326  {
327  return;
328  }
329 
330  this->resize_copy(oldLen, len);
331 
332  // Fill trailing part with new values
333  if (oldLen < this->size_)
334  {
335  std::fill
336  (
337  (this->v_ + oldLen), (this->v_ + this->size_), val
338  );
339  }
340 }
341 
342 
343 template<class T>
344 void Foam::List<T>::transfer(List<T>& list)
345 {
346  if (this == &list)
347  {
348  return; // Self-assignment is a no-op
349  }
350 
351  // Clear and swap
352  clear();
353  this->size_ = list.size_;
354  this->v_ = list.v_;
355 
356  list.size_ = 0;
357  list.v_ = nullptr;
358 }
359 
360 
361 template<class T>
362 template<int SizeMin>
364 {
365  // Remove existing contents before anything else.
366  clear();
367 
368  // Shrink the allocated space to the number of elements used
369  list.shrink_to_fit();
370  transfer(static_cast<List<T>&>(list));
371  list.clearStorage(); // Deletion, capacity=0 etc.
372 }
373 
374 
375 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
376 
377 template<class T>
378 void Foam::List<T>::operator=(const UList<T>& list)
379 {
380  if (this == &list)
381  {
382  return; // Self-assignment is a no-op
383  }
384 
385  reAlloc(list.size_);
386 
387  if (this->size_ > 0)
388  {
389  UList<T>::deepCopy(list);
390  }
391 }
392 
393 
394 template<class T>
395 void Foam::List<T>::operator=(const List<T>& list)
396 {
397  if (this == &list)
398  {
399  return; // Self-assignment is a no-op
400  }
401 
402  reAlloc(list.size_);
403 
404  if (this->size_ > 0)
405  {
407  }
408 }
409 
410 
411 template<class T>
412 template<unsigned N>
413 void Foam::List<T>::operator=(const FixedList<T, N>& list)
414 {
415  reAlloc(list.size());
417  std::copy(list.begin(), list.end(), this->v_);
418 }
419 
420 
421 template<class T>
422 template<class Addr>
424 {
425  reAlloc(list.size());
426  UList<T>::deepCopy(list);
427 }
428 
429 
430 template<class T>
431 void Foam::List<T>::operator=(std::initializer_list<T> list)
432 {
433  reAlloc(list.size());
434 
435  std::copy(list.begin(), list.end(), this->v_);
436 }
437 
438 
439 template<class T>
441 {
442  if (this == &list)
443  {
444  return; // Self-assignment is a no-op
445  }
447  transfer(list);
448 }
449 
450 
451 template<class T>
452 template<int SizeMin>
454 {
455  transfer(list);
456 }
457 
458 
459 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
460 
461 template<class T>
463 (
464  const UList<T>& list
465 )
466 {
467  labelList order;
468  Foam::sortedOrder(list, order, typename UList<T>::less(list));
469  return order;
470 }
471 
472 
473 template<class T>
475 (
476  const UList<T>& list,
477  labelList& order
478 )
479 {
480  Foam::sortedOrder(list, order, typename UList<T>::less(list));
481 }
482 
483 
484 template<class T, class ListComparePredicate>
486 (
487  const UList<T>& list,
488  labelList& order,
489  const ListComparePredicate& comp
490 )
491 {
492  // List lengths must be identical. Old content is overwritten
493  order.resize_nocopy(list.size());
494 
495  Foam::identity(order, 0);
496  Foam::stableSort(order, comp);
497 }
498 
499 
500 // ************************************************************************* //
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:150
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:337
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:600
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
~List()
Destructor.
Definition: List.C:304
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:168
void stableSort(UList< T > &list)
Stable sort the list.
Definition: UList.C:311
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:433
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
T * allocate(IntType n)
Definition: ListPolicy.H:165
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
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:371
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
void deallocate(T *ptr)
Definition: ListPolicy.H:173
#define FOAM_UNLIKELY(cond)
Definition: stdFoam.H:64
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
#define FOAM_LIKELY(cond)
Definition: stdFoam.H:65
const direction noexcept
Definition: scalarImpl.H:255
const volScalarField & T
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:54
surface1 clear()
const char * end
Definition: SVGTools.H:223
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:425
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:61
void resize_copy(const label count, const label len)
Low-level resizing (backend for resize). Change allocation size of list, retaining the first count co...
Definition: List.C:29
constexpr List() noexcept
Default construct.
Definition: ListI.H:116
A list compare binary predicate for normal sort.
Definition: UList.H:232
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:56