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-2023 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_); // Use entire space
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 = min(List<T>::size(), newCapacity);
68 
69  // Corner case - see comments in DynamicList doCapacity
70  if (List<T>::size() == newCapacity)
71  {
72  List<T>::setAddressableSize(currLen+1);
73  }
74 
75  if (nocopy)
76  {
77  List<T>::resize_nocopy(newCapacity);
78  }
79  else
80  {
81  List<T>::resize(newCapacity);
82  }
83 
84  capacity_ = List<T>::size();
85  List<T>::setAddressableSize(currLen);
86 }
87 
88 
89 template<class T, int SizeMin>
91 (
92  const bool nocopy,
93  const label len
94 )
95 {
96  if (capacity_ < len)
97  {
98  // Preserve addressed size
99  const label currLen = List<T>::size();
100 
101  // Increase capacity (doubling)
102  capacity_ = max(SizeMin, max(len, label(2*capacity_)));
103 
104  if (nocopy)
105  {
106  List<T>::resize_nocopy(capacity_);
107  }
108  else
109  {
110  List<T>::resize(capacity_);
111  }
112  List<T>::setAddressableSize(currLen);
113  }
114 }
115 
116 
117 template<class T, int SizeMin>
119 (
120  const bool nocopy,
121  const label len
122 )
123 {
124  this->doReserve(nocopy, len);
126 }
127 
128 
129 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
130 
131 template<class T, int SizeMin>
133 :
134  Field<T>(),
135  capacity_(0)
136 {}
137 
138 
139 template<class T, int SizeMin>
140 inline Foam::DynamicField<T, SizeMin>::DynamicField(const label len)
141 :
142  Field<T>(),
143  capacity_(0)
144 {
145  reserve_nocopy(len);
146 }
147 
148 
149 template<class T, int SizeMin>
151 (
152  const label len,
153  const T& val
154 )
155 :
156  Field<T>(len, val),
157  capacity_(Field<T>::size())
158 {}
159 
160 
161 template<class T, int SizeMin>
163 (
164  const label len,
165  const Foam::zero
166 )
167 :
168  Field<T>(len, Zero),
169  capacity_(Field<T>::size())
170 {}
171 
172 
173 template<class T, int SizeMin>
175 (
176  const DynamicField<T, SizeMin>& list
177 )
178 :
179  Field<T>(list),
180  capacity_(Field<T>::size())
181 {}
182 
183 
184 template<class T, int SizeMin>
185 template<int AnySizeMin>
187 (
188  const DynamicField<T, AnySizeMin>& list
189 )
190 :
191  Field<T>(list),
192  capacity_(Field<T>::size())
193 {}
194 
195 
196 template<class T, int SizeMin>
198 (
199  const UList<T>& list
200 )
201 :
202  Field<T>(list),
203  capacity_(Field<T>::size())
204 {}
205 
206 
207 template<class T, int SizeMin>
208 template<class Addr>
210 (
211  const IndirectListBase<T, Addr>& list
212 )
213 :
214  Field<T>(list),
215  capacity_(Field<T>::size())
216 {}
217 
218 
219 template<class T, int SizeMin>
221 (
222  List<T>&& content
223 )
224 :
225  Field<T>(std::move(content)),
226  capacity_(Field<T>::size())
227 {}
228 
229 
230 template<class T, int SizeMin>
231 template<int AnySizeMin>
233 (
235 )
236 :
237  Field<T>(),
238  capacity_(0)
239 {
240  transfer(list);
241 }
242 
243 
244 template<class T, int SizeMin>
246 (
247  DynamicField<T, SizeMin>&& content
248 )
249 :
250  Field<T>(),
251  capacity_(0)
252 {
253  transfer(content);
254 }
255 
256 
257 template<class T, int SizeMin>
258 template<int AnySizeMin>
260 (
262 )
263 :
264  Field<T>(),
265  capacity_(0)
266 {
267  transfer(content);
268 }
269 
270 
271 template<class T, int SizeMin>
273 (
274  const UList<T>& mapF,
275  const labelUList& mapAddressing
276 )
277 :
278  Field<T>(mapF, mapAddressing),
279  capacity_(Field<T>::size())
280 {}
281 
282 
283 template<class T, int SizeMin>
285 (
286  const UList<T>& mapF,
287  const labelListList& mapAddressing,
288  const scalarListList& weights
289 )
290 :
291  Field<T>(mapF, mapAddressing, weights),
292  capacity_(Field<T>::size())
293 {}
294 
295 
296 template<class T, int SizeMin>
298 (
299  const UList<T>& mapF,
300  const FieldMapper& map
301 )
302 :
303  Field<T>(mapF, map),
304  capacity_(Field<T>::size())
305 {}
306 
307 
308 template<class T, int SizeMin>
310 :
311  Field<T>(is),
312  capacity_(Field<T>::size())
313 {}
314 
315 
316 template<class T, int SizeMin>
319 {
320  return tmp<DynamicField<T, SizeMin>>::New(*this);
321 }
322 
323 
324 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
325 
326 template<class T, int SizeMin>
327 inline std::streamsize
329 {
330  return std::streamsize(capacity_)*sizeof(T);
331 }
332 
333 
334 template<class T, int SizeMin>
336 (
337  const label len
338 )
339 {
340  this->doCapacity(false, len); // nocopy = false
341 }
342 
343 
344 template<class T, int SizeMin>
346 (
347  const label len
348 )
349 {
350  this->doCapacity(true, len); // nocopy = true
351 }
352 
353 
354 template<class T, int SizeMin>
356 (
357  const label len
358 ) noexcept
359 {
360  capacity_ = len;
361 }
362 
363 
364 template<class T, int SizeMin>
366 (
367  const label len
368 )
369 {
370  this->doReserve(false, len); // nocopy = false
371 }
372 
373 
374 template<class T, int SizeMin>
376 (
377  const label len
378 )
379 {
380  this->doReserve(true, len); // nocopy = true
381 }
382 
383 
384 template<class T, int SizeMin>
386 (
387  const label len
388 )
389 {
390  this->doResize(false, len); // nocopy = false
391 }
392 
393 
394 template<class T, int SizeMin>
396 (
397  const label len
398 )
399 {
400  this->doResize(true, len); // nocopy = true
401 }
402 
403 
404 template<class T, int SizeMin>
406 (
407  const label len,
408  const T& val
409 )
410 {
411  label idx = List<T>::size();
412  resize(len);
413 
414  // Fill newly exposed with constant value
415  while (idx < len)
416  {
417  this->operator[](idx) = val;
418  ++idx;
419  }
420 }
421 
422 
423 template<class T, int SizeMin>
425 {
427 }
428 
429 
430 template<class T, int SizeMin>
432 {
433  List<T>::clear();
434  capacity_ = 0;
435 }
436 
437 
438 template<class T, int SizeMin>
440 {
441  const label currLen = List<T>::size();
442 
443  // Allow addressing into the entire list
445 
446  return currLen;
447 }
448 
449 
450 template<class T, int SizeMin>
452 {
453  const label currLen = List<T>::size();
454 
455  if (currLen < capacity_)
456  {
457  // Adjust addressable size to trigger proper resizing
458  List<T>::setAddressableSize(currLen+1);
459 
460  List<T>::resize(currLen);
461  capacity_ = List<T>::size();
462  }
463 }
464 
465 
466 template<class T, int SizeMin>
469 {
470  this->shrinkStorage();
471  return *this;
472 }
473 
474 
475 template<class T, int SizeMin>
476 template<int AnySizeMin>
478 (
480 )
481 {
482  if
483  (
484  static_cast<const List<T>*>(this)
485  == static_cast<const List<T>*>(&other)
486  )
487  {
488  return; // Self-swap is a no-op
489  }
490 
491  // Swap storage and addressable size
492  UList<T>::swap(other);
493 
494  // Swap capacity
495  std::swap(this->capacity_, other.capacity_);
496 }
497 
498 
499 template<class T, int SizeMin>
500 template<int AnySizeMin>
502 (
504 )
505 {
506  if
507  (
508  static_cast<const List<T>*>(this)
509  == static_cast<const List<T>*>(&other)
510  )
511  {
512  return; // Self-swap is a no-op
513  }
514 
515  // Swap storage and addressable size
516  UList<T>::swap(other);
517 
518  // Swap capacity
519  const label oldCap = this->capacity();
520  const label newCap = other.capacity();
522  this->setCapacity_unsafe(newCap);
523  other.setCapacity_unsafe(oldCap);
524 }
525 
526 
527 template<class T, int SizeMin>
529 {
530  // Take over storage, clear addressing for list
531  capacity_ = list.size();
533 }
534 
535 
536 template<class T, int SizeMin>
537 template<int AnySizeMin>
539 (
541 )
542 {
543  if
544  (
545  static_cast<const List<T>*>(this)
546  == static_cast<const List<T>*>(&list)
547  )
548  {
549  return; // Self-assignment is a no-op
550  }
551 
552  // Take over storage as-is (without shrink, without using SizeMin)
553  // clear addressing and storage for old list.
554  capacity_ = list.capacity();
555 
556  Field<T>::transfer(static_cast<List<T>&>(list));
557  list.clearStorage(); // Ensure capacity=0
558 }
559 
560 
561 template<class T, int SizeMin>
562 template<int AnySizeMin>
564 (
566 )
567 {
568  if
569  (
570  static_cast<const List<T>*>(this)
571  == static_cast<const List<T>*>(&list)
572  )
573  {
574  return; // Self-assignment is a no-op
575  }
576 
577  // Take over storage as-is (without shrink, without using SizeMin)
578  // clear addressing and storage for old list.
579  capacity_ = list.capacity();
580 
581  Field<T>::transfer(static_cast<List<T>&>(list));
582  list.clearStorage(); // Ensure capacity=0
583 }
584 
585 
586 template<class T, int SizeMin>
587 template<class... Args>
589 {
590  // This could/should be better with inplace construction
591  // (as per std::vector), but currently lacking the methods for that
592  // so resize and move assign
593 
594  const label idx = List<T>::size();
595  resize(idx + 1);
596 
597  // move assign element
598  this->operator[](idx) = T(std::forward<Args>(args)...);
599  return this->back();
600 }
601 
602 
603 template<class T, int SizeMin>
605 (
606  const T& val
607 )
608 {
609  const label idx = List<T>::size();
610  resize(idx + 1);
612  this->operator[](idx) = val; // copy element
613 }
614 
615 
616 template<class T, int SizeMin>
618 (
619  T&& val
620 )
621 {
622  const label idx = List<T>::size();
623  resize(idx + 1);
625  this->operator[](idx) = std::move(val); // move assign element
626 }
627 
628 
629 template<class T, int SizeMin>
631 (
632  const UList<T>& list
633 )
634 {
635  if (this == &list)
636  {
638  << "Attempted push_back to self"
639  << abort(FatalError);
640  }
641 
642  label idx = List<T>::size();
643  resize(idx + list.size());
644 
645  for (const T& val : list)
646  {
647  this->operator[](idx++) = val; // copy element
648  }
649 }
650 
651 
652 template<class T, int SizeMin>
654 {
655  if (n >= this->size())
656  {
657  this->clear();
658  }
659  else if (n > 0)
660  {
661  resize(this->size() - n);
662  }
663 }
664 
665 
666 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
667 
668 template<class T, int SizeMin>
670 (
671  const label i
672 )
673 {
674  if (i >= List<T>::size())
675  {
676  resize(i + 1);
677  }
679  return this->operator[](i);
680 }
681 
682 
683 template<class T, int SizeMin>
685 (
686  const T& val
687 )
688 {
689  UList<T>::operator=(val);
690 }
691 
692 
693 template<class T, int SizeMin>
695 (
696  const Foam::zero
697 )
698 {
700 }
701 
702 
703 template<class T, int SizeMin>
705 (
706  const UList<T>& list
707 )
708 {
709  doAssignDynList(list);
710 }
711 
712 
713 template<class T, int SizeMin>
715 (
716  const DynamicField<T, SizeMin>& list
717 )
718 {
719  if (this == &list)
720  {
721  return; // Self-assignment is a no-op
722  }
723 
724  doAssignDynList(list);
725 }
726 
727 
728 template<class T, int SizeMin>
729 template<class Addr>
731 (
732  const IndirectListBase<T, Addr>& list
733 )
734 {
735  // NOTE: Self-assignment needs special handling
742  doAssignDynList(list);
743 }
744 
745 
746 template<class T, int SizeMin>
748 (
749  List<T>&& list
750 )
751 {
752  transfer(list);
753 }
754 
755 
756 template<class T, int SizeMin>
758 (
760 )
761 {
762  transfer(list);
763 }
764 
765 
766 template<class T, int SizeMin>
767 template<int AnySizeMin>
769 (
771 )
772 {
773  transfer(list);
774 }
775 
776 
777 template<class T, int SizeMin>
778 template<int AnySizeMin>
780 (
782 )
783 {
784  transfer(list);
785 }
786 
787 
788 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
789 
790 template<class T, int SizeMin>
792 (
793  Istream& is
794 )
795 {
796  // Use DynamicList::readList for reading DynamicField.
797  // The logic should be the same and this avoids duplicate code
798 
800  (*this).swap(list);
801 
802  list.readList(is);
803  (*this).swap(list);
804 
805  return is;
806 }
807 
808 
809 template<class T, int SizeMin>
810 inline Foam::Istream& Foam::operator>>
811 (
812  Istream& is,
813  DynamicField<T, SizeMin>& rhs
814 )
815 {
816  return rhs.readList(is);
817 }
818 
819 
820 template<class T, int SizeMin>
821 inline Foam::Ostream& Foam::operator<<
822 (
823  Ostream& os,
824  const DynamicField<T, SizeMin>& rhs
825 )
826 {
827  os << static_cast<const Field<T>&>(rhs);
828  return os;
829 }
830 
831 
832 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
void setCapacity(const label len)
Alter the size of the underlying storage.
void swap(DynamicField< T, AnySizeMin > &other)
Swap content, independent of sizing parameter.
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:452
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:578
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
DynamicField< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
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 at 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.
void swap(UList< T > &list)
Swap content with another UList of the same type in constant time.
Definition: UListI.H:435
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:219
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...
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicField.H:236
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
label expandStorage() noexcept
Expand the addressable size to fit the allocated capacity.
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
Generic templated field type.
Definition: Field.H:62
void pop_back(label n=1)
Reduce size by 1 or more elements. Can be called on an empty list.
Dynamically sized Field.
Definition: DynamicField.H:45
patchWriters clear()
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
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:99
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
Definition: DynamicListIO.C:43
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
const direction noexcept
Definition: Scalar.H:258
void setCapacity_unsafe(const label len) noexcept
Change the value for the list capacity directly (ADVANCED, UNSAFE) Does not perform any memory manage...
Definition: DynamicListI.H:321
OBJstream os(runTime.globalPath()/outputName)
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 shrinkStorage()
Shrink the allocated space to the number of elements used.
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.
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:396
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
label n
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Foam::argList args(argc, argv)
friend Ostream & operator(Ostream &os, const DynamicField< T, SizeMin > &rhs)
Write to Ostream.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:133