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-2015 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 (
55  const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
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 (
288  DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
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  << "attempted appending to self" << abort(FatalError);
333  }
334 
335  label nextFree = List<T>::size();
336  setSize(nextFree + lst.size());
337 
338  forAll(lst, elemI)
339  {
340  this->operator[](nextFree++) = lst[elemI];
341  }
342  return *this;
343 }
344 
345 
346 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
349 (
350  const UIndirectList<T>& lst
351 )
352 {
353  label nextFree = List<T>::size();
354  setSize(nextFree + lst.size());
355 
356  forAll(lst, elemI)
357  {
358  this->operator[](nextFree++) = lst[elemI];
359  }
360  return *this;
361 }
362 
363 
364 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
366 {
367  const label elemI = List<T>::size() - 1;
368 
369  if (elemI < 0)
370  {
372  << "List is empty" << abort(FatalError);
373  }
374 
375  const T& val = List<T>::operator[](elemI);
376 
377  List<T>::size(elemI);
378 
379  return val;
380 }
381 
382 
383 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
384 
385 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
387 (
388  const label elemI
389 )
390 {
391  if (elemI >= List<T>::size())
392  {
393  setSize(elemI + 1);
394  }
395 
396  return this->operator[](elemI);
397 }
398 
399 
400 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
402 (
403  const T& t
404 )
405 {
407 }
408 
409 
410 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
412 (
413  const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
414 )
415 {
416  if (this == &lst)
417  {
419  << "attempted assignment to self" << abort(FatalError);
420  }
421 
422  if (capacity_ >= lst.size())
423  {
424  // can copy w/o reallocating, match initial size to avoid reallocation
425  List<T>::size(lst.size());
426  List<T>::operator=(lst);
427  }
428  else
429  {
430  // make everything available for the copy operation
431  List<T>::size(capacity_);
432 
433  List<T>::operator=(lst);
434  capacity_ = List<T>::size();
435  }
436 }
437 
438 
439 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
441 (
442  const UList<T>& lst
443 )
444 {
445  if (capacity_ >= lst.size())
446  {
447  // can copy w/o reallocating, match initial size to avoid reallocation
448  List<T>::size(lst.size());
449  List<T>::operator=(lst);
450  }
451  else
452  {
453  // make everything available for the copy operation
454  List<T>::size(capacity_);
455 
456  List<T>::operator=(lst);
457  capacity_ = List<T>::size();
458  }
459 }
460 
461 
462 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
464 (
465  const UIndirectList<T>& lst
466 )
467 {
468  if (capacity_ >= lst.size())
469  {
470  // can copy w/o reallocating, match initial size to avoid reallocation
471  List<T>::size(lst.size());
472  List<T>::operator=(lst);
473  }
474  else
475  {
476  // make everything available for the copy operation
477  List<T>::size(capacity_);
478 
479  List<T>::operator=(lst);
480  capacity_ = List<T>::size();
481  }
482 }
483 
484 // ************************************************************************* //
Foam::DynamicList::resize
void resize(const label)
Alter the addressed list size.
setSize
points setSize(newPointi)
Foam::DynamicList::xfer
Xfer< List< T > > xfer()
Transfer contents to the Xfer container as a plain List.
Definition: DynamicListI.H:301
Foam::DynamicList::capacity
label capacity() const
Size of the underlying storage.
Definition: DynamicListI.H:100
clear
UEqn clear()
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:56
Foam::Xfer
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
List::size
int size() const
Definition: ListI.H:83
Foam::label
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
Foam::DynamicList::clear
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:242
Foam::DynamicList::setCapacity
void setCapacity(const label)
Alter the size of the underlying storage.
Definition: DynamicListI.H:109
Foam::DynamicList::shrink
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:258
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
T
const volScalarField & T
Definition: createFields.H:25
Foam::List
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
Foam::UList
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
Foam::DynamicList::transfer
void transfer(List< T > &)
Transfer contents of the argument List into this.
Foam::DynamicList::clearStorage
void clearStorage()
Clear the list and delete storage.
Definition: DynamicListI.H:249
Foam::DynamicList::remove
T remove()
Remove and return the top element.
Definition: DynamicListI.H:365
Foam::DynamicList::reserve
void reserve(const label)
Reserve allocation space for at least this size.
Definition: DynamicListI.H:130
List
Definition: Test.C:19
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::DynamicList::setSize
void setSize(const label)
Alter the addressed list size.
Foam::DynamicList::operator
friend Ostream & operator(Ostream &, const DynamicList< T, SizeInc, SizeMult, SizeDiv > &)
Foam::DynamicList::DynamicList
DynamicList()
Construct null.
Definition: DynamicListI.H:29