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
|
#pragma once
|
||||||
|
|
||||||
|
#include "functor.hpp"
|
||||||
#include "types/traits.hpp"
|
#include "types/traits.hpp"
|
||||||
#include "tuple/value.hpp"
|
#include "tuple/value.hpp"
|
||||||
#include "variadic.hpp"
|
#include "variadic.hpp"
|
||||||
@ -332,11 +333,11 @@ namespace cruft {
|
|||||||
typename IteratorT,
|
typename IteratorT,
|
||||||
typename = std::make_index_sequence<std::tuple_size_v<IteratorT>>
|
typename = std::make_index_sequence<std::tuple_size_v<IteratorT>>
|
||||||
>
|
>
|
||||||
struct iterator;
|
struct zipped_iterator;
|
||||||
|
|
||||||
|
|
||||||
template <typename IteratorT, std::size_t ...Indices>
|
template <typename IteratorT, std::size_t ...Indices>
|
||||||
struct iterator<IteratorT, std::index_sequence<Indices...>> {
|
struct zipped_iterator<IteratorT, std::index_sequence<Indices...>> {
|
||||||
public:
|
public:
|
||||||
// We can't declare ourselves as a forward_iterator because we're
|
// We can't declare ourselves as a forward_iterator because we're
|
||||||
// unable to supply references to our value_type when we get
|
// unable to supply references to our value_type when we get
|
||||||
@ -347,13 +348,23 @@ namespace cruft {
|
|||||||
// pressing need for this functionality.
|
// pressing need for this functionality.
|
||||||
using iterator_category = std::input_iterator_tag;
|
using iterator_category = std::input_iterator_tag;
|
||||||
using difference_type = std::ptrdiff_t;
|
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)
|
m_iterators (_iterators)
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
iterator&
|
zipped_iterator&
|
||||||
operator++ (void)
|
operator++ (void)
|
||||||
{
|
{
|
||||||
(++std::get<Indices> (m_iterators), ...);
|
(++std::get<Indices> (m_iterators), ...);
|
||||||
@ -361,7 +372,7 @@ namespace cruft {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
iterator operator++ (int);
|
zipped_iterator operator++ (int);
|
||||||
|
|
||||||
|
|
||||||
auto
|
auto
|
||||||
@ -380,14 +391,14 @@ namespace cruft {
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operator== (const iterator &rhs) const
|
operator== (const zipped_iterator &rhs) const
|
||||||
{
|
{
|
||||||
return m_iterators == rhs.m_iterators;
|
return m_iterators == rhs.m_iterators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operator!= (const iterator &rhs) const
|
operator!= (const zipped_iterator &rhs) const
|
||||||
{
|
{
|
||||||
return !(*this == rhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
@ -413,34 +424,53 @@ namespace cruft {
|
|||||||
m_store (std::forward<StoreT> (_store)...)
|
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 indices_t = std::make_index_sequence<sizeof...(StoreT)>;
|
using iterator = zipped_iterator<inner_t, indices_t>;
|
||||||
using begin_t = std::tuple<decltype(std::begin (std::declval<StoreT> ()))...>;
|
|
||||||
using end_t = std::tuple<decltype(std::end (std::declval<StoreT> ()))...>;
|
|
||||||
|
|
||||||
|
|
||||||
auto begin (void)&
|
iterator begin (void)&
|
||||||
{
|
{
|
||||||
return iterator<begin_t, indices_t> (
|
return iterator (
|
||||||
tuple::value::map (
|
tuple::value::map (::cruft::functor::begin {}, m_store)
|
||||||
[] (auto &i) noexcept { return std::begin (i); },
|
);
|
||||||
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> (
|
return iterator (
|
||||||
tuple::value::map (
|
tuple::value::map (cruft::functor::end {}, m_store)
|
||||||
[] (auto &i) noexcept { return std::end (i); },
|
|
||||||
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:
|
private:
|
||||||
std::tuple<StoreT...> m_store;
|
std::tuple<StoreT...> m_store;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user