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-2019 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 UList<T>& lst
54 )
55 :
56  Field<T>(lst),
57  capacity_(Field<T>::size())
58 {}
59 
60 
61 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
63 (
64  List<T>&& lst
65 )
66 :
67  Field<T>(move(lst)),
68  capacity_(Field<T>::size())
69 {}
70 
71 
72 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
74 (
75  const UList<T>& mapF,
76  const labelList& mapAddressing
77 )
78 :
79  Field<T>(mapF, mapAddressing),
80  capacity_(Field<T>::size())
81 {}
82 
83 
84 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
86 (
87  const UList<T>& mapF,
88  const labelListList& mapAddressing,
89  const scalarListList& weights
90 )
91 :
92  Field<T>(mapF, mapAddressing, weights),
93  capacity_(Field<T>::size())
94 {}
95 
96 
97 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
99 (
101 )
102 :
103  Field<T>(lst),
104  capacity_(lst.capacity_)
105 {}
106 
107 
108 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
110 (
112 )
113 :
114  Field<T>(move(lst)),
115  capacity_(lst.capacity_)
116 {
117  lst.capacity_ = 0;
118 }
119 
120 
121 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
122 
123 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
125 const
126 {
127  return capacity_;
128 }
129 
130 
131 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
133 (
134  const label nElem
135 )
136 {
137  label nextFree = Field<T>::size();
138  capacity_ = nElem;
139 
140  if (nextFree > capacity_)
141  {
142  // truncate addressed sizes too
143  nextFree = capacity_;
144  }
145  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
146 
147  Field<T>::setSize(capacity_);
148  Field<T>::size(nextFree);
149 }
150 
151 
152 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
154 (
155  const label nElem
156 )
157 {
158  // allocate more capacity?
159  if (nElem > capacity_)
160  {
161 // TODO: convince the compiler that division by zero does not occur
162 // if (SizeInc && (!SizeMult || !SizeDiv))
163 // {
164 // // resize with SizeInc as the granularity
165 // capacity_ = nElem;
166 // unsigned pad = SizeInc - (capacity_ % SizeInc);
167 // if (pad != SizeInc)
168 // {
169 // capacity_ += pad;
170 // }
171 // }
172 // else
173  {
174  capacity_ = max
175  (
176  nElem,
177  label(SizeInc + capacity_ * SizeMult / SizeDiv)
178  );
179  }
180 
181  // adjust allocated size, leave addressed size untouched
182  label nextFree = Field<T>::size();
183  Field<T>::setSize(capacity_);
184  Field<T>::size(nextFree);
185  }
186 }
187 
188 
189 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
191 (
192  const label nElem
193 )
194 {
195  // allocate more capacity?
196  if (nElem > capacity_)
197  {
198 // TODO: convince the compiler that division by zero does not occur
199 // if (SizeInc && (!SizeMult || !SizeDiv))
200 // {
201 // // resize with SizeInc as the granularity
202 // capacity_ = nElem;
203 // unsigned pad = SizeInc - (capacity_ % SizeInc);
204 // if (pad != SizeInc)
205 // {
206 // capacity_ += pad;
207 // }
208 // }
209 // else
210  {
211  capacity_ = max
212  (
213  nElem,
214  label(SizeInc + capacity_ * SizeMult / SizeDiv)
215  );
216  }
217 
218  Field<T>::setSize(capacity_);
219  }
220 
221  // adjust addressed size
222  Field<T>::size(nElem);
223 }
224 
225 
226 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
228 (
229  const label nElem,
230  const T& t
231 )
232 {
233  label nextFree = Field<T>::size();
234  setSize(nElem);
235 
236  // set new elements to constant value
237  while (nextFree < nElem)
238  {
239  this->operator[](nextFree++) = t;
240  }
241 }
242 
243 
244 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
246 (
247  const label nElem
248 )
249 {
250  this->setSize(nElem);
251 }
252 
253 
254 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
256 (
257  const label nElem,
258  const T& t
259 )
260 {
261  this->setSize(nElem, t);
262 }
263 
264 
265 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
267 {
268  Field<T>::size(0);
269 }
270 
271 
272 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
274 {
275  Field<T>::clear();
276  capacity_ = 0;
277 }
278 
279 
280 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
283 {
284  label nextFree = Field<T>::size();
285  if (capacity_ > nextFree)
286  {
287  // use the full list when resizing
288  Field<T>::size(capacity_);
289 
290  // the new size
291  capacity_ = nextFree;
292  Field<T>::setSize(capacity_);
293  Field<T>::size(nextFree);
294  }
295  return *this;
296 }
297 
298 
299 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
302 (
303  const T& t
304 )
305 {
306  const label elemI = List<T>::size();
307  setSize(elemI + 1);
308 
309  this->operator[](elemI) = t;
310  return *this;
311 }
312 
313 
314 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
317 (
318  const UList<T>& lst
319 )
320 {
321  if (this == &lst)
322  {
324  << "attempted appending to self" << abort(FatalError);
325  }
326 
327  label nextFree = List<T>::size();
328  setSize(nextFree + lst.size());
329 
330  forAll(lst, elemI)
331  {
332  this->operator[](nextFree++) = lst[elemI];
333  }
334  return *this;
335 }
336 
337 
338 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
340 {
341  const label elemI = List<T>::size() - 1;
342 
343  if (elemI < 0)
344  {
346  << "List is empty" << abort(FatalError);
347  }
348 
349  const T& val = List<T>::operator[](elemI);
350 
351  List<T>::size(elemI);
352 
353  return val;
354 }
355 
356 
357 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
358 
359 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
361 (
362  const label elemI
363 )
364 {
365  if (elemI >= Field<T>::size())
366  {
367  setSize(elemI + 1);
368  }
369 
370  return this->operator[](elemI);
371 }
372 
373 
374 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
375 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
376 (
377  const T& t
378 )
379 {
381 }
382 
383 
384 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
385 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
386 (
388 )
389 {
390  if (this == &lst)
391  {
393  << "attempted assignment to self" << abort(FatalError);
394  }
395 
396  if (capacity_ >= lst.size())
397  {
398  // can copy w/o reallocating, match initial size to avoid reallocation
399  Field<T>::size(lst.size());
400  Field<T>::operator=(lst);
401  }
402  else
403  {
404  // make everything available for the copy operation
405  Field<T>::size(capacity_);
406 
407  Field<T>::operator=(lst);
408  capacity_ = Field<T>::size();
409  }
410 }
411 
412 
413 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
414 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
415 (
417 )
418 {
419  if (this == &lst)
420  {
422  << "attempted assignment to self" << abort(FatalError);
423  }
424 
425  Field<T>::operator=(move(lst));
426  capacity_ = lst.capacity_;
427  lst.capacity_ = 0;
428 }
429 
430 
431 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
432 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
433 (
434  const UList<T>& lst
435 )
436 {
437  if (capacity_ >= lst.size())
438  {
439  // can copy w/o reallocating, match initial size to avoid reallocation
440  Field<T>::size(lst.size());
441  Field<T>::operator=(lst);
442  }
443  else
444  {
445  // make everything available for the copy operation
446  Field<T>::size(capacity_);
447 
448  Field<T>::operator=(lst);
449  capacity_ = Field<T>::size();
450  }
451 }
452 
453 
454 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
455 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
456 (
457  List<T>&& lst
458 )
459 {
460  if (this == &lst)
461  {
463  << "attempted assignment to self" << abort(FatalError);
464  }
465 
466  Field<T>::operator=(move(lst));
467  capacity_ = Field<T>::size();
468 }
469 
470 
471 // ************************************************************************* //
friend Ostream & operator(Ostream &, const DynamicField< T, SizeInc, SizeMult, SizeDiv > &)
DynamicField< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
DynamicField()
Construct null.
Definition: DynamicFieldI.H:29
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
tUEqn clear()
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
void setCapacity(const label)
Alter the size of the underlying storage.
error FatalError
void resize(const label)
Alter the addressed list size.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
label capacity() const
Size of the underlying storage.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void clear()
Clear the addressed list, i.e. set the size to zero.
points setSize(newPointi)
Pre-declare SubField and related Field type.
Definition: Field.H:56
void reserve(const label)
Reserve allocation space for at least this size.
Dynamically sized Field.
Definition: DynamicField.H:49
errorManip< error > abort(error &err)
Definition: errorManip.H:131
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:60
const volScalarField & T
void clearStorage()
Clear the list and delete storage.
void setSize(const label)
Alter the addressed list size.
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
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.