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-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 // * * * * * * * * * * * * * 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);
125  List<T>::setAddressableSize(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>
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 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
451  List<T>::setAddressableSize(capacity_);
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  // Cannot compare 'this' for different types, so use cdata()
490  if (this->cdata() == other.cdata())
491  {
492  return; // Self-swap is a no-op
493  }
494 
495  // Swap storage and addressable size
496  UList<T>::swap(other);
497 
498  // Swap capacity
499  std::swap(this->capacity_, other.capacity_);
500 }
501 
502 
503 template<class T, int SizeMin>
504 template<int AnySizeMin>
506 (
508 )
509 {
510  auto& self = (*this);
511 
512  // ... not yet needed:
513  // Cannot compare 'this' for different types, so use cdata()
514  if (self.cdata() == other.cdata())
515  {
516  return; // Self-swap is a no-op
517  }
518 
519  // Swap storage and addressable size
520  UList<T>::swap(other);
521 
522  // Swap capacity
523  const label oldCap = self.capacity();
524  const label newCap = other.capacity();
525 
526  self.setCapacity_unsafe(newCap);
527  other.setCapacity_unsafe(oldCap);
528 }
529 
530 
531 template<class T, int SizeMin>
533 {
534  // Take over storage, clear addressing for list
535  capacity_ = list.size();
536  Field<T>::transfer(list);
537 }
538 
539 
540 template<class T, int SizeMin>
541 template<int AnySizeMin>
543 (
545 )
546 {
547  // Cannot compare 'this' for different types, so use cdata()
548  if (this->cdata() == list.cdata())
549  {
550  return; // Self-assignment is a no-op
551  }
552 
553  // Take over storage as-is (without shrink, without using SizeMin)
554  // clear addressing and storage for old list.
555  capacity_ = list.capacity();
556 
557  Field<T>::transfer(static_cast<List<T>&>(list));
558  list.clearStorage(); // Ensure capacity=0
559 }
560 
561 
562 template<class T, int SizeMin>
563 template<int AnySizeMin>
565 (
567 )
568 {
569  // Cannot compare 'this' for different types, so use cdata()
570  if (this->cdata() == list.cdata())
571  {
572  return; // Self-assignment is a no-op
573  }
574 
575  // Take over storage as-is (without shrink, without using SizeMin)
576  // clear addressing and storage for old list.
577  capacity_ = list.capacity();
578 
579  Field<T>::transfer(static_cast<List<T>&>(list));
580  list.clearStorage(); // Ensure capacity=0
581 }
582 
583 
584 template<class T, int SizeMin>
587 (
588  const T& val
589 )
590 {
591  const label idx = List<T>::size();
592  resize(idx + 1);
593 
594  this->operator[](idx) = val; // copy element
595  return *this;
596 }
597 
598 
599 template<class T, int SizeMin>
602 (
603  T&& val
604 )
605 {
606  const label idx = List<T>::size();
607  resize(idx + 1);
608 
609  this->operator[](idx) = std::move(val); // move assign element
610  return *this;
611 }
612 
613 
614 template<class T, int SizeMin>
617 (
618  const UList<T>& list
619 )
620 {
621  if (this == &list)
622  {
624  << "Attempted appending to self"
625  << abort(FatalError);
626  }
627 
628  label idx = List<T>::size();
629  resize(idx + list.size());
630 
631  for (const T& val : list)
632  {
633  this->operator[](idx++) = val; // copy element
634  }
635  return *this;
636 }
637 
638 
639 template<class T, int SizeMin>
641 {
642  // Location of last element and simultaneously the new size
643  const label idx = List<T>::size() - 1;
644 
645  if (idx < 0)
646  {
648  << "List is empty" << abort(FatalError);
649  }
650 
651  const T& val = List<T>::operator[](idx);
652 
654 
655  return val;
656 }
657 
658 
659 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
660 
661 template<class T, int SizeMin>
663 (
664  const label i
665 )
666 {
667  if (i >= List<T>::size())
668  {
669  resize(i + 1);
670  }
671 
672  return this->operator[](i);
673 }
674 
675 
676 template<class T, int SizeMin>
678 (
679  const T& val
680 )
681 {
682  UList<T>::operator=(val);
683 }
684 
685 
686 template<class T, int SizeMin>
688 (
689  const Foam::zero
690 )
691 {
693 }
694 
695 
696 template<class T, int SizeMin>
698 (
699  const UList<T>& list
700 )
701 {
702  assignDynList(list);
703 }
704 
705 
706 template<class T, int SizeMin>
708 (
709  const DynamicField<T, SizeMin>& list
710 )
711 {
712  if (this == &list)
713  {
714  return; // Self-assignment is a no-op
715  }
716 
717  assignDynList(list);
718 }
719 
720 
721 template<class T, int SizeMin>
723 (
724  List<T>&& list
725 )
726 {
727  transfer(list);
728 }
729 
730 
731 template<class T, int SizeMin>
733 (
735 )
736 {
737  transfer(list);
738 }
739 
740 
741 template<class T, int SizeMin>
742 template<int AnySizeMin>
744 (
746 )
747 {
748  transfer(list);
749 }
750 
751 
752 template<class T, int SizeMin>
753 template<int AnySizeMin>
755 (
757 )
758 {
759  transfer(list);
760 }
761 
762 
763 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
764 
765 template<class T, int SizeMin>
767 (
768  Istream& is
769 )
770 {
771  // Use DynamicList::readList for reading DynamicField.
772  // The logic should be the same and this avoids duplicate code
773 
775  (*this).swap(list);
776 
777  list.readList(is);
778  (*this).swap(list);
779 
780  return is;
781 }
782 
783 
784 template<class T, int SizeMin>
785 inline Foam::Istream& Foam::operator>>
786 (
787  Istream& is,
789 )
790 {
791  return rhs.readList(is);
792 }
793 
794 
795 template<class T, int SizeMin>
796 inline Foam::Ostream& Foam::operator<<
797 (
798  Ostream& os,
799  const DynamicField<T, SizeMin>& rhs
800 )
801 {
802  os << static_cast<const Field<T>&>(rhs);
803  return os;
804 }
805 
806 
807 // ************************************************************************* //
Foam::DynamicField::transfer
void transfer(List< T > &list)
Transfer the parameter contents into this.
Definition: DynamicFieldI.H:532
Foam::DynamicList::setCapacity_unsafe
void setCapacity_unsafe(const label len) noexcept
Definition: DynamicListI.H:323
Foam::DynamicField::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicFieldI.H:438
Foam::DynamicField::resize
void resize(const label len)
Definition: DynamicFieldI.H:393
Foam::DynamicField::setCapacity_nocopy
void setCapacity_nocopy(const label len)
Definition: DynamicFieldI.H:353
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
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::DynamicField::operator
friend Ostream & operator(Ostream &os, const DynamicField< T, SizeMin > &rhs)
Write to Ostream.
Foam::DynamicField::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicFieldI.H:327
Foam::FieldMapper
Abstract base class to hold the Field mapping addressing and weights.
Definition: FieldMapper.H:49
Foam::DynamicList::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicListI.H:287
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::DynamicField::swap
void swap(DynamicField< T, AnySizeMin > &other)
Swap content, independent of sizing parameter.
Definition: DynamicFieldI.H:485
Foam::DynamicList::readList
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
Definition: DynamicListIO.C:50
Foam::DynamicField
Dynamically sized Field.
Definition: DynamicField.H:49
Foam::DynamicField::shrinkStorage
void shrinkStorage()
Shrink the allocated space to the number of elements used.
Definition: DynamicFieldI.H:458
Foam::DynamicField::shrink
DynamicField< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicFieldI.H:475
Foam::DynamicField::setCapacity
void setCapacity(const label len)
Alter the size of the underlying storage.
Definition: DynamicFieldI.H:343
resize
patchWriters resize(patchIds.size())
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::DynamicField::expandStorage
label expandStorage() noexcept
Expand the addressable size to fit the allocated capacity.
Definition: DynamicFieldI.H:446
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::DynamicField::DynamicField
constexpr DynamicField() noexcept
Default construct, an empty field without allocation.
Definition: DynamicFieldI.H:132
Foam::FatalError
error FatalError
Foam::DynamicField::reserve_nocopy
void reserve_nocopy(const label len)
Definition: DynamicFieldI.H:383
os
OBJstream os(runTime.globalPath()/outputName)
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::DynamicField::readList
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
Definition: DynamicFieldI.H:767
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::UList::swap
void swap(UList< T > &list)
Swap content with another UList of the same type in constant time.
Definition: UListI.H:434
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::DynamicField::clone
tmp< DynamicField< T, SizeMin > > clone() const
Clone.
Definition: DynamicFieldI.H:318
Foam::DynamicField::remove
T remove()
Remove and return the top element.
Definition: DynamicFieldI.H:640
clear
patchWriters clear()
Foam::DynamicField::setCapacity_unsafe
void setCapacity_unsafe(const label len) noexcept
Definition: DynamicFieldI.H:363
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::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::DynamicField::reserve
void reserve(const label len)
Definition: DynamicFieldI.H:373
Foam::DynamicList::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:398
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:56
Foam::DynamicField::resize_nocopy
void resize_nocopy(const label len)
Definition: DynamicFieldI.H:403
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::DynamicField::append
DynamicField< T, SizeMin > & append(const T &val)
Append an element at the end of the list.
Definition: DynamicFieldI.H:587
Foam::DynamicField::clear
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicFieldI.H:431
Foam::zero
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:62
Foam::DynamicField::capacity_bytes
std::streamsize capacity_bytes() const noexcept
Number of contiguous bytes of the underlying storage.
Definition: DynamicFieldI.H:335