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-2025 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>(),
46  capacity_(0)
47 {
48  reserve(len);
49 }
50 
51 
52 template<class T, int SizeMin>
54 (
55  const std::pair<label,label>& sizing
56 )
57 :
58  PtrList<T>(std::max(sizing.first, sizing.second)),
59  capacity_(PtrList<T>::size())
60 {
61  PtrList<T>::setAddressableSize(sizing.first);
62 }
63 
64 
65 template<class T, int SizeMin>
67 (
68  const PtrDynList<T, SizeMin>& list
69 )
70 :
71  PtrList<T>(list),
72  capacity_(PtrList<T>::size())
73 {}
74 
75 
76 template<class T, int SizeMin>
78 (
80 )
81 :
82  PtrList<T>(std::move(list)),
83  capacity_(list.capacity())
84 {
85  // FUTURE:
86  // list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
87 
88  list.clearStorage(); // capacity=0 etc.
89 }
90 
91 
92 template<class T, int SizeMin>
93 template<int AnySizeMin>
95 (
97 )
98 :
99  PtrList<T>(std::move(list)),
100  capacity_(list.capacity())
101 {
102  // FUTURE:
103  // list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
105  list.clearStorage(); // capacity=0 etc.
106 }
107 
108 
109 template<class T, int SizeMin>
111 (
112  PtrList<T>&& list
113 ) noexcept
114 :
115  PtrList<T>(std::move(list)),
116  capacity_(PtrList<T>::size())
117 {}
118 
119 
120 template<class T, int SizeMin>
122 :
123  PtrList<T>(list),
124  capacity_(PtrList<T>::size())
125 {}
126 
127 
128 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
129 
130 template<class T, int SizeMin>
131 inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
132 {
133  if (capacity_ < len)
134  {
135  // Preserve addressed size
136  const label currLen = PtrList<T>::size();
137 
138  // Increase capacity (eg, doubling)
139  capacity_ =
140  Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
141 
142  PtrList<T>::resize(capacity_);
144  }
145 }
146 
147 
148 template<class T, int SizeMin>
149 inline void Foam::PtrDynList<T, SizeMin>::reserve_exact(const label len)
150 {
151  if (capacity_ < len)
152  {
153  // Preserve addressed size
154  const label currLen = PtrList<T>::size();
155 
156  capacity_ = len;
157  PtrList<T>::resize(capacity_);
159  }
160 }
161 
162 
163 template<class T, int SizeMin>
164 inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
165 {
166  auto& ptrs = this->ptrs_;
167 
168  const label oldLen = ptrs.size();
169 
170  if (capacity_ < newLen)
171  {
172  // Increase capacity (eg, doubling)
173  capacity_ =
174  Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
175 
176  PtrList<T>::resize(capacity_);
177  }
178  else if (newLen != oldLen)
179  {
180  // Truncation frees old pointers
181  for (label i = newLen; i < oldLen; ++i)
182  {
183  delete ptrs[i];
184  ptrs[i] = nullptr;
185  }
186  }
188  // Adjust addressed size
190 }
191 
192 
193 template<class T, int SizeMin>
194 inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
195 {
196  if (capacity_ < newLen)
197  {
198  // Increase capacity (eg, doubling)
199  capacity_ =
200  Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
201 
202  PtrList<T>::resize_null(capacity_);
203  }
204  else
205  {
206  PtrList<T>::free(); // Free (and nullify) old pointers
207  }
209  // Adjust addressed size
211 }
212 
213 
214 template<class T, int SizeMin>
216 {
217  PtrList<T>::free(); // Free (and nullify) old pointers
219 }
220 
221 
222 template<class T, int SizeMin>
224 {
226  capacity_ = 0;
227 }
228 
229 
230 template<class T, int SizeMin>
232 {
233  const label currLen = PtrList<T>::size();
234  if (currLen < capacity_)
235  {
238  capacity_ = PtrList<T>::size();
239  }
240 }
241 
242 
243 template<class T, int SizeMin>
245 {
246  if (PtrList<T>::empty())
247  {
248  // Delete empty list
250  }
251  capacity_ = PtrList<T>::size();
252 }
253 
254 
255 template<class T, int SizeMin>
257 {
258  const label newLen = UPtrList<T>::squeezeNull();
260  return newLen;
261 }
262 
263 
264 template<class T, int SizeMin>
266 {
267  if
268  (
269  static_cast<const PtrList<T>*>(this)
270  == static_cast<const PtrList<T>*>(&list)
271  )
272  {
273  return; // Self-swap is a no-op
274  }
275 
276  // Remove unused storage
277  this->shrink_to_fit();
278 
279  // Swap storage and addressable size
280  UPtrList<T>::swap(list);
281 
282  // Update capacity
283  capacity_ = PtrList<T>::size();
284 }
285 
286 
287 template<class T, int SizeMin>
288 template<int AnySizeMin>
290 (
292 ) noexcept
293 {
294  if
295  (
296  static_cast<const PtrList<T>*>(this)
297  == static_cast<const PtrList<T>*>(&other)
298  )
299  {
300  return; // Self-swap is a no-op
301  }
302 
303  // Swap storage and addressable size
304  UPtrList<T>::swap(other);
306  // Swap capacity
307  std::swap(this->capacity_, other.capacity_);
308 }
309 
310 
311 template<class T, int SizeMin>
313 {
314  if
315  (
316  static_cast<const PtrList<T>*>(this)
317  == static_cast<const PtrList<T>*>(&list)
318  )
319  {
320  return; // Self assignment is a no-op
321  }
322 
323  PtrList<T>::transfer(list);
324  capacity_ = PtrList<T>::size();
325 }
326 
327 
328 template<class T, int SizeMin>
329 template<int AnySizeMin>
331 (
333 )
334 {
335  if
336  (
337  static_cast<const PtrList<T>*>(this)
338  == static_cast<const PtrList<T>*>(&list)
339  )
340  {
341  return; // Self assignment is a no-op
342  }
343 
344  // Take over storage as-is (without shrink)
345  capacity_ = list.capacity();
346 
347  PtrList<T>::transfer(static_cast<PtrList<T>&>(list));
348  list.clearStorage(); // capacity=0 etc.
349 }
350 
351 
352 template<class T, int SizeMin>
353 template<class... Args>
355 {
356  T* ptr = new T(std::forward<Args>(args)...);
357  this->push_back(ptr);
358  return *ptr;
359 }
360 
361 
362 template<class T, int SizeMin>
364 {
365  const label idx = this->size();
366  resize(idx + 1);
367  this->ptrs_[idx] = ptr;
368 }
369 
370 
371 template<class T, int SizeMin>
372 inline void Foam::PtrDynList<T, SizeMin>::push_back(std::unique_ptr<T>&& ptr)
373 {
374  this->push_back(ptr.release());
375 }
376 
377 
378 template<class T, int SizeMin>
380 {
381  this->push_back(ptr.release());
382 }
383 
384 
385 template<class T, int SizeMin>
387 {
388  this->push_back(ptr.ptr()); // release or clone
389 }
390 
391 
392 template<class T, int SizeMin>
394 {
395  this->push_back(ptr.ptr()); // release or clone
396 }
397 
398 
399 template<class T, int SizeMin>
401 {
402  const label idx = this->size();
403  const label len = other.size();
404 
405  resize(idx + len);
406 
407  for (label i = 0; i < len; ++i)
408  {
409  set(idx + i, other.release(i)); // Take pointer ownership
410  }
411 
412  other.clear();
413 }
414 
415 
416 template<class T, int SizeMin>
417 template<int AnySizeMin>
419 (
421 )
422 {
423  if
424  (
425  static_cast<const PtrList<T>*>(this)
426  == static_cast<const PtrList<T>*>(&other)
427  )
428  {
430  << "Attempted push_back to self"
431  << abort(FatalError);
432  }
433 
434  const label idx = this->size();
435  const label len = other.size();
436 
437  resize(idx + len);
438 
439  for (label i = 0; i < len; ++i)
440  {
441  set(idx + i, other.release(i)); // Take pointer ownership
442  }
443 
444  other.clearStorage(); // Ensure capacity=0
445 }
446 
447 
448 template<class T, int SizeMin>
449 inline void Foam::PtrDynList<T, SizeMin>::pop_back(label n)
450 {
451  if (n >= this->size())
452  {
453  this->clear();
454  }
455  else if (n > 0)
456  {
457  this->resize(this->size() - n);
458  }
459 }
460 
461 
462 template<class T, int SizeMin>
463 template<class... Args>
465 (
466  const label i,
467  Args&&... args
468 )
469 {
470  if (i >= this->size())
471  {
472  resize(i+1);
473  }
474  return PtrList<T>::emplace_set(i, std::forward<Args>(args)...);
475 }
476 
477 
478 template<class T, int SizeMin>
479 template<class... Args>
481 (
482  const label i,
483  Args&&... args
484 )
485 {
486  return this->emplace_set(i, std::forward<Args>(args)...);
487 }
488 
489 
490 template<class T, int SizeMin>
491 template<class... Args>
493 (
494  const label i,
495  Args&&... args
496 )
497 {
498  if (i >= this->size())
499  {
500  resize(i+1);
501  }
502  return PtrList<T>::try_emplace(i, std::forward<Args>(args)...);
503 }
504 
505 
506 template<class T, int SizeMin>
508 (
509  const label i,
510  T* ptr
511 )
512 {
513  if (i >= this->size())
514  {
515  resize(i+1);
516  }
518  return autoPtr<T>(UPtrList<T>::set(i, ptr));
519 }
520 
521 
522 template<class T, int SizeMin>
524 (
525  const label i,
526  std::unique_ptr<T>&& ptr
527 )
528 {
529  return this->set(i, ptr.release());
530 }
531 
532 
533 template<class T, int SizeMin>
535 (
536  const label i,
537  autoPtr<T>&& ptr
538 )
539 {
540  return this->set(i, ptr.release());
541 }
542 
543 
544 template<class T, int SizeMin>
546 (
547  const label i,
548  const refPtr<T>& ptr
549 )
550 {
551  return this->set(i, ptr.ptr()); // release or clone
552 
553 }
554 
555 
556 template<class T, int SizeMin>
558 (
559  const label i,
560  const tmp<T>& ptr
561 )
562 {
563  return this->set(i, ptr.ptr()); // release or clone
564 }
565 
566 
567 template<class T, int SizeMin>
568 inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew)
569 {
570  // Shrinking first is a bit annoying, but saves needing a special version.
571  this->shrink_to_fit();
572  PtrList<T>::reorder(oldToNew);
573 }
574 
575 
576 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
577 
578 template<class T, int SizeMin>
580 (
581  const PtrList<T>& list
582 )
583 {
584  if (this == &list)
585  {
586  return; // Self-assignment is a no-op
587  }
588 
590  capacity_ = PtrList<T>::size();
591 }
592 
593 
594 template<class T, int SizeMin>
596 (
597  const PtrDynList<T, SizeMin>& list
598 )
599 {
600  if (this == &list)
601  {
602  return; // Self-assignment is a no-op
603  }
604 
605  PtrList<T>::operator=(list);
606  capacity_ = PtrList<T>::size();
607 }
608 
609 
610 template<class T, int SizeMin>
611 template<int AnySizeMin>
613 (
614  const PtrDynList<T, AnySizeMin>& list
615 )
616 {
617  if
618  (
619  static_cast<const PtrList<T>*>(this)
620  == static_cast<const PtrList<T>*>(&list)
621  )
622  {
623  return; // Self-assignment is a no-op
624  }
625 
627  capacity_ = PtrList<T>::size();
628 }
629 
630 
631 template<class T, int SizeMin>
633 (
634  PtrList<T>&& list
635 )
636 {
637  this->transfer(list);
638 }
639 
640 
641 template<class T, int SizeMin>
643 (
645 )
646 {
647  this->transfer(list);
648 }
649 
650 
651 template<class T, int SizeMin>
652 template<int AnySizeMin>
654 (
656 )
657 {
658  this->transfer(list);
659 }
660 
661 
662 // ************************************************************************* //
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:600
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
void shrink_to_fit()
Shrink the allocated space to the number of elements used.
Definition: PtrDynListI.H:224
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:280
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:501
void reserve_exact(const label len)
Reserve allocation space for at least this size. If allocation is required, uses the specified size w...
Definition: PtrDynListI.H:142
label squeezeNull()
Squeeze out intermediate nullptr entries in the list of pointers and adjust the addressable size acco...
Definition: PtrDynListI.H:249
void transfer(PtrList< T > &list)
Transfer contents of the argument PtrList into this.
Definition: PtrDynListI.H:305
T & emplace_set(const label i, Args &&... args)
Construct and set a new element at given position, (discard old element at that location). Auto-sizes list as required.
Definition: PtrDynListI.H:458
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
T & emplace_back(Args &&... args)
Construct an element at the end of the list, return reference to the new list element.
Definition: PtrDynListI.H:347
label capacity() const noexcept
Size of the underlying storage.
Definition: PtrDynList.H:128
void reorder(const labelUList &oldToNew)
Reorder elements. Reordering must be unique (ie, shuffle).
Definition: PtrDynListI.H:561
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
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:105
void resize_null(const label newLen)
Set the addressed list to the given size, deleting all existing entries. Afterwards the list contains...
Definition: PtrDynListI.H:187
const direction noexcept
Definition: scalarImpl.H:255
void clearStorage()
Clear the list and delete storage.
Definition: PtrDynListI.H:216
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:442
T & try_emplace(const label i, Args &&... args)
Like emplace_set() but will not overwrite an occupied location.
Definition: PtrDynListI.H:486
void push_back(T *ptr)
Append an element to the end of the list.
Definition: PtrDynListI.H:356
A dynamically resizable PtrList with allocation management.
Definition: PtrDynList.H:48
void swap(PtrList< T > &list)
Swap with plain PtrList content. Implies shrink_to_fit().
Definition: PtrDynListI.H:258
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:54
surface1 clear()
void shrink_unsafe()
Shrink the internal bookkeeping of the allocated space to the number of addressed elements without af...
Definition: PtrDynListI.H:237
triangles reserve(surf.size())
autoPtr< T > release(const label i)
Release ownership of the pointer at the given position.
Definition: PtrListI.H:260
void resize(const label newLen)
Alter the addressed list size.
Definition: PtrDynListI.H:157
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:256
void reserve(const label len)
Reserve allocation space for at least this size.
Definition: PtrDynListI.H:124
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.
T & emplace(const label i, Args &&... args)
Same as emplace_set()
Definition: PtrDynListI.H:474
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: PtrDynListI.H:208