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 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>
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  if (this == &lst)
403  {
404  return; // Self-swap is a no-op
405  }
406 
407  DynamicList<T, SizeMin>& cur = *this;
408 
409  // Make addressable size identical to the allocated capacity
410  const label oldSize1 = cur.expandStorage();
411  const label oldSize2 = lst.expandStorage();
412 
413  // Swap storage
414  Field<T>::swap(lst);
415 
416  // Match capacity to the underlying allocated list size
417  cur.setCapacity(cur.size());
418  lst.setCapacity(lst.size());
419 
420  // Set addressable size
421  cur.setSize(oldSize2);
422  lst.setSize(oldSize1);
423 }
424 
425 
426 template<class T, int SizeMin>
428 {
429  // Take over storage, clear addressing for list.
430  capacity_ = list.size();
431  Field<T>::transfer(list);
432 }
433 
434 
435 template<class T, int SizeMin>
436 template<int AnySizeMin>
438 (
440 )
441 {
442  // Take over storage as-is (without shrink, without using SizeMin)
443  // clear addressing and storage for old list.
444  capacity_ = list.capacity();
445 
446  Field<T>::transfer(static_cast<Field<T>&>(list));
447  list.clearStorage(); // Ensure capacity=0
448 }
449 
450 
451 template<class T, int SizeMin>
452 template<int AnySizeMin>
454 (
456 )
457 {
458  if (this == &list)
459  {
460  return; // Self-assignment is a no-op
461  }
462 
463  // Take over storage as-is (without shrink, without using SizeMin)
464  // clear addressing and storage for old list.
465  capacity_ = list.capacity();
466 
467  Field<T>::transfer(static_cast<Field<T>&>(list));
468  list.clearStorage(); // Ensure capacity=0
469 }
470 
471 
472 template<class T, int SizeMin>
475 (
476  const T& val
477 )
478 {
479  const label idx = List<T>::size();
480  setSize(idx + 1);
481 
482  this->operator[](idx) = val; // copy element
483  return *this;
484 }
485 
486 
487 template<class T, int SizeMin>
490 (
491  const UList<T>& list
492 )
493 {
494  if (this == &list)
495  {
497  << "Attempted appending to self" << abort(FatalError);
498  }
499 
500  label idx = List<T>::size();
501  setSize(idx + list.size());
502 
503  for (const T& val : list)
504  {
505  this->operator[](idx++) = val; // copy element
506  }
507  return *this;
508 }
509 
510 
511 template<class T, int SizeMin>
513 {
514  // Location of last element and simultaneously the new size
515  const label idx = List<T>::size() - 1;
516 
517  if (idx < 0)
518  {
520  << "List is empty" << abort(FatalError);
521  }
522 
523  const T& val = List<T>::operator[](idx);
524 
525  List<T>::size(idx);
526 
527  return val;
528 }
529 
530 
531 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
532 
533 template<class T, int SizeMin>
535 (
536  const label i
537 )
538 {
539  if (i >= Field<T>::size())
540  {
541  setSize(i + 1);
542  }
543 
544  return this->operator[](i);
545 }
546 
547 
548 template<class T, int SizeMin>
550 (
551  const T& val
552 )
553 {
555 }
556 
557 
558 template<class T, int SizeMin>
560 (
561  const UList<T>& list
562 )
563 {
564  assignDynField(list);
565 }
566 
567 
568 template<class T, int SizeMin>
570 (
571  const DynamicField<T, SizeMin>& list
572 )
573 {
574  if (this == &list)
575  {
576  return; // Self-assignment is a no-op
577  }
578 
579  assignDynField(list);
580 }
581 
582 
583 template<class T, int SizeMin>
585 (
586  List<T>&& list
587 )
588 {
589  transfer(list);
590 }
591 
592 
593 template<class T, int SizeMin>
595 (
597 )
598 {
599  transfer(list);
600 }
601 
602 
603 template<class T, int SizeMin>
604 template<int AnySizeMin>
606 (
608 )
609 {
610  transfer(list);
611 }
612 
613 
614 // ************************************************************************* //
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:427
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
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.
Definition: zero.H:128
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:57
Foam::DynamicField::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicFieldI.H:226
Foam::DynamicList::expandStorage
label expandStorage()
Expand the addressable size to fit the allocated capacity.
Definition: DynamicListI.H:363
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::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
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:137
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::Field< T >::operator=
void operator=(const Field< T > &)
Copy assignment.
Definition: Field.C:658
Foam::DynamicList::setSize
void setSize(const label nElem)
Alter addressable list size.
Definition: DynamicListI.H:282
Foam::DynamicList::setCapacity
void setCapacity(const label nElem)
Alter the size of the underlying storage.
Definition: DynamicListI.H:232
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
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:512
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: HashTable.H:102
Foam::UList::operator=
UList< T > & operator=(const UList< T > &)=delete
No copy assignment (default: shallow copy)
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:57
Foam::DynamicField::append
DynamicField< T, SizeMin > & append(const T &val)
Append an element at the end of the list.
Definition: DynamicFieldI.H:475
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), which can be used to avoid manipulating objects that ar...
Definition: zero.H:61