UList.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) 2017-2023 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 "UList.H"
30 #include "contiguous.H"
31 #include "labelRange.H"
32 
33 #include <random>
34 
35 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36 
37 template<class T>
39 Foam::UList<T>::validateRange(const labelRange& requestedRange) const
40 {
41  const labelRange range(requestedRange.subset0(this->size()));
42 
43  #ifdef FULLDEBUG
44  this->checkStart(range.start());
45  this->checkSize(range.start() + range.size());
46  #endif
47 
48  return range;
49 }
50 
51 
52 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
53 
54 template<class T>
55 void Foam::UList<T>::moveFirst(const label i)
56 {
57  checkIndex(i);
58 
59  for (label lower = 0; lower < i; ++lower)
60  {
61  Foam::Swap(this->operator[](lower), this->operator[](i));
62  }
63 }
64 
65 
66 template<class T>
67 void Foam::UList<T>::moveLast(const label i)
68 {
69  checkIndex(i);
70 
71  for (label upper = size()-1; upper > i; --upper)
72  {
73  Foam::Swap(this->operator[](i), this->operator[](upper));
74  }
75 }
76 
77 
78 template<class T>
79 void Foam::UList<T>::swapFirst(const label i)
80 {
81  checkIndex(i);
82 
83  if (i > 0)
84  {
85  Foam::Swap(this->operator[](0), this->operator[](i));
86  }
87 }
88 
89 
90 template<class T>
91 void Foam::UList<T>::swapLast(const label i)
92 {
93  checkIndex(i);
94 
95  const label upper = size()-1;
96 
97  if (i < upper)
98  {
99  Foam::Swap(this->operator[](i), this->operator[](upper));
100  }
101 }
102 
103 
104 template<class T>
105 void Foam::UList<T>::deepCopy(const UList<T>& list)
106 {
107  if (this->size_ != list.size_)
108  {
110  << "Lists have different sizes: "
111  << this->size_ << " != " << list.size() << nl
112  << abort(FatalError);
113  }
114  else if (this->size_ > 0)
115  {
116  // Can dispatch with
117  // - std::execution::parallel_unsequenced_policy
118  // - std::execution::unsequenced_policy
119  std::copy(list.cbegin(), list.cend(), this->v_);
120  }
121 }
122 
123 
124 template<class T>
125 template<class Addr>
126 void Foam::UList<T>::deepCopy(const IndirectListBase<T, Addr>& list)
127 {
128  if (this->size_ != list.size())
129  {
131  << "Lists have different sizes: "
132  << this->size_ << " != " << list.size() << nl
133  << abort(FatalError);
134  }
135  else if (this->size_)
136  {
137  // Copy the indirect list contents
138 
139  // NB: operator[] for list read access (eg, an indirect list)
140  // cannot replace with std::copy
141 
142  const label len = this->size_;
143 
144  auto iter = this->v_;
145 
146  for (label i = 0; i < len; (void)++i, (void)++iter)
147  {
148  *iter = list[i];
149  }
150  }
151 }
152 
153 
154 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
155 
156 // This is non-inlined to allow template specializations
157 template<class T>
159 {
160  this->fill_uniform(Foam::zero{});
161 }
162 
163 
164 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
165 
166 template<class T>
167 std::streamsize Foam::UList<T>::byteSize() const
168 {
169  if (!is_contiguous<T>::value)
170  {
172  << "Invalid for non-contiguous data types"
174  }
175  return this->size_bytes();
176 }
177 
178 
179 template<class T>
180 Foam::label Foam::UList<T>::find(const T& val) const
181 {
182  const auto iter = std::find(this->cbegin(), this->cend(), val);
183  return (iter != this->cend() ? label(iter - this->cbegin()) : label(-1));
184 }
185 
186 
187 template<class T>
188 Foam::label Foam::UList<T>::find(const T& val, label pos, label len) const
189 {
190  if (pos >= 0 && pos < this->size())
191  {
192  // Change sub-length to (one-past) end position
193  // len == -1 (like std::string::npos) - search until end
194 
195  if (len > 0) len += pos;
196  if (len < 0 || len > this->size())
197  {
198  len = this->size();
199  }
200 
201  const auto iter = std::find
202  (
203  (this->cbegin() + pos),
204  (this->cbegin() + len),
205  val
206  );
207 
208  if (iter != (this->cbegin() + len))
209  {
210  return label(iter - this->cbegin());
211  }
212  }
213 
214  return -1;
215 }
216 
217 
218 template<class T>
219 Foam::label Foam::UList<T>::rfind(const T& val, label pos) const
220 {
221  // pos == -1 (like std::string::npos) - search from end
222 
223  if (pos < 0 || pos >= this->size())
224  {
225  pos = this->size()-1;
226  }
227 
228  while (pos >= 0)
229  {
230  if (this->v_[pos] == val)
231  {
232  return pos;
233  }
234 
235  --pos;
236  }
237 
238  return -1;
239 }
240 
241 
242 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
243 
244 template<class T>
245 bool Foam::UList<T>::operator==(const UList<T>& list) const
246 {
247  // Can dispatch with
248  // - std::execution::parallel_unsequenced_policy
249  // - std::execution::unsequenced_policy
250  return
251  (
252  (this->size_ == list.size_)
253  && std::equal(this->cbegin(), this->cend(), list.cbegin())
254  );
255 }
256 
257 
258 template<class T>
259 bool Foam::UList<T>::operator!=(const UList<T>& list) const
260 {
261  return !operator==(list);
262 }
263 
264 
265 template<class T>
266 bool Foam::UList<T>::operator<(const UList<T>& list) const
267 {
268  // Can dispatch with
269  // - std::execution::parallel_unsequenced_policy
270  // - std::execution::unsequenced_policy
271  return std::lexicographical_compare
272  (
273  this->cbegin(), this->cend(),
274  list.cbegin(), list.cend()
275  );
276 }
277 
278 
279 template<class T>
280 bool Foam::UList<T>::operator>(const UList<T>& list) const
281 {
282  return list.operator<(*this);
283 }
284 
285 
286 template<class T>
287 bool Foam::UList<T>::operator<=(const UList<T>& list) const
288 {
289  return !list.operator<(*this);
290 }
291 
292 
293 template<class T>
294 bool Foam::UList<T>::operator>=(const UList<T>& list) const
295 {
296  return !operator<(list);
297 }
298 
299 
300 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
301 
302 template<class T>
303 void Foam::sort(UList<T>& list)
304 {
305  // With which std::execution:: ?
306  std::sort(list.begin(), list.end());
307 }
308 
309 
310 template<class T, class Compare>
311 void Foam::sort(UList<T>& list, const Compare& comp)
312 {
313  // With which std::execution:: ?
314  std::sort(list.begin(), list.end(), comp);
315 }
316 
317 
318 template<class T>
319 void Foam::stableSort(UList<T>& list)
320 {
321  // With which std::execution:: ?
322  std::stable_sort(list.begin(), list.end());
323 }
324 
325 
326 template<class T, class Compare>
327 void Foam::stableSort(UList<T>& list, const Compare& comp)
328 {
329  // With which std::execution:: ?
330  std::stable_sort(list.begin(), list.end(), comp);
331 }
332 
333 
334 template<class T>
335 void Foam::shuffle(UList<T>& list)
336 {
337  std::shuffle(list.begin(), list.end(), std::default_random_engine());
338 }
339 
340 
341 // ************************************************************************* //
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:795
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant UList.
Definition: UListI.H:449
void swapLast(const label i)
Swap element with the last element. Fatal on an empty list.
Definition: UList.C:84
void swapFirst(const label i)
Swap element with the first element. Fatal on an empty list.
Definition: UList.C:72
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
bool operator<=(const UList< T > &list) const
Return true if !(a > b). Takes linear time.
Definition: UList.C:280
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1187
void stableSort(UList< T > &list)
Stable sort the list.
Definition: UList.C:312
labelRange validateRange(const labelRange &requestedRange) const
Return a validated (start,size) subset range, which means that it always addresses a valid section of...
Definition: UList.C:32
bool operator<(const IOstreamOption::versionNumber &a, const IOstreamOption::versionNumber &b) noexcept
Version A older than B.
bool equal(const Matrix< Form1, Type > &A, const Matrix< Form2, Type > &B, const bool verbose=false, const label maxDiffs=10, const scalar relTol=1e-5, const scalar absTol=1e-8)
Compare matrix elements for absolute or relative equality.
Definition: MatrixTools.C:27
scalar range
labelRange subset0(const label size) const
Calculate the intersection with the given 0/size range.
Definition: labelRange.C:189
UList< T > & operator=(const UList< T > &)=delete
No copy assignment (default: shallow copy)
dimensionedScalar pos(const dimensionedScalar &ds)
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
bool operator==(const UList< T > &list) const
Equality operation on ULists of the same type.
Definition: UList.C:238
bool operator!=(const UList< T > &list) const
The opposite of the equality operation. Takes linear time.
Definition: UList.C:252
label rfind(const T &val, label pos=-1) const
Find index of the last occurrence of the value.
Definition: UList.C:212
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:223
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
label find(const T &val) const
Find index of the first occurrence of the value.
Definition: UList.C:173
constexpr auto cbegin(const C &c) -> decltype(c.begin())
Return const_iterator to the beginning of the container c.
Definition: stdFoam.H:190
bool operator<(const UList< T > &list) const
Compare two ULists lexicographically. Takes linear time.
Definition: UList.C:259
void moveLast(const label i)
Move element to the last position.
Definition: UList.C:60
const volScalarField & T
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1171
std::streamsize byteSize() const
Number of contiguous bytes for the List data, runtime FatalError if type is not contiguous.
Definition: UList.C:160
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Exchange contents of lists - see DynamicList::swap().
Definition: DynamicList.H:692
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
Definition: UListI.H:405
void deepCopy(const UList< T > &list)
Copy elements of the given UList. Sizes must match!
Definition: UList.C:98
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
void shuffle(UList< T > &list)
Randomise the list order.
Definition: UList.C:328
void moveFirst(const label i)
Move element to the first position.
Definition: UList.C:48
bool operator>=(const UList< T > &list) const
Return true if !(a < b). Takes linear time.
Definition: UList.C:287
bool operator>(const UList< T > &list) const
Compare two ULists lexicographically. Takes linear time.
Definition: UList.C:273