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-2022 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 "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
39template<class T>
40void Foam::List<T>::doResize(const label len)
41{
42 if (len == this->size_)
43 {
44 return;
45 }
46
47 if (len > 0)
48 {
49 // With sign-check to avoid spurious -Walloc-size-larger-than
50 T* nv = new T[len];
51
52 const label overlap = min(this->size_, len);
53
54 if (overlap)
55 {
56 #ifdef USEMEMCPY
57 if (is_contiguous<T>::value)
58 {
59 std::memcpy
60 (
61 static_cast<void*>(nv), this->v_, overlap*sizeof(T)
62 );
63 }
64 else
65 #endif
66 {
67 List_ACCESS(T, *this, vp);
68 for (label i = 0; i < overlap; ++i)
69 {
70 nv[i] = std::move(vp[i]);
71 }
72 }
73 }
74
75 clear();
76 this->size_ = len;
77 this->v_ = nv;
78 }
79 else
80 {
81 // Or only #ifdef FULLDEBUG
82 if (len < 0)
83 {
85 << "bad size " << len
86 << abort(FatalError);
87 }
88 // #endif
89
90 clear();
91 }
92}
93
94
95// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
96
97template<class T>
98Foam::List<T>::List(const label len)
99:
100 UList<T>(nullptr, len)
101{
102 if (len < 0)
103 {
105 << "bad size " << len
106 << abort(FatalError);
107 }
108
109 doAlloc();
110}
111
112
113template<class T>
114Foam::List<T>::List(const label len, const T& val)
115:
116 UList<T>(nullptr, len)
117{
118 if (len < 0)
119 {
121 << "bad size " << len
122 << abort(FatalError);
123 }
124
125 if (len)
127 doAlloc();
128
129 List_ACCESS(T, (*this), vp);
130 for (label i=0; i < len; ++i)
131 {
132 vp[i] = val;
133 }
134 }
136
137
138template<class T>
139Foam::List<T>::List(const label len, const Foam::zero)
140:
141 UList<T>(nullptr, len)
142{
143 if (len < 0)
146 << "bad size " << len
148 }
149
150 if (len)
151 {
152 doAlloc();
154 List_ACCESS(T, (*this), vp);
155 for (label i=0; i < len; ++i)
156 {
157 vp[i] = Zero;
158 }
159 }
160}
162
163template<class T>
165:
166 UList<T>(new T[1], 1)
168 this->v_[0] = val;
169}
170
172template<class T>
175 UList<T>(new T[1], 1)
176{
177 this->v_[0] = std::move(val);
178}
179
180
181template<class T>
183:
184 UList<T>(new T[1], 1)
185{
186 this->v_[0] = Zero;
187}
188
189
190template<class T>
192:
193 UList<T>(nullptr, a.size_)
195 const label len = this->size_;
196
197 if (len)
198 {
199 doAlloc();
200
201 #ifdef USEMEMCPY
203 {
204 std::memcpy
205 (
206 static_cast<void*>(this->v_), a.v_, this->size_bytes()
207 );
208 }
209 else
210 #endif
211 {
212 List_ACCESS(T, (*this), vp);
213 List_CONST_ACCESS(T, a, ap);
214 for (label i = 0; i < len; ++i)
215 {
216 vp[i] = ap[i];
217 }
218 }
219 }
220}
221
222
223template<class T>
225:
226 UList<T>(nullptr, a.size_)
227{
228 const label len = this->size_;
229
230 if (len)
231 {
232 doAlloc();
233
234 #ifdef USEMEMCPY
236 {
237 std::memcpy
238 (
239 static_cast<void*>(this->v_), a.v_, this->size_bytes()
240 );
241 }
242 else
243 #endif
244 {
245 List_ACCESS(T, (*this), vp);
246 List_CONST_ACCESS(T, a, ap);
247 for (label i = 0; i < len; ++i)
248 {
249 vp[i] = ap[i];
250 }
251 }
252 }
253}
255
256template<class T>
258:
259 UList<T>(nullptr, a.size_)
260{
261 if (reuse)
262 {
263 // Steal content
264 this->v_ = a.v_;
265 a.v_ = nullptr;
266 a.size_ = 0;
267 return;
268 }
269
270 const label len = this->size_;
271
272 if (len)
273 {
274 doAlloc();
275
276 #ifdef USEMEMCPY
279 std::memcpy
280 (
281 static_cast<void*>(this->v_), a.v_, this->size_bytes()
282 );
283 }
284 else
285 #endif
286 {
287 List_ACCESS(T, (*this), vp);
288 List_CONST_ACCESS(T, a, ap);
289 for (label i = 0; i < len; ++i)
291 vp[i] = ap[i];
292 }
293 }
295}
296
298template<class T>
299Foam::List<T>::List(const UList<T>& list, const labelUList& indices)
300:
301 UList<T>(nullptr, indices.size())
302{
303 const label len = indices.size();
304
305 if (len)
306 {
307 doAlloc();
308
309 List_ACCESS(T, (*this), vp);
310
311 for (label i=0; i < len; ++i)
312 {
313 vp[i] = list[indices[i]];
314 }
315 }
316}
317
318
319template<class T>
320template<unsigned N>
322(
323 const UList<T>& list,
324 const FixedList<label,N>& indices
325)
326:
327 UList<T>(nullptr, label(N))
328{
329 const label len = label(N);
330
331 doAlloc();
332
333 List_ACCESS(T, (*this), vp);
334
335 for (label i=0; i < len; ++i)
336 {
337 vp[i] = list[indices[i]];
338 }
339}
340
341
342template<class T>
343template<unsigned N>
345:
346 UList<T>(nullptr, label(N))
347{
348 doAlloc();
349 copyList(list);
350}
351
352
353template<class T>
355:
356 UList<T>(nullptr, list.size())
357{
358 doAlloc();
359 copyList(list);
360}
361
362
363template<class T>
365:
366 List<T>(list.begin(), list.end(), list.size())
367{}
368
369
370template<class T>
371template<class Addr>
373:
374 UList<T>(nullptr, list.size())
375{
376 doAlloc();
377 copyList(list);
378}
379
380
381template<class T>
382Foam::List<T>::List(std::initializer_list<T> list)
383:
384 List<T>(list.begin(), list.end(), list.size())
385{}
386
387
388template<class T>
390:
391 UList<T>()
392{
393 // Can use transfer or swap to manage content
394 transfer(list);
395}
396
397
398template<class T>
399template<int SizeMin>
401:
402 UList<T>()
403{
404 transfer(list);
405}
406
407
408template<class T>
410:
411 UList<T>()
412{
413 operator=(std::move(list));
414}
415
416
417// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
418
419template<class T>
421{
422 if (this->v_)
423 {
424 delete[] this->v_;
425 }
426}
427
428
429// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
430
431template<class T>
432void Foam::List<T>::resize(const label len, const T& val)
433{
434 label idx = this->size_;
435 this->doResize(len);
436
437 List_ACCESS(T, *this, vp);
438 while (idx < len)
439 {
440 vp[idx] = val;
441 ++idx;
442 }
443}
444
445
446template<class T>
448{
449 if (this == &list)
450 {
451 return; // Self-assignment is a no-op
452 }
453
454 // Clear and swap - could also check for self assignment
455 clear();
456 this->size_ = list.size_;
457 this->v_ = list.v_;
458
459 list.size_ = 0;
460 list.v_ = nullptr;
461}
462
463
464template<class T>
465template<int SizeMin>
467{
468 // Shrink the allocated space to the number of elements used
469 list.shrink();
470 transfer(static_cast<List<T>&>(list));
471
472 // Ensure DynamicList has proper capacity=0 too
473 list.clearStorage();
474}
475
476
477// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
478
479template<class T>
481{
482 if (this == &a)
483 {
484 return; // Self-assignment is a no-op
485 }
486
487 reAlloc(a.size_);
488
489 const label len = this->size_;
490
491 if (len)
492 {
493 #ifdef USEMEMCPY
495 {
496 std::memcpy
497 (
498 static_cast<void*>(this->v_), a.v_, this->size_bytes()
499 );
500 }
501 else
502 #endif
503 {
504 List_ACCESS(T, (*this), vp);
505 List_CONST_ACCESS(T, a, ap);
506 for (label i = 0; i < len; ++i)
507 {
508 vp[i] = ap[i];
509 }
510 }
511 }
512}
513
514
515template<class T>
517{
518 if (this == &list)
519 {
520 return; // Self-assignment is a no-op
521 }
522
523 operator=(static_cast<const UList<T>&>(list));
524}
525
526
527template<class T>
529{
530 const label len = list.size();
531
532 reAlloc(len);
533
534 if (len)
535 {
536 T* iter = this->begin();
537
538 for (const T& val : list)
539 {
540 *iter = val;
541 ++iter;
542 }
543 }
544}
545
546
547template<class T>
548template<unsigned N>
550{
551 reAlloc(static_cast<label>(N));
552
553 T* iter = this->begin();
554
555 for (const T& val : list)
556 {
557 *iter = val;
558 ++iter;
559 }
560}
561
562
563template<class T>
564template<class Addr>
566{
567 const label len = list.size();
568
569 reAlloc(len);
570
571 if (len)
572 {
573 List_ACCESS(T, (*this), vp);
574
575 for (label i=0; i < len; ++i)
576 {
577 vp[i] = list[i];
578 }
579 }
580}
581
582
583template<class T>
584void Foam::List<T>::operator=(std::initializer_list<T> list)
585{
586 const label len = list.size();
587
588 reAlloc(len);
589
590 if (len)
591 {
592 T* iter = this->begin();
593
594 for (const T& val : list)
595 {
596 *iter = val;
597 ++iter;
598 }
599 }
600}
601
602
603template<class T>
605{
606 if (this == &list)
607 {
608 return; // Self-assignment is a no-op
609 }
610
611 transfer(list);
612}
613
614
615template<class T>
616template<int SizeMin>
618{
619 transfer(list);
620}
621
622
623template<class T>
625{
626 label len = list.size();
627
628 reAlloc(len);
629
630 for (T* iter = this->begin(); len--; ++iter)
631 {
632 *iter = std::move(list.removeHead());
633 }
634
635 list.clear();
636}
637
638
639// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
640
641template<class T>
643(
644 const UList<T>& list
645)
646{
647 labelList order;
648 Foam::sortedOrder(list, order, typename UList<T>::less(list));
649 return order;
650}
651
652
653template<class T>
655(
656 const UList<T>& list,
657 labelList& order
658)
659{
660 Foam::sortedOrder(list, order, typename UList<T>::less(list));
661}
662
663
664template<class T, class ListComparePredicate>
666(
667 const UList<T>& list,
668 labelList& order,
669 const ListComparePredicate& comp
670)
671{
672 // List lengths must be identical. Old content is overwritten
673 order.resize_nocopy(list.size());
674
675 // Same as std::iota and ListOps::identity
676 label value = 0;
677 for (label& item : order)
678 {
679 item = value;
680 ++value;
681 }
682
683 Foam::stableSort(order, comp);
684}
685
686
687// ************************************************************************* //
Macros for accessing List elements.
#define List_ACCESS(type, f, fp)
Definition: ListLoopM.H:39
#define List_CONST_ACCESS(type, f, fp)
Definition: ListLoopM.H:43
Non-intrusive singly-linked list.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:434
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:398
virtual bool resize()
Resize the ODE solver.
Definition: Euler.C:53
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: FixedList.H:81
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
label size() const noexcept
The number of elements in the list.
Template class for non-intrusive linked lists.
Definition: LList.H:79
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void transfer(List< T > &list)
Definition: List.C:447
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:146
void operator=(const UList< T > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:480
constexpr List() noexcept
Default construct.
Definition: ListI.H:95
~List()
Destructor.
Definition: List.C:420
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
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:94
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:258
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:62
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:63
const volScalarField & T
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const cellCellStencilObject & overlap
Definition: correctPhi.H:57
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
void stableSort(UList< T > &list)
Stable sort the list.
Definition: UList.C:356
A list compare binary predicate for normal sort.
Definition: UList.H:188
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:78
const Vector< label > N(dict.get< Vector< label > >("N"))