6#include <amdis/common/TypeTraits.hpp>
18 template <
class ProxyType>
22 PointerProxy(ProxyType&& p)
26 ProxyType* operator->()
37 template <class I, class F, class C = typename std::iterator_traits<I>::iterator_category>
38 class MappedRangeIterator;
40 template <
class I,
class F>
41 class MappedRangeIterator<I,F,std::forward_iterator_tag>
44 using iterator_category = std::forward_iterator_tag;
45 using reference =
decltype(std::declval<F>()(*(std::declval<I>())));
46 using value_type = std::decay_t<reference>;
47 using pointer = PointerProxy<value_type>;
53 using FunctionPointer =
const F*;
55 constexpr MappedRangeIterator(
const I& it, FunctionPointer f) noexcept
72 constexpr MappedRangeIterator() noexcept
78 constexpr reference operator*() const noexcept
84 pointer operator->() const noexcept
89 constexpr MappedRangeIterator& operator=(MappedRangeIterator
const&) =
default;
91 constexpr bool operator==(
const MappedRangeIterator& other)
const noexcept
93 return (it_ == other.it_);
96 constexpr bool operator!=(
const MappedRangeIterator& other)
const noexcept
98 return (it_ != other.it_);
101 MappedRangeIterator& operator++() noexcept
107 MappedRangeIterator operator++(
int)
noexcept
109 MappedRangeIterator copy(*
this);
120 template <
class I,
class F>
121 class MappedRangeIterator<I,F,std::bidirectional_iterator_tag>
122 :
public MappedRangeIterator<I,F,std::forward_iterator_tag>
125 using Base = MappedRangeIterator<I,F,std::forward_iterator_tag>;
129 using iterator_category = std::bidirectional_iterator_tag;
130 using reference =
typename Base::reference;
131 using value_type =
typename Base::value_type;
132 using pointer =
typename Base::pointer;
134 using FunctionPointer =
typename Base::FunctionPointer;
142 constexpr MappedRangeIterator& operator=(MappedRangeIterator
const&) =
default;
144 MappedRangeIterator& operator++() noexcept
150 MappedRangeIterator operator++(
int)
noexcept
152 MappedRangeIterator copy(*
this);
158 MappedRangeIterator& operator--() noexcept
164 MappedRangeIterator operator--(
int)
noexcept
166 MappedRangeIterator copy(*
this);
173 template <
class I,
class F>
174 class MappedRangeIterator<I,F,std::random_access_iterator_tag>
175 :
public MappedRangeIterator<I,F,std::bidirectional_iterator_tag>
178 using Base = MappedRangeIterator<I,F,std::bidirectional_iterator_tag>;
182 using iterator_category = std::random_access_iterator_tag;
183 using reference =
typename Base::reference;
184 using value_type =
typename Base::value_type;
185 using pointer =
typename Base::pointer;
186 using difference_type =
typename std::iterator_traits<I>::difference_type;
188 using FunctionPointer =
typename Base::FunctionPointer;
196 constexpr MappedRangeIterator& operator=(MappedRangeIterator
const&) =
default;
198 MappedRangeIterator& operator++() noexcept
204 MappedRangeIterator operator++(
int)
noexcept
206 MappedRangeIterator copy(*
this);
214 MappedRangeIterator& operator--() noexcept
220 MappedRangeIterator operator--(
int)
noexcept
222 MappedRangeIterator copy(*
this);
228 MappedRangeIterator& operator+=(difference_type n)
noexcept
234 MappedRangeIterator& operator-=(difference_type n)
noexcept
240 bool operator<(
const MappedRangeIterator& other)
noexcept
242 return it_<other.it_;
245 bool operator<=(
const MappedRangeIterator& other)
noexcept
247 return it_<=other.it_;
250 bool operator>(
const MappedRangeIterator& other)
noexcept
252 return it_>other.it_;
255 bool operator>=(
const MappedRangeIterator& other)
noexcept
257 return it_>=other.it_;
260 reference operator[](difference_type n)
noexcept
262 return (*f_)(*(it_+n));
266 MappedRangeIterator operator+(
const MappedRangeIterator& it, difference_type n)
noexcept
268 return MappedRangeIterator(it.it_+n, it.f_);
272 MappedRangeIterator operator+(difference_type n,
const MappedRangeIterator& it)
noexcept
274 return MappedRangeIterator(n+it.it_, it.f_);
278 MappedRangeIterator operator-(
const MappedRangeIterator& it, difference_type n)
noexcept
280 return MappedRangeIterator(it.it_-n, it.f_);
284 difference_type operator-(
const MappedRangeIterator& first,
const MappedRangeIterator& second)
noexcept
286 return first.it_-second.it_;
323 template <
class R,
class F>
326 using RawConstIterator = TYPEOF(std::declval<const R>().
begin());
327 using RawIterator = TYPEOF(std::declval<R>().
begin());
339 using iterator = Impl::MappedRangeIterator<RawIterator, F>;
341 using value_type =
typename iterator::value_type;
348 : rawRange_(FWD(rawRange))
365 constexpr iterator
begin() noexcept
367 return iterator(rawRange_.begin(), &f_);
376 template <class RR = R, class = decltype(std::declval<RR>().size())>
377 constexpr auto size()
const noexcept
379 return rawRange_.size();
383 template <class RR = R, class = decltype(std::declval<RR>().operator[](std::size_t(0)))>
384 decltype(
auto)
operator[](std::size_t i)
const
386 return f_(rawRange_[i]);
392 constexpr bool empty() const noexcept
394 return rawRange_.begin() == rawRange_.end();
410 constexpr iterator
end() noexcept
412 return iterator(rawRange_.end(), &f_);
446 template <
class R,
class F>
447 auto mappedRangeView(R&& range, F
const& f)
449 return MappedRangeView<R, F>(FWD(range), f);
453 template <
class Iter,
class F>
454 auto mappedIterator(Iter it, F
const* f)
456 using iterator = Impl::MappedRangeIterator<Iter, F>;
457 return iterator(it, f);
460 template <
class ConstIter,
class F>
461 auto mappedConstIterator(ConstIter it, F
const* f)
463 using const_iterator = Impl::MappedRangeIterator<ConstIter, F>;
464 return const_iterator(it, f);
A range transforming the values of another range on-the-fly.
Definition: MappedRangeView.hpp:325
constexpr const_iterator begin() const noexcept
Obtain a iterator to the first element.
Definition: MappedRangeView.hpp:360
Impl::MappedRangeIterator< RawConstIterator, F > const_iterator
Iterator type.
Definition: MappedRangeView.hpp:337
constexpr const_iterator end() const noexcept
Obtain a iterator past the last element.
Definition: MappedRangeView.hpp:405
constexpr MappedRangeView(RR &&rawRange, F const &f) noexcept
Construct from range and function.
Definition: MappedRangeView.hpp:347
constexpr bool empty() const noexcept
Checks whether the range is empty.
Definition: MappedRangeView.hpp:392
constexpr auto size() const noexcept
Return the number of elements in the range, if availble.
Definition: MappedRangeView.hpp:377