From a2592edc536f2a8da1a7a7ced18759c9f054aba0 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 5 Feb 2019 11:58:57 +1100 Subject: [PATCH] iterator: add full iterator_traits for cruft::zip --- iterator.hpp | 74 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/iterator.hpp b/iterator.hpp index 2a472511..1abbecb8 100644 --- a/iterator.hpp +++ b/iterator.hpp @@ -8,6 +8,7 @@ #pragma once +#include "functor.hpp" #include "types/traits.hpp" #include "tuple/value.hpp" #include "variadic.hpp" @@ -332,11 +333,11 @@ namespace cruft { typename IteratorT, typename = std::make_index_sequence> > - struct iterator; + struct zipped_iterator; template - struct iterator> { + struct zipped_iterator> { public: // We can't declare ourselves as a forward_iterator because we're // unable to supply references to our value_type when we get @@ -347,13 +348,23 @@ namespace cruft { // pressing need for this functionality. using iterator_category = std::input_iterator_tag; using difference_type = std::ptrdiff_t; + using value_type = std::tuple< + decltype( + *std::get ( + std::declval () + ) + )... + >; + using reference = value_type; + using pointer = value_type*; - iterator (IteratorT _iterators): + + zipped_iterator (IteratorT _iterators): m_iterators (_iterators) { ; } - iterator& + zipped_iterator& operator++ (void) { (++std::get (m_iterators), ...); @@ -361,7 +372,7 @@ namespace cruft { } - iterator operator++ (int); + zipped_iterator operator++ (int); auto @@ -380,14 +391,14 @@ namespace cruft { bool - operator== (const iterator &rhs) const + operator== (const zipped_iterator &rhs) const { return m_iterators == rhs.m_iterators; } bool - operator!= (const iterator &rhs) const + operator!= (const zipped_iterator &rhs) const { return !(*this == rhs); } @@ -413,34 +424,53 @@ namespace cruft { m_store (std::forward (_store)...) { ; } + using inner_t = std::tuple ()))...>; + using indices_t = std::make_index_sequence; - using indices_t = std::make_index_sequence; - using begin_t = std::tuple ()))...>; - using end_t = std::tuple ()))...>; + using iterator = zipped_iterator; - auto begin (void)& + iterator begin (void)& { - return iterator ( - tuple::value::map ( - [] (auto &i) noexcept { return std::begin (i); }, - m_store - ) + return iterator ( + tuple::value::map (::cruft::functor::begin {}, m_store) + ); + } + + iterator begin (void) const& + { + return iterator ( + tuple::value::map (::cruft::functor::begin {}, m_store) ); } - auto end (void)& + iterator end (void)& { - return iterator ( - tuple::value::map ( - [] (auto &i) noexcept { return std::end (i); }, - m_store - ) + return iterator ( + tuple::value::map (cruft::functor::end {}, m_store) ); } + iterator end (void) const & + { + return iterator ( + tuple::value::map (cruft::functor::end {}, m_store) + ); + } + + + /// Returns the number of elements in the sequence. + decltype (auto) + size (void) const + { + // All stores should have the same size so we arbitrarily pick + // the first to query. + return std::get<0> (m_store).size (); + } + + private: std::tuple m_store; };