DUNE PDELab (2.8)

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
19namespace 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>
292 inline static IntegralRange<std::underlying_type_t<std::decay_t<T>>> range(T &&to) noexcept
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 {
802 return TransformedRangeView<R, F, IteratorTransformationTag>(std::forward<R>(range), f);
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
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
static constexpr iterator end() noexcept
obtain a random-access iterator past the last element
Definition: rangeutilities.hh:249
decltype(shift_integer_sequence< from >(std::make_integer_sequence< T, to-from >())) integer_sequence
type of corresponding std::integer_sequence
Definition: rangeutilities.hh:236
constexpr StaticIntegralRange() noexcept=default
default constructor
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 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
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
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
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 TransformedRangeView(RR &&rawRange, const F &f) noexcept
Construct from range and function.
Definition: rangeutilities.hh:660
const RawRange & rawRange() const
Export the wrapped untransformed range.
Definition: rangeutilities.hh:720
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
constexpr const_iterator end() const noexcept
Obtain a iterator past the last element.
Definition: rangeutilities.hh:692
RawRange & rawRange()
Export the wrapped untransformed range.
Definition: rangeutilities.hh:728
Traits for type conversions and type information.
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 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:658
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 ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:257
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
Dune namespace.
Definition: alignedallocator.hh:11
STL namespace.
Tag to enable iterator based transformations in TransformedRangeView.
Definition: rangeutilities.hh:319
Tag to enable value based transformations in TransformedRangeView.
Definition: rangeutilities.hh:314
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 24, 22:29, 2024)