3 #ifndef DUNE_COMMON_RANGE_UTILITIES_HH
4 #define DUNE_COMMON_RANGE_UTILITIES_HH
33 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
34 typename T::value_type
36 using std::max_element;
37 return *max_element(v.begin(), v.end());
41 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
50 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
51 typename T::value_type
53 using std::min_element;
54 return *min_element(v.begin(), v.end());
58 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
67 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
70 for (
const auto & e : v)
76 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
77 bool any_true(
const T & v) {
return v; }
79 template<std::
size_t N>
91 typename std::enable_if<IsIterable<T>::value,
int>::type = 0>
94 for (
const auto & e : v)
100 typename std::enable_if<!IsIterable<T>::value,
int>::type = 0>
101 bool all_true(
const T & v) {
return v; }
103 template<std::
size_t N>
115 class IntegralRangeIterator
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;
124 constexpr IntegralRangeIterator() noexcept : value_(0) {}
125 constexpr
explicit IntegralRangeIterator(value_type value) noexcept : value_(value) {}
127 pointer operator->() const noexcept {
return &value_; }
128 constexpr reference
operator*() const noexcept {
return value_; }
130 constexpr reference operator[]( difference_type n )
const noexcept {
return (value_ + n); }
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_); }
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_); }
140 IntegralRangeIterator& operator++() noexcept { ++value_;
return *
this; }
141 IntegralRangeIterator operator++(
int) noexcept { IntegralRangeIterator copy( *
this ); ++(*this);
return copy; }
143 IntegralRangeIterator& operator--() noexcept { --value_;
return *
this; }
144 IntegralRangeIterator operator--(
int) noexcept { IntegralRangeIterator copy( *
this ); --(*this);
return copy; }
146 IntegralRangeIterator& operator+=(difference_type n) noexcept { value_ += n;
return *
this; }
147 IntegralRangeIterator& operator-=(difference_type n) noexcept { value_ -= n;
return *
this; }
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); }
153 constexpr difference_type
operator-(
const IntegralRangeIterator &other)
const noexcept {
return (
static_cast<difference_type
>(value_) -
static_cast<difference_type
>(other.value_)); }
198 constexpr
bool empty() const noexcept {
return (from_ == to_); }
221 template <
class T, T to, T from = 0>
224 template <T ofs, T... i>
225 static std::integer_sequence<T, (i+ofs)...> shift_integer_sequence(std::integer_sequence<T, i...>);
236 typedef decltype(shift_integer_sequence<from>(std::make_integer_sequence<T, to-from>()))
integer_sequence;
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)>
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 {}; }
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>
285 template<
class T, std::enable_if_t<std::is_
integral<std::decay_t<T>>::value,
int> = 0>
291 template<
class T, std::enable_if_t<std::is_enum<std::decay_t<T>>::value,
int> = 0>
297 template<
class T, T from, T to>
303 template<
class T, T to>
328 template<
class ProxyType>
332 PointerProxy(ProxyType&& p) : p_(p)
335 ProxyType* operator->()
346 template <class I, class F, class TransformationType, class C = typename std::iterator_traits<I>::iterator_category>
347 class TransformedRangeIterator;
349 template <
class I,
class F,
class TransformationType>
350 class TransformedRangeIterator<I,F,TransformationType,std::forward_iterator_tag>
354 static decltype(
auto) transform(const F& f, const I& it) {
355 if constexpr (std::is_same_v<TransformationType,IteratorTransformationTag>)
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>;
371 using FunctionPointer =
const F*;
373 constexpr TransformedRangeIterator(
const I& it, FunctionPointer f) noexcept :
390 constexpr TransformedRangeIterator() noexcept :
396 constexpr reference
operator*() const noexcept {
397 return transform(*f_, it_);
401 pointer operator->() const noexcept {
402 return transform(*f_, it_);
405 constexpr TransformedRangeIterator& operator=(
const TransformedRangeIterator& other) =
default;
407 constexpr
bool operator==(
const TransformedRangeIterator& other)
const noexcept {
408 return (it_ == other.it_);
411 constexpr
bool operator!=(
const TransformedRangeIterator& other)
const noexcept {
412 return (it_ != other.it_);
415 TransformedRangeIterator& operator++() noexcept {
420 TransformedRangeIterator operator++(
int) noexcept {
421 TransformedRangeIterator copy(*
this);
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>
438 using Base = TransformedRangeIterator<I,F,T,std::forward_iterator_tag>;
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;
447 using FunctionPointer =
typename Base::FunctionPointer;
454 constexpr TransformedRangeIterator& operator=(
const TransformedRangeIterator& other) =
default;
456 TransformedRangeIterator& operator++() noexcept {
461 TransformedRangeIterator operator++(
int) noexcept {
462 TransformedRangeIterator copy(*
this);
468 TransformedRangeIterator& operator--() noexcept {
473 TransformedRangeIterator operator--(
int) noexcept {
474 TransformedRangeIterator copy(*
this);
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>
487 using Base = TransformedRangeIterator<I,F,T,std::bidirectional_iterator_tag>;
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;
497 using FunctionPointer =
typename Base::FunctionPointer;
504 constexpr TransformedRangeIterator& operator=(
const TransformedRangeIterator& other) =
default;
506 TransformedRangeIterator& operator++() noexcept {
511 TransformedRangeIterator operator++(
int) noexcept {
512 TransformedRangeIterator copy(*
this);
520 TransformedRangeIterator& operator--() noexcept {
525 TransformedRangeIterator operator--(
int) noexcept {
526 TransformedRangeIterator copy(*
this);
532 TransformedRangeIterator& operator+=(difference_type n) noexcept {
537 TransformedRangeIterator& operator-=(difference_type n) noexcept {
542 bool operator<(
const TransformedRangeIterator& other) noexcept {
543 return it_<other.it_;
546 bool operator<=(
const TransformedRangeIterator& other) noexcept {
547 return it_<=other.it_;
550 bool operator>(
const TransformedRangeIterator& other) noexcept {
551 return it_>other.it_;
554 bool operator>=(
const TransformedRangeIterator& other) noexcept {
555 return it_>=other.it_;
558 reference operator[](difference_type n) noexcept {
559 return Base::transform(*f_, it_+n);
563 TransformedRangeIterator
operator+(
const TransformedRangeIterator& it, difference_type n) noexcept {
564 return TransformedRangeIterator(it.it_+n, it.f_);
568 TransformedRangeIterator
operator+(difference_type n,
const TransformedRangeIterator& it) noexcept {
569 return TransformedRangeIterator(n+it.it_, it.f_);
573 TransformedRangeIterator
operator-(
const TransformedRangeIterator& it, difference_type n) noexcept {
574 return TransformedRangeIterator(it.it_-n, it.f_);
578 difference_type
operator-(
const TransformedRangeIterator& first,
const TransformedRangeIterator& second) noexcept {
579 return first.it_-second.it_;
624 template <
class R,
class F,
class T=ValueTransformationTag>
627 using RawConstIterator = std::decay_t<decltype(std::declval<const R>().
begin())>;
628 using RawIterator = std::decay_t<decltype(std::declval<R>().begin())>;
646 using iterator = Impl::TransformedRangeIterator<RawIterator, F, T>;
661 rawRange_(std::forward<RR>(
rawRange)),
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.");
681 return iterator(rawRange_.begin(), &f_);
697 return iterator(rawRange_.end(), &f_);
710 template<
class Dummy=R,
711 class = std::void_t<decltype(std::declval<Dummy>().size())>>
714 return rawRange_.size();
766 template <
class R,
class F>
799 template <
class R,
class F>
818 template<
class Range>
821 return std::tuple<decltype(*it), decltype(it.index())>(*it, it.index());
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