DynamicListI.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 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  List<T>(0),
32  capacity_(0)
33 {
34  List<T>::size(0);
35 }
36 
37 
38 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
40 (
41  const label nElem
42 )
43 :
44  List<T>(nElem),
45  capacity_(nElem)
46 {
47  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
48  List<T>::size(0);
49 }
50 
51 
52 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
54 (
56 )
57 :
58  List<T>(lst),
59  capacity_(lst.size())
60 {}
61 
62 
63 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
65 (
66  const UList<T>& lst
67 )
68 :
69  List<T>(lst),
70  capacity_(lst.size())
71 {}
72 
73 
74 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
76 (
77  const UIndirectList<T>& lst
78 )
79 :
80  List<T>(lst),
81  capacity_(lst.size())
82 {}
83 
84 
85 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
87 (
88  const Xfer<List<T> >& lst
89 )
90 :
91  List<T>(lst),
92  capacity_(List<T>::size())
93 {}
94 
95 
96 
97 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
98 
99 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
101 const
102 {
103  return capacity_;
104 }
105 
106 
107 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
109 (
110  const label nElem
111 )
112 {
113  label nextFree = List<T>::size();
114  capacity_ = nElem;
115 
116  if (nextFree > capacity_)
117  {
118  // truncate addressed sizes too
119  nextFree = capacity_;
120  }
121  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
122 
123  List<T>::setSize(capacity_);
124  List<T>::size(nextFree);
125 }
126 
127 
128 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
130 (
131  const label nElem
132 )
133 {
134  // allocate more capacity?
135  if (nElem > capacity_)
136  {
137 // TODO: convince the compiler that division by zero does not occur
138 // if (SizeInc && (!SizeMult || !SizeDiv))
139 // {
140 // // resize with SizeInc as the granularity
141 // capacity_ = nElem;
142 // unsigned pad = SizeInc - (capacity_ % SizeInc);
143 // if (pad != SizeInc)
144 // {
145 // capacity_ += pad;
146 // }
147 // }
148 // else
149  {
150  capacity_ = max
151  (
152  nElem,
153  label(SizeInc + capacity_ * SizeMult / SizeDiv)
154  );
155  }
156 
157  // adjust allocated size, leave addressed size untouched
158  label nextFree = List<T>::size();
159  List<T>::setSize(capacity_);
160  List<T>::size(nextFree);
161  }
162 }
163 
164 
165 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
167 (
168  const label nElem
169 )
170 {
171  // allocate more capacity?
172  if (nElem > capacity_)
173  {
174 // TODO: convince the compiler that division by zero does not occur
175 // if (SizeInc && (!SizeMult || !SizeDiv))
176 // {
177 // // resize with SizeInc as the granularity
178 // capacity_ = nElem;
179 // unsigned pad = SizeInc - (capacity_ % SizeInc);
180 // if (pad != SizeInc)
181 // {
182 // capacity_ += pad;
183 // }
184 // }
185 // else
186  {
187  capacity_ = max
188  (
189  nElem,
190  label(SizeInc + capacity_ * SizeMult / SizeDiv)
191  );
192  }
193 
194  List<T>::setSize(capacity_);
195  }
196 
197  // adjust addressed size
198  List<T>::size(nElem);
199 }
200 
201 
202 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
204 (
205  const label nElem,
206  const T& t
207 )
208 {
209  label nextFree = List<T>::size();
210  setSize(nElem);
211 
212  // set new elements to constant value
213  while (nextFree < nElem)
214  {
215  this->operator[](nextFree++) = t;
216  }
217 }
218 
219 
220 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
222 (
223  const label nElem
224 )
225 {
226  this->setSize(nElem);
227 }
228 
229 
230 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
232 (
233  const label nElem,
234  const T& t
235 )
236 {
237  this->setSize(nElem, t);
238 }
239 
240 
241 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
243 {
244  List<T>::size(0);
245 }
246 
247 
248 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
250 {
251  List<T>::clear();
252  capacity_ = 0;
253 }
254 
255 
256 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
259 {
260  label nextFree = List<T>::size();
261  if (capacity_ > nextFree)
262  {
263  // use the full list when resizing
264  List<T>::size(capacity_);
265 
266  // the new size
267  capacity_ = nextFree;
268  List<T>::setSize(capacity_);
269  List<T>::size(nextFree);
270  }
271  return *this;
272 }
273 
274 
275 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
276 inline void
278 {
279  capacity_ = lst.size();
280  List<T>::transfer(lst); // take over storage, clear addressing for lst.
281 }
282 
283 
284 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
285 inline void
287 (
289 )
290 {
291  // take over storage as-is (without shrink), clear addressing for lst.
292  capacity_ = lst.capacity_;
293  lst.capacity_ = 0;
294 
295  List<T>::transfer(static_cast<List<T>&>(lst));
296 }
297 
298 
299 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
302 {
303  return xferMoveTo< List<T> >(*this);
304 }
305 
306 
307 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
310 (
311  const T& t
312 )
313 {
314  const label elemI = List<T>::size();
315  setSize(elemI + 1);
316 
317  this->operator[](elemI) = t;
318  return *this;
319 }
320 
321 
322 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
325 (
326  const UList<T>& lst
327 )
328 {
329  if (this == &lst)
330  {
332  (
333  "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
334  "(const UList<T>&)"
335  ) << "attempted appending to self" << abort(FatalError);
336  }
337 
338  label nextFree = List<T>::size();
339  setSize(nextFree + lst.size());
340 
341  forAll(lst, elemI)
342  {
343  this->operator[](nextFree++) = lst[elemI];
344  }
345  return *this;
346 }
347 
348 
349 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
352 (
353  const UIndirectList<T>& lst
354 )
355 {
356  label nextFree = List<T>::size();
357  setSize(nextFree + lst.size());
358 
359  forAll(lst, elemI)
360  {
361  this->operator[](nextFree++) = lst[elemI];
362  }
363  return *this;
364 }
365 
366 
367 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
369 {
370  const label elemI = List<T>::size() - 1;
371 
372  if (elemI < 0)
373  {
375  (
376  "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
377  ) << "List is empty" << abort(FatalError);
378  }
379 
380  const T& val = List<T>::operator[](elemI);
381 
382  List<T>::size(elemI);
383 
384  return val;
385 }
386 
387 
388 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
389 
390 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
392 (
393  const label elemI
394 )
395 {
396  if (elemI >= List<T>::size())
397  {
398  setSize(elemI + 1);
399  }
400 
401  return this->operator[](elemI);
402 }
403 
404 
405 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
406 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
407 (
408  const T& t
409 )
410 {
412 }
413 
414 
415 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
416 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
417 (
419 )
420 {
421  if (this == &lst)
422  {
424  (
425  "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
426  "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
427  ) << "attempted assignment to self" << abort(FatalError);
428  }
429 
430  if (capacity_ >= lst.size())
431  {
432  // can copy w/o reallocating, match initial size to avoid reallocation
433  List<T>::size(lst.size());
434  List<T>::operator=(lst);
435  }
436  else
437  {
438  // make everything available for the copy operation
439  List<T>::size(capacity_);
440 
441  List<T>::operator=(lst);
442  capacity_ = List<T>::size();
443  }
444 }
445 
446 
447 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
448 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
449 (
450  const UList<T>& lst
451 )
452 {
453  if (capacity_ >= lst.size())
454  {
455  // can copy w/o reallocating, match initial size to avoid reallocation
456  List<T>::size(lst.size());
457  List<T>::operator=(lst);
458  }
459  else
460  {
461  // make everything available for the copy operation
462  List<T>::size(capacity_);
463 
464  List<T>::operator=(lst);
465  capacity_ = List<T>::size();
466  }
467 }
468 
469 
470 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
471 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
472 (
473  const UIndirectList<T>& lst
474 )
475 {
476  if (capacity_ >= lst.size())
477  {
478  // can copy w/o reallocating, match initial size to avoid reallocation
479  List<T>::size(lst.size());
480  List<T>::operator=(lst);
481  }
482  else
483  {
484  // make everything available for the copy operation
485  List<T>::size(capacity_);
486 
487  List<T>::operator=(lst);
488  capacity_ = List<T>::size();
489  }
490 }
491 
492 // ************************************************************************* //
void transfer(List< T > &)
Transfer contents of the argument List into this.
Definition: DynamicListI.H:277
friend Ostream & operator(Ostream &, const DynamicList< T, SizeInc, SizeMult, SizeDiv > &)
void setCapacity(const label)
Alter the size of the underlying storage.
Definition: DynamicListI.H:109
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:242
label capacity() const
Size of the underlying storage.
Definition: DynamicListI.H:100
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 size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:310
T remove()
Remove and return the top element.
Definition: DynamicListI.H:368
const volScalarField & T
Definition: createFields.H:25
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
T & operator[](const label)
Return element of UList.
Definition: UListI.H:163
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
void setSize(const label)
Reset size of List.
Definition: List.C:318
A List with indirect addressing.
Definition: fvMatrix.H:106
Xfer< List< T > > xfer()
Transfer contents to the Xfer container as a plain List.
Definition: DynamicListI.H:301
label size() const
Return the number of elements in the list.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define forAll(list, i)
Definition: UList.H:421
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:258
void resize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:222
void setSize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:167
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
DynamicList()
Construct null.
Definition: DynamicListI.H:29
errorManip< error > abort(error &err)
Definition: errorManip.H:131
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
void operator=(const T &)
Assignment of all entries to the given value.
Definition: UList.C:70
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
error FatalError
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
label size() const
Return the number of elements in the UList.
Definition: ListI.H:83
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:249
void reserve(const label)
Reserve allocation space for at least this size.
Definition: DynamicListI.H:130
void operator=(const UList< T > &)
Assignment from UList operator. Takes linear time.
Definition: List.C:429