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-------------------------------------------------------------------------------
11License
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
31template<class T, int SizeMin>
32template<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
54template<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
89template<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
110 List<T>::resize(capacity_);
111 }
113 }
114}
116
117template<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
131template<class T, int SizeMin>
134 Field<T>(),
135 capacity_(0)
137
138
139template<class T, int SizeMin>
141:
142 Field<T>(),
143 capacity_(0)
144{
145 reserve_nocopy(len);
146}
148
149template<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
161template<class T, int SizeMin>
163(
164 const label len,
166)
167:
168 Field<T>(len, Zero),
169 capacity_(Field<T>::size())
170{}
171
173template<class T, int SizeMin>
176 const DynamicField<T, SizeMin>& list
177)
178:
179 Field<T>(list),
180 capacity_(Field<T>::size())
181{}
182
183
184template<class T, int SizeMin>
185template<int AnySizeMin>
187(
189)
191 Field<T>(list),
192 capacity_(Field<T>::size())
193{}
194
195
196template<class T, int SizeMin>
198(
199 const UList<T>& list
200)
201:
202 Field<T>(list),
203 capacity_(Field<T>::size())
204{}
206
207template<class T, int SizeMin>
208template<class Addr>
210(
211 const IndirectListBase<T, Addr>& list
212)
213:
214 Field<T>(list),
215 capacity_(Field<T>::size())
216{}
217
218
219template<class T, int SizeMin>
221(
222 List<T>&& content
223)
224:
225 Field<T>(std::move(content)),
226 capacity_(Field<T>::size())
228
229
230template<class T, int SizeMin>
231template<int AnySizeMin>
233(
235)
237 Field<T>(),
238 capacity_(0)
239{
240 transfer(list);
241}
242
243
244template<class T, int SizeMin>
248)
250 Field<T>(),
251 capacity_(0)
252{
253 transfer(content);
254}
255
257template<class T, int SizeMin>
258template<int AnySizeMin>
262)
263:
264 Field<T>(),
265 capacity_(0)
266{
267 transfer(content);
268}
269
270
271template<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
283template<class T, int SizeMin>
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{}
295
296template<class T, int SizeMin>
298(
299 const UList<T>& mapF,
300 const FieldMapper& map
302:
303 Field<T>(mapF, map),
304 capacity_(Field<T>::size())
305{}
306
308template<class T, int SizeMin>
311 Field<T>(is),
312 capacity_(Field<T>::size())
314
315
316template<class T, int SizeMin>
320 return tmp<DynamicField<T, SizeMin>>::New(*this);
321}
323
324// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
325
326template<class T, int SizeMin>
327inline Foam::label Foam::DynamicField<T, SizeMin>::capacity() const noexcept
328{
329 return capacity_;
330}
331
332
333template<class T, int SizeMin>
334inline std::streamsize
336{
337 return std::streamsize(capacity_)*sizeof(T);
338}
339
340
341template<class T, int SizeMin>
343(
344 const label len
345)
346{
347 this->doCapacity(false, len); // nocopy = false
348}
349
350
351template<class T, int SizeMin>
353(
354 const label len
355)
356{
357 this->doCapacity(true, len); // nocopy = true
358}
359
360
361template<class T, int SizeMin>
363(
364 const label len
365) noexcept
366{
367 capacity_ = len;
368}
369
370
371template<class T, int SizeMin>
373(
374 const label len
375)
376{
377 this->doReserve(false, len); // nocopy = false
378}
379
380
381template<class T, int SizeMin>
383(
384 const label len
385)
386{
387 this->doReserve(true, len); // nocopy = true
388}
389
390
391template<class T, int SizeMin>
393(
394 const label len
395)
396{
397 this->doResize(false, len); // nocopy = false
398}
399
400
401template<class T, int SizeMin>
403(
404 const label len
405)
406{
407 this->doResize(true, len); // nocopy = true
408}
409
410
411template<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
430template<class T, int SizeMin>
432{
434}
435
436
437template<class T, int SizeMin>
439{
441 capacity_ = 0;
442}
443
444
445template<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
457template<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
466
467 List<T>::resize(currLen);
468 capacity_ = List<T>::size();
469 }
470}
471
472
473template<class T, int SizeMin>
476{
477 this->shrinkStorage();
478 return *this;
479}
480
481
482template<class T, int SizeMin>
483template<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
506template<class T, int SizeMin>
507template<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();
528
529 this->setCapacity_unsafe(newCap);
530 other.setCapacity_unsafe(oldCap);
531}
532
533
534template<class T, int SizeMin>
536{
537 // Take over storage, clear addressing for list
538 capacity_ = list.size();
539 Field<T>::transfer(list);
540}
541
542
543template<class T, int SizeMin>
544template<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
568template<class T, int SizeMin>
569template<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
593template<class T, int SizeMin>
595(
596 const T& val
597)
598{
599 const label idx = List<T>::size();
600 resize(idx + 1);
601
602 this->operator[](idx) = val; // copy element
603}
604
605
606template<class T, int SizeMin>
608(
609 T&& val
610)
611{
612 const label idx = List<T>::size();
613 resize(idx + 1);
614
615 this->operator[](idx) = std::move(val); // move assign element
616}
617
618
619template<class T, int SizeMin>
621(
622 const UList<T>& list
623)
624{
625 if (this == &list)
626 {
628 << "Attempted appending 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
642template<class T, int SizeMin>
644{
645 // Location of last element and simultaneously the new size
646 const label idx = List<T>::size() - 1;
647
648 if (idx < 0)
649 {
651 << "List is empty" << abort(FatalError);
652 }
653
654 const T& val = List<T>::operator[](idx);
655
657
658 return val;
659}
660
661
662// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
663
664template<class T, int SizeMin>
666(
667 const label i
668)
669{
670 if (i >= List<T>::size())
671 {
672 resize(i + 1);
673 }
674
675 return this->operator[](i);
676}
677
678
679template<class T, int SizeMin>
681(
682 const T& val
683)
684{
686}
687
688
689template<class T, int SizeMin>
691(
692 const Foam::zero
693)
694{
696}
697
698
699template<class T, int SizeMin>
701(
702 const UList<T>& list
703)
704{
705 assignDynList(list);
706}
707
708
709template<class T, int SizeMin>
711(
712 const DynamicField<T, SizeMin>& list
713)
714{
715 if (this == &list)
716 {
717 return; // Self-assignment is a no-op
718 }
719
720 assignDynList(list);
721}
722
723
724template<class T, int SizeMin>
726(
727 List<T>&& list
728)
729{
730 transfer(list);
731}
732
733
734template<class T, int SizeMin>
736(
738)
739{
740 transfer(list);
741}
742
743
744template<class T, int SizeMin>
745template<int AnySizeMin>
747(
749)
750{
751 transfer(list);
752}
753
754
755template<class T, int SizeMin>
756template<int AnySizeMin>
758(
760)
761{
762 transfer(list);
763}
764
765
766// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
767
768template<class T, int SizeMin>
770(
771 Istream& is
772)
773{
774 // Use DynamicList::readList for reading DynamicField.
775 // The logic should be the same and this avoids duplicate code
776
778 (*this).swap(list);
779
780 list.readList(is);
781 (*this).swap(list);
782
783 return is;
784}
785
786
787template<class T, int SizeMin>
788inline Foam::Istream& Foam::operator>>
789(
790 Istream& is,
792)
793{
794 return rhs.readList(is);
795}
796
797
798template<class T, int SizeMin>
799inline Foam::Ostream& Foam::operator<<
800(
801 Ostream& os,
802 const DynamicField<T, SizeMin>& rhs
803)
804{
805 os << static_cast<const Field<T>&>(rhs);
806 return os;
807}
808
809
810// ************************************************************************* //
Y[inertIndex] max(0.0)
Dynamically sized Field.
Definition: DynamicField.H:65
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
T remove()
Remove and return the top element.
void swap(DynamicField< T, AnySizeMin > &other)
Swap content, independent of sizing parameter.
void resize_nocopy(const label len)
void setCapacity_nocopy(const label len)
void reserve_nocopy(const label len)
void setCapacity_unsafe(const label len) noexcept
std::streamsize capacity_bytes() const noexcept
Number of contiguous bytes of the underlying storage.
void clearStorage()
Clear the list and delete storage.
label capacity() const noexcept
Size of the underlying storage.
void shrinkStorage()
Shrink the allocated space to the number of elements used.
tmp< DynamicField< T, SizeMin > > clone() const
Clone.
label expandStorage() noexcept
Expand the addressable size to fit the allocated capacity.
constexpr DynamicField() noexcept
Default construct, an empty field without allocation.
DynamicField< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
void reserve(const label len)
void setCapacity(const label len)
Alter the size of the underlying storage.
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
friend Ostream & operator(Ostream &os, const DynamicField< T, SizeMin > &rhs)
Write to Ostream.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void setCapacity_unsafe(const label len) noexcept
Definition: DynamicListI.H:323
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:398
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicListI.H:287
Istream & readList(Istream &is)
Read from Istream, discarding existing contents.
Definition: DynamicListIO.C:50
virtual bool resize()
Resize the ODE solver.
Definition: Euler.C:53
Abstract base class to hold the Field mapping addressing and weights.
Definition: FieldMapper.H:50
Generic templated field type.
Definition: Field.H:82
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A class for managing temporary objects.
Definition: tmp.H:65
bool append() const noexcept
True if output format uses an append mode.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:63
const volScalarField & T
patchWriters resize(patchIds.size())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError