IntRange.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) 2020-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 Class
27  Foam::IntRange
28 
29 Description
30  An interval of (signed) integers defined by a start and a size.
31 
32 Note
33  Only a minimum of IO operators are defined, to avoid incurring
34  too many dependencies or cyclic dependencies.
35 
36 SourceFiles
37  IntRangeI.H
38  IntRanges.C
39 
40 \*---------------------------------------------------------------------------*/
41 
42 #ifndef Foam_IntRange_H
43 #define Foam_IntRange_H
44 
45 #include "labelFwd.H"
46 #include <iterator>
47 #include <type_traits>
48 
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 
51 namespace Foam
52 {
53 
54 // Forward Declarations
55 class Istream;
56 class Ostream;
57 template<class T> class List;
58 
59 /*---------------------------------------------------------------------------*\
60  Class IntRange Declaration
61 \*---------------------------------------------------------------------------*/
62 
63 template<class IntType>
64 class IntRange
65 {
66  static_assert(std::is_integral<IntType>::value, "Integral required");
67 
68  // Private Data
69 
70  //- The start of the interval
71  IntType start_;
72 
73  //- The length of the interval
74  IntType size_;
75 
76 
77 public:
78 
79  // STL type definitions
80 
81  //- Type of values the range contains
82  typedef IntType value_type;
83 
84  //- The type that can represent the size of the range
85  typedef IntType size_type;
86 
87  //- Input iterator with const access
88  class const_iterator;
89 
90  //- Reverse input iterator with const access
91  class const_reverse_iterator;
92 
93 
94  // Public Classes
95 
96  //- Unary predicate for greater than 0 (int values)
97  struct gt0
98  {
99  template<class Int>
100  constexpr bool operator()(const Int val) const noexcept
101  {
102  return (val > 0);
103  }
104  };
105 
106  //- Unary predicate for less than 0 (int values)
107  struct lt0
108  {
109  template<class Int>
110  constexpr bool operator()(const Int val) const noexcept
111  {
112  return (val < 0);
113  }
114  };
115 
116  //- Unary predicate for greater-equal 0 (int values)
117  struct ge0
118  {
119  template<class Int>
120  constexpr bool operator()(const Int val) const noexcept
121  {
122  return (val >= 0);
123  }
124  };
125 
126  //- Unary predicate for less-equal 0 (int values)
127  struct le0
128  {
129  template<class Int>
130  constexpr bool operator()(const Int val) const noexcept
131  {
132  return (val <= 0);
133  }
134  };
135 
136 
137  // Generated Methods: copy/move construct, copy/move assignment
138 
139 
140  // Constructors
141 
142  //- Default construct an empty range (0,0)
143  inline constexpr IntRange() noexcept;
144 
145  //- Construct a range with specified length, starting at zero (0,len)
146  inline explicit constexpr IntRange(const IntType len) noexcept;
147 
148  //- Construct a range from start/length, no checks
149  inline constexpr IntRange
150  (
151  const IntType beg,
152  const IntType len
153  ) noexcept;
154 
155 
156  // Member Functions
157 
158  // Access
159 
160  //- True if range is empty (zero-sized)
161  bool empty() const noexcept { return !size_; }
162 
163  //- True if range has size greater than zero
164  bool good() const noexcept { return (size_ > 0); }
165 
166  //- The size of the range
167  IntType size() const noexcept { return size_; }
168 
169  //- Non-const access to size of the range
170  IntType& size() noexcept { return size_; }
171 
172  //- The (inclusive) lower value of the range
173  IntType start() const noexcept { return start_; }
174 
175  //- Non-const access to start of the range
176  IntType& start() noexcept { return start_; }
177 
178  //- The (inclusive) lower value of the range,
179  //- same as start(), begin_value()
180  IntType min() const noexcept { return start_; }
181 
182  //- The (inclusive) upper value of the range,
183  //- same as rbegin_value(). Ill-defined for an empty range
184  IntType max() const noexcept { return (start_ + (size_ - 1)); }
185 
186 
187  // Edit
188 
189  //- Reset to zero start and zero size
190  inline void reset() noexcept;
191 
192  //- Reset start and length, no checks
193  inline void reset(const IntType beg, const IntType len) noexcept;
195  //- Same as reset() - reset to zero start and zero size
196  void clear() noexcept { reset(); }
197 
198  //- Set the start position, no checks
199  inline void setStart(const IntType i) noexcept;
200 
201  //- Change the size, no checks. Identical to resize()
202  inline void setSize(const IntType n) noexcept;
203 
204  //- Change the size, no checks. Identical to setSize()
205  inline void resize(const IntType n) noexcept;
206 
207  //- Enforce non-negative size
208  inline void clampSize() noexcept;
210 
211  // Search
212 
213  //- True if the (global) value is within the range
214  inline bool contains(const IntType value) const noexcept;
216  //- True if the (global) value is within the range
217  bool found(const IntType val) const noexcept { return contains(val); }
218 
219 
220  // Member Operators
222  //- Return const_iterator to a position within the range,
223  //- with bounds checking.
224  // \return iterator at the requested position, or end() for
225  // out-of-bounds
226  inline const_iterator at(const IntType i) const;
227 
228  //- Offset dereference, without bounds checking
229  inline constexpr IntType operator[](const IntType i) const noexcept;
230 
231  //- True if the global value is located within the range.
232  // Behaviour identical to contains() - usable as a predicate
233  bool operator()(const IntType i) const noexcept { return contains(i); }
234 
235  //- Increase the size by 1.
236  inline IntType operator++() noexcept;
237  inline IntType operator++(int) noexcept;
238 
239  //- Increase the size by n.
240  inline IntType operator+=(const IntType n) noexcept;
241 
242  //- Decrease the size by 1, but never below 0.
243  inline IntType operator--() noexcept;
244  inline IntType operator--(int) noexcept;
245 
246  //- Decrease the size by n, but never below 0.
247  inline IntType operator-=(const IntType n) noexcept;
248 
249  //- True if range has size greater than zero. Same as good()
250  explicit operator bool() const noexcept { return (size_ > 0); }
251 
252 
253  // Iterator ranges
254 
255  //- The value at the beginning of the range - same as min(), start()
256  inline IntType begin_value() const noexcept;
257 
258  //- The value 1 beyond the end of the range.
259  inline IntType end_value() const noexcept;
260 
261  //- The max value of the range.
262  inline IntType rbegin_value() const noexcept;
263 
264  //- The value 1 before the begin of range
265  inline IntType rend_value() const noexcept;
266 
267 
268  // Bidirectional input iterators (const)
269 
270  //- Random-access input iterator with const access
271  // \note No operator+(IntType, iterator) since this provokes
272  // misleading resolution errors
273  class const_iterator
274  {
275  //- The global value
276  IntType value_;
277 
278  public:
279 
280  // STL definitions (as per std::iterator)
281  typedef std::random_access_iterator_tag iterator_category;
282  typedef IntType value_type;
283  typedef IntType difference_type;
284  typedef const IntType* pointer;
285  typedef IntType reference;
286 
287 
288  // Constructors
289 
290  //- Construct with specified value, or default construct
291  explicit constexpr const_iterator(IntType val = 0) noexcept
292  :
293  value_(val)
294  {}
295 
297  // Member Operators
298 
299  //- Return the value
300  constexpr IntType operator*() const noexcept { return value_; }
301 
302  //- Offset dereference operator
303  inline constexpr IntType operator[](const IntType n) const noexcept;
304 
305  //- Prefix increment
306  inline const_iterator& operator++() noexcept;
307 
308  //- Postfix increment
309  inline const_iterator operator++(int) noexcept;
310 
311  //- Prefix decrement
312  inline const_iterator& operator--() noexcept;
313 
314  //- Postfix decrement
315  inline const_iterator operator--(int) noexcept;
316 
317  //- Arbitrary increment
318  inline const_iterator& operator+=(const IntType n) noexcept;
319 
320  //- Arbitrary decrement
321  inline const_iterator& operator-=(const IntType n) noexcept;
322 
323  //- Return iterator with offset
324  inline constexpr const_iterator operator+
325  (
326  const IntType n
327  ) const noexcept;
328 
329  //- Return iterator with offset
330  inline constexpr const_iterator operator-
331  (
332  const IntType n
333  ) const noexcept;
334 
335  //- Difference operator
336  inline constexpr IntType operator-
337  (
338  const const_iterator& iter
339  ) const noexcept;
340 
341 
342  // Comparison
343 
344  //- Test for equality of values
345  inline constexpr bool operator==(const const_iterator& iter)
346  const noexcept;
347 
348  //- Compare less-than
349  inline constexpr bool operator<(const const_iterator& iter)
350  const noexcept;
351 
352 
353  // Derived comparisons
354 
355  constexpr bool operator!=(const const_iterator& iter)
356  const noexcept
357  {
358  return !(*this == iter);
359  }
360 
361  constexpr bool operator<=(const const_iterator& iter)
362  const noexcept
363  {
364  return !(iter < *this);
365  }
366 
367  constexpr bool operator>(const const_iterator& iter)
368  const noexcept
369  {
370  return (iter < *this);
371  }
372 
373  constexpr bool operator>=(const const_iterator& iter)
374  const noexcept
375  {
376  return !(*this < iter);
377  }
378  };
380 
381  //- Random-access reverse input iterator with const access
382  // \note No operator+(IntType, iterator) since this provokes
383  // misleading resolution errors
385  {
386  //- The global value
387  IntType value_;
388 
389  public:
391  // STL definitions (as per std::iterator)
392  typedef std::random_access_iterator_tag iterator_category;
393  typedef IntType value_type;
394  typedef IntType difference_type;
395  typedef const IntType* pointer;
396  typedef IntType reference;
397 
398 
399  // Constructors
400 
401  //- Construct with specified value, or default construct
402  explicit constexpr const_reverse_iterator(IntType val = 0) noexcept
403  :
404  value_(val)
405  {}
406 
407 
408  // Member Operators
409 
410  //- Return the value
411  constexpr IntType operator*() const noexcept { return value_; }
412 
413  //- Offset dereference operator
414  inline constexpr IntType operator[](const IntType n) const noexcept;
415 
416  //- Prefix increment
418 
419  //- Postfix increment
420  inline const_reverse_iterator operator++(int) noexcept;
421 
422  //- Prefix decrement
423  inline const_reverse_iterator& operator--() noexcept;
424 
425  //- Postfix decrement
426  inline const_reverse_iterator operator--(int) noexcept;
427 
428  //- Arbitrary increment
429  inline const_reverse_iterator& operator+=(const IntType n) noexcept;
430 
431  //- Arbitrary decrement
432  inline const_reverse_iterator& operator-=(const IntType n) noexcept;
433 
434  //- Return iterator with offset
435  inline constexpr const_reverse_iterator operator+
436  (
437  const IntType n
438  ) const noexcept;
439 
440  //- Return iterator with offset
441  inline constexpr const_reverse_iterator operator-
442  (
443  const IntType n
444  ) const noexcept;
445 
446  //- Difference operator
447  inline constexpr IntType operator-
448  (
449  const const_reverse_iterator& iter
450  )const noexcept;
451 
452 
453  // Comparison
454 
455  //- Test for equality of values
456  inline constexpr bool operator==(const const_reverse_iterator& iter)
457  const noexcept;
458 
459  //- Reverse compare less-than
460  inline constexpr bool operator<(const const_reverse_iterator& iter)
461  const noexcept;
462 
463 
464  // Derived comparisons
465 
466  constexpr bool operator!=(const const_reverse_iterator& iter)
467  const noexcept
468  {
469  return !(*this == iter);
470  }
471 
472  constexpr bool operator<=(const const_reverse_iterator& iter)
473  const noexcept
474  {
475  return !(iter < *this);
476  }
477 
478  constexpr bool operator>(const const_reverse_iterator& iter)
479  const noexcept
480  {
481  return (iter < *this);
482  }
483 
484  constexpr bool operator>=(const const_reverse_iterator& iter)
485  const noexcept
486  {
487  return !(*this < iter);
488  }
489  };
490 
491 
492  // Bidirectional input iterators (const)
493 
494  //- A const_iterator set to the beginning of the range
495  inline const_iterator begin() const noexcept;
496 
497  //- A const_iterator set to the beginning of the range
498  inline const_iterator cbegin() const noexcept;
499 
500  //- A const_iterator set to 1 beyond the end of the range.
501  inline const_iterator cend() const noexcept;
502 
503  //- A const_iterator set to 1 beyond the end of the range.
504  inline const_iterator end() const noexcept;
505 
506 
507  // Bidirectional reverse input iterators (const)
508 
509  //- A const_reverse_iterator set to 1 before the end of range
510  inline const_reverse_iterator rbegin() const noexcept;
512  //- A const_reverse_iterator set to 1 before the end of range
515  //- A const_reverse_iterator set to 1 before the begin of range
516  inline const_reverse_iterator rend() const noexcept;
517 
518  //- A const_reverse_iterator set to 1 before the begin of range
519  inline const_reverse_iterator crend() const noexcept;
520 };
521 
522 
523 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
524 
525 // Identity function for common integer types
526 
527 //- Identity map from an int32_t IntRange
528 List<label> identity(const IntRange<int32_t>& range);
529 
530 #if defined(WM_LABEL_SIZE) && (WM_LABEL_SIZE >= 64)
531 //- Identity map from an int64_t IntRange
533 #endif
535 
536 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
537 
538 // Input operators for common integer types
539 
540 //- Read IntRange from Istream as bracketed (start size) tuple, no checks
542 
543 //- Read IntRange from Istream as bracketed (start size) tuple, no checks
545 
546 
547 // Output operators for common integer types
548 
549 //- Write IntRange to Ostream as bracketed (start size) tuple
550 Ostream& operator<<(Ostream& os, const IntRange<int32_t>& range);
551 
552 //- Write IntRange to Ostream as bracketed (start size) tuple
553 Ostream& operator<<(Ostream& os, const IntRange<int64_t>& range);
554 
555 
556 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
557 
558 //- Test for equality of begin/size values
559 template<class IntType>
560 inline constexpr bool operator==
561 (
562  const IntRange<IntType>& a,
563  const IntRange<IntType>& b
564 ) noexcept
565 {
566  return (a.start() == b.start() && a.size() == b.size());
567 }
568 
569 
570 //- Comparison function for sorting, compares the start.
571 // If the start values are equal, also compares the size.
572 template<class IntType>
573 inline constexpr bool operator<
574 (
575  const IntRange<IntType>& a,
576  const IntRange<IntType>& b
577 ) noexcept
578 {
579  return
580  (
581  a.start() < b.start()
582  ||
583  (
584  !(b.start() < a.start())
585  && a.size() < b.size()
586  )
587  );
588 }
589 
590 
591 // Derived comparisons
592 
593 template<class IntType>
594 inline constexpr bool operator!=
595 (
596  const IntRange<IntType>& a,
597  const IntRange<IntType>& b
598 ) noexcept
599 {
600  return !(a == b);
601 }
602 
603 template<class IntType>
604 inline constexpr bool operator<=
605 (
606  const IntRange<IntType>& a,
607  const IntRange<IntType>& b
608 ) noexcept
609 {
610  return !(b < a);
611 }
612 
613 template<class IntType>
614 inline constexpr bool operator>
615 (
616  const IntRange<IntType>& a,
617  const IntRange<IntType>& b
618 ) noexcept
619 {
620  return (b < a);
621 }
622 
623 template<class IntType>
624 inline constexpr bool operator>=
625 (
626  const IntRange<IntType>& a,
627  const IntRange<IntType>& b
628 ) noexcept
629 
630 {
631  return !(a < b);
632 }
633 
634 
635 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
636 
637 } // End namespace Foam
638 
639 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
640 
641 #include "IntRangeI.H"
642 
643 #endif
644 
645 // ************************************************************************* //
constexpr bool operator>(const const_reverse_iterator &iter) const noexcept
Definition: IntRange.H:625
Random-access input iterator with const access.
Definition: IntRange.H:357
constexpr IntType operator[](const IntType i) const noexcept
Offset dereference, without bounds checking.
Definition: IntRangeI.H:458
constexpr bool operator()(const Int val) const noexcept
Definition: IntRange.H:121
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
An interval of (signed) integers defined by a start and a size.
Definition: IntRange.H:59
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void setSize(const IntType n) noexcept
Change the size, no checks. Identical to resize()
Definition: IntRangeI.H:423
void resize(const IntType n) noexcept
Change the size, no checks. Identical to setSize()
Definition: IntRangeI.H:430
const_reverse_iterator crbegin() const noexcept
A const_reverse_iterator set to 1 before the end of range.
Definition: IntRangeI.H:372
bool contains(const IntType value) const noexcept
True if the (global) value is within the range.
Definition: IntRangeI.H:444
bool operator>(const IOstreamOption::versionNumber &a, const IOstreamOption::versionNumber &b) noexcept
Version A newer than B.
constexpr bool operator()(const Int val) const noexcept
Definition: IntRange.H:145
const_reverse_iterator & operator++() noexcept
Prefix increment.
Definition: IntRangeI.H:216
IntType rbegin_value() const noexcept
The max value of the range.
Definition: IntRangeI.H:71
constexpr bool operator()(const Int val) const noexcept
Definition: IntRange.H:133
IntType size_type
The type that can represent the size of the range.
Definition: IntRange.H:88
const_reverse_iterator crend() const noexcept
A const_reverse_iterator set to 1 before the begin of range.
Definition: IntRangeI.H:388
bool operator>=(const IOstreamOption::versionNumber &a, const IOstreamOption::versionNumber &b) noexcept
Version A same or newer than B.
constexpr const_reverse_iterator(IntType val=0) noexcept
Construct with specified value, or default construct.
Definition: IntRange.H:523
IntType end_value() const noexcept
The value 1 beyond the end of the range.
Definition: IntRangeI.H:64
scalar range
void clampSize() noexcept
Enforce non-negative size.
Definition: IntRangeI.H:437
Random-access reverse input iterator with const access.
Definition: IntRange.H:501
Typedefs for label/uLabel without requiring label.H.
void clear() noexcept
Same as reset() - reset to zero start and zero size.
Definition: IntRange.H:239
constexpr bool operator<=(const const_reverse_iterator &iter) const noexcept
Definition: IntRange.H:619
IntType max() const noexcept
The (inclusive) upper value of the range, same as rbegin_value(). Ill-defined for an empty range...
Definition: IntRange.H:221
bool good() const noexcept
True if range has size greater than zero.
Definition: IntRange.H:189
bool operator<=(const IOstreamOption::versionNumber &a, const IOstreamOption::versionNumber &b) noexcept
Version A same or older than B.
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
std::random_access_iterator_tag iterator_category
Definition: IntRange.H:511
constexpr bool operator()(const Int val) const noexcept
Definition: IntRange.H:109
const_iterator begin() const noexcept
A const_iterator set to the beginning of the range.
Definition: IntRangeI.H:332
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
bool operator()(const IntType i) const noexcept
True if the global value is located within the range.
Definition: IntRange.H:296
Istream & operator>>(Istream &, directionInfo &)
IntType value_type
Type of values the range contains.
Definition: IntRange.H:83
const_iterator cend() const noexcept
A const_iterator set to 1 beyond the end of the range.
Definition: IntRangeI.H:356
const_reverse_iterator rbegin() const noexcept
A const_reverse_iterator set to 1 before the end of range.
Definition: IntRangeI.H:364
IntType start() const noexcept
The (inclusive) lower value of the range.
Definition: IntRange.H:204
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
IntType operator++() noexcept
Increase the size by 1.
Definition: IntRangeI.H:466
const_iterator cbegin() const noexcept
A const_iterator set to the beginning of the range.
Definition: IntRangeI.H:340
OBJstream os(runTime.globalPath()/outputName)
const_reverse_iterator rend() const noexcept
A const_reverse_iterator set to 1 before the begin of range.
Definition: IntRangeI.H:380
const_iterator end() const noexcept
A const_iterator set to 1 beyond the end of the range.
Definition: IntRangeI.H:348
const_iterator at(const IntType i) const
Return const_iterator to a position within the range, with bounds checking.
Definition: IntRangeI.H:324
IntType begin_value() const noexcept
The value at the beginning of the range - same as min(), start()
Definition: IntRangeI.H:57
bool empty() const noexcept
True if range is empty (zero-sized)
Definition: IntRange.H:184
bool found(const IntType val) const noexcept
True if the (global) value is within the range.
Definition: IntRange.H:272
IntType min() const noexcept
The (inclusive) lower value of the range, same as start(), begin_value()
Definition: IntRange.H:215
label n
constexpr bool operator>=(const const_reverse_iterator &iter) const noexcept
Definition: IntRange.H:631
constexpr IntType operator[](const IntType n) const noexcept
Offset dereference operator.
Definition: IntRangeI.H:207
IntType rend_value() const noexcept
The value 1 before the begin of range.
Definition: IntRangeI.H:78
IntType size() const noexcept
The size of the range.
Definition: IntRange.H:194
Unary predicate for less than 0 (int values)
Definition: IntRange.H:118
void reset() noexcept
Reset to zero start and zero size.
Definition: IntRangeI.H:397
constexpr IntType operator*() const noexcept
Return the value.
Definition: IntRange.H:534
constexpr IntRange() noexcept
Default construct an empty range (0,0)
Definition: IntRangeI.H:24
void setStart(const IntType i) noexcept
Set the start position, no checks.
Definition: IntRangeI.H:416
Namespace for OpenFOAM.