DynamicFieldI.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-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 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
31 template<class T, int SizeMin>
32 template<class ListType>
34 (
35  const ListType& list
36 )
37 {
38  const label len = list.size();
39 
40  if (capacity_ < len)
41  {
42  // Needs more space for the copy operation
43  List<T>::setAddressableSize(capacity_);
44  List<T>::resize_nocopy(len);
45  capacity_ = List<T>::size();
46  }
47 
48  // Perform copy into addressable portion
49  List<T>::setAddressableSize(len);
50  List<T>::operator=(list);
51 }
52 
53 
54 template<class T, int SizeMin>
56 (
57  const bool nocopy,
58  const label newCapacity
59 )
60 {
61  if (newCapacity == capacity_)
62  {
63  return;
64  }
65 
66  // Addressable length, possibly truncated by new capacity
67  const label currLen = Foam::min(List<T>::size(), newCapacity);
68 
69  List<T>::setAddressableSize(capacity_);
70  if (nocopy)
71  {
72  List<T>::resize_nocopy(newCapacity);
73  }
74  else
75  {
76  List<T>::resize_copy(currLen, newCapacity);
77  }
78 
79  capacity_ = List<T>::size();
80  List<T>::setAddressableSize(currLen);
81 }
82 
83 
84 template<class T, int SizeMin>
86 (
87  const bool nocopy,
88  const label len
89 )
90 {
91  if (capacity_ < len)
92  {
93  // Preserve addressed size
94  const label currLen = List<T>::size();
95 
96  // Increase capacity (eg, doubling)
97  capacity_ =
98  Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
99 
100  if (nocopy)
101  {
102  List<T>::resize_nocopy(capacity_);
103  }
104  else
105  {
106  List<T>::resize(capacity_);
107  }
108  List<T>::setAddressableSize(currLen);
109  }
110 }
111 
112 
113 template<class T, int SizeMin>
115 (
116  const bool nocopy,
117  const label len
118 )
119 {
120  this->doReserve(nocopy, len);
122 }
123 
124 
125 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 
127 template<class T, int SizeMin>
129 :
130  Field<T>(),
131  capacity_(0)
132 {}
133 
134 
135 template<class T, int SizeMin>
136 inline Foam::DynamicField<T, SizeMin>::DynamicField(const label initialCapacity)
137 :
138  Field<T>(),
139  capacity_(0)
140 {
141  reserve_nocopy(initialCapacity);
142 }
143 
144 
145 template<class T, int SizeMin>
147 (
148  const std::pair<label,label>& sizing
149 )
150 :
151  Field<T>(std::max(sizing.first, sizing.second)),
152  capacity_(Field<T>::size())
153 {
154  List<T>::setAddressableSize(sizing.first);
155 }
156 
157 
158 template<class T, int SizeMin>
160 (
161  const label len,
162  const T& val
163 )
164 :
165  Field<T>(len, val),
166  capacity_(Field<T>::size())
167 {}
168 
169 
170 template<class T, int SizeMin>
172 (
173  const label len,
174  Foam::zero
175 )
176 :
177  Field<T>(len, Foam::zero{}),
178  capacity_(Field<T>::size())
179 {}
180 
181 
182 template<class T, int SizeMin>
184 (
185  const DynamicField<T, SizeMin>& list
186 )
187 :
188  Field<T>(list),
189  capacity_(Field<T>::size())
190 {}
191 
192 
193 template<class T, int SizeMin>
194 template<int AnySizeMin>
196 (
197  const DynamicField<T, AnySizeMin>& list
198 )
199 :
200  Field<T>(list),
201  capacity_(Field<T>::size())
202 {}
203 
204 
205 template<class T, int SizeMin>
207 (
208  const UList<T>& list
209 )
210 :
211  Field<T>(list),
212  capacity_(Field<T>::size())
213 {}
214 
215 
216 template<class T, int SizeMin>
217 template<class Addr>
219 (
220  const IndirectListBase<T, Addr>& list
221 )
222 :
223  Field<T>(list),
224  capacity_(Field<T>::size())
225 {}
226 
227 
228 template<class T, int SizeMin>
230 (
231  List<T>&& content
232 ) noexcept
233 :
234  Field<T>(std::move(content)),
235  capacity_(Field<T>::size())
236 {}
237 
238 
239 template<class T, int SizeMin>
240 template<int AnySizeMin>
242 (
244 ) noexcept
245 :
246  Field<T>(std::move(static_cast<List<T>&>(content))),
247  capacity_(content.capacity())
248 {
249  content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
250 }
251 
252 
253 template<class T, int SizeMin>
255 (
256  DynamicField<T, SizeMin>&& content
257 ) noexcept
258 :
259  Field<T>(std::move(static_cast<List<T>&>(content))),
260  capacity_(content.capacity())
261 {
262  content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
263 }
264 
265 
266 template<class T, int SizeMin>
267 template<int AnySizeMin>
269 (
271 ) noexcept
272 :
273  Field<T>(std::move(static_cast<List<T>&>(content))),
274  capacity_(content.capacity())
275 {
276  content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
277 }
278 
279 
280 template<class T, int SizeMin>
281 template<int AnySizeMin>
283 (
285  bool reuse
286 )
287 :
288  Field<T>(),
289  capacity_(0)
290 {
291  if (reuse)
292  {
293  Field<T>::transfer(static_cast<List<T>&>(content));
294  capacity_ = content.capacity();
295  content.setCapacity_unsafe(0);
296  }
297  else
298  {
299  Field<T>::operator=(content);
300  capacity_ = content.size();
301  }
302 }
303 
304 
305 template<class T, int SizeMin>
306 template<int AnySizeMin>
308 (
309  DynamicList<T, AnySizeMin>& content,
310  bool reuse
311 )
312 :
313  Field<T>(),
314  capacity_(0)
315 {
316  if (reuse)
317  {
318  Field<T>::transfer(static_cast<List<T>&>(content));
319  capacity_ = content.capacity();
320  content.setCapacity_unsafe(0);
321  }
322  else
323  {
324  Field<T>::operator=(content);
325  capacity_ = content.size();
326  }
327 }
328 
329 
330 template<class T, int SizeMin>
332 (
333  List<T>& content,
334  bool reuse
335 )
336 :
337  Field<T>(),
338  capacity_(content.size())
339 {
340  if (reuse)
341  {
342  Field<T>::transfer(content);
343  }
344  else
345  {
347  }
348 }
349 
350 
351 template<class T, int SizeMin>
353 (
354  const UList<T>& mapF,
355  const labelUList& mapAddressing
356 )
357 :
358  Field<T>(mapF, mapAddressing),
359  capacity_(Field<T>::size())
360 {}
361 
362 
363 template<class T, int SizeMin>
365 (
366  const UList<T>& mapF,
367  const labelListList& mapAddressing,
368  const scalarListList& weights
369 )
370 :
371  Field<T>(mapF, mapAddressing, weights),
372  capacity_(Field<T>::size())
373 {}
374 
375 
376 template<class T, int SizeMin>
378 (
379  const UList<T>& mapF,
380  const FieldMapper& map
381 )
382 :
383  Field<T>(mapF, map),
384  capacity_(Field<T>::size())
385 {}
386 
387 
388 template<class T, int SizeMin>
390 :
391  Field<T>(is),
392  capacity_(Field<T>::size())
393 {}
394 
395 
396 template<class T, int SizeMin>
399 {
400  return tmp<DynamicField<T, SizeMin>>::New(*this);
401 }
402 
403 
404 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
405 
406 template<class T, int SizeMin>
407 inline std::streamsize
409 {
410  return std::streamsize(capacity_)*sizeof(T);
411 }
412 
413 
414 template<class T, int SizeMin>
416 (
417  const label len
418 )
419 {
420  this->doCapacity(false, len); // nocopy = false
421 }
422 
423 
424 template<class T, int SizeMin>
426 (
427  const label len
428 )
429 {
430  this->doCapacity(true, len); // nocopy = true
431 }
432 
433 
434 template<class T, int SizeMin>
436 (
437  const label len
438 )
439 {
440  this->doReserve(false, len); // nocopy = false
441 }
442 
443 
444 template<class T, int SizeMin>
446 (
447  const label len
448 )
449 {
450  this->doReserve(true, len); // nocopy = true
451 }
452 
453 
454 template<class T, int SizeMin>
456 (
457  const label len
458 )
459 {
460  if (capacity_ < len)
461  {
462  // Preserve addressed size
463  const label currLen = List<T>::size();
464 
465  capacity_ = len;
466  List<T>::resize(capacity_);
468  }
469 }
470 
471 
472 template<class T, int SizeMin>
474 (
475  const label len
476 )
477 {
478  this->doResize(false, len); // nocopy = false
479 }
480 
481 
482 template<class T, int SizeMin>
484 (
485  const label len
486 )
487 {
488  this->doResize(true, len); // nocopy = true
489 }
490 
491 
492 template<class T, int SizeMin>
494 (
495  const label len,
496  const T& val
497 )
498 {
499  this->doResize(true, len); // nocopy = true
500  UList<T>::operator=(val);
501 }
502 
503 
504 template<class T, int SizeMin>
506 (
507  const label len,
508  const T& val
509 )
510 {
511  const label oldLen = List<T>::size();
512  resize(len);
513 
514  // Fill newly exposed with constant value
515  if (oldLen < List<T>::size())
516  {
517  std::fill
518  (
519  this->begin(oldLen), this->end(), val
520  );
521  }
522 }
523 
524 
525 template<class T, int SizeMin>
527 {
529 }
530 
531 
532 template<class T, int SizeMin>
534 {
535  List<T>::clear();
536  capacity_ = 0;
537 }
538 
539 
540 template<class T, int SizeMin>
542 {
543  const label currLen = List<T>::size();
544 
545  if (currLen < capacity_)
546  {
547  List<T>::setAddressableSize(capacity_);
548  List<T>::resize(currLen);
549  capacity_ = List<T>::size();
550  }
551 }
552 
553 
554 template<class T, int SizeMin>
556 {
557  if (List<T>::empty())
558  {
559  // Delete storage if empty
560  List<T>::clear();
561  }
562  capacity_ = List<T>::size();
563 }
564 
565 
566 template<class T, int SizeMin>
567 inline void
569 {
570  if
571  (
572  static_cast<const List<T>*>(this)
573  == static_cast<const List<T>*>(&list)
574  )
575  {
576  return; // Self-swap is a no-op
577  }
578 
579  // Remove unused storage
580  this->shrink_to_fit();
581 
582  // Swap storage and addressable size
583  UList<T>::swap(list);
584 
585  // Update capacity
586  capacity_ = List<T>::size();
587 }
588 
589 
590 template<class T, int SizeMin>
591 template<int AnySizeMin>
593 (
595 ) noexcept
596 {
597  if
598  (
599  static_cast<const List<T>*>(this)
600  == static_cast<const List<T>*>(&other)
601  )
602  {
603  return; // Self-swap is a no-op
604  }
605 
606  // Swap storage and addressable size
607  UList<T>::swap(other);
608 
609  // Swap capacity
610  std::swap(this->capacity_, other.capacity_);
611 }
612 
613 
614 template<class T, int SizeMin>
615 template<int AnySizeMin>
617 (
619 ) noexcept
620 {
621  if
622  (
623  static_cast<const List<T>*>(this)
624  == static_cast<const List<T>*>(&other)
625  )
626  {
627  return; // Self-swap is a no-op
628  }
629 
630  // Swap storage and addressable size
631  UList<T>::swap(other);
632 
633  // Swap capacity
634  const label oldCap = this->capacity();
635  const label newCap = other.capacity();
637  this->setCapacity_unsafe(newCap);
638  other.setCapacity_unsafe(oldCap);
639 }
640 
641 
642 template<class T, int SizeMin>
644 {
645  Field<T>::transfer(list);
646  capacity_ = Field<T>::size();
647 }
648 
649 
650 template<class T, int SizeMin>
651 template<int AnySizeMin>
653 (
655 )
656 {
657  if
658  (
659  static_cast<const List<T>*>(this)
660  == static_cast<const List<T>*>(&list)
661  )
662  {
663  return; // Self-assignment is a no-op
664  }
665 
666  // Take over storage as-is (without shrink)
667  capacity_ = list.capacity();
668  Field<T>::transfer(static_cast<List<T>&>(list));
669  list.clearStorage(); // capacity=0 etc.
670 }
671 
672 
673 template<class T, int SizeMin>
674 template<int AnySizeMin>
676 (
678 )
679 {
680  if
681  (
682  static_cast<const List<T>*>(this)
683  == static_cast<const List<T>*>(&list)
684  )
685  {
686  return; // Self-assignment is a no-op
687  }
688 
689  // Take over storage as-is (without shrink)
690  capacity_ = list.capacity();
691  Field<T>::transfer(static_cast<List<T>&>(list));
692  list.clearStorage(); // capacity=0 etc.
693 }
694 
695 
696 template<class T, int SizeMin>
697 template<class... Args>
699 {
700  // This could/should be better with inplace construction
701  // (as per std::vector), but currently lacking the methods for that
702  // so resize and move assign
703 
704  const label idx = List<T>::size();
705  resize(idx + 1);
706 
707  // move assign element
708  this->operator[](idx) = T(std::forward<Args>(args)...);
709  return this->operator[](idx);
710 }
711 
712 
713 template<class T, int SizeMin>
715 (
716  const T& val
717 )
718 {
719  const label idx = List<T>::size();
720  resize(idx + 1);
722  this->operator[](idx) = val; // copy element
723 }
724 
725 
726 template<class T, int SizeMin>
728 (
729  T&& val
730 )
731 {
732  const label idx = List<T>::size();
733  resize(idx + 1);
735  this->operator[](idx) = std::move(val); // move assign element
736 }
737 
738 
739 template<class T, int SizeMin>
741 (
742  const UList<T>& list
743 )
744 {
745  if (this == &list)
746  {
748  << "Attempted push_back to self"
749  << abort(FatalError);
750  }
751 
752  const label idx = List<T>::size();
753  resize(idx + list.size());
755  std::copy(list.begin(), list.end(), this->begin(idx));
756 }
757 
758 
759 template<class T, int SizeMin>
761 (
762  List<T>&& list
763 )
764 {
765  if (this == &list)
766  {
768  << "Attempted push_back to self"
769  << abort(FatalError);
770  }
771 
772  const label idx = List<T>::size();
773  resize(idx + list.size());
774 
775  std::move(list.begin(), list.end(), this->begin(idx));
776 
777  list.clear();
778 }
779 
780 
781 template<class T, int SizeMin>
783 {
784  if (n >= this->size())
785  {
786  this->clear();
787  }
788  else if (n > 0)
789  {
790  resize(this->size() - n);
791  }
792 }
793 
794 
795 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
796 
797 template<class T, int SizeMin>
799 (
800  const label i
801 )
802 {
803  if (i >= List<T>::size())
804  {
805  resize(i + 1);
806  }
808  return this->operator[](i);
809 }
810 
811 
812 template<class T, int SizeMin>
814 (
815  const T& val
816 )
817 {
818  UList<T>::operator=(val);
819 }
820 
821 
822 template<class T, int SizeMin>
824 (
825  Foam::zero
826 )
827 {
829 }
830 
831 
832 template<class T, int SizeMin>
834 (
835  const UList<T>& list
836 )
837 {
838  doAssignDynList(list);
839 }
840 
841 
842 template<class T, int SizeMin>
844 (
845  const DynamicField<T, SizeMin>& list
846 )
847 {
848  if (this == &list)
849  {
850  return; // Self-assignment is a no-op
851  }
852 
853  doAssignDynList(list);
854 }
855 
856 
857 template<class T, int SizeMin>
858 template<class Addr>
860 (
861  const IndirectListBase<T, Addr>& list
862 )
863 {
864  // NOTE: Self-assignment needs special handling
871  doAssignDynList(list);
872 }
873 
874 
875 template<class T, int SizeMin>
877 (
878  List<T>&& list
879 )
880 {
881  transfer(list);
882 }
883 
884 
885 template<class T, int SizeMin>
887 (
889 )
890 {
891  transfer(list);
892 }
893 
894 
895 template<class T, int SizeMin>
896 template<int AnySizeMin>
898 (
900 )
901 {
902  transfer(list);
903 }
904 
905 
906 template<class T, int SizeMin>
907 template<int AnySizeMin>
909 (
911 )
912 {
913  transfer(list);
914 }
915 
916 
917 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
918 
919 template<class T, int SizeMin>
921 (
922  Istream& is
923 )
924 {
925  // Use DynamicList::readList for reading DynamicField.
926  // The logic should be the same and this avoids duplicate code
927 
929  this->swap(list);
930 
931  list.readList(is);
932  this->swap(list);
933 
934  return is;
935 }
936 
937 
938 template<class T, int SizeMin>
939 inline Foam::Istream& Foam::operator>>
940 (
941  Istream& is,
942  DynamicField<T, SizeMin>& rhs
943 )
944 {
945  return rhs.readList(is);
946 }
947 
948 
949 template<class T, int SizeMin>
950 inline Foam::Ostream& Foam::operator<<
951 (
952  Ostream& os,
953  const DynamicField<T, SizeMin>& rhs
954 )
955 {
956  os << static_cast<const Field<T>&>(rhs);
957  return os;
958 }
959 
960 
961 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
void swap(List< T > &list)
Swap with plain List content. Implies shrink_to_fit().
void setCapacity(const label len)
Alter the size of the underlying storage.
patchWriters resize(patchIds.size())
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
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
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void reserve_exact(const label len)
Reserve allocation space for at least this size, allocating new space if required and retaining old c...
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
void push_back(const T &val)
Copy append an element to the end of the list.
constexpr DynamicField() noexcept
Default construct, an empty field without allocation.
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
void transfer(List< T > &list)
Transfer the parameter contents into this.
void reserve_nocopy(const label len)
Reserve allocation space for at least this size, allocating new space if required without retaining o...
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicList.H:236
void resize_nocopy(const label len)
Alter addressable list size, allocating new space if required without necessarily recovering old cont...
tmp< DynamicField< T, SizeMin > > clone() const
Clone.
void setCapacity_unsafe(const label len) noexcept
Change the value for the list capacity directly (ADVANCED, UNSAFE) Does not perform any memory manage...
Definition: DynamicField.H:288
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicField.H:254
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
Abstract base class to hold the Field mapping addressing and weights.
Definition: FieldMapper.H:43
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
label capacity() const noexcept
Size of the underlying storage.
Definition: UList.H:707
Generic templated field type.
Definition: Field.H:63
void shrink_to_fit()
Shrink the allocated space to the number of elements used.
void pop_back(label n=1)
Reduce size by 1 or more elements. Can be called on an empty list.
Dynamically sized Field. Similar to DynamicList, but inheriting from a Field instead of a List...
Definition: DynamicField.H:46
void reserve(const label len)
Reserve allocation space for at least this size, allocating new space if required and retaining old c...
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
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:385
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
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
void shrink_unsafe()
Shrink the internal bookkeeping of the allocated space to the number of addressed elements without af...
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: scalarImpl.H:255
void resize_fill(const label len, const T &val)
Alter addressable size and set val for all addressed entries.
void setCapacity_unsafe(const label len) noexcept
Change the value for the list capacity directly (ADVANCED, UNSAFE) Does not perform any memory manage...
Definition: DynamicList.H:270
OBJstream os(runTime.globalPath()/outputName)
void operator=(const Field< T > &)
Copy assignment.
Definition: Field.C:781
const volScalarField & T
T & emplace_back(Args &&... args)
Construct an element at the end of the list, return reference to the new list element.
void clearStorage()
Clear the list and delete storage.
void setCapacity_nocopy(const label len)
Alter the size of the underlying storage, without retaining old content.
std::streamsize capacity_bytes() const noexcept
Number of contiguous bytes of the underlying storage.
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
label n
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:429
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Foam::argList args(argc, argv)
A non-counting (dummy) refCount.
Definition: refCount.H:55
Namespace for OpenFOAM.
friend Ostream & operator(Ostream &os, const DynamicField< T, SizeMin > &rhs)
Write to Ostream.