dune-common  2.8.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 
19 namespace Dune
20 {
21 
32  template <typename T,
33  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
34  typename T::value_type
35  max_value(const T & v) {
36  using std::max_element;
37  return *max_element(v.begin(), v.end());
38  }
39 
40  template <typename T,
41  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
42  const T & max_value(const T & v) { return v; }
43 
49  template <typename T,
50  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
51  typename T::value_type
52  min_value(const T & v) {
53  using std::min_element;
54  return *min_element(v.begin(), v.end());
55  }
56 
57  template <typename T,
58  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
59  const T & min_value(const T & v) { return v; }
60 
66  template <typename T,
67  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
68  bool any_true(const T & v) {
69  bool b = false;
70  for (const auto & e : v)
71  b = b or bool(e);
72  return b;
73  }
74 
75  template <typename T,
76  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
77  bool any_true(const T & v) { return v; }
78 
79  template<std::size_t N>
80  bool any_true(const std::bitset<N> & b)
81  {
82  return b.any();
83  }
84 
90  template <typename T,
91  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
92  bool all_true(const T & v) {
93  bool b = true;
94  for (const auto & e : v)
95  b = b and bool(e);
96  return b;
97  }
98 
99  template <typename T,
100  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
101  bool all_true(const T & v) { return v; }
102 
103  template<std::size_t N>
104  bool all_true(const std::bitset<N> & b)
105  {
106  return b.all();
107  }
108 
109 
110 
111  namespace Impl
112  {
113 
114  template <class T>
115  class IntegralRangeIterator
116  {
117  public:
118  typedef std::random_access_iterator_tag iterator_category;
119  typedef T value_type;
120  typedef std::make_signed_t<T> difference_type;
121  typedef const T *pointer;
122  typedef T reference;
123 
124  constexpr IntegralRangeIterator() noexcept : value_(0) {}
125  constexpr explicit IntegralRangeIterator(value_type value) noexcept : value_(value) {}
126 
127  pointer operator->() const noexcept { return &value_; }
128  constexpr reference operator*() const noexcept { return value_; }
129 
130  constexpr reference operator[]( difference_type n ) const noexcept { return (value_ + n); }
131 
132  constexpr bool operator==(const IntegralRangeIterator & other) const noexcept { return (value_ == other.value_); }
133  constexpr bool operator!=(const IntegralRangeIterator & other) const noexcept { return (value_ != other.value_); }
134 
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  constexpr bool operator>(const IntegralRangeIterator & other) const noexcept { return (value_ >= other.value_); }
138  constexpr bool operator>=(const IntegralRangeIterator & other) const noexcept { return (value_ >= other.value_); }
139 
140  IntegralRangeIterator& operator++() noexcept { ++value_; return *this; }
141  IntegralRangeIterator operator++(int) noexcept { IntegralRangeIterator copy( *this ); ++(*this); return copy; }
142 
143  IntegralRangeIterator& operator--() noexcept { --value_; return *this; }
144  IntegralRangeIterator operator--(int) noexcept { IntegralRangeIterator copy( *this ); --(*this); return copy; }
145 
146  IntegralRangeIterator& operator+=(difference_type n) noexcept { value_ += n; return *this; }
147  IntegralRangeIterator& operator-=(difference_type n) noexcept { value_ -= n; return *this; }
148 
149  friend constexpr IntegralRangeIterator operator+(const IntegralRangeIterator &a, difference_type n) noexcept { return IntegralRangeIterator(a.value_ + n); }
150  friend constexpr IntegralRangeIterator operator+(difference_type n, const IntegralRangeIterator &a) noexcept { return IntegralRangeIterator(a.value_ + n); }
151  friend constexpr IntegralRangeIterator operator-(const IntegralRangeIterator &a, difference_type n) noexcept { return IntegralRangeIterator(a.value_ - n); }
152 
153  constexpr difference_type operator-(const IntegralRangeIterator &other) const noexcept { return (static_cast<difference_type>(value_) - static_cast<difference_type>(other.value_)); }
154 
155  private:
156  value_type value_;
157  };
158 
159  } // namespace Impl
160 
161 
162 
171  template <class T>
173  {
174  public:
176  typedef T value_type;
178  typedef Impl::IntegralRangeIterator<T> iterator;
180  typedef std::make_unsigned_t<T> size_type;
181 
183  constexpr IntegralRange(value_type from, value_type to) noexcept : from_(from), to_(to) {}
185  constexpr explicit IntegralRange(value_type to) noexcept : from_(0), to_(to) {}
187  constexpr IntegralRange(std::pair<value_type, value_type> range) noexcept : from_(range.first), to_(range.second) {}
188 
190  constexpr iterator begin() const noexcept { return iterator(from_); }
192  constexpr iterator end() const noexcept { return iterator(to_); }
193 
195  constexpr value_type operator[](const value_type &i) const noexcept { return (from_ + i); }
196 
198  constexpr bool empty() const noexcept { return (from_ == to_); }
200  constexpr size_type size() const noexcept { return (static_cast<size_type>(to_) - static_cast<size_type>(from_)); }
201 
202  private:
203  value_type from_, to_;
204  };
205 
206 
221  template <class T, T to, T from = 0>
223  {
224  template <T ofs, T... i>
225  static std::integer_sequence<T, (i+ofs)...> shift_integer_sequence(std::integer_sequence<T, i...>);
226 
227  public:
229  typedef T value_type;
231  typedef Impl::IntegralRangeIterator<T> iterator;
233  typedef std::make_unsigned_t<T> size_type;
234 
236  typedef decltype(shift_integer_sequence<from>(std::make_integer_sequence<T, to-from>())) integer_sequence;
237 
239  constexpr StaticIntegralRange() noexcept = default;
240 
242  constexpr operator IntegralRange<T>() const noexcept { return {from, to}; }
244  constexpr operator integer_sequence() const noexcept { return {}; }
245 
247  static constexpr iterator begin() noexcept { return iterator(from); }
249  static constexpr iterator end() noexcept { return iterator(to); }
250 
252  template <class U, U i>
253  constexpr auto operator[](const std::integral_constant<U, i> &) const noexcept
254  -> std::integral_constant<value_type, from + static_cast<value_type>(i)>
255  {
256  return {};
257  }
258 
260  constexpr value_type operator[](const size_type &i) const noexcept { return (from + static_cast<value_type>(i)); }
261 
263  static constexpr std::integral_constant<bool, from == to> empty() noexcept { return {}; }
265  static constexpr std::integral_constant<size_type, static_cast<size_type>(to) - static_cast<size_type>(from) > size() noexcept { return {}; }
266  };
267 
277  template<class T, class U,
278  std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>::value, int> = 0,
279  std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
280  inline static IntegralRange<std::decay_t<T>> range(T &&from, U &&to) noexcept
281  {
282  return IntegralRange<std::decay_t<T>>(std::forward<T>(from), std::forward<U>(to));
283  }
284 
285  template<class T, std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
286  inline static IntegralRange<std::decay_t<T>> range(T &&to) noexcept
287  {
288  return IntegralRange<std::decay_t<T>>(std::forward<T>(to));
289  }
290 
291  template<class T, std::enable_if_t<std::is_enum<std::decay_t<T>>::value, int> = 0>
293  {
294  return IntegralRange<std::underlying_type_t<std::decay_t<T>>>(std::forward<T>(to));
295  }
296 
297  template<class T, T from, T to>
298  inline static StaticIntegralRange<T, to, from> range(std::integral_constant<T, from>, std::integral_constant<T, to>) noexcept
299  {
300  return {};
301  }
302 
303  template<class T, T to>
304  inline static StaticIntegralRange<T, to> range(std::integral_constant<T, to>) noexcept
305  {
306  return {};
307  }
308 
309 
310 
315 
320 
321  namespace Impl
322  {
323 
324  // Helper class to mimic a pointer for proxy objects.
325  // This is needed to implement operator-> on an iterator
326  // using proxy-values. It stores the proxy value but
327  // provides operator-> like a pointer.
328  template<class ProxyType>
329  class PointerProxy
330  {
331  public:
332  PointerProxy(ProxyType&& p) : p_(p)
333  {}
334 
335  ProxyType* operator->()
336  {
337  return &p_;
338  }
339 
340  ProxyType p_;
341  };
342 
343  // An iterator transforming a wrapped iterator using
344  // an unary function. It inherits the iterator-category
345  // of the underlying iterator.
346  template <class I, class F, class TransformationType, class C = typename std::iterator_traits<I>::iterator_category>
347  class TransformedRangeIterator;
348 
349  template <class I, class F, class TransformationType>
350  class TransformedRangeIterator<I,F,TransformationType,std::forward_iterator_tag>
351  {
352  protected:
353 
354  static decltype(auto) transform(const F& f, const I& it) {
355  if constexpr (std::is_same_v<TransformationType,IteratorTransformationTag>)
356  return f(it);
357  else
358  return f(*it);
359  }
360 
361  public:
362  using iterator_category = std::forward_iterator_tag;
363  using reference = decltype(transform(std::declval<F>(), std::declval<I>()));
364  using value_type = std::decay_t<reference>;
365  using pointer = PointerProxy<value_type>;
366 
367  // If we later want to allow standalone TransformedRangeIterators,
368  // we could customize the FunctionPointer to be a default-constructible,
369  // copy-assignable type storing a function but acting like a pointer
370  // to function.
371  using FunctionPointer = const F*;
372 
373  constexpr TransformedRangeIterator(const I& it, FunctionPointer f) noexcept :
374  it_(it),
375  f_(f)
376  {}
377 
378  // Explicitly initialize members. Using a plain
379  //
380  // constexpr TransformedRangeIterator() noexcept {}
381  //
382  // would default-initialize the members while
383  //
384  // constexpr TransformedRangeIterator() noexcept : it_(), f_() {}
385  //
386  // leads to value-initialization. This is a case where
387  // both are really different. If it_ is a raw pointer (i.e. POD)
388  // then default-initialization leaves it uninitialized while
389  // value-initialization zero-initializes it.
390  constexpr TransformedRangeIterator() noexcept :
391  it_(),
392  f_()
393  {}
394 
395  // Dereferencing returns a value created by the function
396  constexpr reference operator*() const noexcept {
397  return transform(*f_, it_);
398  }
399 
400  // Dereferencing returns a value created by the function
401  pointer operator->() const noexcept {
402  return transform(*f_, it_);
403  }
404 
405  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
406 
407  constexpr bool operator==(const TransformedRangeIterator& other) const noexcept {
408  return (it_ == other.it_);
409  }
410 
411  constexpr bool operator!=(const TransformedRangeIterator& other) const noexcept {
412  return (it_ != other.it_);
413  }
414 
415  TransformedRangeIterator& operator++() noexcept {
416  ++it_;
417  return *this;
418  }
419 
420  TransformedRangeIterator operator++(int) noexcept {
421  TransformedRangeIterator copy(*this);
422  ++(*this);
423  return copy;
424  }
425 
426  protected:
427  I it_;
428  FunctionPointer f_;
429  };
430 
431 
432 
433  template <class I, class F, class T>
434  class TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag> :
435  public TransformedRangeIterator<I,F,T,std::forward_iterator_tag>
436  {
437  protected:
438  using Base = TransformedRangeIterator<I,F,T,std::forward_iterator_tag>;
439  using Base::it_;
440  using Base::f_;
441  public:
442  using iterator_category = std::bidirectional_iterator_tag;
443  using reference = typename Base::reference;
444  using value_type = typename Base::value_type;
445  using pointer = typename Base::pointer;
446 
447  using FunctionPointer = typename Base::FunctionPointer;
448 
449  using Base::Base;
450 
451  // Member functions of the forward_iterator that need
452  // to be redefined because the base class methods return a
453  // forward_iterator.
454  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
455 
456  TransformedRangeIterator& operator++() noexcept {
457  ++it_;
458  return *this;
459  }
460 
461  TransformedRangeIterator operator++(int) noexcept {
462  TransformedRangeIterator copy(*this);
463  ++(*this);
464  return copy;
465  }
466 
467  // Additional member functions of bidirectional_iterator
468  TransformedRangeIterator& operator--() noexcept {
469  --(this->it_);
470  return *this;
471  }
472 
473  TransformedRangeIterator operator--(int) noexcept {
474  TransformedRangeIterator copy(*this);
475  --(*this);
476  return copy;
477  }
478  };
479 
480 
481 
482  template <class I, class F, class T>
483  class TransformedRangeIterator<I,F,T,std::random_access_iterator_tag> :
484  public TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>
485  {
486  protected:
487  using Base = TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>;
488  using Base::it_;
489  using Base::f_;
490  public:
491  using iterator_category = std::random_access_iterator_tag;
492  using reference = typename Base::reference;
493  using value_type = typename Base::value_type;
494  using pointer = typename Base::pointer;
495  using difference_type = typename std::iterator_traits<I>::difference_type;
496 
497  using FunctionPointer = typename Base::FunctionPointer;
498 
499  using Base::Base;
500 
501  // Member functions of the forward_iterator that need
502  // to be redefined because the base class methods return a
503  // forward_iterator.
504  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
505 
506  TransformedRangeIterator& operator++() noexcept {
507  ++it_;
508  return *this;
509  }
510 
511  TransformedRangeIterator operator++(int) noexcept {
512  TransformedRangeIterator copy(*this);
513  ++(*this);
514  return copy;
515  }
516 
517  // Member functions of the bidirectional_iterator that need
518  // to be redefined because the base class methods return a
519  // bidirectional_iterator.
520  TransformedRangeIterator& operator--() noexcept {
521  --(this->it_);
522  return *this;
523  }
524 
525  TransformedRangeIterator operator--(int) noexcept {
526  TransformedRangeIterator copy(*this);
527  --(*this);
528  return copy;
529  }
530 
531  // Additional member functions of random_access_iterator
532  TransformedRangeIterator& operator+=(difference_type n) noexcept {
533  it_ += n;
534  return *this;
535  }
536 
537  TransformedRangeIterator& operator-=(difference_type n) noexcept {
538  it_ -= n;
539  return *this;
540  }
541 
542  bool operator<(const TransformedRangeIterator& other) noexcept {
543  return it_<other.it_;
544  }
545 
546  bool operator<=(const TransformedRangeIterator& other) noexcept {
547  return it_<=other.it_;
548  }
549 
550  bool operator>(const TransformedRangeIterator& other) noexcept {
551  return it_>other.it_;
552  }
553 
554  bool operator>=(const TransformedRangeIterator& other) noexcept {
555  return it_>=other.it_;
556  }
557 
558  reference operator[](difference_type n) noexcept {
559  return Base::transform(*f_, it_+n);
560  }
561 
562  friend
563  TransformedRangeIterator operator+(const TransformedRangeIterator& it, difference_type n) noexcept {
564  return TransformedRangeIterator(it.it_+n, it.f_);
565  }
566 
567  friend
568  TransformedRangeIterator operator+(difference_type n, const TransformedRangeIterator& it) noexcept {
569  return TransformedRangeIterator(n+it.it_, it.f_);
570  }
571 
572  friend
573  TransformedRangeIterator operator-(const TransformedRangeIterator& it, difference_type n) noexcept {
574  return TransformedRangeIterator(it.it_-n, it.f_);
575  }
576 
577  friend
578  difference_type operator-(const TransformedRangeIterator& first, const TransformedRangeIterator& second) noexcept {
579  return first.it_-second.it_;
580  }
581  };
582 
583 
584  } // namespace Impl
585 
586 
587 
624  template <class R, class F, class T=ValueTransformationTag>
626  {
627  using RawConstIterator = std::decay_t<decltype(std::declval<const R>().begin())>;
628  using RawIterator = std::decay_t<decltype(std::declval<R>().begin())>;
629 
630  public:
631 
638  using const_iterator = Impl::TransformedRangeIterator<RawConstIterator, F, T>;
639 
646  using iterator = Impl::TransformedRangeIterator<RawIterator, F, T>;
647 
654  using RawRange = std::remove_reference_t<R>;
655 
659  template<class RR>
660  constexpr TransformedRangeView(RR&& rawRange, const F& f) noexcept :
661  rawRange_(std::forward<RR>(rawRange)),
662  f_(f)
663  {
664  static_assert(std::is_same_v<T, ValueTransformationTag> or std::is_same_v<T, IteratorTransformationTag>,
665  "The TransformationType passed to TransformedRangeView has to be either ValueTransformationTag or IteratorTransformationTag.");
666  }
667 
676  constexpr const_iterator begin() const noexcept {
677  return const_iterator(rawRange_.begin(), &f_);
678  }
679 
680  constexpr iterator begin() noexcept {
681  return iterator(rawRange_.begin(), &f_);
682  }
683 
692  constexpr const_iterator end() const noexcept {
693  return const_iterator(rawRange_.end(), &f_);
694  }
695 
696  constexpr iterator end() noexcept {
697  return iterator(rawRange_.end(), &f_);
698  }
699 
710  template<class Dummy=R,
711  class = std::void_t<decltype(std::declval<Dummy>().size())>>
712  auto size() const
713  {
714  return rawRange_.size();
715  }
716 
720  const RawRange& rawRange() const
721  {
722  return rawRange_;
723  }
724 
729  {
730  return rawRange_;
731  }
732 
733  private:
734  R rawRange_;
735  F f_;
736  };
737 
766  template <class R, class F>
767  auto transformedRangeView(R&& range, const F& f)
768  {
769  return TransformedRangeView<R, F, ValueTransformationTag>(std::forward<R>(range), f);
770  }
771 
799  template <class R, class F>
800  auto iteratorTransformedRangeView(R&& range, const F& f)
801  {
803  }
804 
805 
818  template<class Range>
819  auto sparseRange(Range&& range) {
820  return Dune::iteratorTransformedRangeView(std::forward<Range>(range), [](auto&& it) {
821  return std::tuple<decltype(*it), decltype(it.index())>(*it, it.index());
822  });
823  }
824 
829 }
830 
831 #endif // DUNE_COMMON_RANGE_UTILITIES_HH
Traits for type conversions and type information.
static StaticIntegralRange< T, to, from > range(std::integral_constant< T, from >, std::integral_constant< T, to >) noexcept
Definition: rangeutilities.hh:298
auto sparseRange(Range &&range)
Allow structured-binding for-loops for sparse iterators.
Definition: rangeutilities.hh:819
auto iteratorTransformedRangeView(R &&range, const F &f)
Create a TransformedRangeView using an iterator transformation.
Definition: rangeutilities.hh:800
auto transformedRangeView(R &&range, const F &f)
Create a TransformedRangeView.
Definition: rangeutilities.hh:767
bigunsignedint< k > operator+(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:530
bigunsignedint< k > operator*(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:544
bigunsignedint< k > operator-(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:537
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:257
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:681
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:635
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:235
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:703
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:658
Dune namespace.
Definition: alignedallocator.hh:11
bool any_true(const AlignedNumber< bool, align > &val)
Definition: debugalign.hh:480
bool all_true(const AlignedNumber< bool, align > &val)
Definition: debugalign.hh:486
T max_value(const AlignedNumber< T, align > &val)
Definition: debugalign.hh:468
T min_value(const AlignedNumber< T, align > &val)
Definition: debugalign.hh:474
dynamic integer range for use in range-based for loops
Definition: rangeutilities.hh:173
constexpr iterator begin() const noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:190
constexpr iterator end() const noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:192
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:180
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:178
constexpr value_type operator[](const value_type &i) const noexcept
access specified element
Definition: rangeutilities.hh:195
constexpr bool empty() const noexcept
check whether the range is empty
Definition: rangeutilities.hh:198
constexpr IntegralRange(std::pair< value_type, value_type > range) noexcept
construct integer range std::pair
Definition: rangeutilities.hh:187
constexpr IntegralRange(value_type from, value_type to) noexcept
construct integer range [from, to)
Definition: rangeutilities.hh:183
constexpr size_type size() const noexcept
obtain number of elements in the range
Definition: rangeutilities.hh:200
constexpr IntegralRange(value_type to) noexcept
construct integer range [0, to)
Definition: rangeutilities.hh:185
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:176
static integer range for use in range-based for loops
Definition: rangeutilities.hh:223
decltype(shift_integer_sequence< from >(std::make_integer_sequence< T, to-from >())) typedef integer_sequence
type of corresponding std::integer_sequence
Definition: rangeutilities.hh:236
static constexpr iterator end() noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:249
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:233
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:229
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:253
static constexpr std::integral_constant< bool, from==to > empty() noexcept
check whether the range is empty
Definition: rangeutilities.hh:263
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:265
static constexpr iterator begin() noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:247
constexpr value_type operator[](const size_type &i) const noexcept
access specified element (dynamic version)
Definition: rangeutilities.hh:260
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:231
Tag to enable value based transformations in TransformedRangeView.
Definition: rangeutilities.hh:314
Tag to enable iterator based transformations in TransformedRangeView.
Definition: rangeutilities.hh:319
A range transforming the values of another range on-the-fly.
Definition: rangeutilities.hh:626
auto size() const
Obtain the size of the range.
Definition: rangeutilities.hh:712
constexpr iterator end() noexcept
Definition: rangeutilities.hh:696
std::remove_reference_t< R > RawRange
Export type of the wrapped untransformed range.
Definition: rangeutilities.hh:654
Impl::TransformedRangeIterator< RawConstIterator, F, T > const_iterator
Const iterator type.
Definition: rangeutilities.hh:638
constexpr iterator begin() noexcept
Definition: rangeutilities.hh:680
constexpr TransformedRangeView(RR &&rawRange, const F &f) noexcept
Construct from range and function.
Definition: rangeutilities.hh:660
Impl::TransformedRangeIterator< RawIterator, F, T > iterator
Iterator type.
Definition: rangeutilities.hh:646
constexpr const_iterator begin() const noexcept
Obtain a iterator to the first element.
Definition: rangeutilities.hh:676
RawRange & rawRange()
Export the wrapped untransformed range.
Definition: rangeutilities.hh:728
const RawRange & rawRange() const
Export the wrapped untransformed range.
Definition: rangeutilities.hh:720
constexpr const_iterator end() const noexcept
Obtain a iterator past the last element.
Definition: rangeutilities.hh:692