namespace cruft::iterator { /////////////////////////////////////////////////////////////////////////// // template <typename IteratorT> struct numeric_iterator : public std::iterator< typename std::iterator_traits<IteratorT>::iterator_category, decltype (+std::declval<typename std::iterator_traits<IteratorT>::value_type> ()), typename std::iterator_traits<IteratorT>::difference_type, typename std::iterator_traits<IteratorT>::pointer, typename std::iterator_traits<IteratorT>::reference > { static_assert (std::is_arithmetic_v<typename std::iterator_traits<numeric_iterator>::value_type>); explicit numeric_iterator (IteratorT _inner): m_inner (_inner) { ; } auto operator++ (void) { ++m_inner; return *this; } auto operator- (const numeric_iterator &rhs) const { return typename std::iterator_traits<IteratorT>::difference_type { m_inner - rhs.m_inner }; } auto operator* (void) const { return +*m_inner; } auto operator== (const numeric_iterator &rhs) const { return m_inner == rhs.m_inner; } auto operator!= (const numeric_iterator &rhs) const { return m_inner != rhs.m_inner; } private: IteratorT m_inner; }; //------------------------------------------------------------------------- // convenience function that constructs a view of numeric_iterators for a // provided container template <typename ContainerT> auto numeric_view (ContainerT &data) { return cruft::view { numeric_iterator (std::begin (data)), numeric_iterator (std::end (data)) }; } //------------------------------------------------------------------------- template <typename ContainerT> auto numeric_view (const ContainerT &data) { return cruft::view { numeric_iterator (std::begin (data)), numeric_iterator (std::end (data)) }; } }