DynamicFieldI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
27 
28 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
30 :
31  Field<T>(0),
32  capacity_(Field<T>::size())
33 {}
34 
35 
36 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
38 (
39  const label nElem
40 )
41 :
42  Field<T>(nElem),
43  capacity_(Field<T>::size())
44 {
45  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
46  Field<T>::size(0);
47 }
48 
49 
50 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
52 (
53  const label nElem,
54  const T& t
55 )
56 :
57  Field<T>(nElem, t),
58  capacity_(Field<T>::size())
59 {}
60 
61 
62 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
64 (
65  const label nElem,
66  const zero
67 )
68 :
69  Field<T>(nElem, Zero),
70  capacity_(Field<T>::size())
71 {}
72 
73 
74 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
76 (
77  const UList<T>& lst
78 )
79 :
80  Field<T>(lst),
81  capacity_(Field<T>::size())
82 {}
83 
84 
85 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
87 (
88  List<T>&& lst
89 )
90 :
91  Field<T>(move(lst)),
92  capacity_(Field<T>::size())
93 {}
94 
95 
96 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
98 (
99  const UList<T>& mapF,
100  const labelList& mapAddressing
101 )
102 :
103  Field<T>(mapF, mapAddressing),
104  capacity_(Field<T>::size())
105 {}
106 
107 
108 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
110 (
111  const UList<T>& mapF,
112  const labelListList& mapAddressing,
113  const scalarListList& weights
114 )
115 :
116  Field<T>(mapF, mapAddressing, weights),
117  capacity_(Field<T>::size())
118 {}
119 
120 
121 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
123 (
125 )
126 :
127  Field<T>(lst),
128  capacity_(lst.capacity_)
129 {}
130 
131 
132 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
134 (
136  const bool reuse
137 )
138 :
139  Field<T>(lst, reuse),
140  capacity_(lst.capacity_)
141 {
142  lst.capacity_ = 0;
143 }
144 
145 
146 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
148 (
150 )
151 :
152  Field<T>(move(lst)),
153  capacity_(lst.capacity_)
154 {
155  lst.capacity_ = 0;
156 }
157 
158 
159 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
160 
161 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
163 const
164 {
165  return capacity_;
166 }
167 
168 
169 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
171 (
172  const label nElem
173 )
174 {
175  label nextFree = Field<T>::size();
176  capacity_ = nElem;
177 
178  if (nextFree > capacity_)
179  {
180  // truncate addressed sizes too
181  nextFree = capacity_;
182  }
183  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
184 
185  Field<T>::setSize(capacity_);
186  Field<T>::size(nextFree);
187 }
188 
189 
190 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
192 (
193  const label nElem
194 )
195 {
196  // allocate more capacity?
197  if (nElem > capacity_)
198  {
199 // TODO: convince the compiler that division by zero does not occur
200 // if (SizeInc && (!SizeMult || !SizeDiv))
201 // {
202 // // resize with SizeInc as the granularity
203 // capacity_ = nElem;
204 // unsigned pad = SizeInc - (capacity_ % SizeInc);
205 // if (pad != SizeInc)
206 // {
207 // capacity_ += pad;
208 // }
209 // }
210 // else
211  {
212  capacity_ = max
213  (
214  nElem,
215  label(SizeInc + capacity_ * SizeMult / SizeDiv)
216  );
217  }
218 
219  // adjust allocated size, leave addressed size untouched
220  label nextFree = Field<T>::size();
221  Field<T>::setSize(capacity_);
222  Field<T>::size(nextFree);
223  }
224 }
225 
226 
227 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
229 (
230  const label nElem
231 )
232 {
233  // allocate more capacity?
234  if (nElem > capacity_)
235  {
236 // TODO: convince the compiler that division by zero does not occur
237 // if (SizeInc && (!SizeMult || !SizeDiv))
238 // {
239 // // resize with SizeInc as the granularity
240 // capacity_ = nElem;
241 // unsigned pad = SizeInc - (capacity_ % SizeInc);
242 // if (pad != SizeInc)
243 // {
244 // capacity_ += pad;
245 // }
246 // }
247 // else
248  {
249  capacity_ = max
250  (
251  nElem,
252  label(SizeInc + capacity_ * SizeMult / SizeDiv)
253  );
254  }
255 
256  Field<T>::setSize(capacity_);
257  }
258 
259  // adjust addressed size
260  Field<T>::size(nElem);
261 }
262 
263 
264 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
266 (
267  const label nElem,
268  const T& t
269 )
270 {
271  label nextFree = Field<T>::size();
272  setSize(nElem);
273 
274  // set new elements to constant value
275  while (nextFree < nElem)
276  {
277  this->operator[](nextFree++) = t;
278  }
279 }
280 
281 
282 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
284 (
285  const label nElem
286 )
287 {
288  this->setSize(nElem);
289 }
290 
291 
292 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
294 (
295  const label nElem,
296  const T& t
297 )
298 {
299  this->setSize(nElem, t);
300 }
301 
302 
303 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
305 {
306  Field<T>::size(0);
307 }
308 
309 
310 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
312 {
313  Field<T>::clear();
314  capacity_ = 0;
315 }
316 
317 
318 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
320 (
322 )
323 {
324  this->operator=(lst);
325 }
326 
327 
328 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
330 (
331  const UList<T>& lst
332 )
333 {
334  this->operator=(lst);
335 }
336 
337 
338 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
341 {
342  label nextFree = Field<T>::size();
343  if (capacity_ > nextFree)
344  {
345  // use the full list when resizing
346  Field<T>::size(capacity_);
347 
348  // the new size
349  capacity_ = nextFree;
350  Field<T>::setSize(capacity_);
351  Field<T>::size(nextFree);
352  }
353  return *this;
354 }
355 
356 
357 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
360 (
361  const T& t
362 )
363 {
364  const label elemI = List<T>::size();
365  setSize(elemI + 1);
366 
367  this->operator[](elemI) = t;
368  return *this;
369 }
370 
371 
372 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
375 (
376  const UList<T>& lst
377 )
378 {
379  if (this == &lst)
380  {
382  << "attempted appending to self" << abort(FatalError);
383  }
384 
385  label nextFree = List<T>::size();
386  setSize(nextFree + lst.size());
387 
388  forAll(lst, elemI)
389  {
390  this->operator[](nextFree++) = lst[elemI];
391  }
392  return *this;
393 }
394 
395 
396 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
398 {
399  const label elemI = List<T>::size() - 1;
400 
401  if (elemI < 0)
402  {
404  << "List is empty" << abort(FatalError);
405  }
406 
407  const T& val = List<T>::operator[](elemI);
408 
409  List<T>::size(elemI);
410 
411  return val;
412 }
413 
414 
415 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
416 
417 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
419 (
420  const label elemI
421 )
422 {
423  if (elemI >= Field<T>::size())
424  {
425  setSize(elemI + 1);
426  }
427 
428  return this->operator[](elemI);
429 }
430 
431 
432 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
434 (
435  const T& t
436 )
437 {
439 }
440 
441 
442 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
444 (
446 )
447 {
448  if (this == &lst)
449  {
451  << "attempted assignment to self" << abort(FatalError);
452  }
453 
454  if (capacity_ >= lst.size())
455  {
456  // can copy w/o reallocating, match initial size to avoid reallocation
457  Field<T>::size(lst.size());
458  Field<T>::operator=(lst);
459  }
460  else
461  {
462  // make everything available for the copy operation
463  Field<T>::size(capacity_);
464 
465  Field<T>::operator=(lst);
466  capacity_ = Field<T>::size();
467  }
468 }
469 
470 
471 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
473 (
475 )
476 {
477  if (this == &lst)
478  {
480  << "attempted assignment to self" << abort(FatalError);
481  }
482 
483  Field<T>::operator=(move(lst));
484  capacity_ = lst.capacity_;
485  lst.capacity_ = 0;
486 }
487 
488 
489 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
491 (
492  const UList<T>& lst
493 )
494 {
495  if (capacity_ >= lst.size())
496  {
497  // can copy w/o reallocating, match initial size to avoid reallocation
498  Field<T>::size(lst.size());
499  Field<T>::operator=(lst);
500  }
501  else
502  {
503  // make everything available for the copy operation
504  Field<T>::size(capacity_);
505 
506  Field<T>::operator=(lst);
507  capacity_ = Field<T>::size();
508  }
509 }
510 
511 
512 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
514 (
515  List<T>&& lst
516 )
517 {
518  if (this == &lst)
519  {
521  << "attempted assignment to self" << abort(FatalError);
522  }
523 
524  Field<T>::operator=(move(lst));
525  capacity_ = Field<T>::size();
526 }
527 
528 
529 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Dynamically sized Field.
Definition: DynamicField.H:72
T remove()
Remove and return the top element.
DynamicField< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
void setCapacity(const label)
Alter the size of the underlying storage.
void resize(const label)
Alter the addressed list size.
label capacity() const
Size of the underlying storage.
DynamicField()
Construct null.
Definition: DynamicFieldI.H:29
DynamicField< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
void reserve(const label)
Reserve allocation space for at least this size.
void clearStorage()
Clear the list and delete storage.
void clear()
Clear the addressed list, i.e. set the size to zero.
void setSize(const label)
Alter the addressed list size.
void reset(const DynamicField< T, SizeInc, SizeMult, SizeDiv > &)
Reset the field values to the given field.
friend Ostream & operator(Ostream &, const DynamicField< T, SizeInc, SizeMult, SizeDiv > &)
Pre-declare SubField and related Field type.
Definition: Field.H:83
void operator=(const Field< Type > &)
Definition: Field.C:557
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
label size() const
Return the number of elements in the UList.
Definition: ListI.H:171
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
void setSize(const label)
Reset size of List.
Definition: List.C:281
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:74
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
T & operator[](const label)
Return element of UList.
Definition: UListI.H:167
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
Definition: zero.H:50
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
static const zero Zero
Definition: zero.H:97
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:59
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void T(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
error FatalError
points setSize(newPointi)