Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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 "UPtrList.H"
32
33// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
34
35// Only a limited number of internal size checks.
36// Caller knows what they are doing.
37template<class T>
38void Foam::List<T>::resize_copy(label count, const label len)
39{
40 if (this->size_ == len)
41 {
42 // no-op
43 }
44 else if (FOAM_LIKELY(len > 0))
45 {
46 // With sign-check to avoid spurious -Walloc-size-larger-than
47
48 T* old = this->v_;
49 const label oldLen = this->size_;
50
51 // The count truncated by the new length?
52 count = std::min(count, len);
53
54 // Extra safety, probably not necessary:
55 // The count truncated by the old length?
56 // // count = std::min(count, oldLen);
57
58 if (count > 0)
59 {
60 // Recover overlapping content when resizing
61
62 this->size_ = len;
63 this->v_ = ListPolicy::allocate<T>(len);
64
65 // Can dispatch with
66 // - std::execution::par_unseq
67 // - std::execution::unseq
68 std::move(old, (old + count), this->v_);
69
70 ListPolicy::deallocate(old, oldLen);
71 }
72 else
73 {
74 // No overlapping content
75 ListPolicy::deallocate(old, oldLen);
76
77 this->size_ = len;
78 this->v_ = ListPolicy::allocate<T>(len);
79 }
80 }
81 else
82 {
83 // Or only #ifdef FULLDEBUG
84 if (FOAM_UNLIKELY(len < 0))
85 {
87 << "bad size " << len
88 << abort(FatalError);
89 }
90 // #endif
91
92 clear();
93 }
94}
95
96
97// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
98
99template<class T>
100Foam::List<T>::List(const label len)
101:
102 UList<T>()
103{
104 if (FOAM_UNLIKELY(len < 0))
105 {
107 << "bad size " << len
108 << abort(FatalError);
109 }
110
111 if (len > 0)
112 {
113 // resize_nocopy()
114 doAlloc(len);
115 }
116}
117
118
119template<class T>
120Foam::List<T>::List(const label len, const T& val)
121:
122 UList<T>()
123{
124 if (FOAM_UNLIKELY(len < 0))
125 {
127 << "bad size " << len
128 << abort(FatalError);
129 }
130
131 if (len > 0)
132 {
133 // resize_fill()
134 doAlloc(len);
136 }
137}
138
139
140template<class T>
141Foam::List<T>::List(const label len, Foam::zero)
142:
143 UList<T>()
144{
145 if (FOAM_UNLIKELY(len < 0))
146 {
148 << "bad size " << len
149 << abort(FatalError);
150 }
151
152 if (len > 0)
153 {
154 // resize_fill()
155 doAlloc(len);
157 }
158}
159
160
161template<class T>
162Foam::List<T>::List(Foam::one, const T& val)
163:
164 UList<T>(ListPolicy::allocate<T>(1), 1)
165{
166 this->v_[0] = val;
167}
168
169
170template<class T>
172:
173 UList<T>(ListPolicy::allocate<T>(1), 1)
174{
175 this->v_[0] = std::move(val);
176}
177
178
179template<class T>
181:
182 UList<T>(ListPolicy::allocate<T>(1), 1)
183{
184 this->v_[0] = Foam::zero{};
185}
186
187
188template<class T>
189Foam::List<T>::List(const UList<T>& list)
190:
191 UList<T>()
192{
193 if (!list.empty())
194 {
195 doAlloc(list.size());
196 UList<T>::deepCopy(list);
197 }
198}
199
200
201template<class T>
202Foam::List<T>::List(const List<T>& list)
203:
204 UList<T>()
205{
206 if (!list.empty())
207 {
208 doAlloc(list.size());
209 UList<T>::deepCopy(list);
210 }
211}
212
213
214template<class T>
215Foam::List<T>::List(List<T>& list, bool reuse)
216:
217 UList<T>()
218{
219 if (reuse)
220 {
221 // Steal content
222 this->v_ = list.v_;
223 this->size_ = list.size_;
224 list.v_ = nullptr;
225 list.size_ = 0;
226 }
227 else if (!list.empty())
228 {
229 doAlloc(list.size());
230 UList<T>::deepCopy(list);
231 }
232}
233
234
235template<class T>
236Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
237:
238 UList<T>()
239{
240 if (!indices.empty())
241 {
242 doAlloc(indices.size());
243 copyList(list, indices); // <- deepCopy()
244 }
245}
246
247
248template<class T>
249template<unsigned N>
251(
252 const UList<T>& list,
253 const FixedList<label,N>& indices
255:
256 UList<T>()
257{
258 // if (!FixedList::empty()) is always true
259 {
260 doAlloc(indices.size());
261 copyList(list, indices); // <- deepCopy()
262 }
263}
264
265
266template<class T>
267template<unsigned N>
269:
270 List<T>(list.begin(), list.end(), list.size())
271{}
272
273
274template<class T>
276:
277 UList<T>()
278{
279 if (!list.empty())
280 {
281 doAlloc(list.size());
282 copyList(list);
284}
285
286
287template<class T>
288template<class Addr>
290:
291 UList<T>()
292{
293 if (!list.empty())
294 {
295 doAlloc(list.size());
296 UList<T>::deepCopy(list);
297 }
298}
299
300
301template<class T>
302Foam::List<T>::List(std::initializer_list<T> list)
304 List<T>(list.begin(), list.end(), list.size())
305{}
306
308template<class T>
309template<int SizeMin>
311:
312 UList<T>()
313{
314 transfer(list);
315}
316
317
318// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
319
320template<class T>
322{
323 //TODO? May need to verify that size is accurate (for correct alignment)
324 ListPolicy::deallocate(this->v_, this->size_);
325}
326
327
328// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
329
330template<class T>
331void Foam::List<T>::resize(const label len, const T& val)
332{
333 const label oldLen = this->size_;
334
335 if (oldLen == len)
336 {
337 return;
338 }
339
340 resize_copy(oldLen, len);
341
342 // Fill trailing part with new values
343 if (oldLen < this->size_)
344 {
345 std::fill
346 (
347 (this->v_ + oldLen), (this->v_ + this->size_), val
348 );
349 }
350}
351
352
353template<class T>
354void Foam::List<T>::transfer(List<T>& list)
355{
356 if (this == &list)
357 {
358 return; // Self-assignment is a no-op
359 }
360
361 // Clear and swap
362 clear();
363 this->size_ = list.size_;
364 this->v_ = list.v_;
365
366 list.size_ = 0;
367 list.v_ = nullptr;
368}
369
370
371template<class T>
372template<int SizeMin>
374{
375 // Remove existing contents before anything else.
376 clear();
377
378 // Shrink the allocated space to the number of elements used
379 list.shrink_to_fit();
380 transfer(static_cast<List<T>&>(list));
381 list.setCapacity_unsafe(0); // All contents moved
382}
383
384
385// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
386
387template<class T>
388void Foam::List<T>::operator=(const UList<T>& list)
389{
390 if (this == &list)
391 {
392 return; // Self-assignment is a no-op
393 }
394
395 resize_nocopy(list.size());
396
397 if (!list.empty())
399 UList<T>::deepCopy(list);
400 }
401}
402
403
404template<class T>
405void Foam::List<T>::operator=(const List<T>& list)
406{
407 if (this == &list)
408 {
409 return; // Self-assignment is a no-op
410 }
411
412 resize_nocopy(list.size());
413
414 if (!list.empty())
415 {
417 }
418}
419
420
421template<class T>
422template<unsigned N>
423void Foam::List<T>::operator=(const FixedList<T, N>& list)
424{
425 resize_nocopy(list.size());
427 std::copy(list.begin(), list.end(), this->v_);
428}
429
430
431template<class T>
432template<class Addr>
435 resize_nocopy(list.size());
436 UList<T>::deepCopy(list);
437}
438
439
440template<class T>
441void Foam::List<T>::operator=(std::initializer_list<T> list)
443 resize_nocopy(list.size());
444 std::copy(list.begin(), list.end(), this->v_);
445}
446
447
448template<class T>
450{
451 if (this == &list)
452 {
453 return; // Self-assignment is a no-op
454 }
456 transfer(list);
457}
458
459
460template<class T>
461template<int SizeMin>
463{
464 transfer(list);
465}
466
467
468// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
469
470template<class T>
472(
473 const UList<T>& list
474)
475{
477 Foam::sortedOrder(list, order, typename UList<T>::less(list));
478 return order;
479}
480
481
482template<class T>
484(
485 const UList<T>& list,
486 labelList& order
488{
489 Foam::sortedOrder(list, order, typename UList<T>::less(list));
490}
491
492
493template<class T, class ListComparePredicate>
495(
496 const UList<T>& list,
497 labelList& order,
498 const ListComparePredicate& comp
499)
500{
501 // List lengths must be identical. Old content is overwritten
502 order.resize_nocopy(list.size());
503
504 Foam::identity(order, 0);
505 Foam::stableSort(order, comp);
506}
507
508
509// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void setCapacity_unsafe(label len) noexcept
Change the value for the list capacity directly (ADVANCED, UNSAFE) Does not perform any memory manage...
void shrink_to_fit()
Shrink the allocated space to the number of elements used.
A 1D vector of objects of type <T> with a fixed length <N>.
Definition FixedList.H:73
static constexpr label size() noexcept
Return the number of elements in the FixedList.
Definition FixedList.H:619
iterator end() noexcept
Return an iterator to end traversing the FixedList.
Definition FixedListI.H:526
iterator begin() noexcept
Return an iterator to begin traversing the FixedList.
Definition FixedListI.H:478
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
label size() const noexcept
The number of elements in the list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition List.C:347
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition ListI.H:171
void operator=(const UList< T > &list)
Assignment to UList operator. Takes linear time.
Definition List.C:381
constexpr List() noexcept
Default construct.
Definition ListI.H:108
void resize_copy(label count, const label len)
Change allocated size of list, retaining the first count elements.
Definition List.C:31
~List()
Destructor.
Definition List.C:314
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
void deepCopy(const UList< T > &list)
Copy elements of the given UList. Sizes must match!
Definition UList.C:95
UList(const UList< T > &) noexcept=default
Copy construct, shallow copy.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
UList< T > & operator=(const UList< T > &)=delete
No copy assignment (default: shallow copy).
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition UPtrList.H:101
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition UPtrListI.H:99
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition one.H:57
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
const volScalarField & T
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
surface1 clear()
Additional compile-time controls of List behaviour.
T * allocate(IntType n)
Allocate from memory pool (if active), or aligned, or normal.
Definition ListPolicy.H:190
void deallocate(T *ptr)
Deallocate from memory pool, or normal.
Definition ListPolicy.H:236
List< label > labelList
A List of labels.
Definition List.H:62
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
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...
errorManip< error > abort(error &err)
Definition errorManip.H:139
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
UList< label > labelUList
A UList of labels.
Definition UList.H:75
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
void stableSort(UList< T > &list)
Stable sort the list.
Definition UList.C:299
#define FOAM_LIKELY(cond)
Definition stdFoam.H:65
#define FOAM_UNLIKELY(cond)
Definition stdFoam.H:64
A list compare binary predicate for normal sort.
Definition UList.H:237