Dune Core Modules (2.9.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 // SPDX-FileCopyrightInfo: Copyright (C) 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 
204  private:
205  value_type from_, to_;
206  };
207 
208 
223  template <class T, T to, T from = 0>
225  {
226  template <T ofs, T... i>
227  static std::integer_sequence<T, (i+ofs)...> shift_integer_sequence(std::integer_sequence<T, i...>);
228 
229  public:
231  typedef T value_type;
233  typedef Impl::IntegralRangeIterator<T> iterator;
235  typedef std::make_unsigned_t<T> size_type;
236 
238  typedef decltype(shift_integer_sequence<from>(std::make_integer_sequence<T, to-from>())) integer_sequence;
239 
241  constexpr StaticIntegralRange() noexcept = default;
242 
244  constexpr operator IntegralRange<T>() const noexcept { return {from, to}; }
246  constexpr operator integer_sequence() const noexcept { return {}; }
247 
249  static constexpr iterator begin() noexcept { return iterator(from); }
251  static constexpr iterator end() noexcept { return iterator(to); }
252 
254  template <class U, U i>
255  constexpr auto operator[](const std::integral_constant<U, i> &) const noexcept
256  -> std::integral_constant<value_type, from + static_cast<value_type>(i)>
257  {
258  return {};
259  }
260 
262  constexpr value_type operator[](const size_type &i) const noexcept { return (from + static_cast<value_type>(i)); }
263 
265  static constexpr std::integral_constant<bool, from == to> empty() noexcept { return {}; }
267  static constexpr std::integral_constant<size_type, static_cast<size_type>(to) - static_cast<size_type>(from) > size() noexcept { return {}; }
268  };
269 
279  template<class T, class U,
280  std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>::value, int> = 0,
281  std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
282  inline static IntegralRange<std::decay_t<T>> range(T &&from, U &&to) noexcept
283  {
284  return IntegralRange<std::decay_t<T>>(std::forward<T>(from), std::forward<U>(to));
285  }
286 
287  template<class T, std::enable_if_t<std::is_integral<std::decay_t<T>>::value, int> = 0>
288  inline static IntegralRange<std::decay_t<T>> range(T &&to) noexcept
289  {
290  return IntegralRange<std::decay_t<T>>(std::forward<T>(to));
291  }
292 
293  template<class T, std::enable_if_t<std::is_enum<std::decay_t<T>>::value, int> = 0>
294  inline static IntegralRange<std::underlying_type_t<std::decay_t<T>>> range(T &&to) noexcept
295  {
296  return IntegralRange<std::underlying_type_t<std::decay_t<T>>>(std::forward<T>(to));
297  }
298 
299  template<class T, T from, T to>
300  inline static StaticIntegralRange<T, to, from> range(std::integral_constant<T, from>, std::integral_constant<T, to>) noexcept
301  {
302  return {};
303  }
304 
305  template<class T, T to>
306  inline static StaticIntegralRange<T, to> range(std::integral_constant<T, to>) noexcept
307  {
308  return {};
309  }
310 
311 
312 
317 
322 
323  namespace Impl
324  {
325 
326  // Helper class to mimic a pointer for proxy objects.
327  // This is needed to implement operator-> on an iterator
328  // using proxy-values. It stores the proxy value but
329  // provides operator-> like a pointer.
330  template<class ProxyType>
331  class PointerProxy
332  {
333  public:
334  PointerProxy(ProxyType&& p) : p_(p)
335  {}
336 
337  ProxyType* operator->()
338  {
339  return &p_;
340  }
341 
342  ProxyType p_;
343  };
344 
345  // An iterator transforming a wrapped iterator using
346  // an unary function. It inherits the iterator-category
347  // of the underlying iterator.
348  template <class I, class F, class TransformationType, class C = typename std::iterator_traits<I>::iterator_category>
349  class TransformedRangeIterator;
350 
351  template <class I, class F, class TransformationType>
352  class TransformedRangeIterator<I,F,TransformationType,std::forward_iterator_tag>
353  {
354  protected:
355 
356  static decltype(auto) transform(const F& f, const I& it) {
357  if constexpr (std::is_same_v<TransformationType,IteratorTransformationTag>)
358  return f(it);
359  else
360  return f(*it);
361  }
362 
363  public:
364  using iterator_category = std::forward_iterator_tag;
365  using reference = decltype(transform(std::declval<F>(), std::declval<I>()));
366  using value_type = std::decay_t<reference>;
367  using pointer = PointerProxy<value_type>;
368 
369  // If we later want to allow standalone TransformedRangeIterators,
370  // we could customize the FunctionPointer to be a default-constructible,
371  // copy-assignable type storing a function but acting like a pointer
372  // to function.
373  using FunctionPointer = const F*;
374 
375  constexpr TransformedRangeIterator(const I& it, FunctionPointer f) noexcept :
376  it_(it),
377  f_(f)
378  {}
379 
380  // Explicitly initialize members. Using a plain
381  //
382  // constexpr TransformedRangeIterator() noexcept {}
383  //
384  // would default-initialize the members while
385  //
386  // constexpr TransformedRangeIterator() noexcept : it_(), f_() {}
387  //
388  // leads to value-initialization. This is a case where
389  // both are really different. If it_ is a raw pointer (i.e. POD)
390  // then default-initialization leaves it uninitialized while
391  // value-initialization zero-initializes it.
392  constexpr TransformedRangeIterator() noexcept :
393  it_(),
394  f_()
395  {}
396 
397  // Dereferencing returns a value created by the function
398  constexpr reference operator*() const noexcept {
399  return transform(*f_, it_);
400  }
401 
402  // Dereferencing returns a value created by the function
403  pointer operator->() const noexcept {
404  return transform(*f_, it_);
405  }
406 
407  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
408 
409  constexpr bool operator==(const TransformedRangeIterator& other) const noexcept {
410  return (it_ == other.it_);
411  }
412 
413  constexpr bool operator!=(const TransformedRangeIterator& other) const noexcept {
414  return (it_ != other.it_);
415  }
416 
417  TransformedRangeIterator& operator++() noexcept {
418  ++it_;
419  return *this;
420  }
421 
422  TransformedRangeIterator operator++(int) noexcept {
423  TransformedRangeIterator copy(*this);
424  ++(*this);
425  return copy;
426  }
427 
428  protected:
429  I it_;
430  FunctionPointer f_;
431  };
432 
433 
434 
435  template <class I, class F, class T>
436  class TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag> :
437  public TransformedRangeIterator<I,F,T,std::forward_iterator_tag>
438  {
439  protected:
440  using Base = TransformedRangeIterator<I,F,T,std::forward_iterator_tag>;
441  using Base::it_;
442  using Base::f_;
443  public:
444  using iterator_category = std::bidirectional_iterator_tag;
445  using reference = typename Base::reference;
446  using value_type = typename Base::value_type;
447  using pointer = typename Base::pointer;
448 
449  using FunctionPointer = typename Base::FunctionPointer;
450 
451  using Base::Base;
452 
453  // Member functions of the forward_iterator that need
454  // to be redefined because the base class methods return a
455  // forward_iterator.
456  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
457 
458  TransformedRangeIterator& operator++() noexcept {
459  ++it_;
460  return *this;
461  }
462 
463  TransformedRangeIterator operator++(int) noexcept {
464  TransformedRangeIterator copy(*this);
465  ++(*this);
466  return copy;
467  }
468 
469  // Additional member functions of bidirectional_iterator
470  TransformedRangeIterator& operator--() noexcept {
471  --(this->it_);
472  return *this;
473  }
474 
475  TransformedRangeIterator operator--(int) noexcept {
476  TransformedRangeIterator copy(*this);
477  --(*this);
478  return copy;
479  }
480  };
481 
482 
483 
484  template <class I, class F, class T>
485  class TransformedRangeIterator<I,F,T,std::random_access_iterator_tag> :
486  public TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>
487  {
488  protected:
489  using Base = TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>;
490  using Base::it_;
491  using Base::f_;
492  public:
493  using iterator_category = std::random_access_iterator_tag;
494  using reference = typename Base::reference;
495  using value_type = typename Base::value_type;
496  using pointer = typename Base::pointer;
497  using difference_type = typename std::iterator_traits<I>::difference_type;
498 
499  using FunctionPointer = typename Base::FunctionPointer;
500 
501  using Base::Base;
502 
503  // Member functions of the forward_iterator that need
504  // to be redefined because the base class methods return a
505  // forward_iterator.
506  constexpr TransformedRangeIterator& operator=(const TransformedRangeIterator& other) = default;
507 
508  TransformedRangeIterator& operator++() noexcept {
509  ++it_;
510  return *this;
511  }
512 
513  TransformedRangeIterator operator++(int) noexcept {
514  TransformedRangeIterator copy(*this);
515  ++(*this);
516  return copy;
517  }
518 
519  // Member functions of the bidirectional_iterator that need
520  // to be redefined because the base class methods return a
521  // bidirectional_iterator.
522  TransformedRangeIterator& operator--() noexcept {
523  --(this->it_);
524  return *this;
525  }
526 
527  TransformedRangeIterator operator--(int) noexcept {
528  TransformedRangeIterator copy(*this);
529  --(*this);
530  return copy;
531  }
532 
533  // Additional member functions of random_access_iterator
534  TransformedRangeIterator& operator+=(difference_type n) noexcept {
535  it_ += n;
536  return *this;
537  }
538 
539  TransformedRangeIterator& operator-=(difference_type n) noexcept {
540  it_ -= n;
541  return *this;
542  }
543 
544  bool operator<(const TransformedRangeIterator& other) noexcept {
545  return it_<other.it_;
546  }
547 
548  bool operator<=(const TransformedRangeIterator& other) noexcept {
549  return it_<=other.it_;
550  }
551 
552  bool operator>(const TransformedRangeIterator& other) noexcept {
553  return it_>other.it_;
554  }
555 
556  bool operator>=(const TransformedRangeIterator& other) noexcept {
557  return it_>=other.it_;
558  }
559 
560  reference operator[](difference_type n) noexcept {
561  return Base::transform(*f_, it_+n);
562  }
563 
564  friend
565  TransformedRangeIterator operator+(const TransformedRangeIterator& it, difference_type n) noexcept {
566  return TransformedRangeIterator(it.it_+n, it.f_);
567  }
568 
569  friend
570  TransformedRangeIterator operator+(difference_type n, const TransformedRangeIterator& it) noexcept {
571  return TransformedRangeIterator(n+it.it_, it.f_);
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  difference_type operator-(const TransformedRangeIterator& first, const TransformedRangeIterator& second) noexcept {
581  return first.it_-second.it_;
582  }
583  };
584 
585 
586  } // namespace Impl
587 
588 
589 
626  template <class R, class F, class T=ValueTransformationTag>
628  {
629  using RawConstIterator = std::decay_t<decltype(std::declval<const R>().begin())>;
630  using RawIterator = std::decay_t<decltype(std::declval<R>().begin())>;
631 
632  public:
633 
640  using const_iterator = Impl::TransformedRangeIterator<RawConstIterator, F, T>;
641 
648  using iterator = Impl::TransformedRangeIterator<RawIterator, F, T>;
649 
656  using RawRange = std::remove_reference_t<R>;
657 
661  template<class RR>
662  constexpr TransformedRangeView(RR&& rawRange, const F& f) noexcept :
663  rawRange_(std::forward<RR>(rawRange)),
664  f_(f)
665  {
666  static_assert(std::is_same_v<T, ValueTransformationTag> or std::is_same_v<T, IteratorTransformationTag>,
667  "The TransformationType passed to TransformedRangeView has to be either ValueTransformationTag or IteratorTransformationTag.");
668  }
669 
678  constexpr const_iterator begin() const noexcept {
679  return const_iterator(rawRange_.begin(), &f_);
680  }
681 
682  constexpr iterator begin() noexcept {
683  return iterator(rawRange_.begin(), &f_);
684  }
685 
694  constexpr const_iterator end() const noexcept {
695  return const_iterator(rawRange_.end(), &f_);
696  }
697 
698  constexpr iterator end() noexcept {
699  return iterator(rawRange_.end(), &f_);
700  }
701 
712  template<class Dummy=R,
713  class = std::void_t<decltype(std::declval<Dummy>().size())>>
714  auto size() const
715  {
716  return rawRange_.size();
717  }
718 
722  const RawRange& rawRange() const
723  {
724  return rawRange_;
725  }
726 
731  {
732  return rawRange_;
733  }
734 
735  private:
736  R rawRange_;
737  F f_;
738  };
739 
768  template <class R, class F>
769  auto transformedRangeView(R&& range, const F& f)
770  {
771  return TransformedRangeView<R, F, ValueTransformationTag>(std::forward<R>(range), f);
772  }
773 
801  template <class R, class F>
802  auto iteratorTransformedRangeView(R&& range, const F& f)
803  {
804  return TransformedRangeView<R, F, IteratorTransformationTag>(std::forward<R>(range), f);
805  }
806 
807 
820  template<class Range>
821  auto sparseRange(Range&& range) {
822  return Dune::iteratorTransformedRangeView(std::forward<Range>(range), [](auto&& it) {
823  return std::tuple<decltype(*it), decltype(it.index())>(*it, it.index());
824  });
825  }
826 
831 }
832 
833 #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 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:225
decltype(shift_integer_sequence< from >(std::make_integer_sequence< T, to-from >())) typedef integer_sequence
type of corresponding std::integer_sequence
Definition: rangeutilities.hh:238
static constexpr iterator end() noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:251
std::make_unsigned_t< T > size_type
unsigned integer type corresponding to value_type
Definition: rangeutilities.hh:235
T value_type
type of integers contained in the range
Definition: rangeutilities.hh:231
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:255
static constexpr std::integral_constant< bool, from==to > empty() noexcept
check whether the range is empty
Definition: rangeutilities.hh:265
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:267
static constexpr iterator begin() noexcept
obtain a random-access iterator to the first element
Definition: rangeutilities.hh:249
constexpr value_type operator[](const size_type &i) const noexcept
access specified element (dynamic version)
Definition: rangeutilities.hh:262
Impl::IntegralRangeIterator< T > iterator
type of iterator
Definition: rangeutilities.hh:233
A range transforming the values of another range on-the-fly.
Definition: rangeutilities.hh:628
auto size() const
Obtain the size of the range.
Definition: rangeutilities.hh:714
std::remove_reference_t< R > RawRange
Export type of the wrapped untransformed range.
Definition: rangeutilities.hh:656
Impl::TransformedRangeIterator< RawConstIterator, F, T > const_iterator
Const iterator type.
Definition: rangeutilities.hh:640
constexpr TransformedRangeView(RR &&rawRange, const F &f) noexcept
Construct from range and function.
Definition: rangeutilities.hh:662
Impl::TransformedRangeIterator< RawIterator, F, T > iterator
Iterator type.
Definition: rangeutilities.hh:648
constexpr const_iterator begin() const noexcept
Obtain a iterator to the first element.
Definition: rangeutilities.hh:678
RawRange & rawRange()
Export the wrapped untransformed range.
Definition: rangeutilities.hh:730
const RawRange & rawRange() const
Export the wrapped untransformed range.
Definition: rangeutilities.hh:722
constexpr const_iterator end() const noexcept
Obtain a iterator past the last element.
Definition: rangeutilities.hh:694
Traits for type conversions and type information.
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:821
auto iteratorTransformedRangeView(R &&range, const F &f)
Create a TransformedRangeView using an iterator transformation.
Definition: rangeutilities.hh:802
auto transformedRangeView(R &&range, const F &f)
Create a TransformedRangeView.
Definition: rangeutilities.hh:769
Dune namespace.
Definition: alignedallocator.hh:13
std::vector< decltype(std::declval< Op >)(std::declval< T >))) > transform(const std::vector< T > &in, Op op)
copy a vector, performing an operation on each element
Definition: misc.hh:24
Tag to enable iterator based transformations in TransformedRangeView.
Definition: rangeutilities.hh:321
Tag to enable value based transformations in TransformedRangeView.
Definition: rangeutilities.hh:316
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 26, 22:29, 2024)