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-2023 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 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  // FUTURE:
73  // list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
74 
75  list.clearStorage(); // capacity=0 etc.
76 }
77 
78 
79 template<class T, int SizeMin>
80 template<int AnySizeMin>
82 (
84 )
85 :
86  PtrList<T>(std::move(list)),
87  capacity_(list.capacity())
88 {
89  // FUTURE:
90  // list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
91 
92  list.clearStorage(); // capacity=0 etc.
93 }
94 
95 
96 template<class T, int SizeMin>
98 (
99  PtrList<T>&& list
100 ) noexcept
101 :
102  PtrList<T>(std::move(list)),
103  capacity_(PtrList<T>::size())
104 {}
105 
106 
107 template<class T, int SizeMin>
109 :
110  PtrList<T>(list),
111  capacity_(PtrList<T>::size())
112 {}
113 
114 
115 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
116 
117 template<class T, int SizeMin>
118 inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
119 {
120  if (capacity_ < len)
121  {
122  // Preserve addressed size
123  const label currLen = PtrList<T>::size();
124 
125  // Increase capacity (doubling)
126  capacity_ = max(SizeMin, max(len, label(2*capacity_)));
127 
128  PtrList<T>::resize(capacity_);
130  }
131 }
132 
133 
134 template<class T, int SizeMin>
135 inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
136 {
137  auto& ptrs = this->ptrs_;
138 
139  const label oldLen = ptrs.size();
140 
141  if (capacity_ < newLen)
142  {
143  // Increase capacity (doubling)
144  capacity_ = max(SizeMin, max(newLen, label(2*capacity_)));
145 
146  PtrList<T>::resize(capacity_);
147  }
148  else if (newLen != oldLen)
149  {
150  // Truncation frees old pointers
151  for (label i = newLen; i < oldLen; ++i)
152  {
153  delete ptrs[i];
154  ptrs[i] = nullptr;
155  }
156  }
158  // Adjust addressed size
160 }
161 
162 
163 template<class T, int SizeMin>
164 inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
165 {
166  if (capacity_ < newLen)
167  {
168  // Increase capacity (doubling)
169  capacity_ = max(SizeMin, max(newLen, label(2*capacity_)));
170 
171  PtrList<T>::resize_null(capacity_);
172  }
173  else
174  {
175  PtrList<T>::free(); // Free (and nullify) old pointers
176  }
178  // Adjust addressed size
180 }
181 
182 
183 template<class T, int SizeMin>
185 {
186  PtrList<T>::free(); // Free (and nullify) old pointers
188 }
189 
190 
191 template<class T, int SizeMin>
193 {
195  capacity_ = 0;
196 }
197 
198 
199 template<class T, int SizeMin>
201 {
202  const label currLen = PtrList<T>::size();
203  if (currLen < capacity_)
204  {
205  // Adjust addressable size to trigger proper resizing
208  capacity_ = PtrList<T>::size();
209  }
210 }
211 
212 
213 template<class T, int SizeMin>
215 {
216  if (PtrList<T>::empty())
217  {
218  // Delete empty list
220  }
221  capacity_ = PtrList<T>::size();
222 }
223 
224 
225 template<class T, int SizeMin>
227 {
228  const label newLen = UPtrList<T>::squeezeNull();
230  return newLen;
231 }
232 
233 
234 template<class T, int SizeMin>
236 {
237  if
238  (
239  static_cast<const PtrList<T>*>(this)
240  == static_cast<const PtrList<T>*>(&list)
241  )
242  {
243  return; // Self-swap is a no-op
244  }
245 
246  // Remove unused storage
247  this->shrink_to_fit();
248 
249  // Swap storage and addressable size
250  UPtrList<T>::swap(list);
251 
252  // Update capacity
253  capacity_ = PtrList<T>::size();
254 }
255 
256 
257 template<class T, int SizeMin>
258 template<int AnySizeMin>
260 (
262 ) noexcept
263 {
264  if
265  (
266  static_cast<const PtrList<T>*>(this)
267  == static_cast<const PtrList<T>*>(&other)
268  )
269  {
270  return; // Self-swap is a no-op
271  }
272 
273  // Swap storage and addressable size
274  UPtrList<T>::swap(other);
276  // Swap capacity
277  std::swap(this->capacity_, other.capacity_);
278 }
279 
280 
281 template<class T, int SizeMin>
283 {
284  if
285  (
286  static_cast<const PtrList<T>*>(this)
287  == static_cast<const PtrList<T>*>(&list)
288  )
289  {
290  return; // Self assignment is a no-op
291  }
292 
293  PtrList<T>::transfer(list);
294  capacity_ = PtrList<T>::size();
295 }
296 
297 
298 template<class T, int SizeMin>
299 template<int AnySizeMin>
301 (
303 )
304 {
305  if
306  (
307  static_cast<const PtrList<T>*>(this)
308  == static_cast<const PtrList<T>*>(&list)
309  )
310  {
311  return; // Self assignment is a no-op
312  }
313 
314  // Take over storage as-is (without shrink)
315  capacity_ = list.capacity();
316 
317  PtrList<T>::transfer(static_cast<PtrList<T>&>(list));
318  list.clearStorage(); // capacity=0 etc.
319 }
320 
321 
322 template<class T, int SizeMin>
323 template<class... Args>
325 {
326  T* ptr = new T(std::forward<Args>(args)...);
327  this->push_back(ptr);
328  return *ptr;
329 }
330 
331 
332 template<class T, int SizeMin>
334 {
335  const label idx = this->size();
336  resize(idx + 1);
337  this->ptrs_[idx] = ptr;
338 }
339 
340 
341 template<class T, int SizeMin>
342 inline void Foam::PtrDynList<T, SizeMin>::push_back(std::unique_ptr<T>&& ptr)
343 {
344  this->push_back(ptr.release());
345 }
346 
347 
348 template<class T, int SizeMin>
350 {
351  this->push_back(ptr.release());
352 }
353 
354 
355 template<class T, int SizeMin>
357 {
358  this->push_back(ptr.ptr()); // release or clone
359 }
360 
361 
362 template<class T, int SizeMin>
364 {
365  this->push_back(ptr.ptr()); // release or clone
366 }
367 
368 
369 template<class T, int SizeMin>
371 {
372  const label idx = this->size();
373  const label len = other.size();
374 
375  resize(idx + len);
376 
377  for (label i = 0; i < len; ++i)
378  {
379  set(idx + i, other.release(i)); // Take pointer ownership
380  }
381 
382  other.clear();
383 }
384 
385 
386 template<class T, int SizeMin>
387 template<int AnySizeMin>
389 (
391 )
392 {
393  if
394  (
395  static_cast<const PtrList<T>*>(this)
396  == static_cast<const PtrList<T>*>(&other)
397  )
398  {
400  << "Attempted push_back to self"
401  << abort(FatalError);
402  }
403 
404  const label idx = this->size();
405  const label len = other.size();
406 
407  resize(idx + len);
408 
409  for (label i = 0; i < len; ++i)
410  {
411  set(idx + i, other.release(i)); // Take pointer ownership
412  }
413 
414  other.clearStorage(); // Ensure capacity=0
415 }
416 
417 
418 template<class T, int SizeMin>
419 inline void Foam::PtrDynList<T, SizeMin>::pop_back(label n)
420 {
421  if (n >= this->size())
422  {
423  this->clear();
424  }
425  else if (n > 0)
426  {
427  this->resize(this->size() - n);
428  }
429 }
430 
431 
432 template<class T, int SizeMin>
433 template<class... Args>
435 (
436  const label i,
437  Args&&... args
438 )
439 {
440  if (i >= this->size())
441  {
442  resize(i+1);
443  }
444  return PtrList<T>::emplace_set(i, std::forward<Args>(args)...);
445 }
446 
447 
448 template<class T, int SizeMin>
449 template<class... Args>
451 (
452  const label i,
453  Args&&... args
454 )
455 {
456  return this->emplace_set(i, std::forward<Args>(args)...);
457 }
458 
459 
460 template<class T, int SizeMin>
461 template<class... Args>
463 (
464  const label i,
465  Args&&... args
466 )
467 {
468  if (i >= this->size())
469  {
470  resize(i+1);
471  }
472  return PtrList<T>::try_emplace(i, std::forward<Args>(args)...);
473 }
474 
475 
476 template<class T, int SizeMin>
478 (
479  const label i,
480  T* ptr
481 )
482 {
483  if (i >= this->size())
484  {
485  resize(i+1);
486  }
488  return autoPtr<T>(UPtrList<T>::set(i, ptr));
489 }
490 
491 
492 template<class T, int SizeMin>
494 (
495  const label i,
496  std::unique_ptr<T>&& ptr
497 )
498 {
499  return this->set(i, ptr.release());
500 }
501 
502 
503 template<class T, int SizeMin>
505 (
506  const label i,
507  autoPtr<T>&& ptr
508 )
509 {
510  return this->set(i, ptr.release());
511 }
512 
513 
514 template<class T, int SizeMin>
516 (
517  const label i,
518  const refPtr<T>& ptr
519 )
520 {
521  return this->set(i, ptr.ptr()); // release or clone
522 
523 }
524 
525 
526 template<class T, int SizeMin>
528 (
529  const label i,
530  const tmp<T>& ptr
531 )
532 {
533  return this->set(i, ptr.ptr()); // release or clone
534 }
535 
536 
537 template<class T, int SizeMin>
538 inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew)
539 {
540  // Shrinking first is a bit annoying, but saves needing a special version.
541  this->shrink_to_fit();
542  PtrList<T>::reorder(oldToNew);
543 }
544 
545 
546 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
547 
548 template<class T, int SizeMin>
550 (
551  const PtrList<T>& list
552 )
553 {
554  if (this == &list)
555  {
556  return; // Self-assignment is a no-op
557  }
558 
560  capacity_ = PtrList<T>::size();
561 }
562 
563 
564 template<class T, int SizeMin>
566 (
567  const PtrDynList<T, SizeMin>& list
568 )
569 {
570  if (this == &list)
571  {
572  return; // Self-assignment is a no-op
573  }
574 
575  PtrList<T>::operator=(list);
576  capacity_ = PtrList<T>::size();
577 }
578 
579 
580 template<class T, int SizeMin>
581 template<int AnySizeMin>
583 (
584  const PtrDynList<T, AnySizeMin>& list
585 )
586 {
587  if
588  (
589  static_cast<const PtrList<T>*>(this)
590  == static_cast<const PtrList<T>*>(&list)
591  )
592  {
593  return; // Self-assignment is a no-op
594  }
595 
597  capacity_ = PtrList<T>::size();
598 }
599 
600 
601 template<class T, int SizeMin>
603 (
604  PtrList<T>&& list
605 )
606 {
607  this->transfer(list);
608 }
609 
610 
611 template<class T, int SizeMin>
613 (
615 )
616 {
617  this->transfer(list);
618 }
619 
620 
621 template<class T, int SizeMin>
622 template<int AnySizeMin>
624 (
626 )
627 {
628  this->transfer(list);
629 }
630 
631 
632 // ************************************************************************* //
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:598
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:193
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:471
label squeezeNull()
Squeeze out intermediate nullptr entries in the list of pointers and adjust the addressable size acco...
Definition: PtrDynListI.H:219
void transfer(PtrList< T > &list)
Transfer contents of the argument PtrList into this.
Definition: PtrDynListI.H:275
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:428
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
patchWriters clear()
T & emplace_back(Args &&... args)
Construct an element at the end of the list, return reference to the new list element.
Definition: PtrDynListI.H:317
label capacity() const noexcept
Size of the underlying storage.
Definition: PtrDynList.H:123
void reorder(const labelUList &oldToNew)
Reorder elements. Reordering must be unique (ie, shuffle).
Definition: PtrDynListI.H:531
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:157
const direction noexcept
Definition: Scalar.H:258
void clearStorage()
Clear the list and delete storage.
Definition: PtrDynListI.H:185
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:412
T & try_emplace(const label i, Args &&... args)
Like emplace_set() but will not overwrite an occupied location.
Definition: PtrDynListI.H:456
void push_back(T *ptr)
Append an element to the end of the list.
Definition: PtrDynListI.H:326
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:228
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
void shrink_unsafe()
Shrink the internal bookkeeping of the allocated space to the number of addressed elements without af...
Definition: PtrDynListI.H:207
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:128
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:111
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:444
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: PtrDynListI.H:177