PtrDynListI.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2018-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "autoPtr.H"
29 #include "refPtr.H"
30 #include "tmp.H"
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
34 template<class T, int SizeMin>
36 :
37  PtrList<T>(),
38  capacity_(0)
39 {}
40 
41 
42 template<class T, int SizeMin>
43 inline Foam::PtrDynList<T, SizeMin>::PtrDynList(const label len)
44 :
45  PtrList<T>(len),
46  capacity_(len)
47 {
49 }
50 
51 
52 template<class T, int SizeMin>
54 (
55  const PtrDynList<T, SizeMin>& list
56 )
57 :
58  PtrList<T>(list),
59  capacity_(PtrList<T>::size())
60 {}
61 
62 
63 template<class T, int SizeMin>
65 (
67 )
68 :
69  PtrList<T>(std::move(list)),
70  capacity_(list.capacity_)
71 {
72  list.clearStorage();
73 }
74 
75 
76 template<class T, int SizeMin>
78 (
79  PtrList<T>&& list
80 )
81 :
82  PtrList<T>(std::move(list)),
83  capacity_(PtrList<T>::size())
84 {}
85 
86 
87 template<class T, int SizeMin>
89 :
90  PtrList<T>(list),
91  capacity_(PtrList<T>::size())
92 {}
93 
94 
95 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
96 
97 template<class T, int SizeMin>
98 inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
99 {
100  if (capacity_ < len)
101  {
102  // Preserve addressed size
103  const label currLen = PtrList<T>::size();
104 
105  // Increase capacity (doubling)
106  capacity_ = max(SizeMin, max(len, label(2*capacity_)));
107 
108  PtrList<T>::resize(capacity_);
110  }
111 }
112 
113 
114 template<class T, int SizeMin>
115 inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
116 {
117  auto& ptrs = this->ptrs_;
118 
119  const label oldLen = ptrs.size();
120 
121  if (capacity_ < newLen)
122  {
123  // Increase capacity (doubling)
124  capacity_ = max(SizeMin, max(newLen, label(2*capacity_)));
125 
126  PtrList<T>::resize(capacity_);
127  }
128  else if (newLen != oldLen)
129  {
130  // Truncation frees old pointers
131  for (label i = newLen; i < oldLen; ++i)
132  {
133  delete ptrs[i];
134  ptrs[i] = nullptr;
135  }
136  }
138  // Adjust addressed size
140 }
141 
142 
143 template<class T, int SizeMin>
145 {
146  (this->ptrs_).free(); // free old pointers
148 }
149 
150 
151 template<class T, int SizeMin>
153 {
155  capacity_ = 0;
156 }
157 
158 
159 template<class T, int SizeMin>
161 {
162  const label currLen = PtrList<T>::size();
163 
164  // Allow addressing into the entire list
166 
167  return currLen;
168 }
169 
170 
171 template<class T, int SizeMin>
173 {
174  const label currLen = PtrList<T>::size();
175  if (currLen < capacity_)
176  {
177  // Adjust addressable size to trigger proper resizing
179 
181  capacity_ = PtrList<T>::size();
182  }
183 }
184 
185 
186 template<class T, int SizeMin>
188 {
189  const label newLen = UPtrList<T>::squeezeNull();
190  resize(newLen);
191  return newLen;
192 }
193 
194 
195 template<class T, int SizeMin>
196 template<int AnySizeMin>
198 (
200 )
201 {
202  if
203  (
204  static_cast<const PtrList<T>*>(this)
205  == static_cast<const PtrList<T>*>(&other)
206  )
207  {
208  return; // Self-swap is a no-op
209  }
210 
211  // Swap storage and addressable size
212  UPtrList<T>::swap(other);
213 
214  // Swap capacity
215  std::swap(this->capacity_, other.capacity_);
216 }
217 
218 
219 template<class T, int SizeMin>
220 template<class... Args>
222 {
223  this->push_back(new T(std::forward<Args>(args)...));
224 }
225 
226 
227 template<class T, int SizeMin>
229 {
230  const label idx = this->size();
231  resize(idx + 1);
232  this->ptrs_[idx] = ptr;
233 }
234 
235 
236 template<class T, int SizeMin>
237 inline void Foam::PtrDynList<T, SizeMin>::push_back(std::unique_ptr<T>&& ptr)
238 {
239  this->push_back(ptr.release());
240 }
241 
242 
243 template<class T, int SizeMin>
245 {
246  this->push_back(ptr.release());
247 }
248 
249 
250 template<class T, int SizeMin>
252 {
253  this->push_back(ptr.ptr()); // release or clone
254 }
255 
256 
257 template<class T, int SizeMin>
259 {
260  this->push_back(ptr.ptr()); // release or clone
261 }
262 
263 
264 template<class T, int SizeMin>
266 {
267  const label idx = this->size();
268  const label len = other.size();
269 
270  resize(idx + len);
271 
272  for (label i = 0; i < len; ++i)
273  {
274  set(idx + i, other.release(i)); // Take pointer ownership
275  }
276 
277  other.clear();
278 }
279 
280 
281 template<class T, int SizeMin>
282 template<int AnySizeMin>
284 (
286 )
287 {
288  if
289  (
290  static_cast<const PtrList<T>*>(this)
291  == static_cast<const PtrList<T>*>(&other)
292  )
293  {
295  << "Attempted push_back to self"
296  << abort(FatalError);
297  }
298 
299  const label idx = this->size();
300  const label len = other.size();
301 
302  resize(idx + len);
303 
304  for (label i = 0; i < len; ++i)
305  {
306  set(idx + i, other.release(i)); // Take pointer ownership
307  }
308 
309  other.clearStorage(); // Ensure capacity=0
310 }
311 
312 
313 template<class T, int SizeMin>
314 inline void Foam::PtrDynList<T, SizeMin>::pop_back(label n)
315 {
316  if (n >= this->size())
317  {
318  this->clear();
319  }
320  else if (n > 0)
321  {
322  this->resize(this->size() - n);
323  }
324 }
325 
326 
327 template<class T, int SizeMin>
329 {
330  // Location of last element and simultaneously the new size
331  const label idx = (this->size() - 1);
332 
333  if (idx < 0)
334  {
335  return nullptr; // List is empty
336  }
337 
338  autoPtr<T> old(this->ptrs_[idx]);
339  this->ptrs_[idx] = nullptr;
340  PtrList<T>::setAddressableSize(idx);
341 
342  return old;
343 }
344 
345 
346 template<class T, int SizeMin>
347 template<class... Args>
349 (
350  const label i,
351  Args&&... args
352 )
353 {
354  return this->set(i, new T(std::forward<Args>(args)...));
355 }
356 
357 
358 template<class T, int SizeMin>
360 (
361  const label i,
362  T* ptr
363 )
364 {
365  if (i >= this->size())
366  {
367  resize(i+1);
368  }
370  return autoPtr<T>(UPtrList<T>::set(i, ptr));
371 }
372 
373 
374 template<class T, int SizeMin>
376 (
377  const label i,
378  std::unique_ptr<T>&& ptr
379 )
380 {
381  return this->set(i, ptr.release());
382 }
383 
384 
385 template<class T, int SizeMin>
387 (
388  const label i,
389  autoPtr<T>&& ptr
390 )
391 {
392  return this->set(i, ptr.release());
393 }
394 
395 
396 template<class T, int SizeMin>
398 (
399  const label i,
400  const refPtr<T>& ptr
401 )
402 {
403  return this->set(i, ptr.ptr()); // release or clone
404 
405 }
406 
407 
408 template<class T, int SizeMin>
410 (
411  const label i,
412  const tmp<T>& ptr
413 )
414 {
415  return this->set(i, ptr.ptr()); // release or clone
416 }
417 
418 
419 template<class T, int SizeMin>
420 inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew)
421 {
422  // Shrinking first is a bit annoying, but saves needing a special version.
423  shrink();
424  PtrList<T>::reorder(oldToNew);
425 }
426 
427 
428 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
429 
430 template<class T, int SizeMin>
432 (
433  const PtrList<T>& list
434 )
435 {
436  if (this == &list)
437  {
438  return; // Self-assignment is a no-op
439  }
440 
442  capacity_ = PtrList<T>::size();
443 }
444 
445 
446 template<class T, int SizeMin>
448 (
449  const PtrDynList<T, SizeMin>& list
450 )
451 {
452  if (this == &list)
453  {
454  return; // Self-assignment is a no-op
455  }
456 
457  PtrList<T>::operator=(list);
458  capacity_ = PtrList<T>::size();
459 }
460 
461 
462 template<class T, int SizeMin>
463 template<int AnySizeMin>
465 (
466  const PtrDynList<T, AnySizeMin>& list
467 )
468 {
469  if
470  (
471  static_cast<const PtrList<T>*>(this)
472  == static_cast<const PtrList<T>*>(&list)
473  )
474  {
475  return; // Self-assignment is a no-op
476  }
477 
479  capacity_ = PtrList<T>::size();
480 }
481 
482 
483 template<class T, int SizeMin>
485 (
486  PtrList<T>&& list
487 )
488 {
489  if (this == &list)
490  {
491  return; // Self-assignment is a no-op
492  }
493 
494  PtrList<T>::transfer(list);
495  capacity_ = PtrList<T>::size();
496  list.clearStorage();
497 }
498 
499 
500 template<class T, int SizeMin>
502 (
504 )
505 {
506  if (this == &list)
507  {
508  return; // Self-assignment is a no-op
509  }
510 
511  PtrList<T>::transfer(list);
512  capacity_ = list.capacity();
513  list.clearStorage();
514 }
515 
516 
517 template<class T, int SizeMin>
518 template<int AnySizeMin>
520 (
522 )
523 {
524  if
525  (
526  static_cast<const PtrList<T>*>(this)
527  == static_cast<const PtrList<T>*>(&list)
528  )
529  {
530  return; // Self-assignment is a no-op
531  }
532 
533  PtrList<T>::transfer(list);
534  capacity_ = list.capacity();
535  list.clearStorage();
536 }
537 
538 
539 // ************************************************************************* //
autoPtr< T > remove()
Remove and return the top element. Can be called on an empty list.
Definition: PtrDynListI.H:321
constexpr PtrDynList() noexcept
Default construct.
Definition: PtrDynListI.H:28
patchWriters resize(patchIds.size())
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
void set(List< bool > &bools, const labelUList &locations)
Set the listed locations (assign &#39;true&#39;).
Definition: BitOps.C:30
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: refPtrI.H:258
A class for managing references or pointers (no reference counting)
Definition: HashPtrTable.H:49
autoPtr< T > set(const label i, T *ptr)
Set element to given pointer and return old element (can be null). Auto-sizes list as required...
Definition: PtrDynListI.H:353
void shrink()
Shrink the allocated space to the number of elements used.
Definition: PtrDynListI.H:165
label squeezeNull()
Squeeze out intermediate nullptr entries in the list of pointers and adjust the addressable size acco...
Definition: PtrDynListI.H:180
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:99
void emplace_back(Args &&... args)
Construct an element at the end of the list.
Definition: PtrDynListI.H:214
patchWriters clear()
label capacity() const noexcept
Size of the underlying storage.
Definition: PtrDynList.H:117
void reorder(const labelUList &oldToNew)
Reorder elements. Reordering must be unique (ie, shuffle).
Definition: PtrDynListI.H:413
autoPtr< T > emplace(const label i, Args &&... args)
Construct and set an element.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
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:99
label expandStorage() noexcept
Expand the addressable size to fit the allocated capacity.
Definition: PtrDynListI.H:153
const direction noexcept
Definition: Scalar.H:258
void clearStorage()
Clear the list and delete storage.
Definition: PtrDynListI.H:145
const volScalarField & T
void pop_back(label n=1)
Reduce size by 1 or more elements. Can be called on an empty list.
Definition: PtrDynListI.H:307
void push_back(T *ptr)
Append an element to the end of the list.
Definition: PtrDynListI.H:221
A dynamically resizable PtrList with allocation management.
Definition: PtrDynList.H:48
void swap(PtrDynList< T, AnySizeMin > &other)
Swap content, independent of sizing parameter.
Definition: PtrDynListI.H:191
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
autoPtr< T > release(const label i)
Release ownership of the pointer at the given position.
Definition: PtrListI.H:232
void resize(const label newLen)
Alter the addressed list size.
Definition: PtrDynListI.H:108
label n
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: tmpI.H:231
void reserve(const label len)
Reserve allocation space for at least this size.
Definition: PtrDynListI.H:91
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Foam::argList args(argc, argv)
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: PtrDynListI.H:137