5#ifndef DUNE_COMMON_RANGE_UTILITIES_HH
6#define DUNE_COMMON_RANGE_UTILITIES_HH
35 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
36 typename T::value_type
38 using std::max_element;
39 return *max_element(v.begin(), v.end());
43 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
52 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
53 typename T::value_type
55 using std::min_element;
56 return *min_element(v.begin(), v.end());
60 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
69 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
72 for (
const auto & e : v)
78 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
79 bool any_true(
const T & v) {
return v; }
81 template<std::
size_t N>
93 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
96 for (
const auto & e : v)
101 template <
typename T,
102 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
103 bool all_true(
const T & v) {
return v; }
105 template<std::
size_t N>
117 class IntegralRangeIterator
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;
126 constexpr IntegralRangeIterator() noexcept : value_(0) {}
127 constexpr explicit IntegralRangeIterator(value_type value) noexcept : value_(value) {}
129 pointer operator->() const noexcept {
return &value_; }
130 constexpr reference
operator*() const noexcept {
return value_; }
132 constexpr reference operator[]( difference_type n )
const noexcept {
return (value_ + n); }
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_); }
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_); }
142 IntegralRangeIterator& operator++() noexcept { ++value_;
return *
this; }
143 IntegralRangeIterator operator++(
int)
noexcept { IntegralRangeIterator copy( *
this ); ++(*this);
return copy; }
145 IntegralRangeIterator& operator--() noexcept { --value_;
return *
this; }
146 IntegralRangeIterator operator--(
int)
noexcept { IntegralRangeIterator copy( *
this ); --(*this);
return copy; }
148 IntegralRangeIterator& operator+=(difference_type n)
noexcept { value_ += n;
return *
this; }
149 IntegralRangeIterator& operator-=(difference_type n)
noexcept { value_ -= n;
return *
this; }
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); }
155 constexpr difference_type
operator-(
const IntegralRangeIterator &other)
const noexcept {
return (
static_cast<difference_type
>(value_) -
static_cast<difference_type
>(other.value_)); }
200 constexpr bool empty() const noexcept {
return (from_ == to_); }
223 template <
class T, T to, T from = 0>
226 template <T ofs, T... i>
227 static std::integer_sequence<T, (i+ofs)...> shift_integer_sequence(std::integer_sequence<T, i...>);
238 typedef decltype(shift_integer_sequence<from>(std::make_integer_sequence<T, to-from>()))
integer_sequence;
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)>
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 {}; }
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>
287 template<
class T, std::enable_if_t<std::is_
integral<std::decay_t<T>>::value,
int> = 0>
293 template<
class T, std::enable_if_t<std::is_enum<std::decay_t<T>>::value,
int> = 0>
299 template<
class T, T from, T to>
305 template<
class T, T to>
330 template<
class ProxyType>
334 PointerProxy(ProxyType&& p) : p_(p)
337 ProxyType* operator->()
348 template <class I, class F, class TransformationType, class C = typename std::iterator_traits<I>::iterator_category>
349 class TransformedRangeIterator;
351 template <
class I,
class F,
class TransformationType>
352 class TransformedRangeIterator<I,F,TransformationType,
std::forward_iterator_tag>
356 static decltype(
auto) transform(
const F& f,
const I& it) {
357 if constexpr (std::is_same_v<TransformationType,IteratorTransformationTag>)
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>;
373 using FunctionPointer =
const F*;
375 constexpr TransformedRangeIterator(
const I& it, FunctionPointer f) noexcept :
392 constexpr TransformedRangeIterator() noexcept :
398 constexpr reference
operator*() const noexcept {
399 return transform(*f_, it_);
403 pointer operator->() const noexcept {
404 return transform(*f_, it_);
407 constexpr TransformedRangeIterator& operator=(
const TransformedRangeIterator& other) =
default;
409 constexpr bool operator==(
const TransformedRangeIterator& other)
const noexcept {
410 return (it_ == other.it_);
413 constexpr bool operator!=(
const TransformedRangeIterator& other)
const noexcept {
414 return (it_ != other.it_);
417 TransformedRangeIterator& operator++() noexcept {
422 TransformedRangeIterator operator++(
int)
noexcept {
423 TransformedRangeIterator copy(*
this);
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>
440 using Base = TransformedRangeIterator<I,F,T,std::forward_iterator_tag>;
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;
449 using FunctionPointer =
typename Base::FunctionPointer;
456 constexpr TransformedRangeIterator& operator=(
const TransformedRangeIterator& other) =
default;
458 TransformedRangeIterator& operator++() noexcept {
463 TransformedRangeIterator operator++(
int)
noexcept {
464 TransformedRangeIterator copy(*
this);
470 TransformedRangeIterator& operator--() noexcept {
475 TransformedRangeIterator operator--(
int)
noexcept {
476 TransformedRangeIterator copy(*
this);
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>
489 using Base = TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>;
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;
499 using FunctionPointer =
typename Base::FunctionPointer;
506 constexpr TransformedRangeIterator& operator=(
const TransformedRangeIterator& other) =
default;
508 TransformedRangeIterator& operator++() noexcept {
513 TransformedRangeIterator operator++(
int)
noexcept {
514 TransformedRangeIterator copy(*
this);
522 TransformedRangeIterator& operator--() noexcept {
527 TransformedRangeIterator operator--(
int)
noexcept {
528 TransformedRangeIterator copy(*
this);
534 TransformedRangeIterator& operator+=(difference_type n)
noexcept {
539 TransformedRangeIterator& operator-=(difference_type n)
noexcept {
544 bool operator<(
const TransformedRangeIterator& other)
noexcept {
545 return it_<other.it_;
548 bool operator<=(
const TransformedRangeIterator& other)
noexcept {
549 return it_<=other.it_;
552 bool operator>(
const TransformedRangeIterator& other)
noexcept {
553 return it_>other.it_;
556 bool operator>=(
const TransformedRangeIterator& other)
noexcept {
557 return it_>=other.it_;
560 reference operator[](difference_type n)
noexcept {
561 return Base::transform(*f_, it_+n);
565 TransformedRangeIterator
operator+(
const TransformedRangeIterator& it, difference_type n)
noexcept {
566 return TransformedRangeIterator(it.it_+n, it.f_);
570 TransformedRangeIterator
operator+(difference_type n,
const TransformedRangeIterator& it)
noexcept {
571 return TransformedRangeIterator(n+it.it_, it.f_);
575 TransformedRangeIterator
operator-(
const TransformedRangeIterator& it, difference_type n)
noexcept {
576 return TransformedRangeIterator(it.it_-n, it.f_);
580 difference_type
operator-(
const TransformedRangeIterator& first,
const TransformedRangeIterator& second)
noexcept {
581 return first.it_-second.it_;
626 template <
class R,
class F,
class T=ValueTransformationTag>
629 using RawConstIterator = std::decay_t<decltype(std::declval<const R>().
begin())>;
630 using RawIterator = std::decay_t<decltype(std::declval<R>().begin())>;
648 using iterator = Impl::TransformedRangeIterator<RawIterator, F, T>;
663 rawRange_(std::forward<RR>(
rawRange)),
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.");
683 return iterator(rawRange_.begin(), &f_);
699 return iterator(rawRange_.end(), &f_);
712 template<
class Dummy=R,
713 class = std::void_t<decltype(std::declval<Dummy>().size())>>
716 return rawRange_.size();
768 template <
class R,
class F>
801 template <
class R,
class F>
820 template<
class Range>
823 return std::tuple<
decltype(*it),
decltype(it.index())>(*it, it.index());
Traits for type conversions and type information.
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
static StaticIntegralRange< T, to, from > range(std::integral_constant< T, from >, std::integral_constant< T, to >) noexcept
Definition rangeutilities.hh:300
bigunsignedint< k > operator*(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:549
bigunsignedint< k > operator-(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:542
bigunsignedint< k > operator+(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:535
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 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:660
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 ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition iteratorfacades.hh:259
Dune namespace.
Definition alignedallocator.hh:13
bool any_true(const AlignedNumber< bool, align > &val)
Definition debugalign.hh:493
bool all_true(const AlignedNumber< bool, align > &val)
Definition debugalign.hh:499
T max_value(const AlignedNumber< T, align > &val)
Definition debugalign.hh:481
T min_value(const AlignedNumber< T, align > &val)
Definition debugalign.hh:487
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
static constexpr iterator end() noexcept
obtain a random-access iterator past the last element
Definition rangeutilities.hh:251
decltype(shift_integer_sequence< from >(std::make_integer_sequence< T, to-from >())) integer_sequence
type of corresponding std::integer_sequence
Definition rangeutilities.hh:238
constexpr StaticIntegralRange() noexcept=default
default constructor
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 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
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
Tag to enable value based transformations in TransformedRangeView.
Definition rangeutilities.hh:316
Tag to enable iterator based transformations in TransformedRangeView.
Definition rangeutilities.hh:321
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
constexpr iterator end() noexcept
Definition rangeutilities.hh:698
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 iterator begin() noexcept
Definition rangeutilities.hh:682
constexpr TransformedRangeView(RR &&rawRange, const F &f) noexcept
Construct from range and function.
Definition rangeutilities.hh:662
const RawRange & rawRange() const
Export the wrapped untransformed range.
Definition rangeutilities.hh:722
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
constexpr const_iterator end() const noexcept
Obtain a iterator past the last element.
Definition rangeutilities.hh:694
RawRange & rawRange()
Export the wrapped untransformed range.
Definition rangeutilities.hh:730