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;
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 <
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<IndexV, IteratorT>
>::reference...
// Because std::default_sentinel_t doesn't have iterator members
typename zipped_reference<
typename std::iterator_traits<
std::tuple_element_t<IndexV, IteratorT>
>
>::type...
>;
using reference = value_type;
@ -107,11 +120,11 @@ namespace cruft::iterator {
);
}
template <typename OtherT, typename OtherIndexV>
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);
}
auto const& inner (void) const& { return m_iterators; }
private:
IteratorT m_iterators;