iterator: add full iterator_traits for cruft::zip
This commit is contained in:
parent
9982ea2bb7
commit
a2592edc53
74
iterator.hpp
74
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<std::tuple_size_v<IteratorT>>
|
||||
>
|
||||
struct iterator;
|
||||
struct zipped_iterator;
|
||||
|
||||
|
||||
template <typename IteratorT, std::size_t ...Indices>
|
||||
struct iterator<IteratorT, std::index_sequence<Indices...>> {
|
||||
struct zipped_iterator<IteratorT, std::index_sequence<Indices...>> {
|
||||
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<Indices> (
|
||||
std::declval<IteratorT> ()
|
||||
)
|
||||
)...
|
||||
>;
|
||||
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<Indices> (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<StoreT> (_store)...)
|
||||
{ ; }
|
||||
|
||||
|
||||
using inner_t = std::tuple<decltype(std::begin (std::declval<StoreT> ()))...>;
|
||||
using indices_t = std::make_index_sequence<sizeof...(StoreT)>;
|
||||
using begin_t = std::tuple<decltype(std::begin (std::declval<StoreT> ()))...>;
|
||||
using end_t = std::tuple<decltype(std::end (std::declval<StoreT> ()))...>;
|
||||
|
||||
using iterator = zipped_iterator<inner_t, indices_t>;
|
||||
|
||||
|
||||
auto begin (void)&
|
||||
iterator begin (void)&
|
||||
{
|
||||
return iterator<begin_t, indices_t> (
|
||||
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<end_t, indices_t> (
|
||||
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<StoreT...> m_store;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user