Added zip() functionality for combining iterators.

This commit is contained in:
Patrick 2023-11-16 23:39:45 +01:00
parent a92148aac1
commit 4dfc116830

View File

@ -169,6 +169,86 @@ Enumeratable<TIdx, TIterable> enumerate(TIterable&& iterable)
return {.base = {std::forward<TIterable>(iterable)}};
}
template<typename TFirstIterator, typename TSecondIterator>
struct ZippingIterator
{
TFirstIterator first;
TSecondIterator second;
ZippingIterator(TFirstIterator first_, TSecondIterator second_) noexcept : first(first_), second(second_) {}
ZippingIterator(const ZippingIterator&) noexcept = default;
ZippingIterator& operator=(const ZippingIterator&) noexcept = default;
auto operator*() const noexcept
{
return std::tie(*first, *second);
}
ZippingIterator& operator++() noexcept
{
++first;
++second;
return *this;
}
ZippingIterator operator++(int) noexcept
{
ZippingIterator copy(*this);
++(*this);
return copy;
}
ZippingIterator& operator--() noexcept
{
--first;
--second;
return *this;
}
ZippingIterator operator--(int) noexcept
{
ZippingIterator copy(*this);
--(*this);
return copy;
}
bool operator==(const ZippingIterator& other) const noexcept
{
return first == other.first || second == other.second; // note: this uses or so reaching the end on one range also ends the zipped one.
}
bool operator!=(const ZippingIterator& other) const noexcept
{
return !(*this == other);
}
};
template<typename TFirstIterator, typename TSecondIterator>
ZippingIterator(TFirstIterator, TSecondIterator) -> ZippingIterator<TFirstIterator, TSecondIterator>;
template<typename TFirst, typename TSecond>
struct ZippingRange : RangeAdapter
{
RangeRef<TFirst> first;
RangeRef<TSecond> second;
auto begin() const noexcept
{
return ZippingIterator(first.begin(), second.begin());
}
auto end() const noexcept
{
return ZippingIterator(first.end(), second.end());
}
};
template<typename TFirst, typename TSecond>
ZippingRange<TFirst, TSecond> zip(TFirst&& first, TSecond&& second)
{
return {.first = {std::forward<TFirst>(first)}, .second = {std::forward<TSecond>(second)}};
}
template<typename TIterator>
struct ReplacingIterator
{