From 8128632f1aa4db1a2ec6de8f89ce401b09a29e8a Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Sat, 10 Aug 2024 14:19:25 +1000 Subject: [PATCH] iterator/zip: allow ranges with differing begin/end types --- cruft/util/iterator/zip.hpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/cruft/util/iterator/zip.hpp b/cruft/util/iterator/zip.hpp index b02e15fc..1eae3f02 100644 --- a/cruft/util/iterator/zip.hpp +++ b/cruft/util/iterator/zip.hpp @@ -26,6 +26,16 @@ namespace cruft::iterator { class zipped_iterator; + template + struct zipped_reference { using type = void; }; + + template + requires requires { typename KlassT::reference; } + struct zipped_reference { + using type = KlassT::reference; + }; + + template < typename IteratorT, std::size_t ...IndexV @@ -46,9 +56,12 @@ namespace cruft::iterator { using difference_type = std::ptrdiff_t; using value_type = std::tuple< - typename std::iterator_traits< - std::tuple_element_t - >::reference... + // Because std::default_sentinel_t doesn't have iterator members + typename zipped_reference< + typename std::iterator_traits< + std::tuple_element_t + > + >::type... >; using reference = value_type; @@ -107,11 +120,11 @@ namespace cruft::iterator { ); } - + template bool - operator== (zipped_iterator const &rhs) const + operator== (zipped_iterator const &rhs) const { - return m_iterators == rhs.m_iterators; + return m_iterators == rhs.inner (); } @@ -121,6 +134,7 @@ namespace cruft::iterator { return !(*this == rhs); } + auto const& inner (void) const& { return m_iterators; } private: IteratorT m_iterators;