DynamicListI.H
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) 2016-2021 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 "FixedList.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 template<class T, int SizeMin>
34 template<class ListType>
36 (
37  const ListType& list
38 )
39 {
40  const label len = list.size();
41 
42  if (capacity_ < len)
43  {
44  // Needs more space for the copy operation
45  List<T>::setAddressableSize(capacity_); // Use entire space
46  List<T>::resize_nocopy(len);
47  capacity_ = List<T>::size();
48  }
49 
50  // Perform copy into addressable portion
51  List<T>::setAddressableSize(len);
52  List<T>::operator=(list);
53 }
54 
55 
56 template<class T, int SizeMin>
58 (
59  const bool nocopy,
60  const label newCapacity
61 )
62 {
63  if (newCapacity == capacity_)
64  {
65  return;
66  }
67 
68  // Addressable length, possibly truncated by new capacity
69  const label currLen = min(List<T>::size(), newCapacity);
70 
71  // Corner case...
72  if (List<T>::size() == newCapacity)
73  {
74  // Adjust addressable size to trigger proper resizing.
75  // Using (old size+1) is safe since it does not affect the 'overlap'
76  // of old and new addressable regions, but incurs fewew copy
77  // operations than extending to use the current capacity would.
78  List<T>::setAddressableSize(currLen+1);
79  }
80 
81  if (nocopy)
82  {
83  List<T>::resize_nocopy(newCapacity);
84  }
85  else
86  {
87  List<T>::resize(newCapacity);
88  }
89 
90  capacity_ = List<T>::size();
91  List<T>::setAddressableSize(currLen);
92 }
93 
94 
95 template<class T, int SizeMin>
97 (
98  const bool nocopy,
99  const label len
100 )
101 {
102  if (capacity_ < len)
103  {
104  // Preserve addressed size
105  const label currLen = List<T>::size();
106 
107  // Increase capacity (doubling)
108  capacity_ = max(SizeMin, max(len, label(2*capacity_)));
109 
110  if (nocopy)
111  {
112  List<T>::resize_nocopy(capacity_);
113  }
114  else
115  {
116  List<T>::resize(capacity_);
117  }
118  List<T>::setAddressableSize(currLen);
119  }
120 }
121 
122 
123 template<class T, int SizeMin>
125 (
126  const bool nocopy,
127  const label len
128 )
129 {
130  this->doReserve(nocopy, len);
131  List<T>::setAddressableSize(len);
132 }
133 
134 
135 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
136 
137 template<class T, int SizeMin>
139 :
140  List<T>(),
141  capacity_(0)
142 {}
143 
144 
145 template<class T, int SizeMin>
147 :
148  List<T>(),
149  capacity_(0)
150 {
151  reserve_nocopy(len);
152 }
153 
154 
155 template<class T, int SizeMin>
157 (
158  const label len,
159  const T& val
160 )
161 :
162  List<T>(len, val),
163  capacity_(List<T>::size())
164 {}
165 
166 
167 template<class T, int SizeMin>
169 (
170  const label len,
171  const Foam::zero
172 )
173 :
174  List<T>(len, Zero),
175  capacity_(List<T>::size())
176 {}
177 
178 
179 template<class T, int SizeMin>
181 (
182  const DynamicList<T, SizeMin>& list
183 )
184 :
185  List<T>(list),
186  capacity_(List<T>::size())
187 {}
188 
189 
190 template<class T, int SizeMin>
191 template<int AnySizeMin>
193 (
194  const DynamicList<T, AnySizeMin>& list
195 )
196 :
197  List<T>(list),
198  capacity_(List<T>::size())
199 {}
200 
201 
202 template<class T, int SizeMin>
204 (
205  const UList<T>& list
206 )
207 :
208  List<T>(list),
209  capacity_(List<T>::size())
210 {}
211 
212 
213 template<class T, int SizeMin>
214 template<unsigned N>
216 (
217  const FixedList<T, N>& list
218 )
219 :
220  List<T>(list),
221  capacity_(List<T>::size())
222 {}
223 
224 
225 template<class T, int SizeMin>
227 (
228  std::initializer_list<T> lst
229 )
230 :
231  List<T>(lst),
232  capacity_(List<T>::size())
233 {}
234 
235 
236 template<class T, int SizeMin>
237 template<class Addr>
239 (
240  const IndirectListBase<T, Addr>& lst
241 )
242 :
243  List<T>(lst),
244  capacity_(List<T>::size())
245 {}
246 
247 
248 template<class T, int SizeMin>
250 (
252 )
253 :
254  capacity_(0)
255 {
256  transfer(lst);
257 }
258 
259 
260 template<class T, int SizeMin>
261 template<int AnySizeMin>
263 (
265 )
266 :
267  capacity_(0)
268 {
269  transfer(lst);
270 }
271 
272 
273 template<class T, int SizeMin>
275 (
276  List<T>&& lst
277 )
278 :
279  List<T>(std::move(lst)),
280  capacity_(List<T>::size())
281 {}
282 
283 
284 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
285 
286 template<class T, int SizeMin>
287 inline Foam::label Foam::DynamicList<T, SizeMin>::capacity() const noexcept
288 {
289  return capacity_;
290 }
291 
292 
293 template<class T, int SizeMin>
294 inline std::streamsize
296 {
297  return std::streamsize(capacity_)*sizeof(T);
298 }
299 
300 
301 template<class T, int SizeMin>
303 (
304  const label len
305 )
306 {
307  this->doCapacity(false, len); // nocopy = false
308 }
309 
310 
311 template<class T, int SizeMin>
313 (
314  const label len
315 )
316 {
317  this->doCapacity(true, len); // nocopy = true
318 }
319 
320 
321 template<class T, int SizeMin>
323 (
324  const label len
325 ) noexcept
326 {
327  capacity_ = len;
328 }
329 
330 
331 template<class T, int SizeMin>
333 (
334  const label len
335 )
336 {
337  this->doReserve(false, len); // nocopy = false
338 }
339 
340 
341 template<class T, int SizeMin>
343 (
344  const label len
345 )
346 {
347  this->doReserve(true, len); // nocopy = true
348 }
349 
350 
351 template<class T, int SizeMin>
353 (
354  const label len
355 )
356 {
357  this->doResize(false, len); // nocopy = false
358 }
359 
360 
361 template<class T, int SizeMin>
363 (
364  const label len
365 )
366 {
367  this->doResize(true, len); // nocopy = true
368 }
369 
370 
371 template<class T, int SizeMin>
373 (
374  const label len,
375  const T& val
376 )
377 {
378  label idx = List<T>::size();
379  resize(len);
380 
381  // Fill newly exposed with constant value
382  while (idx < len)
383  {
384  this->operator[](idx) = val;
385  ++idx;
386  }
387 }
388 
389 
390 template<class T, int SizeMin>
392 {
394 }
395 
396 
397 template<class T, int SizeMin>
399 {
400  List<T>::clear();
401  capacity_ = 0;
402 }
403 
404 
405 template<class T, int SizeMin>
406 inline Foam::label Foam::DynamicList<T, SizeMin>::expandStorage() noexcept
407 {
408  const label currLen = List<T>::size();
409 
410  // Address into the entire list
411  List<T>::setAddressableSize(capacity_);
412 
413  return currLen;
414 }
415 
416 
417 template<class T, int SizeMin>
419 {
420  const label currLen = List<T>::size();
421  if (currLen < capacity_)
422  {
423  // Adjust addressable size to trigger proper resizing
424  List<T>::setAddressableSize(currLen+1);
425 
426  List<T>::resize(currLen);
427  capacity_ = List<T>::size();
428  }
429 }
430 
431 
432 template<class T, int SizeMin>
435 {
436  this->shrinkStorage();
437  return *this;
438 }
439 
440 
441 template<class T, int SizeMin>
442 template<int AnySizeMin>
444 (
446 )
447 {
448  // Cannot compare 'this' for different types, so use cdata()
449  if (this->cdata() == other.cdata())
450  {
451  return; // Self-swap is a no-op
452  }
453 
454  // Swap storage and addressable size
455  UList<T>::swap(other);
456 
457  // Swap capacity
458  std::swap(this->capacity_, other.capacity_);
459 }
460 
461 
462 template<class T, int SizeMin>
463 inline void
465 {
466  // Take over storage, clear addressing for list
467  capacity_ = list.size();
468  List<T>::transfer(list);
469 }
470 
471 
472 template<class T, int SizeMin>
473 template<int AnySizeMin>
474 inline void
476 (
478 )
479 {
480  // Cannot compare 'this' for different types, so use cdata()
481  if (this->cdata() == list.cdata())
482  {
483  return; // Self-assignment is a no-op
484  }
485 
486  // Take over storage as-is (without shrink, without using SizeMin)
487  // clear addressing and storage for old lst.
488  capacity_ = list.capacity();
489 
490  List<T>::transfer(static_cast<List<T>&>(list));
491  list.clearStorage(); // Ensure capacity=0
492 }
493 
494 
495 template<class T, int SizeMin>
496 inline void
498 (
499  SortableList<T>& list
500 )
501 {
502  list.shrink(); // Shrink away sort indices
503  capacity_ = list.size(); // Capacity after transfer == list size
504  List<T>::transfer(list);
505 }
506 
507 
508 template<class T, int SizeMin>
511 (
512  const T& val
513 )
514 {
515  const label idx = List<T>::size();
516  resize(idx + 1);
517 
518  this->operator[](idx) = val; // copy element
519  return *this;
520 }
521 
522 
523 template<class T, int SizeMin>
526 (
527  T&& val
528 )
529 {
530  const label idx = List<T>::size();
531  resize(idx + 1);
532 
533  this->operator[](idx) = std::move(val); // move assign element
534  return *this;
535 }
536 
537 
538 template<class T, int SizeMin>
541 (
542  const UList<T>& lst
543 )
544 {
545  if (this == &lst)
546  {
548  << "Attempted appending to self"
549  << abort(FatalError);
550  }
551 
552  label idx = List<T>::size();
553  resize(idx + lst.size());
554 
555  for (const T& val : lst)
556  {
557  this->operator[](idx++) = val; // copy element
558  }
559  return *this;
560 }
561 
562 
563 template<class T, int SizeMin>
564 template<unsigned N>
567 (
568  const FixedList<T, N>& lst
569 )
570 {
571  label idx = List<T>::size();
572  resize(idx + lst.size());
573 
574  for (const T& val : lst)
575  {
576  this->operator[](idx++) = val; // copy element
577  }
578  return *this;
579 }
580 
581 
582 template<class T, int SizeMin>
585 (
586  std::initializer_list<T> lst
587 )
588 {
589  label idx = List<T>::size();
590  resize(idx + lst.size());
591 
592  for (const T& val : lst)
593  {
594  this->operator[](idx++) = val; // copy element
595  }
596  return *this;
597 }
598 
599 
600 template<class T, int SizeMin>
601 template<class Addr>
604 (
605  const IndirectListBase<T, Addr>& lst
606 )
607 {
608  label idx = List<T>::size();
609  const label n = lst.size();
610 
611  resize(idx + n);
612 
613  for (label i=0; i<n; ++i)
614  {
615  this->operator[](idx++) = lst[i]; // copy element
616  }
617  return *this;
618 }
619 
620 
621 template<class T, int SizeMin>
624 (
625  List<T>&& list
626 )
627 {
628  if (this == &list)
629  {
631  << "Attempted appending to self"
632  << abort(FatalError);
633  }
634 
635  label idx = List<T>::size();
636  resize(idx + list.size());
637 
638  for (T& val : list)
639  {
640  Foam::Swap(this->operator[](idx++), val); // moved content
641  }
642 
643  list.clear();
644  return *this;
645 }
646 
647 
648 template<class T, int SizeMin>
651 (
653 )
654 {
655  append(std::move(static_cast<List<T>&>(lst)));
656  lst.clearStorage(); // Ensure capacity=0
657  return *this;
658 }
659 
660 
661 template<class T, int SizeMin>
662 template<int AnySizeMin>
665 (
667 )
668 {
669  append(std::move(static_cast<List<T>&>(lst)));
670  lst.clearStorage(); // Ensure capacity=0
671  return *this;
672 }
673 
674 
675 template<class T, int SizeMin>
678 (
679  SortableList<T>&& lst
680 )
681 {
682  lst.shrink(); // Shrink away sort indices
683  append(std::move(static_cast<List<T>&>(lst)));
684  return *this;
685 }
686 
687 
688 template<class T, int SizeMin>
689 inline Foam::label Foam::DynamicList<T, SizeMin>::appendUniq(const T& val)
690 {
691  if (this->found(val))
692  {
693  return 0;
694  }
695  else
696  {
697  this->append(val);
698  return 1; // Increased list length by one
699  }
700 }
701 
702 
703 template<class T, int SizeMin>
705 {
706  // Location of last element and simultaneously the new size
707  const label idx = List<T>::size() - 1;
708 
709  if (idx < 0)
710  {
712  << "List is empty" << abort(FatalError);
713  }
714 
715  const T& val = List<T>::operator[](idx);
716 
718 
719  return val;
720 }
721 
722 
723 template<class T, int SizeMin>
725 (
726  const label idx,
727  const bool fast
728 )
729 {
730  if (fast)
731  {
732  // Simply swap idx <=> last
733  this->swapLast(idx);
734  }
735  else
736  {
737  // Move element to the end and move everything down
738  this->moveLast(idx);
739  }
740 
741  // Element to remove is now at the end
742  return this->remove();
743 }
744 
745 
746 template<class T, int SizeMin>
747 inline Foam::label Foam::DynamicList<T, SizeMin>::remove
748 (
749  const labelRange& range
750 )
751 {
752  return this->removeElements(this->validateRange(range));
753 }
754 
755 
756 template<class T, int SizeMin>
757 inline Foam::label Foam::DynamicList<T, SizeMin>::remove
758 (
759  std::initializer_list<label> start_size
760 )
761 {
762  return this->removeElements(this->validateRange(start_size));
763 }
764 
765 
766 template<class T, int SizeMin>
767 inline Foam::label Foam::DynamicList<T, SizeMin>::subset
768 (
769  const labelRange& range
770 )
771 {
772  return this->subsetElements(this->validateRange(range));
773 }
774 
775 
776 template<class T, int SizeMin>
777 inline Foam::label Foam::DynamicList<T, SizeMin>::subset
778 (
779  std::initializer_list<label> start_size
780 )
781 {
782  return this->subsetElements(this->validateRange(start_size));
783 }
784 
785 
786 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
787 
788 template<class T, int SizeMin>
790 (
791  const label i
792 )
793 {
794  if (i >= List<T>::size())
795  {
796  resize(i + 1);
797  }
798 
799  return this->operator[](i);
800 }
801 
802 
803 template<class T, int SizeMin>
805 (
806  const T& val
807 )
808 {
809  UList<T>::operator=(val);
810 }
811 
812 
813 template<class T, int SizeMin>
815 (
816  const Foam::zero
817 )
818 {
820 }
821 
822 
823 template<class T, int SizeMin>
825 (
826  const UList<T>& lst
827 )
828 {
829  assignDynList(lst);
830 }
831 
832 
833 template<class T, int SizeMin>
834 template<unsigned N>
836 (
837  const FixedList<T, N>& lst
838 )
839 {
840  assignDynList(lst);
841 }
842 
843 
844 template<class T, int SizeMin>
846 (
847  const DynamicList<T, SizeMin>& lst
848 )
849 {
850  if (this == &lst)
851  {
852  return; // Self-assignment is a no-op
853  }
854 
855  assignDynList(lst);
856 }
857 
858 
859 template<class T, int SizeMin>
860 template<int AnySizeMin>
862 (
863  const DynamicList<T, AnySizeMin>& list
864 )
865 {
866  // Cannot compare 'this' for different types, so use cdata()
867  if (this->cdata() == list.cdata())
868  {
869  return; // Self-assignment is a no-op
870  }
871 
872  assignDynList(list);
873 }
874 
875 
876 template<class T, int SizeMin>
878 (
879  std::initializer_list<T> lst
880 )
881 {
882  assignDynList(lst);
883 }
884 
885 
886 template<class T, int SizeMin>
887 template<class Addr>
889 (
890  const IndirectListBase<T, Addr>& lst
891 )
892 {
893  assignDynList(lst);
894 }
895 
896 
897 template<class T, int SizeMin>
899 (
900  List<T>&& lst
901 )
902 {
903  clear();
904  transfer(lst);
905 }
906 
907 
908 template<class T, int SizeMin>
910 (
912 )
913 {
914  if (this == &lst)
915  {
916  return; // Self-assignment is a no-op
917  }
918 
919  clear();
920  transfer(lst);
921 }
922 
923 
924 template<class T, int SizeMin>
925 template<int AnySizeMin>
927 (
929 )
930 {
931  // Cannot compare 'this' for different types, so use cdata()
932  if (this->cdata() == list.cdata())
933  {
934  return; // Self-assignment is a no-op
935  }
936 
937  clear();
938  transfer(list);
939 }
940 
941 
942 template<class T, int SizeMin>
944 (
945  SortableList<T>&& lst
946 )
947 {
948  clear();
949  transfer(lst);
950 }
951 
952 
953 // ************************************************************************* //
Foam::DynamicList::resize
void resize(const label len)
Definition: DynamicListI.H:353
Foam::DynamicList::subset
label subset(const labelRange &range)
Retain a (start,size) subset from the list.
Definition: DynamicListI.H:768
Foam::DynamicList::setCapacity_unsafe
void setCapacity_unsafe(const label len) noexcept
Definition: DynamicListI.H:323
Foam::DynamicList::DynamicList
constexpr DynamicList() noexcept
Default construct, an empty list without allocation.
Definition: DynamicListI.H:138
Foam::Swap
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Definition: DynamicList.H:429
Foam::DynamicList::setCapacity_nocopy
void setCapacity_nocopy(const label len)
Definition: DynamicListI.H:313
Foam::DynamicList::swap
void swap(DynamicList< T, AnySizeMin > &other)
Swap content, independent of sizing parameter.
Definition: DynamicListI.H:444
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::DynamicList::shrinkStorage
void shrinkStorage()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:418
Foam::DynamicList::capacity_bytes
std::streamsize capacity_bytes() const noexcept
Number of contiguous bytes of the underlying storage.
Definition: DynamicListI.H:295
Foam::FixedList::size
static constexpr label size() noexcept
Return the number of elements in the FixedList.
Definition: FixedList.H:416
Foam::DynamicList::operator
friend Ostream & operator(Ostream &os, const DynamicList< T, SizeMin > &list)
Write to Ostream.
Foam::DynamicList::reserve
void reserve(const label len)
Definition: DynamicListI.H:333
Foam::DynamicList::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicListI.H:287
append
rAUs append(new volScalarField(IOobject::groupName("rAU", phase1.name()), 1.0/(U1Eqn.A()+byDt(max(phase1.residualAlpha() - alpha1, scalar(0)) *rho1))))
Foam::DynamicList::shrink
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:434
Foam::DynamicList::clear
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
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::DynamicList::expandStorage
label expandStorage() noexcept
Expand the addressable size to fit the allocated capacity.
Definition: DynamicListI.H:406
Foam::DynamicList::setCapacity
void setCapacity(const label len)
Alter the size of the underlying storage.
Definition: DynamicListI.H:303
n
label n
Definition: TABSMDCalcMethod2.H:31
resize
patchWriters resize(patchIds.size())
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::labelRange
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:55
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::SortableList::shrink
List< T > & shrink()
Clear the indices and return a reference to the underlying List.
Definition: SortableList.C:116
Foam::DynamicList::reserve_nocopy
void reserve_nocopy(const label len)
Definition: DynamicListI.H:343
Foam::FatalError
error FatalError
Foam::SortableList
A list that is sorted upon construction or when explicitly requested with the sort() method.
Definition: List.H:60
Foam::IndirectListBase::size
label size() const noexcept
The number of elements in the list.
Definition: IndirectListBase.H:125
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
found
bool found
Definition: TABSMDCalcMethod2.H:32
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
range
scalar range
Definition: LISASMDCalcMethod1.H:12
clear
patchWriters clear()
Foam::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:63
Foam::FixedList
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:104
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:398
Foam::DynamicList::remove
T remove()
Remove and return the last element. Fatal on an empty list.
Definition: DynamicListI.H:704
Foam::DynamicList::transfer
void transfer(List< T > &list)
Transfer contents of the argument List into this.
Definition: DynamicListI.H:464
Foam::DynamicList::resize_nocopy
void resize_nocopy(const label len)
Definition: DynamicListI.H:363
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:56
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
FixedList.H
Foam::DynamicList::appendUniq
label appendUniq(const T &val)
Append an element if not already in the list.
Definition: DynamicListI.H:689
Foam::zero
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:62