FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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>(SizeInc),
32  capacity_(SizeInc)
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>
309 (
310  const T& t
311 )
312 {
313  label elemI = List<T>::size();
314  setSize(elemI + 1);
315 
316  this->operator[](elemI) = t;
317 }
318 
319 
320 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
322 (
323  const UList<T>& lst
324 )
325 {
326  if (this == &lst)
327  {
329  (
330  "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
331  "(const UList<T>&)"
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 }
343 
344 
345 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
347 (
348  const UIndirectList<T>& lst
349 )
350 {
351  label nextFree = List<T>::size();
352  setSize(nextFree + lst.size());
353 
354  forAll(lst, elemI)
355  {
356  this->operator[](nextFree++) = lst[elemI];
357  }
358 }
359 
360 
361 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
363 {
364  label elemI = List<T>::size() - 1;
365 
366  if (elemI < 0)
367  {
369  (
370  "Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()"
371  ) << "List is empty" << abort(FatalError);
372  }
373 
374  const T& val = List<T>::operator[](elemI);
375 
376  List<T>::size(elemI);
377 
378  return val;
379 }
380 
381 
382 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
383 
384 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
386 (
387  const label elemI
388 )
389 {
390  if (elemI >= List<T>::size())
391  {
392  setSize(elemI + 1);
393  }
394 
395  return this->operator[](elemI);
396 }
397 
398 
399 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
401 (
402  const T& t
403 )
404 {
406 }
407 
408 
409 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
410 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
411 (
412  const UList<T>& lst
413 )
414 {
415  if (capacity_ >= lst.size())
416  {
417  // can copy w/o reallocating, match initial size to avoid reallocation
418  List<T>::size(lst.size());
419  List<T>::operator=(lst);
420  }
421  else
422  {
423  // make everything available for the copy operation
424  List<T>::size(capacity_);
425 
426  List<T>::operator=(lst);
427  capacity_ = List<T>::size();
428  }
429 }
430 
431 
432 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
433 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
434 (
436 )
437 {
438  if (this == &lst)
439  {
441  (
442  "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
443  "(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&)"
444  ) << "attempted assignment to self" << abort(FatalError);
445  }
446 
447  if (capacity_ >= lst.size())
448  {
449  // can copy w/o reallocating, match initial size to avoid reallocation
450  List<T>::size(lst.size());
451  List<T>::operator=(lst);
452  }
453  else
454  {
455  // make everything available for the copy operation
456  List<T>::size(capacity_);
457 
458  List<T>::operator=(lst);
459  capacity_ = List<T>::size();
460  }
461 }
462 
463 
464 // ************************ vim: set sw=4 sts=4 et: ************************ //