Skip to content

Instantly share code, notes, and snippets.

@foolnotion
Created May 25, 2021 17:29
Show Gist options
  • Save foolnotion/c5fa20b22aebca3fe12911dc88674cc0 to your computer and use it in GitHub Desktop.
Save foolnotion/c5fa20b22aebca3fe12911dc88674cc0 to your computer and use it in GitHub Desktop.
template<typename InputIt, typename Projection>
struct ProjectionIterator {
using T = typename std::iterator_traits<InputIt>::value_type;
using R = std::result_of_t<Projection(T)>;
// projection iterator traits
using value_type = std::remove_reference_t<R>;
using pointer = void;
using reference = value_type&;
using difference_type = typename std::iterator_traits<InputIt>::difference_type;
using iterator_category = typename std::iterator_traits<InputIt>::iterator_category;
explicit ProjectionIterator(InputIt it, Projection pr) : it_(it), pr_(pr) { }
inline value_type operator*() const noexcept { return std::invoke(pr_, std::forward<typename std::iterator_traits<InputIt>::reference>(*it_)); }
inline bool operator==(ProjectionIterator const& rhs) const noexcept
{
return it_ == rhs.it_;
}
inline bool operator!=(ProjectionIterator const& rhs) const noexcept
{
return !(*this == rhs);
}
inline bool operator<(ProjectionIterator const& rhs) const noexcept
{
return it_ < rhs.it_;
}
inline bool operator>(ProjectionIterator const& rhs) const noexcept
{
return rhs < *this;
}
inline bool operator<=(ProjectionIterator const& rhs) const noexcept
{
return !(*this > rhs);
}
inline bool operator>=(ProjectionIterator const& rhs) const noexcept
{
return !(rhs < *this);
}
inline difference_type operator+(ProjectionIterator const& rhs) const noexcept
{
return it_ + rhs.it_;
}
inline difference_type operator-(ProjectionIterator const& rhs) const noexcept
{
return it_ - rhs.it_;
}
inline ProjectionIterator& operator++() noexcept
{
++it_;
return *this;
}
inline ProjectionIterator operator++(int) noexcept
{
auto ret = *this;
++*this;
return ret;
}
inline ProjectionIterator& operator--() noexcept
{
--it_;
return *this;
}
inline ProjectionIterator operator--(int) noexcept
{
auto ret = *this;
--*this;
return ret;
}
inline ProjectionIterator& operator+=(int n) noexcept
{
it_ += n;
return *this;
}
inline ProjectionIterator operator+(int n) noexcept
{
auto ret = *this;
ret += n;
return ret;
}
inline ProjectionIterator& operator-=(int n) noexcept
{
it_ -= n;
return *this;
}
inline ProjectionIterator operator-(int n) noexcept
{
auto ret = *this;
ret -= n;
return ret;
}
private:
InputIt it_;
Projection pr_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment