iterator/zip: allow ranges with differing begin/end types

This commit is contained in:
Danny Robson 2024-08-10 14:19:25 +10:00
parent f141cb3e95
commit 8128632f1a

View File

@ -26,6 +26,16 @@ namespace cruft::iterator {
class zipped_iterator; class zipped_iterator;
template <typename T>
struct zipped_reference { using type = void; };
template <typename KlassT>
requires requires { typename KlassT::reference; }
struct zipped_reference<KlassT> {
using type = KlassT::reference;
};
template < template <
typename IteratorT, typename IteratorT,
std::size_t ...IndexV std::size_t ...IndexV
@ -46,9 +56,12 @@ namespace cruft::iterator {
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using value_type = std::tuple< using value_type = std::tuple<
// Because std::default_sentinel_t doesn't have iterator members
typename zipped_reference<
typename std::iterator_traits< typename std::iterator_traits<
std::tuple_element_t<IndexV, IteratorT> std::tuple_element_t<IndexV, IteratorT>
>::reference... >
>::type...
>; >;
using reference = value_type; using reference = value_type;
@ -107,11 +120,11 @@ namespace cruft::iterator {
); );
} }
template <typename OtherT, typename OtherIndexV>
bool bool
operator== (zipped_iterator const &rhs) const operator== (zipped_iterator<OtherT, OtherIndexV> const &rhs) const
{ {
return m_iterators == rhs.m_iterators; return m_iterators == rhs.inner ();
} }
@ -121,6 +134,7 @@ namespace cruft::iterator {
return !(*this == rhs); return !(*this == rhs);
} }
auto const& inner (void) const& { return m_iterators; }
private: private:
IteratorT m_iterators; IteratorT m_iterators;