DynamicListI.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  capacity_(0)
32 {}
33 
34 
35 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
37 (
38  const label nElem
39 )
40 :
41  List<T>(nElem),
42  capacity_(nElem)
43 {
44  // We could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
45  List<T>::size(0);
46 }
47 
48 
49 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
51 (
52  const label nElem,
53  const T& a
54 )
55 :
56  List<T>(nElem, a),
57  capacity_(nElem)
58 {}
59 
60 
61 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
63 (
65 )
66 :
67  List<T>(lst),
68  capacity_(lst.size())
69 {}
70 
71 
72 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
74 (
76 )
77 :
78  List<T>(move(lst)),
79  capacity_(lst.capacity_)
80 {
81  lst.capacity_ = 0;
82 }
83 
84 
85 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
87 (
88  const UList<T>& lst
89 )
90 :
91  List<T>(lst),
92  capacity_(lst.size())
93 {}
94 
95 
96 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
98 (
99  const UIndirectList<T>& lst
100 )
101 :
102  List<T>(lst),
103  capacity_(lst.size())
104 {}
105 
106 
107 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
109 (
110  List<T>&& lst
111 )
112 :
113  List<T>(move(lst)),
114  capacity_(List<T>::size())
115 {}
116 
117 
118 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
119 
120 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
122 const
123 {
124  return capacity_;
125 }
126 
127 
128 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
130 (
131  const label nElem
132 )
133 {
134  label nextFree = List<T>::size();
135  capacity_ = nElem;
136 
137  if (nextFree > capacity_)
138  {
139  // Truncate addressed sizes too
140  nextFree = capacity_;
141  }
142 
143  // We could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
144 
145  List<T>::setSize(capacity_);
146  List<T>::size(nextFree);
147 }
148 
149 
150 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
152 (
153  const label nElem
154 )
155 {
156  // Allocate more capacity if necessary
157  if (nElem > capacity_)
158  {
159  capacity_ = max
160  (
161  nElem,
162  label(SizeInc + capacity_ * SizeMult / SizeDiv)
163  );
164 
165  // Adjust allocated size, leave addressed size untouched
166  label nextFree = List<T>::size();
167  List<T>::setSize(capacity_);
168  List<T>::size(nextFree);
169  }
170 }
171 
172 
173 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
175 (
176  const label nElem
177 )
178 {
179  // Allocate more capacity if necessary
180  if (nElem > capacity_)
181  {
182  capacity_ = max
183  (
184  nElem,
185  label(SizeInc + capacity_ * SizeMult / SizeDiv)
186  );
187 
188  List<T>::setSize(capacity_);
189  }
190 
191  // Adjust addressed size
192  List<T>::size(nElem);
193 }
194 
195 
196 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
198 (
199  const label nElem,
200  const T& t
201 )
202 {
203  label nextFree = List<T>::size();
204  setSize(nElem);
205 
206  // Set new elements to constant value
207  while (nextFree < nElem)
208  {
209  this->operator[](nextFree++) = t;
210  }
211 }
212 
213 
214 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
216 (
217  const label nElem
218 )
219 {
220  this->setSize(nElem);
221 }
222 
223 
224 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
226 (
227  const label nElem,
228  const T& t
229 )
230 {
231  this->setSize(nElem, t);
232 }
233 
234 
235 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
237 {
238  List<T>::size(0);
239 }
240 
241 
242 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
244 {
245  List<T>::clear();
246  capacity_ = 0;
247 }
248 
249 
250 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
253 {
254  label nextFree = List<T>::size();
255  if (capacity_ > nextFree)
256  {
257  // Use the full list when resizing
258  List<T>::size(capacity_);
259 
260  // The new size
261  capacity_ = nextFree;
262  List<T>::setSize(capacity_);
263  List<T>::size(nextFree);
264  }
265  return *this;
266 }
267 
268 
269 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
270 inline void
272 (
274 )
275 {
276  // Take over storage as-is (without shrink), clear addressing for lst.
277  capacity_ = lst.capacity_;
278  lst.capacity_ = 0;
279  List<T>::transfer(static_cast<List<T>&>(lst));
280 }
281 
282 
283 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
284 inline void
286 {
287  // Take over storage, clear addressing for lst.
288  capacity_ = lst.size();
289  List<T>::transfer(lst);
290 }
291 
292 
293 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
296 (
297  const T& t
298 )
299 {
300  const label elemI = List<T>::size();
301  setSize(elemI + 1);
302 
303  this->operator[](elemI) = t;
304  return *this;
305 }
306 
307 
308 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
311 (
312  const UList<T>& lst
313 )
314 {
315  if (this == &lst)
316  {
318  << "Attempted appending to self" << abort(FatalError);
319  }
320 
321  label nextFree = List<T>::size();
322  setSize(nextFree + lst.size());
323 
324  forAll(lst, elemI)
325  {
326  this->operator[](nextFree++) = lst[elemI];
327  }
328  return *this;
329 }
330 
331 
332 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
335 (
336  const UIndirectList<T>& lst
337 )
338 {
339  label nextFree = List<T>::size();
340  setSize(nextFree + lst.size());
341 
342  forAll(lst, elemI)
343  {
344  this->operator[](nextFree++) = lst[elemI];
345  }
346  return *this;
347 }
348 
349 
350 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
352 {
353  const label elemI = List<T>::size() - 1;
354 
355  if (elemI < 0)
356  {
358  << "List is empty" << abort(FatalError);
359  }
360 
361  const T& val = List<T>::operator[](elemI);
362 
363  List<T>::size(elemI);
364 
365  return val;
366 }
367 
368 
369 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
370 
371 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
373 (
374  const label elemI
375 )
376 {
377  if (elemI >= List<T>::size())
378  {
379  setSize(elemI + 1);
380  }
381 
382  return this->operator[](elemI);
383 }
384 
385 
386 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
387 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
388 (
389  const T& t
390 )
391 {
393 }
394 
395 
396 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
397 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
398 (
400 )
401 {
402  if (this == &lst)
403  {
405  << "Attempted assignment to self" << abort(FatalError);
406  }
407 
408  if (capacity_ >= lst.size())
409  {
410  // Can copy w/o reallocating, match initial size to avoid reallocation
411  List<T>::size(lst.size());
412  List<T>::operator=(lst);
413  }
414  else
415  {
416  // Make everything available for the copy operation
417  List<T>::size(capacity_);
418 
419  List<T>::operator=(lst);
420  capacity_ = List<T>::size();
421  }
422 }
423 
424 
425 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
426 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
427 (
429 )
430 {
431  if (this == &lst)
432  {
434  << "Attempted assignment to self" << abort(FatalError);
435  }
436 
437  List<T>::operator=(move(lst));
438  capacity_ = lst.capacity_;
439  lst.capacity_ = 0;
440 }
441 
442 
443 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
444 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
445 (
446  List<T>&& lst
447 )
448 {
449  if (this == &lst)
450  {
452  << "Attempted assignment to self" << abort(FatalError);
453  }
454 
455  List<T>::operator=(move(lst));
456  capacity_ = List<T>::size();
457 }
458 
459 
460 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
461 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
462 (
463  const UList<T>& lst
464 )
465 {
466  if (capacity_ >= lst.size())
467  {
468  // Can copy w/o reallocating, match initial size to avoid reallocation
469  List<T>::size(lst.size());
470  List<T>::operator=(lst);
471  }
472  else
473  {
474  // Make everything available for the copy operation
475  List<T>::size(capacity_);
476 
477  List<T>::operator=(lst);
478  capacity_ = List<T>::size();
479  }
480 }
481 
482 
483 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
484 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
485 (
486  const UIndirectList<T>& lst
487 )
488 {
489  if (capacity_ >= lst.size())
490  {
491  // Can copy w/o reallocating, match initial size to avoid reallocation
492  List<T>::size(lst.size());
493  List<T>::operator=(lst);
494  }
495  else
496  {
497  // Make everything available for the copy operation
498  List<T>::size(capacity_);
499 
500  List<T>::operator=(lst);
501  capacity_ = List<T>::size();
502  }
503 }
504 
505 
506 // * * * * * * * * * * * * * * STL Member Functions * * * * * * * * * * * * //
507 
508 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
511 (
512  typename UList<T>::iterator curIter
513 )
514 {
515  typename Foam::UList<T>::iterator iter = curIter;
516  typename Foam::UList<T>::iterator nextIter = curIter;
517 
518  if (iter != this->end())
519  {
520  ++iter;
521 
522  while (iter != this->end())
523  {
524  *nextIter++ = *iter++;
525  }
526 
527  this->setSize(this->size() - 1);
528  }
529 
530  return curIter;
531 }
532 
533 
534 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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 resize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:216
error FatalError
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
tUEqn clear()
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
UList< T >::iterator erase(typename UList< T >::iterator)
Erase an element, move the remaining elements to fill the gap.
Definition: DynamicListI.H:511
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
T * iterator
Random access iterator for traversing UList.
Definition: UList.H:269
void reserve(const label)
Reserve allocation space for at least this size.
Definition: DynamicListI.H:152
points setSize(newPointi)
void setSize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:175
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
DynamicList()
Construct null.
Definition: DynamicListI.H:29
label size() const
Return the number of elements in the list.
void setCapacity(const label)
Alter the size of the underlying storage.
Definition: DynamicListI.H:130
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
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
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:252
const volScalarField & T
T remove()
Remove and return the top element.
Definition: DynamicListI.H:351
A List with indirect addressing.
Definition: fvMatrix.H:106
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:243
label capacity() const
Size of the underlying storage.
Definition: DynamicListI.H:121
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:236
void transfer(List< T > &)
Transfer contents of the argument List into this.
Definition: DynamicListI.H:285
friend Ostream & operator(Ostream &, const DynamicList< T, SizeInc, SizeMult, SizeDiv > &)