Added zip() functionality for combining iterators.
This commit is contained in:
parent
a92148aac1
commit
4dfc116830
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user