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 | Copyright (C) 2011-2016 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  const Xfer<List<T>>& lst
65 )
66 :
67  Field<T>(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 //- Construct by mapping from the given field
98 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
100 (
101  const UList<T>& mapF,
102  const FieldMapper& map
103 )
104 :
105  Field<T>(mapF, map),
106  capacity_(Field<T>::size())
107 {}
108 
109 
110 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
112 (
114 )
115 :
116  Field<T>(lst),
117  capacity_(lst.capacity())
118 {}
119 
120 
121 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
123 (
125 )
126 :
127  Field<T>(lst),
128  capacity_(Field<T>::size())
129 {}
130 
131 
132 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
133 
134 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
136 const
137 {
138  return capacity_;
139 }
140 
141 
142 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
144 (
145  const label nElem
146 )
147 {
148  label nextFree = Field<T>::size();
149  capacity_ = nElem;
150 
151  if (nextFree > capacity_)
152  {
153  // truncate addressed sizes too
154  nextFree = capacity_;
155  }
156  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
157 
158  Field<T>::setSize(capacity_);
159  Field<T>::size(nextFree);
160 }
161 
162 
163 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
165 (
166  const label nElem
167 )
168 {
169  // allocate more capacity?
170  if (nElem > capacity_)
171  {
172 // TODO: convince the compiler that division by zero does not occur
173 // if (SizeInc && (!SizeMult || !SizeDiv))
174 // {
175 // // resize with SizeInc as the granularity
176 // capacity_ = nElem;
177 // unsigned pad = SizeInc - (capacity_ % SizeInc);
178 // if (pad != SizeInc)
179 // {
180 // capacity_ += pad;
181 // }
182 // }
183 // else
184  {
185  capacity_ = max
186  (
187  nElem,
188  label(SizeInc + capacity_ * SizeMult / SizeDiv)
189  );
190  }
191 
192  // adjust allocated size, leave addressed size untouched
193  label nextFree = Field<T>::size();
194  Field<T>::setSize(capacity_);
195  Field<T>::size(nextFree);
196  }
197 }
198 
199 
200 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
202 (
203  const label nElem
204 )
205 {
206  // allocate more capacity?
207  if (nElem > capacity_)
208  {
209 // TODO: convince the compiler that division by zero does not occur
210 // if (SizeInc && (!SizeMult || !SizeDiv))
211 // {
212 // // resize with SizeInc as the granularity
213 // capacity_ = nElem;
214 // unsigned pad = SizeInc - (capacity_ % SizeInc);
215 // if (pad != SizeInc)
216 // {
217 // capacity_ += pad;
218 // }
219 // }
220 // else
221  {
222  capacity_ = max
223  (
224  nElem,
225  label(SizeInc + capacity_ * SizeMult / SizeDiv)
226  );
227  }
228 
229  Field<T>::setSize(capacity_);
230  }
231 
232  // adjust addressed size
233  Field<T>::size(nElem);
234 }
235 
236 
237 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
239 (
240  const label nElem,
241  const T& t
242 )
243 {
244  label nextFree = Field<T>::size();
245  setSize(nElem);
246 
247  // set new elements to constant value
248  while (nextFree < nElem)
249  {
250  this->operator[](nextFree++) = t;
251  }
252 }
253 
254 
255 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
257 (
258  const label nElem
259 )
260 {
261  this->setSize(nElem);
262 }
263 
264 
265 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
267 (
268  const label nElem,
269  const T& t
270 )
271 {
272  this->setSize(nElem, t);
273 }
274 
275 
276 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
278 {
279  Field<T>::size(0);
280 }
281 
282 
283 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
285 {
286  Field<T>::clear();
287  capacity_ = 0;
288 }
289 
290 
291 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
294 {
295  label nextFree = Field<T>::size();
296  if (capacity_ > nextFree)
297  {
298  // use the full list when resizing
299  Field<T>::size(capacity_);
300 
301  // the new size
302  capacity_ = nextFree;
303  Field<T>::setSize(capacity_);
304  Field<T>::size(nextFree);
305  }
306  return *this;
307 }
308 
309 
310 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
313 {
314  return xferMoveTo<List<T>>(*this);
315 }
316 
317 
318 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
321 (
322  const T& t
323 )
324 {
325  const label elemI = List<T>::size();
326  setSize(elemI + 1);
327 
328  this->operator[](elemI) = t;
329  return *this;
330 }
331 
332 
333 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
336 (
337  const UList<T>& lst
338 )
339 {
340  if (this == &lst)
341  {
343  << "attempted appending to self" << abort(FatalError);
344  }
345 
346  label nextFree = List<T>::size();
347  setSize(nextFree + lst.size());
348 
349  forAll(lst, elemI)
350  {
351  this->operator[](nextFree++) = lst[elemI];
352  }
353  return *this;
354 }
355 
356 
357 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
359 {
360  const label elemI = List<T>::size() - 1;
361 
362  if (elemI < 0)
363  {
365  << "List is empty" << abort(FatalError);
366  }
367 
368  const T& val = List<T>::operator[](elemI);
369 
370  List<T>::size(elemI);
371 
372  return val;
373 }
374 
375 
376 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
377 
378 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
380 (
381  const label elemI
382 )
383 {
384  if (elemI >= Field<T>::size())
385  {
386  setSize(elemI + 1);
387  }
388 
389  return this->operator[](elemI);
390 }
391 
392 
393 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
394 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
395 (
396  const T& t
397 )
398 {
400 }
401 
402 
403 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
404 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
405 (
407 )
408 {
409  if (this == &lst)
410  {
412  << "attempted assignment to self" << abort(FatalError);
413  }
414 
415  if (capacity_ >= lst.size())
416  {
417  // can copy w/o reallocating, match initial size to avoid reallocation
418  Field<T>::size(lst.size());
419  Field<T>::operator=(lst);
420  }
421  else
422  {
423  // make everything available for the copy operation
424  Field<T>::size(capacity_);
425 
426  Field<T>::operator=(lst);
427  capacity_ = Field<T>::size();
428  }
429 }
430 
431 
432 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
433 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
434 (
435  const UList<T>& lst
436 )
437 {
438  if (capacity_ >= lst.size())
439  {
440  // can copy w/o reallocating, match initial size to avoid reallocation
441  Field<T>::size(lst.size());
442  Field<T>::operator=(lst);
443  }
444  else
445  {
446  // make everything available for the copy operation
447  Field<T>::size(capacity_);
448 
449  Field<T>::operator=(lst);
450  capacity_ = Field<T>::size();
451  }
452 }
453 
454 
455 // ************************************************************************* //
DynamicField< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
DynamicField()
Construct null.
Definition: DynamicFieldI.H:29
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
void setCapacity(const label)
Alter the size of the underlying storage.
error FatalError
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
T & operator[](const label)
Return element of UList.
Definition: UListI.H:167
void resize(const label)
Alter the addressed list size.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
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:60
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
void clear()
Clear the addressed list, i.e. set the size to zero.
friend Ostream & operator(Ostream &, const Field< T > &)
Abstract base class to hold the Field mapping addressing and weights.
Definition: FieldMapper.H:45
Pre-declare SubField and related Field type.
Definition: Field.H:57
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:124
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:61
void map(const UList< T > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition: Field.C:358
void operator=(const Field< Type > &)
Definition: Field.C:764
const volScalarField & T
void setSize(const label)
Reset size of List.
Definition: List.C:281
void clearStorage()
Clear the list and delete storage.
void setSize(const label)
Alter the addressed list size.
tmp< Field< T > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:717
Xfer< List< T > > xfer()
Transfer contents to the Xfer container as a plain List.
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
T remove()
Remove and return the top element.
label size() const
Return the number of elements in the UList.
Definition: ListI.H:170
DynamicField< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.