Dune Core Modules (2.6.0)

rangeutilities.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_COMMON_RANGE_UTILITIES_HH
4 #define DUNE_COMMON_RANGE_UTILITIES_HH
5 
7 #include <algorithm>
8 #include <utility>
9 #include <type_traits>
10 #include <bitset>
11 
23 namespace Dune
24 {
30  template <typename T,
31  typename std::enable_if<is_range<T>::value, int>::type = 0>
32  typename T::value_type
33  max_value(const T & v) {
34  using std::max_element;
35  return *max_element(v.begin(), v.end());
36  }
37 
38  template <typename T,
39  typename std::enable_if<!is_range<T>::value, int>::type = 0>
40  const T & max_value(const T & v) { return v; }
41 
47  template <typename T,
48  typename std::enable_if<is_range<T>::value, int>::type = 0>
49  typename T::value_type
50  min_value(const T & v) {
51  using std::min_element;
52  return *min_element(v.begin(), v.end());
53  }
54 
55  template <typename T,
56  typename std::enable_if<!is_range<T>::value, int>::type = 0>
57  const T & min_value(const T & v) { return v; }
58 
64  template <typename T,
65  typename std::enable_if<is_range<T>::value, int>::type = 0>
66  bool any_true(const T & v) {
67  bool b = false;
68  for (const auto & e : v)
69  b = b or bool(e);
70  return b;
71  }
72 
73  template <typename T,
74  typename std::enable_if<!is_range<T>::value, int>::type = 0>
75  bool any_true(const T & v) { return v; }
76 
77  template<std::size_t N>
78  bool any_true(const std::bitset<N> & b)
79  {
80  return b.any();
81  }
82 
88  template <typename T,
89  typename std::enable_if<is_range<T>::value, int>::type = 0>
90  bool all_true(const T & v) {
91  bool b = true;
92  for (const auto & e : v)
93  b = b and bool(e);
94  return b;
95  }
96 
97  template <typename T,
98  typename std::enable_if<!is_range<T>::value, int>::type = 0>
99  bool all_true(const T & v) { return v; }
100 
101  template<std::size_t N>
102  bool all_true(const std::bitset<N> & b)
103  {
104  return b.all();
105  }
106 
107 
108 
109  namespace Impl
110  {
111 
112  template <class T>
113  class IntegralRangeIterator
114  {
115  public:
116  typedef std::random_access_iterator_tag iterator_category;
117  typedef T value_type;
118  typedef std::make_signed_t<T> difference_type;
119  typedef const T *pointer;
120  typedef T reference;
121 
122  constexpr IntegralRangeIterator() noexcept = default;
123  constexpr explicit IntegralRangeIterator(value_type value) noexcept : value_(value) {}
124 
125  pointer operator->() const noexcept { return &value_; }
126  constexpr reference operator*() const noexcept { return value_; }
127 
128  constexpr reference operator[]( difference_type n ) const noexcept { return (value_ + n); }
129 
130  constexpr bool operator==(const IntegralRangeIterator & other) const noexcept { return (value_ == other.value_); }
131  constexpr bool operator!=(const IntegralRangeIterator & other) const noexcept { return (value_ != other.value_); }
132 
133  constexpr bool operator<(const IntegralRangeIterator & other) const noexcept { return (value_ <= other.value_); }
134  constexpr bool operator<=(const IntegralRangeIterator & other) const noexcept { return (value_ <= other.value_); }
135  constexpr bool operator>(const IntegralRangeIterator & other) const noexcept { return (value_ >= other.value_); }
136  constexpr bool operator>=(const IntegralRangeIterator & other) const noexcept { return (value_ >= other.value_); }
137 
138  IntegralRangeIterator& operator++() noexcept { ++value_; return *this; }
139  IntegralRangeIterator operator++(int) noexcept { IntegralRangeIterator copy( *this ); ++(*this); return copy; }
140 
141  IntegralRangeIterator& operator--() noexcept { --value_; return *this; }
142  IntegralRangeIterator operator--(int) noexcept { IntegralRangeIterator copy( *this ); --(*this); return copy; }
143 
144  IntegralRangeIterator& operator+=(difference_type n) noexcept { value_ += n; return *this; }
145  IntegralRangeIterator& operator-=(difference_type n) noexcept { value_ -= n; return *this; }
146 
147  friend constexpr IntegralRangeIterator operator+(const IntegralRangeIterator &a, difference_type n) noexcept { return IntegralRangeIterator(a.value_ + n); }
148  friend constexpr IntegralRangeIterator operator+(difference_type n, const IntegralRangeIterator &a) noexcept { return IntegralRangeIterator(a.value_ + n); }
149  friend constexpr IntegralRangeIterator operator-(const IntegralRangeIterator &a, difference_type n) noexcept { return IntegralRangeIterator(a.value_ - n); }
150 
151  constexpr difference_type operator-(const IntegralRangeIterator &other) const noexcept { return (static_cast<difference_type>(value_) - static_cast<difference_type>(other.value_)); }
152 
153  private:
154  value_type value_;
155  };
156 
157  } // namespace Impl
158 
159 
160 
169  template <class T>
171  {
172  public:
174  typedef T value_type;
176  typedef Impl::IntegralRangeIterator<T> iterator;
178  typedef std::make_unsigned_t<T> size_type;
179 
181  constexpr IntegralRange(value_type from, value_type to) noexcept : from_(from), to_(to) {}
183  constexpr explicit IntegralRange(value_type to) noexcept : from_(0), to_(to) {}
185  constexpr IntegralRange(std::pair<value_type, value_type> range) noexcept : from_(range.first), to_(range.second) {}
186 
188  constexpr iterator begin() const noexcept { return iterator(from_); }
190  constexpr iterator end() const noexcept { return iterator(to_); }
191 
193  constexpr value_type operator[](const value_type &i) const noexcept { return (from_ + i); }
194 
196  constexpr bool empty() const noexcept { return (from_ == to_); }
198  constexpr size_type size() const noexcept { return (static_cast<size_type>(to_) - static_cast<size_type>(from_)); }
199 
200  private:
201  value_type from_, to_;
202  };
203 
204 
219  template <class T, T to, T from = 0>
221  {
222  template <T ofs, T... i>
223  static std::integer_sequence<T, (i+ofs)...> shift_integer_sequence(std::integer_sequence<T, i...>);
224 
225  public:
227  typedef T value_type;
229  typedef Impl::IntegralRangeIterator<T> iterator;
231  typedef std::make_unsigned_t<T> size_type;
232 
234  typedef decltype(shift_integer_sequence<from>(std::make_integer_sequence<T, to-from>())) integer_sequence;
235 
237  constexpr StaticIntegralRange() noexcept = default;
238 
240  constexpr operator IntegralRange<T>() const noexcept { return {from, to}; }
242  constexpr operator integer_sequence() const noexcept { return {}; }
243 
245  static constexpr iterator begin() noexcept { return iterator(from); }
247  static constexpr iterator end() noexcept { return iterator(to); }
248 
250  template <class U, U i>
251  constexpr auto operator[](const std::integral_constant<U, i> &) const noexcept
252  -> std::integral_constant<value_type, from + static_cast<value_type>(i)>
253  {
254  return {};
255  }
256 
258  constexpr value_type operator[](const size_type &i) const noexcept { return (from + static_cast<value_type>(i)); }
259 
261  static constexpr std::integral_constant<bool, from == to> empty() noexcept { return {}; }
263  static constexpr std::integral_constant<size_type, static_cast<size_type>(to) - static_cast<size_type>(from) > size() noexcept { return {}; }
264  };
265 
275  template<class T, class U,
276  std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>::value, int> = 0,
277  std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
278  inline static IntegralRange<std::decay_t<T>> range(T &&from, U &&to) noexcept
279  {
280  return IntegralRange<std::decay_t<T>>(std::forward<T>(from), std::forward<U>(to));
281  }
282 
283  template<class T, std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
284  inline static IntegralRange<std::decay_t<T>> range(T &&to) noexcept
285  {
286  return IntegralRange<std::decay_t<T>>(std::forward<T>(to));
287  }
288 
289  template<class T, T from, T to>
290  inline static StaticIntegralRange<T, to, from> range(std::integral_constant<T, from>, std::integral_constant<T, to>) noexcept
291  {
292  return {};
293  }
294 
295  template<class T, T to>
296  inline static StaticIntegralRange<T, to> range(std::integral_constant<T, to>) noexcept
297  {
298  return {};
299  }
300 
301 }
302 
303 #endif // DUNE_COMMON_RANGE_UTILITIES_HH
dynamic integer range for use in range-based for loops
Definition: rangeutilities.hh:171
static integer range for use in range-based for loops
Definition: rangeutilities.hh:221
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:255
EnableIfInterOperable< T1, T2, bool >::type operator>(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:675
EnableIfInterOperable< T1, T2, bool >::type operator<(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:629
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:233
EnableIfInterOperable< T1, T2, bool >::type operator>=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:697
EnableIfInterOperable< T1, T2, bool >::type operator<=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:652
decltype(shift_integer_sequence< from >(std::make_integer_sequence< T, to-from >())) typedef integer_sequence
type of corresponding std::integer_sequence
Definition: rangeutilities.hh:234
constexpr iterator begin() const noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:188
static constexpr iterator end() noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:247
constexpr iterator end() const noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:190
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:178
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:231
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:227
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:176
constexpr auto operator[](const std::integral_constant< U, i > &) const noexcept -> std::integral_constant< value_type, from+static_cast< value_type >(i)>
access specified element (static version)
Definition: rangeutilities.hh:251
static constexpr std::integral_constant< bool, from==to > empty() noexcept
check whether the range is empty
Definition: rangeutilities.hh:261
constexpr value_type operator[](const value_type &i) const noexcept
access specified element
Definition: rangeutilities.hh:193
constexpr bool empty() const noexcept
check whether the range is empty
Definition: rangeutilities.hh:196
constexpr IntegralRange(std::pair< value_type, value_type > range) noexcept
construct integer range std::pair
Definition: rangeutilities.hh:185
constexpr IntegralRange(value_type from, value_type to) noexcept
construct integer range [from, to)
Definition: rangeutilities.hh:181
static constexpr std::integral_constant< size_type, static_cast< size_type >to) - static_cast< size_type >from) > size() noexcept
obtain number of elements in the range
Definition: rangeutilities.hh:263
static constexpr iterator begin() noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:245
constexpr size_type size() const noexcept
obtain number of elements in the range
Definition: rangeutilities.hh:198
constexpr IntegralRange(value_type to) noexcept
construct integer range [0, to)
Definition: rangeutilities.hh:183
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:174
constexpr value_type operator[](const size_type &i) const noexcept
access specified element (dynamic version)
Definition: rangeutilities.hh:258
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:229
Dune namespace.
Definition: alignedallocator.hh:10
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 29, 22:29, 2024)