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-2022 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>
70 {
71  label newLen = this->size();
72 
73  for (label i = newLen-1; i >= 0 && !ptrs_[i]; --i)
74  {
75  --newLen;
76  }
77 
78  // Or mutable?
79  // const_cast<Detail::PtrListDetail<T>&>(ptrs_).setAddressableSize(newLen);
80 
81  ptrs_.setAddressableSize(newLen);
82 }
83 
84 
85 template<class T>
86 void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
87 {
88  const label len = this->size();
89 
90  if (oldToNew.size() != len)
91  {
93  << "Size of map (" << oldToNew.size()
94  << ") not equal to list size (" << len
95  << ") for type " << typeid(T).name() << nl
96  << abort(FatalError);
97  }
98 
99  Detail::PtrListDetail<T> newList(len);
100 
101  for (label i=0; i<len; ++i)
102  {
103  const label newIdx = oldToNew[i];
104 
105  if (newIdx < 0 || newIdx >= len)
106  {
108  << "Illegal index " << newIdx << nl
109  << "Valid indices are [0," << len << ") for type "
110  << typeid(T).name() << nl
111  << abort(FatalError);
112  }
113 
114  if (newList[newIdx])
115  {
117  << "reorder map is not unique; element " << newIdx
118  << " already used for type " << typeid(T).name()
119  << abort(FatalError);
120  }
121  newList[newIdx] = ptrs_[i];
122  }
123 
124  // Verify all pointers were indeed set
125  if (check)
126  {
127  newList.checkNonNull();
128  }
129 
130  ptrs_.transfer(newList);
131 }
132 
133 
134 template<class T>
135 void Foam::UPtrList<T>::sortOrder(const labelUList& order, const bool check)
136 {
137  const label len = this->size();
138 
139  if (order.size() != len)
140  {
142  << "Size of map (" << order.size()
143  << ") not equal to list size (" << len
144  << ") for type " << typeid(T).name() << nl
145  << abort(FatalError);
146  }
147 
148  Detail::PtrListDetail<T> newList(len);
149  Detail::PtrListDetail<T> guard(len);
150 
151  for (label i=0; i<len; ++i)
152  {
153  const label oldIdx = order[i];
154 
155  if (oldIdx < 0 || oldIdx >= len)
156  {
158  << "Illegal index " << oldIdx << nl
159  << "Valid indices are [0," << len << ") for type "
160  << typeid(T).name() << nl
161  << abort(FatalError);
162  }
163 
164  if (guard[oldIdx])
165  {
167  << "order map is not unique; element " << oldIdx
168  << " already used for type " << typeid(T).name()
169  << abort(FatalError);
170  }
171 
172  guard[oldIdx] = ptrs_[oldIdx];
173  newList[i] = ptrs_[oldIdx];
174  }
175 
176  // Verify that all pointers were indeed set
177  if (check)
178  {
179  newList.checkNonNull();
180  }
181 
182  ptrs_.transfer(newList);
183 }
184 
185 
186 // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
187 
188 template<class T>
189 Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list)
190 {
191  return list.ptrs_.write(os);
192 }
193 
194 
195 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
196 
197 template<class T>
198 void Foam::sort(UPtrList<T>& list)
199 {
200  std::stable_sort
201  (
202  list.begin_ptr(),
203  list.end_ptr(),
204  // Compare less, with nullptr protect and sort nullptr to end
205  [](const T* const a, const T* const b) -> bool
206  {
207  return (a && b) ? (*a < *b) : !b;
208  }
209  );
210 }
211 
212 
213 template<class T, class Compare>
214 void Foam::sort(UPtrList<T>& list, const Compare& comp)
215 {
216  std::stable_sort
217  (
218  list.begin_ptr(),
219  list.end_ptr(),
220  typename UPtrList<T>::template value_compare<Compare>(comp)
221  );
222 }
223 
224 
225 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
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
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:79
constexpr UPtrList() noexcept=default
Default construct.
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
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:296
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
OBJstream os(runTime.globalPath()/outputName)
static void check(const int retVal, const char *what)
const volScalarField & T
void trimTrailingNull()
Reduce addressable list size to ignore any trailing null pointers.
Definition: UPtrList.C:62
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
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:128