Dune Core Modules (unstable)

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 // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 #ifndef DUNE_COMMON_RANGE_UTILITIES_HH
6 #define DUNE_COMMON_RANGE_UTILITIES_HH
7 
9 #include <algorithm>
10 #include <utility>
11 #include <type_traits>
12 #include <bitset>
13 
21 namespace Dune
22 {
23 
34  template <typename T,
35  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
36  typename T::value_type
37  max_value(const T & v) {
38  using std::max_element;
39  return *max_element(v.begin(), v.end());
40  }
41 
42  template <typename T,
43  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
44  const T & max_value(const T & v) { return v; }
45 
51  template <typename T,
52  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
53  typename T::value_type
54  min_value(const T & v) {
55  using std::min_element;
56  return *min_element(v.begin(), v.end());
57  }
58 
59  template <typename T,
60  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
61  const T & min_value(const T & v) { return v; }
62 
68  template <typename T,
69  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
70  bool any_true(const T & v) {
71  bool b = false;
72  for (const auto & e : v)
73  b = b or bool(e);
74  return b;
75  }
76 
77  template <typename T,
78  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
79  bool any_true(const T & v) { return v; }
80 
81  template<std::size_t N>
82  bool any_true(const std::bitset<N> & b)
83  {
84  return b.any();
85  }
86 
92  template <typename T,
93  typename std::enable_if<IsIterable<T>::value, int>::type = 0>
94  bool all_true(const T & v) {
95  bool b = true;
96  for (const auto & e : v)
97  b = b and bool(e);
98  return b;
99  }
100 
101  template <typename T,
102  typename std::enable_if<!IsIterable<T>::value, int>::type = 0>
103  bool all_true(const T & v) { return v; }
104 
105  template<std::size_t N>
106  bool all_true(const std::bitset<N> & b)
107  {
108  return b.all();
109  }
110 
111 
112 
113  namespace Impl
114  {
115 
116  template <class T>
117  class IntegralRangeIterator
118  {
119  public:
120  typedef std::random_access_iterator_tag iterator_category;
121  typedef T value_type;
122  typedef std::make_signed_t<T> difference_type;
123  typedef const T *pointer;
124  typedef T reference;
125 
126  constexpr IntegralRangeIterator() noexcept : value_(0) {}
127  constexpr explicit IntegralRangeIterator(value_type value) noexcept : value_(value) {}
128 
129  pointer operator->() const noexcept { return &value_; }
130  constexpr reference operator*() const noexcept { return value_; }
131 
132  constexpr reference operator[]( difference_type n ) const noexcept { return (value_ + n); }
133 
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 
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  constexpr bool operator>(const IntegralRangeIterator & other) const noexcept { return (value_ >= other.value_); }
140  constexpr bool operator>=(const IntegralRangeIterator & other) const noexcept { return (value_ >= other.value_); }
141 
142  IntegralRangeIterator& operator++() noexcept { ++value_; return *this; }
143  IntegralRangeIterator operator++(int) noexcept { IntegralRangeIterator copy( *this ); ++(*this); return copy; }
144 
145  IntegralRangeIterator& operator--() noexcept { --value_; return *this; }
146  IntegralRangeIterator operator--(int) noexcept { IntegralRangeIterator copy( *this ); --(*this); return copy; }
147 
148  IntegralRangeIterator& operator+=(difference_type n) noexcept { value_ += n; return *this; }
149  IntegralRangeIterator& operator-=(difference_type n) noexcept { value_ -= n; return *this; }
150 
151  friend constexpr IntegralRangeIterator operator+(const IntegralRangeIterator &a, difference_type n) noexcept { return IntegralRangeIterator(a.value_ + n); }
152  friend constexpr IntegralRangeIterator operator+(difference_type n, const IntegralRangeIterator &a) noexcept { return IntegralRangeIterator(a.value_ + n); }
153  friend constexpr IntegralRangeIterator operator-(const IntegralRangeIterator &a, difference_type n) noexcept { return IntegralRangeIterator(a.value_ - n); }
154 
155  constexpr difference_type operator-(const IntegralRangeIterator &other) const noexcept { return (static_cast<difference_type>(value_) - static_cast<difference_type>(other.value_)); }
156 
157  private:
158  value_type value_;
159  };
160 
161  } // namespace Impl
162 
163 
164 
173  template <class T>
175  {
176  public:
178  typedef T value_type;
180  typedef Impl::IntegralRangeIterator<T> iterator;
182  typedef std::make_unsigned_t<T> size_type;
183 
185  constexpr IntegralRange(value_type from, value_type to) noexcept : from_(from), to_(to) {}
187  constexpr explicit IntegralRange(value_type to) noexcept : from_(0), to_(to) {}
189  constexpr IntegralRange(std::pair<value_type, value_type> range) noexcept : from_(range.first), to_(range.second) {}
190 
192  constexpr iterator begin() const noexcept { return iterator(from_); }
194  constexpr iterator end() const noexcept { return iterator(to_); }
195 
197  constexpr value_type operator[](const value_type &i) const noexcept { return (from_ + i); }
198 
200  constexpr bool empty() const noexcept { return (from_ == to_); }
202  constexpr size_type size() const noexcept { return (static_cast<size_type>(to_) - static_cast<size_type>(from_)); }
203 
205  constexpr bool contains(value_type index) const noexcept { return from_ <= index && index < to_; }
206 
207  private:
208  value_type from_, to_;
209  };
210 
211 
226  template <class T, T to, T from = 0>
228  {
229  template <T ofs, T... i>
230  static std::integer_sequence<T, (i+ofs)...> shift_integer_sequence(std::integer_sequence<T, i...>);
231 
232  public:
234  typedef T value_type;
236  typedef Impl::IntegralRangeIterator<T> iterator;
238  typedef std::make_unsigned_t<T> size_type;
239 
241  typedef decltype(shift_integer_sequence<from>(std::make_integer_sequence<T, to-from>())) integer_sequence;
242 
244  constexpr StaticIntegralRange() noexcept = default;
245 
247  constexpr operator IntegralRange<T>() const noexcept { return {from, to}; }
249  constexpr operator integer_sequence() const noexcept { return {}; }
250 
252  static constexpr integer_sequence to_integer_sequence() noexcept { return {}; }
253 
255  static constexpr iterator begin() noexcept { return iterator(from); }
257  static constexpr iterator end() noexcept { return iterator(to); }
258 
260  template <class U, U i>
261  constexpr auto operator[](const std::integral_constant<U, i> &) const noexcept
262  -> std::integral_constant<value_type, from + static_cast<value_type>(i)>
263  {
264  return {};
265  }
266 
268  constexpr value_type operator[](const size_type &i) const noexcept { return (from + static_cast<value_type>(i)); }
269 
271  static constexpr std::integral_constant<bool, from == to> empty() noexcept { return {}; }
273  static constexpr std::integral_constant<size_type, static_cast<size_type>(to) - static_cast<size_type>(from) > size() noexcept { return {}; }
274 
276  static constexpr bool contains(value_type index) noexcept { return from <= index && index < to; }
277 
278  };
279 
289  template<class T, class U,
290  std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>::value, int> = 0,
291  std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
292  inline static IntegralRange<std::decay_t<T>> range(T &&from, U &&to) noexcept
293  {
294  return IntegralRange<std::decay_t<T>>(std::forward<T>(from), std::forward<U>(to));
295  }
296 
297  template<class T, std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
298  inline static IntegralRange<std::decay_t<T>> range(T &&to) noexcept
299  {
300  return IntegralRange<std::decay_t<T>>(std::forward<T>(to));
301  }
302 
303  template<class T, std::enable_if_t<std::is_enum<std::decay_t<T>>::value, int> = 0>
304  inline static IntegralRange<std::underlying_type_t<std::decay_t<T>>> range(T &&to) noexcept
305  {
306  return IntegralRange<std::underlying_type_t<std::decay_t<T>>>(std::forward<T>(to));
307  }
308 
309  template<class T, T from, T to>
310  inline static StaticIntegralRange<T, to, from> range(std::integral_constant<T, from>, std::integral_constant<T, to>) noexcept
311  {
312  return {};
313  }
314 
315  template<class T, T to>
316  inline static StaticIntegralRange<T, to> range(std::integral_constant<T, to>) noexcept
317  {
318  return {};
319  }
320 
321 
322 
327 
332 
333  namespace Impl
334  {
335 
336  // Helper class to mimic a pointer for proxy objects.
337  // This is needed to implement operator-> on an iterator
338  // using proxy-values. It stores the proxy value but
339  // provides operator-> like a pointer.
340  template<class ProxyType>
341  class PointerProxy
342  {
343  public:
344  PointerProxy(ProxyType&& p) : p_(p)
345  {}
346 
347  ProxyType* operator->()
348  {
349  return &p_;
350  }
351 
352  ProxyType p_;
353  };
354 
355  // An iterator transforming a wrapped iterator using
356  // an unary function. It inherits the iterator-category
357  // of the underlying iterator.
358  template <class I, class F, class TransformationType, class C = typename std::iterator_traits<I>::iterator_category>
359  class TransformedRangeIterator;
360 
361  template <class I, class F, class TransformationType>
362  class TransformedRangeIterator<I,F,TransformationType,std::forward_iterator_tag>
363  {
364  protected:
365 
366  static decltype(auto) transform(const F& f, const I& it) {
367  if constexpr (std::is_same_v<TransformationType,IteratorTransformationTag>)
368  return f(it);
369  else
370  return f(*it);
371  }
372 
373  public:
374  using iterator_category = std::forward_iterator_tag;
375  using reference = decltype(transform(std::declval<F>(), std::declval<I>()));
376  using value_type = std::decay_t<reference>;
377  using pointer = PointerProxy<value_type>;
378 
379  // If we later want to allow standalone TransformedRangeIterators,
380  // we could customize the FunctionPointer to be a default-constructible,
381  // copy-assignable type storing a function but acting like a pointer
382  // to function.
383  using FunctionPointer = const F*;
384 
385  constexpr TransformedRangeIterator(const I& it, FunctionPointer f) noexcept :
386  it_(it),
387  f_(f)
388  {}
389 
390  // Explicitly initialize members. Using a plain
391  //
392  // constexpr TransformedRangeIterator() noexcept {}
393  //
394  // would default-initialize the members while
395  //
396  // constexpr TransformedRangeIterator() noexcept : it_(), f_() {}
397  //
398  // leads to value-initialization. This is a case where
399  // both are really different. If it_ is a raw pointer (i.e. POD)
400  // then default-initialization leaves it uninitialized while
401  // value-initialization zero-initializes it.
402  constexpr TransformedRangeIterator() noexcept :
403  it_(),
404  f_()
405  {}
406 
407  // Dereferencing returns a value created by the function
408  constexpr reference operator*() const noexcept {
409  return transform(*f_, it_);
410  }
411 
412  // Dereferencing returns a value created by the function
413  pointer operator->() const noexcept {
414  return transform(*f_, it_);
415  }
416 
417  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
418 
419  constexpr bool operator==(const TransformedRangeIterator& other) const noexcept {
420  return (it_ == other.it_);
421  }
422 
423  constexpr bool operator!=(const TransformedRangeIterator& other) const noexcept {
424  return (it_ != other.it_);
425  }
426 
427  TransformedRangeIterator& operator++() noexcept {
428  ++it_;
429  return *this;
430  }
431 
432  TransformedRangeIterator operator++(int) noexcept {
433  TransformedRangeIterator copy(*this);
434  ++(*this);
435  return copy;
436  }
437 
438  protected:
439  I it_;
440  FunctionPointer f_;
441  };
442 
443 
444 
445  template <class I, class F, class T>
446  class TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag> :
447  public TransformedRangeIterator<I,F,T,std::forward_iterator_tag>
448  {
449  protected:
450  using Base = TransformedRangeIterator<I,F,T,std::forward_iterator_tag>;
451  using Base::it_;
452  using Base::f_;
453  public:
454  using iterator_category = std::bidirectional_iterator_tag;
455  using reference = typename Base::reference;
456  using value_type = typename Base::value_type;
457  using pointer = typename Base::pointer;
458 
459  using FunctionPointer = typename Base::FunctionPointer;
460 
461  using Base::Base;
462 
463  // Member functions of the forward_iterator that need
464  // to be redefined because the base class methods return a
465  // forward_iterator.
466  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
467 
468  TransformedRangeIterator& operator++() noexcept {
469  ++it_;
470  return *this;
471  }
472 
473  TransformedRangeIterator operator++(int) noexcept {
474  TransformedRangeIterator copy(*this);
475  ++(*this);
476  return copy;
477  }
478 
479  // Additional member functions of bidirectional_iterator
480  TransformedRangeIterator& operator--() noexcept {
481  --(this->it_);
482  return *this;
483  }
484 
485  TransformedRangeIterator operator--(int) noexcept {
486  TransformedRangeIterator copy(*this);
487  --(*this);
488  return copy;
489  }
490  };
491 
492 
493 
494  template <class I, class F, class T>
495  class TransformedRangeIterator<I,F,T,std::random_access_iterator_tag> :
496  public TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>
497  {
498  protected:
499  using Base = TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>;
500  using Base::it_;
501  using Base::f_;
502  public:
503  using iterator_category = std::random_access_iterator_tag;
504  using reference = typename Base::reference;
505  using value_type = typename Base::value_type;
506  using pointer = typename Base::pointer;
507  using difference_type = typename std::iterator_traits<I>::difference_type;
508 
509  using FunctionPointer = typename Base::FunctionPointer;
510 
511  using Base::Base;
512 
513  // Member functions of the forward_iterator that need
514  // to be redefined because the base class methods return a
515  // forward_iterator.
516  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
517 
518  TransformedRangeIterator& operator++() noexcept {
519  ++it_;
520  return *this;
521  }
522 
523  TransformedRangeIterator operator++(int) noexcept {
524  TransformedRangeIterator copy(*this);
525  ++(*this);
526  return copy;
527  }
528 
529  // Member functions of the bidirectional_iterator that need
530  // to be redefined because the base class methods return a
531  // bidirectional_iterator.
532  TransformedRangeIterator& operator--() noexcept {
533  --(this->it_);
534  return *this;
535  }
536 
537  TransformedRangeIterator operator--(int) noexcept {
538  TransformedRangeIterator copy(*this);
539  --(*this);
540  return copy;
541  }
542 
543  // Additional member functions of random_access_iterator
544  TransformedRangeIterator& operator+=(difference_type n) noexcept {
545  it_ += n;
546  return *this;
547  }
548 
549  TransformedRangeIterator& operator-=(difference_type n) noexcept {
550  it_ -= n;
551  return *this;
552  }
553 
554  bool operator<(const TransformedRangeIterator& other) const noexcept {
555  return it_<other.it_;
556  }
557 
558  bool operator<=(const TransformedRangeIterator& other) const noexcept {
559  return it_<=other.it_;
560  }
561 
562  bool operator>(const TransformedRangeIterator& other) const noexcept {
563  return it_>other.it_;
564  }
565 
566  bool operator>=(const TransformedRangeIterator& other) const noexcept {
567  return it_>=other.it_;
568  }
569 
570  reference operator[](difference_type n) noexcept {
571  return Base::transform(*f_, it_+n);
572  }
573 
574  friend
575  TransformedRangeIterator operator+(const TransformedRangeIterator& it, difference_type n) noexcept {
576  return TransformedRangeIterator(it.it_+n, it.f_);
577  }
578 
579  friend
580  TransformedRangeIterator operator+(difference_type n, const TransformedRangeIterator& it) noexcept {
581  return TransformedRangeIterator(n+it.it_, it.f_);
582  }
583 
584  friend
585  TransformedRangeIterator operator-(const TransformedRangeIterator& it, difference_type n) noexcept {
586  return TransformedRangeIterator(it.it_-n, it.f_);
587  }
588 
589  friend
590  difference_type operator-(const TransformedRangeIterator& first, const TransformedRangeIterator& second) noexcept {
591  return first.it_-second.it_;
592  }
593  };
594 
595 
596  } // namespace Impl
597 
598 
599 
636  template <class R, class F, class T=ValueTransformationTag>
638  {
639  using RawConstIterator = std::decay_t<decltype(std::declval<const R>().begin())>;
640  using RawIterator = std::decay_t<decltype(std::declval<R>().begin())>;
641 
642  public:
643 
650  using const_iterator = Impl::TransformedRangeIterator<RawConstIterator, F, T>;
651 
658  using iterator = Impl::TransformedRangeIterator<RawIterator, F, T>;
659 
666  using RawRange = std::remove_reference_t<R>;
667 
671  template<class RR>
672  constexpr TransformedRangeView(RR&& rawRange, const F& f) noexcept :
673  rawRange_(std::forward<RR>(rawRange)),
674  f_(f)
675  {
676  static_assert(std::is_same_v<T, ValueTransformationTag> or std::is_same_v<T, IteratorTransformationTag>,
677  "The TransformationType passed to TransformedRangeView has to be either ValueTransformationTag or IteratorTransformationTag.");
678  }
679 
688  constexpr const_iterator begin() const noexcept {
689  return const_iterator(rawRange_.begin(), &f_);
690  }
691 
692  constexpr iterator begin() noexcept {
693  return iterator(rawRange_.begin(), &f_);
694  }
695 
704  constexpr const_iterator end() const noexcept {
705  return const_iterator(rawRange_.end(), &f_);
706  }
707 
708  constexpr iterator end() noexcept {
709  return iterator(rawRange_.end(), &f_);
710  }
711 
715  template<class It=const_iterator,
716  std::enable_if_t<std::is_same_v<typename It::iterator_category,std::random_access_iterator_tag>, int> = 0>
717  constexpr decltype(auto) operator[](std::size_t i) const noexcept
718  {
719  return this->begin()[i];
720  }
721 
725  template<class It=iterator,
726  std::enable_if_t<std::is_same_v<typename It::iterator_category,std::random_access_iterator_tag>, int> = 0>
727  constexpr decltype(auto) operator[](std::size_t i) noexcept
728  {
729  return this->begin()[i];
730  }
731 
742  template<class Range=R,
743  class = std::void_t<decltype(std::declval<const Range>().size())>>
744  auto size() const noexcept
745  {
746  return rawRange_.size();
747  }
748 
752  constexpr bool empty() const noexcept
753  {
754  return rawRange_.begin() == rawRange_.end();
755  }
756 
760  const RawRange& rawRange() const noexcept
761  {
762  return rawRange_;
763  }
764 
768  RawRange& rawRange() noexcept
769  {
770  return rawRange_;
771  }
772 
773  private:
774  R rawRange_;
775  F f_;
776  };
777 
806  template <class R, class F>
807  auto transformedRangeView(R&& range, const F& f)
808  {
809  return TransformedRangeView<R, F, ValueTransformationTag>(std::forward<R>(range), f);
810  }
811 
839  template <class R, class F>
840  auto iteratorTransformedRangeView(R&& range, const F& f)
841  {
842  return TransformedRangeView<R, F, IteratorTransformationTag>(std::forward<R>(range), f);
843  }
844 
845 
858  template<class Range>
859  auto sparseRange(Range&& range) {
860  return Dune::iteratorTransformedRangeView(std::forward<Range>(range), [](auto&& it) {
861  return std::tuple<decltype(*it), decltype(it.index())>(*it, it.index());
862  });
863  }
864 
869 }
870 
871 #endif // DUNE_COMMON_RANGE_UTILITIES_HH
dynamic integer range for use in range-based for loops
Definition: rangeutilities.hh:175
constexpr iterator begin() const noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:192
constexpr iterator end() const noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:194
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:182
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:180
constexpr value_type operator[](const value_type &i) const noexcept
access specified element
Definition: rangeutilities.hh:197
constexpr bool contains(value_type index) const noexcept
check whether given index is within range [from, to)
Definition: rangeutilities.hh:205
constexpr bool empty() const noexcept
check whether the range is empty
Definition: rangeutilities.hh:200
constexpr IntegralRange(std::pair< value_type, value_type > range) noexcept
construct integer range std::pair
Definition: rangeutilities.hh:189
constexpr IntegralRange(value_type from, value_type to) noexcept
construct integer range [from, to)
Definition: rangeutilities.hh:185
constexpr size_type size() const noexcept
obtain number of elements in the range
Definition: rangeutilities.hh:202
constexpr IntegralRange(value_type to) noexcept
construct integer range [0, to)
Definition: rangeutilities.hh:187
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:178
static integer range for use in range-based for loops
Definition: rangeutilities.hh:228
decltype(shift_integer_sequence< from >(std::make_integer_sequence< T, to-from >())) typedef integer_sequence
type of corresponding std::integer_sequence
Definition: rangeutilities.hh:241
static constexpr iterator end() noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:257
static constexpr bool contains(value_type index) noexcept
check whether given index is within range [from, to)
Definition: rangeutilities.hh:276
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:238
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:234
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:261
static constexpr std::integral_constant< bool, from==to > empty() noexcept
check whether the range is empty
Definition: rangeutilities.hh:271
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:273
static constexpr iterator begin() noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:255
static constexpr integer_sequence to_integer_sequence() noexcept
return corresponding std::integer_sequence
Definition: rangeutilities.hh:252
constexpr value_type operator[](const size_type &i) const noexcept
access specified element (dynamic version)
Definition: rangeutilities.hh:268
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:236
A range transforming the values of another range on-the-fly.
Definition: rangeutilities.hh:638
std::remove_reference_t< R > RawRange
Export type of the wrapped untransformed range.
Definition: rangeutilities.hh:666
Impl::TransformedRangeIterator< RawConstIterator, F, T > const_iterator
Const iterator type.
Definition: rangeutilities.hh:650
const RawRange & rawRange() const noexcept
Export the wrapped untransformed range.
Definition: rangeutilities.hh:760
constexpr TransformedRangeView(RR &&rawRange, const F &f) noexcept
Construct from range and function.
Definition: rangeutilities.hh:672
Impl::TransformedRangeIterator< RawIterator, F, T > iterator
Iterator type.
Definition: rangeutilities.hh:658
constexpr const_iterator begin() const noexcept
Obtain a iterator to the first element.
Definition: rangeutilities.hh:688
auto size() const noexcept
Obtain the size of the range.
Definition: rangeutilities.hh:744
RawRange & rawRange() noexcept
Export the wrapped untransformed range.
Definition: rangeutilities.hh:768
constexpr const_iterator end() const noexcept
Obtain a iterator past the last element.
Definition: rangeutilities.hh:704
constexpr bool empty() const noexcept
Checks whether the range is empty.
Definition: rangeutilities.hh:752
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:259
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:683
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:637
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:237
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:705
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:660
auto sparseRange(Range &&range)
Allow structured-binding for-loops for sparse iterators.
Definition: rangeutilities.hh:859
auto iteratorTransformedRangeView(R &&range, const F &f)
Create a TransformedRangeView using an iterator transformation.
Definition: rangeutilities.hh:840
auto transformedRangeView(R &&range, const F &f)
Create a TransformedRangeView.
Definition: rangeutilities.hh:807
Dune namespace.
Definition: alignedallocator.hh:13
Tag to enable iterator based transformations in TransformedRangeView.
Definition: rangeutilities.hh:331
Tag to enable value based transformations in TransformedRangeView.
Definition: rangeutilities.hh:326
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)