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-2019 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 newSize = list.size();
39 
40  if (capacity_ >= newSize)
41  {
42  // Can copy w/o reallocating - adjust addressable size accordingly.
43  Field<T>::size(list.size());
44  Field<T>::operator=(list);
45  }
46  else
47  {
48  // Ensure list size consistency prior to copying.
49  Field<T>::size(capacity_);
50 
51  Field<T>::operator=(list);
52  capacity_ = Field<T>::size();
53  }
54 }
55 
56 
57 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
58 
59 template<class T, int SizeMin>
61 :
62  Field<T>(),
63  capacity_(0)
64 {}
65 
66 
67 template<class T, int SizeMin>
69 :
70  Field<T>(len),
71  capacity_(Field<T>::size())
72 {
73  Field<T>::size(0);
74 }
75 
76 
77 template<class T, int SizeMin>
79 (
80  const label len,
81  const T& val
82 )
83 :
84  Field<T>(len, val),
85  capacity_(Field<T>::size())
86 {}
87 
88 
89 template<class T, int SizeMin>
91 (
92  const label len,
93  const Foam::zero
94 )
95 :
96  Field<T>(len, Zero),
97  capacity_(Field<T>::size())
98 {}
99 
100 
101 template<class T, int SizeMin>
103 (
104  const DynamicField<T, SizeMin>& list
105 )
106 :
107  Field<T>(list),
108  capacity_(Field<T>::size())
109 {}
110 
111 
112 template<class T, int SizeMin>
113 template<int AnySizeMin>
115 (
116  const DynamicField<T, AnySizeMin>& list
117 )
118 :
119  Field<T>(list),
120  capacity_(Field<T>::size())
121 {}
122 
123 
124 template<class T, int SizeMin>
126 (
127  const UList<T>& list
128 )
129 :
130  Field<T>(list),
131  capacity_(Field<T>::size())
132 {}
133 
134 
135 template<class T, int SizeMin>
136 template<class Addr>
138 (
139  const IndirectListBase<T, Addr>& list
140 )
141 :
142  Field<T>(list),
143  capacity_(Field<T>::size())
144 {}
145 
146 
147 template<class T, int SizeMin>
149 (
150  List<T>&& content
151 )
152 :
153  Field<T>(std::move(content)),
154  capacity_(Field<T>::size())
155 {}
156 
157 
158 template<class T, int SizeMin>
160 (
161  DynamicField<T, SizeMin>&& content
162 )
163 :
164  Field<T>(),
165  capacity_(0)
166 {
167  transfer(content);
168 }
169 
170 
171 template<class T, int SizeMin>
172 template<int AnySizeMin>
174 (
176 )
177 :
178  Field<T>(),
179  capacity_(0)
180 {
181  transfer(content);
182 }
183 
184 
185 template<class T, int SizeMin>
187 (
188  const UList<T>& mapF,
189  const labelUList& mapAddressing
190 )
191 :
192  Field<T>(mapF, mapAddressing),
193  capacity_(Field<T>::size())
194 {}
195 
196 
197 template<class T, int SizeMin>
199 (
200  const UList<T>& mapF,
201  const labelListList& mapAddressing,
202  const scalarListList& weights
203 )
204 :
205  Field<T>(mapF, mapAddressing, weights),
206  capacity_(Field<T>::size())
207 {}
208 
209 
210 //- Construct by mapping from the given field
211 template<class T, int SizeMin>
213 (
214  const UList<T>& mapF,
215  const FieldMapper& map
216 )
217 :
218  Field<T>(mapF, map),
219  capacity_(Field<T>::size())
220 {}
221 
222 
223 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
224 
225 template<class T, int SizeMin>
226 inline Foam::label Foam::DynamicField<T, SizeMin>::capacity() const noexcept
227 {
228  return capacity_;
229 }
230 
231 
232 template<class T, int SizeMin>
234 (
235  const label nElem
236 )
237 {
238  label nextFree = Field<T>::size();
239  capacity_ = nElem;
240 
241  if (nextFree > capacity_)
242  {
243  // truncate addressed sizes too
244  nextFree = capacity_;
245  }
246 
247  // We could also enforce sizing granularity
248 
249  Field<T>::setSize(capacity_);
250  Field<T>::size(nextFree);
251 }
252 
253 
254 template<class T, int SizeMin>
256 (
257  const label nElem
258 )
259 {
260  // Allocate more capacity if necessary
261  if (nElem > capacity_)
262  {
263  capacity_ = max
264  (
265  SizeMin,
266  max
267  (
268  nElem,
269  // label(SizeInc + capacity_ * SizeMult / SizeDiv)
270  label(2*capacity_)
271  )
272  );
273 
274  // Adjust allocated size, leave addressed size untouched
275  const label nextFree = Field<T>::size();
276  Field<T>::setSize(capacity_);
277  Field<T>::size(nextFree);
278  }
279 }
280 
281 
282 template<class T, int SizeMin>
284 (
285  const label nElem
286 )
287 {
288  // Allocate more capacity if necessary
289  if (nElem > capacity_)
290  {
291  capacity_ = max
292  (
293  SizeMin,
294  max
295  (
296  nElem,
297  // label(SizeInc + capacity_ * SizeMult / SizeDiv)
298  label(2*capacity_)
299  )
300  );
301 
302  Field<T>::setSize(capacity_);
303  }
304 
305  // Adjust addressed size
306  Field<T>::size(nElem);
307 }
308 
309 
310 template<class T, int SizeMin>
312 (
313  const label nElem,
314  const T& val
315 )
316 {
317  label nextFree = Field<T>::size();
318  setSize(nElem);
319 
320  // Set new elements to constant value
321  while (nextFree < nElem)
322  {
323  this->operator[](nextFree++) = val;
324  }
325 }
326 
327 
328 template<class T, int SizeMin>
330 (
331  const label nElem
332 )
333 {
334  this->setSize(nElem);
335 }
336 
337 
338 template<class T, int SizeMin>
340 (
341  const label nElem,
342  const T& val
343 )
344 {
345  this->setSize(nElem, val);
346 }
347 
348 
349 template<class T, int SizeMin>
351 {
352  Field<T>::size(0);
353 }
354 
355 
356 template<class T, int SizeMin>
358 {
359  Field<T>::clear();
360  capacity_ = 0;
361 }
362 
363 
364 template<class T, int SizeMin>
366 {
367  const label nextFree = Field<T>::size();
368 
369  // Allow addressing into the entire list
370  Field<T>::size(capacity_);
371 
372  return nextFree;
373 }
374 
375 
376 template<class T, int SizeMin>
379 {
380  label nextFree = Field<T>::size();
381  if (capacity_ > nextFree)
382  {
383  // Use the full list when resizing
384  Field<T>::size(capacity_);
385 
386  // The new size
387  capacity_ = nextFree;
388  Field<T>::setSize(capacity_);
389  Field<T>::size(nextFree);
390  }
391  return *this;
392 }
393 
394 
395 template<class T, int SizeMin>
396 template<int AnySizeMin>
398 (
400 )
401 {
402  // Cannot compare 'this' for different types, so use cdata()
403  if (this->cdata() == lst.cdata())
404  {
405  return; // Self-swap is a no-op
406  }
407 
408  DynamicField<T, SizeMin>& cur = *this;
409 
410  // Make addressable size identical to the allocated capacity
411  const label oldSize1 = cur.expandStorage();
412  const label oldSize2 = lst.expandStorage();
413 
414  // Swap storage
415  Field<T>::swap(lst);
416 
417  // Match capacity to the underlying allocated list size
418  cur.setCapacity(cur.size());
419  lst.setCapacity(lst.size());
420 
421  // Set addressable size
422  cur.setSize(oldSize2);
423  lst.setSize(oldSize1);
424 }
425 
426 
427 template<class T, int SizeMin>
429 {
430  // Take over storage, clear addressing for list.
431  capacity_ = list.size();
432  Field<T>::transfer(list);
433 }
434 
435 
436 template<class T, int SizeMin>
437 template<int AnySizeMin>
439 (
441 )
442 {
443  // Cannot compare 'this' for different types, so use cdata()
444  if (this->cdata() == list.cdata())
445  {
446  return; // Self-swap is a no-op
447  }
448 
449  // Take over storage as-is (without shrink, without using SizeMin)
450  // clear addressing and storage for old list.
451  capacity_ = list.capacity();
452 
453  Field<T>::transfer(static_cast<Field<T>&>(list));
454  list.clearStorage(); // Ensure capacity=0
455 }
456 
457 
458 template<class T, int SizeMin>
459 template<int AnySizeMin>
461 (
463 )
464 {
465  // Cannot compare 'this' for different types, so use cdata()
466  if (this->cdata() == list.cdata())
467  {
468  return; // Self-swap is a no-op
469  }
470 
471  // Take over storage as-is (without shrink, without using SizeMin)
472  // clear addressing and storage for old list.
473  capacity_ = list.capacity();
474 
475  Field<T>::transfer(static_cast<Field<T>&>(list));
476  list.clearStorage(); // Ensure capacity=0
477 }
478 
479 
480 template<class T, int SizeMin>
483 (
484  const T& val
485 )
486 {
487  const label idx = List<T>::size();
488  setSize(idx + 1);
489 
490  this->operator[](idx) = val; // copy element
491  return *this;
492 }
493 
494 
495 template<class T, int SizeMin>
498 (
499  const UList<T>& list
500 )
501 {
502  if (this == &list)
503  {
505  << "Attempted appending to self" << abort(FatalError);
506  }
507 
508  label idx = List<T>::size();
509  setSize(idx + list.size());
510 
511  for (const T& val : list)
512  {
513  this->operator[](idx++) = val; // copy element
514  }
515  return *this;
516 }
517 
518 
519 template<class T, int SizeMin>
521 {
522  // Location of last element and simultaneously the new size
523  const label idx = List<T>::size() - 1;
524 
525  if (idx < 0)
526  {
528  << "List is empty" << abort(FatalError);
529  }
530 
531  const T& val = List<T>::operator[](idx);
532 
533  List<T>::size(idx);
534 
535  return val;
536 }
537 
538 
539 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
540 
541 template<class T, int SizeMin>
543 (
544  const label i
545 )
546 {
547  if (i >= Field<T>::size())
548  {
549  setSize(i + 1);
550  }
551 
552  return this->operator[](i);
553 }
554 
555 
556 template<class T, int SizeMin>
558 (
559  const T& val
560 )
561 {
562  UList<T>::operator=(val);
563 }
564 
565 
566 template<class T, int SizeMin>
568 (
569  const UList<T>& list
570 )
571 {
572  assignDynField(list);
573 }
574 
575 
576 template<class T, int SizeMin>
578 (
579  const DynamicField<T, SizeMin>& list
580 )
581 {
582  if (this == &list)
583  {
584  return; // Self-assignment is a no-op
585  }
586 
587  assignDynField(list);
588 }
589 
590 
591 template<class T, int SizeMin>
593 (
594  List<T>&& list
595 )
596 {
597  transfer(list);
598 }
599 
600 
601 template<class T, int SizeMin>
603 (
605 )
606 {
607  transfer(list);
608 }
609 
610 
611 template<class T, int SizeMin>
612 template<int AnySizeMin>
614 (
616 )
617 {
618  transfer(list);
619 }
620 
621 
622 // ************************************************************************* //
Foam::DynamicField::clear
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicFieldI.H:350
setSize
points setSize(newPointi)
Foam::DynamicField::transfer
void transfer(List< T > &list)
Transfer the parameter contents into this.
Definition: DynamicFieldI.H:428
Foam::DynamicField::setSize
void setSize(const label nElem)
Alter the addressed list size.
Definition: DynamicFieldI.H:284
Foam::DynamicField::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicFieldI.H:357
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::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicFieldI.H:226
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:224
Foam::DynamicField
Dynamically sized Field.
Definition: DynamicField.H:51
Foam::DynamicField::shrink
DynamicField< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicFieldI.H:378
Foam::Field
Generic templated field type.
Definition: Field.H:63
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
Construct null.
Definition: DynamicFieldI.H:60
Foam::FatalError
error FatalError
Foam::DynamicField::swap
void swap(DynamicField< T, AnySizeMin > &list)
Swap content with any sized DynamicField.
Definition: DynamicFieldI.H:398
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::Field< T >::operator=
void operator=(const Field< T > &)
Copy assignment.
Definition: Field.C:647
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::DynamicField::reserve
void reserve(const label nElem)
Reserve allocation space for at least this size.
Definition: DynamicFieldI.H:256
Foam::DynamicField::remove
T remove()
Remove and return the top element.
Definition: DynamicFieldI.H:520
clear
patchWriters clear()
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::DynamicField::expandStorage
label expandStorage()
Expand the addressable size to fit the allocated capacity.
Definition: DynamicFieldI.H:365
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::DynamicList::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:355
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
Foam::DynamicField::setCapacity
void setCapacity(const label nElem)
Alter the size of the underlying storage.
Definition: DynamicFieldI.H:234
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:56
Foam::DynamicField::append
DynamicField< T, SizeMin > & append(const T &val)
Append an element at the end of the list.
Definition: DynamicFieldI.H:483
Foam::DynamicField::resize
void resize(const label nElem)
Alter the addressed list size.
Definition: DynamicFieldI.H:330
Foam::zero
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:62