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>
376 (
377  const T& t
378 )
379 {
381 }
382 
383 
384 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
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>
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>
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>
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 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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.
friend Ostream & operator(Ostream &, const DynamicField< T, SizeInc, SizeMult, SizeDiv > &)
Pre-declare SubField and related Field type.
Definition: Field.H:82
void operator=(const Field< Type > &)
Definition: Field.C:526
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
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
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
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
error FatalError
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
points setSize(newPointi)