UPtrList.C
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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2026 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "UPtrList.H"
30 #include "PtrList.H"
31 #include "Ostream.H"
32 
33 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
34 
35 template<class T>
37 :
38  ptrs_(list.ptrs_) // shallow copy (via const reference)
39 {}
40 
41 
42 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
43 
44 template<class T>
46 {
47  const label len = this->size();
48  label newLen = 0;
49 
50  for (label i=0; i < len; ++i)
51  {
52  T* ptr = ptrs_[i];
53  if (ptr)
54  {
55  if (i != newLen)
56  {
57  ptrs_[newLen] = ptr;
58  ptrs_[i] = nullptr;
59  }
60  ++newLen;
61  }
62  }
63 
64  return newLen;
65 }
66 
67 
68 template<class T>
69 void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
70 {
71  const label len = this->size();
72 
73  if (oldToNew.size() != len)
74  {
76  << "Size of map (" << oldToNew.size()
77  << ") not equal to list size (" << len
78  << ") for type " << error::demangle<T>() << nl
79  << abort(FatalError);
80  }
81 
82  Detail::PtrListDetail<T> newList(len);
83 
84  for (label i = 0; i < len; ++i)
85  {
86  const label newIdx = oldToNew[i];
87 
88  if (newIdx < 0 || newIdx >= len)
89  {
91  << "Illegal index " << newIdx << nl
92  << "Valid indices are [0," << len << ") for type "
93  << error::demangle<T>() << nl
94  << abort(FatalError);
95  }
96 
97  if (newList[newIdx])
98  {
100  << "reorder map is not unique; element " << newIdx
101  << " already used for type "
102  << error::demangle<T>() << nl
103  << abort(FatalError);
104  }
105  newList[newIdx] = ptrs_[i];
106  }
107 
108  // Verify all pointers were indeed set
109  if (check)
110  {
111  newList.checkNonNull();
112  }
114  // Copy the pointers, do not swap or transfer lists!
115  ptrs_ = newList;
116 }
117 
118 
119 template<class T>
120 void Foam::UPtrList<T>::sortOrder(const labelUList& order, const bool check)
121 {
122  const label len = this->size();
123 
124  if (order.size() != len)
125  {
127  << "Size of map (" << order.size()
128  << ") not equal to list size (" << len
129  << ") for type " << error::demangle<T>() << nl
130  << abort(FatalError);
131  }
132 
133  Detail::PtrListDetail<T> newList(len);
134  Detail::PtrListDetail<T> guard(len);
135 
136  for (label i = 0; i < len; ++i)
137  {
138  const label oldIdx = order[i];
139 
140  if (oldIdx < 0 || oldIdx >= len)
141  {
143  << "Illegal index " << oldIdx << nl
144  << "Valid indices are [0," << len << ") for type "
145  << error::demangle<T>() << nl
146  << abort(FatalError);
147  }
148 
149  if (guard[oldIdx])
150  {
152  << "order map is not unique; element " << oldIdx
153  << " already used for type "
154  << error::demangle<T>() << nl
155  << abort(FatalError);
156  }
157 
158  guard[oldIdx] = ptrs_[oldIdx];
159  newList[i] = ptrs_[oldIdx];
160  }
161 
162  // Verify that all pointers were indeed set
163  if (check)
164  {
165  newList.checkNonNull();
166  }
167 
168  // Copy the pointers, do not swap or transfer lists!
169  ptrs_ = newList;
170 }
171 
172 
173 // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
174 
175 template<class T>
177 {
178  return ptrs_.printAddresses(os);
179 }
180 
181 
182 template<class T>
184 (
185  Ostream& os,
186  const bool trimNull
187 ) const
188 {
189  return ptrs_.write(os, trimNull);
190 }
191 
192 
193 template<class T>
194 Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list)
195 {
196  return list.writeList(os, false); // Do not ignore null
197 }
198 
199 
200 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
201 
202 template<class T>
203 void Foam::sort(UPtrList<T>& list)
204 {
205  std::stable_sort
206  (
207  list.begin_ptr(),
208  list.end_ptr(),
209  // Compare less, with nullptr protect and sort nullptr to end
210  [](const T* const a, const T* const b) -> bool
211  {
212  return (a && b) ? (*a < *b) : !b;
213  }
214  );
215 }
216 
217 
218 template<class T, class Compare>
219 void Foam::sort(UPtrList<T>& list, const Compare& comp)
220 {
221  std::stable_sort
222  (
223  list.begin_ptr(),
224  list.end_ptr(),
225  typename UPtrList<T>::template value_compare<Compare>(comp)
226  );
227 }
228 
229 
230 // ************************************************************************* //
Ostream & printAddresses(Ostream &os) const
Print pointer addresses to Ostream (debugging only)
Definition: UPtrList.C:169
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:119
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:652
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
void reorder(const labelUList &oldToNew, const bool check=false)
Reorder elements. Reordering must be unique (ie, shuffle).
Definition: UPtrList.C:62
constexpr UPtrList() noexcept=default
Default construct.
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:283
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
Ostream & writeList(Ostream &os, const bool trimNull=false) const
Write UPtrList to Ostream, optionally ignoring null entries.
Definition: UPtrList.C:177
static void check(const int retVal, const char *what)
const volScalarField & T
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: PtrList.H:56
label squeezeNull()
Squeeze out nullptr entries in the list of pointers after which any null pointers will be at the end ...
Definition: UPtrList.C:38
void sortOrder(const labelUList &order, const bool check=false)
Reorder elements according to new order mapping (newToOld). Reordering must be unique (ie...
Definition: UPtrList.C:113