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-2022 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 {
321 }
322 
323 
324 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
325 
326 template<class T, int SizeMin>
327 inline Foam::label Foam::DynamicField<T, SizeMin>::capacity() const noexcept
328 {
329  return capacity_;
330 }
331 
332 
333 template<class T, int SizeMin>
334 inline std::streamsize
336 {
337  return std::streamsize(capacity_)*sizeof(T);
338 }
339 
340 
341 template<class T, int SizeMin>
343 (
344  const label len
345 )
346 {
347  this->doCapacity(false, len); // nocopy = false
348 }
349 
350 
351 template<class T, int SizeMin>
353 (
354  const label len
355 )
356 {
357  this->doCapacity(true, len); // nocopy = true
358 }
359 
360 
361 template<class T, int SizeMin>
363 (
364  const label len
365 ) noexcept
366 {
367  capacity_ = len;
368 }
369 
370 
371 template<class T, int SizeMin>
373 (
374  const label len
375 )
376 {
377  this->doReserve(false, len); // nocopy = false
378 }
379 
380 
381 template<class T, int SizeMin>
383 (
384  const label len
385 )
386 {
387  this->doReserve(true, len); // nocopy = true
388 }
389 
390 
391 template<class T, int SizeMin>
393 (
394  const label len
395 )
396 {
397  this->doResize(false, len); // nocopy = false
398 }
399 
400 
401 template<class T, int SizeMin>
403 (
404  const label len
405 )
406 {
407  this->doResize(true, len); // nocopy = true
408 }
409 
410 
411 template<class T, int SizeMin>
413 (
414  const label len,
415  const T& val
416 )
417 {
418  label idx = List<T>::size();
419  resize(len);
420 
421  // Fill newly exposed with constant value
422  while (idx < len)
423  {
424  this->operator[](idx) = val;
425  ++idx;
426  }
427 }
428 
429 
430 template<class T, int SizeMin>
432 {
434 }
435 
436 
437 template<class T, int SizeMin>
439 {
440  List<T>::clear();
441  capacity_ = 0;
442 }
443 
444 
445 template<class T, int SizeMin>
447 {
448  const label currLen = List<T>::size();
449 
450  // Allow addressing into the entire list
452 
453  return currLen;
454 }
455 
456 
457 template<class T, int SizeMin>
459 {
460  const label currLen = List<T>::size();
461 
462  if (currLen < capacity_)
463  {
464  // Adjust addressable size to trigger proper resizing
465  List<T>::setAddressableSize(currLen+1);
466 
467  List<T>::resize(currLen);
468  capacity_ = List<T>::size();
469  }
470 }
471 
472 
473 template<class T, int SizeMin>
476 {
477  this->shrinkStorage();
478  return *this;
479 }
480 
481 
482 template<class T, int SizeMin>
483 template<int AnySizeMin>
485 (
487 )
488 {
489  if
490  (
491  static_cast<const List<T>*>(this)
492  == static_cast<const List<T>*>(&other)
493  )
494  {
495  return; // Self-swap is a no-op
496  }
497 
498  // Swap storage and addressable size
499  UList<T>::swap(other);
500 
501  // Swap capacity
502  std::swap(this->capacity_, other.capacity_);
503 }
504 
505 
506 template<class T, int SizeMin>
507 template<int AnySizeMin>
509 (
511 )
512 {
513  if
514  (
515  static_cast<const List<T>*>(this)
516  == static_cast<const List<T>*>(&other)
517  )
518  {
519  return; // Self-swap is a no-op
520  }
521 
522  // Swap storage and addressable size
523  UList<T>::swap(other);
524 
525  // Swap capacity
526  const label oldCap = this->capacity();
527  const label newCap = other.capacity();
529  this->setCapacity_unsafe(newCap);
530  other.setCapacity_unsafe(oldCap);
531 }
532 
533 
534 template<class T, int SizeMin>
536 {
537  // Take over storage, clear addressing for list
538  capacity_ = list.size();
540 }
541 
542 
543 template<class T, int SizeMin>
544 template<int AnySizeMin>
546 (
548 )
549 {
550  if
551  (
552  static_cast<const List<T>*>(this)
553  == static_cast<const List<T>*>(&list)
554  )
555  {
556  return; // Self-assignment is a no-op
557  }
558 
559  // Take over storage as-is (without shrink, without using SizeMin)
560  // clear addressing and storage for old list.
561  capacity_ = list.capacity();
562 
563  Field<T>::transfer(static_cast<List<T>&>(list));
564  list.clearStorage(); // Ensure capacity=0
565 }
566 
567 
568 template<class T, int SizeMin>
569 template<int AnySizeMin>
571 (
573 )
574 {
575  if
576  (
577  static_cast<const List<T>*>(this)
578  == static_cast<const List<T>*>(&list)
579  )
580  {
581  return; // Self-assignment is a no-op
582  }
583 
584  // Take over storage as-is (without shrink, without using SizeMin)
585  // clear addressing and storage for old list.
586  capacity_ = list.capacity();
587 
588  Field<T>::transfer(static_cast<List<T>&>(list));
589  list.clearStorage(); // Ensure capacity=0
590 }
591 
592 
593 template<class T, int SizeMin>
595 (
596  const T& val
597 )
598 {
599  const label idx = List<T>::size();
600  resize(idx + 1);
602  this->operator[](idx) = val; // copy element
603 }
604 
605 
606 template<class T, int SizeMin>
608 (
609  T&& val
610 )
611 {
612  const label idx = List<T>::size();
613  resize(idx + 1);
615  this->operator[](idx) = std::move(val); // move assign element
616 }
617 
618 
619 template<class T, int SizeMin>
621 (
622  const UList<T>& list
623 )
624 {
625  if (this == &list)
626  {
628  << "Attempted push_back to self"
629  << abort(FatalError);
630  }
631 
632  label idx = List<T>::size();
633  resize(idx + list.size());
634 
635  for (const T& val : list)
636  {
637  this->operator[](idx++) = val; // copy element
638  }
639 }
640 
641 
642 template<class T, int SizeMin>
644 {
645  if (n >= this->size())
646  {
647  this->clear();
648  }
649  else if (n > 0)
650  {
651  resize(this->size() - n);
652  }
653 }
654 
655 
656 template<class T, int SizeMin>
658 {
659  // Location of last element and simultaneously the new size
660  const label idx = List<T>::size() - 1;
661 
662  if (idx < 0)
663  {
665  << "List is empty" << abort(FatalError);
666  }
667 
668  const T& val = List<T>::operator[](idx);
669 
670  List<T>::setAddressableSize(idx);
671 
672  return val;
673 }
674 
675 
676 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
677 
678 template<class T, int SizeMin>
680 (
681  const label i
682 )
683 {
684  if (i >= List<T>::size())
685  {
686  resize(i + 1);
687  }
689  return this->operator[](i);
690 }
691 
692 
693 template<class T, int SizeMin>
695 (
696  const T& val
697 )
698 {
699  UList<T>::operator=(val);
700 }
701 
702 
703 template<class T, int SizeMin>
705 (
706  const Foam::zero
707 )
708 {
710 }
711 
712 
713 template<class T, int SizeMin>
715 (
716  const UList<T>& list
717 )
718 {
719  assignDynList(list);
720 }
721 
722 
723 template<class T, int SizeMin>
725 (
726  const DynamicField<T, SizeMin>& list
727 )
728 {
729  if (this == &list)
730  {
731  return; // Self-assignment is a no-op
732  }
734  assignDynList(list);
735 }
736 
737 
738 template<class T, int SizeMin>
740 (
741  List<T>&& list
742 )
743 {
744  transfer(list);
745 }
746 
747 
748 template<class T, int SizeMin>
750 (
752 )
753 {
754  transfer(list);
755 }
756 
757 
758 template<class T, int SizeMin>
759 template<int AnySizeMin>
761 (
763 )
764 {
765  transfer(list);
766 }
767 
768 
769 template<class T, int SizeMin>
770 template<int AnySizeMin>
772 (
774 )
775 {
776  transfer(list);
777 }
778 
779 
780 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
781 
782 template<class T, int SizeMin>
784 (
785  Istream& is
786 )
787 {
788  // Use DynamicList::readList for reading DynamicField.
789  // The logic should be the same and this avoids duplicate code
790 
792  (*this).swap(list);
793 
794  list.readList(is);
795  (*this).swap(list);
796 
797  return is;
798 }
799 
800 
801 template<class T, int SizeMin>
802 inline Foam::Istream& Foam::operator>>
803 (
804  Istream& is,
805  DynamicField<T, SizeMin>& rhs
806 )
807 {
808  return rhs.readList(is);
809 }
810 
811 
812 template<class T, int SizeMin>
813 inline Foam::Ostream& Foam::operator<<
814 (
815  Ostream& os,
816  const DynamicField<T, SizeMin>& rhs
817 )
818 {
819  os << static_cast<const Field<T>&>(rhs);
820  return os;
821 }
822 
823 
824 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
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:439
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.
void push_back(const T &val)
Append an element at the end of the list.
constexpr DynamicField() noexcept
Default construct, an empty field without allocation.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
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:427
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...
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...
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:61
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:316
OBJstream os(runTime.globalPath()/outputName)
const volScalarField & T
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicListI.H:280
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:391
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:58
label n
A class for managing temporary objects.
Definition: HashPtrTable.H:50
T remove()
Remove and return the last element. Fatal on an empty list.
label capacity() const noexcept
Size of the underlying storage.
friend Ostream & operator(Ostream &os, const DynamicField< T, SizeMin > &rhs)
Write to Ostream.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157