91 lines
2.1 KiB
C++
91 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#if !defined(MIJIN_UTIL_ITERATORS_HPP_INCLUDED)
|
|
#define MIJIN_UTIL_ITERATORS_HPP_INCLUDED 1
|
|
|
|
#include <cstddef>
|
|
#include <tuple>
|
|
|
|
namespace mijin
|
|
{
|
|
template<typename TIdx, typename TIterator>
|
|
struct EnumeratingIterator
|
|
{
|
|
TIdx idx;
|
|
TIterator base;
|
|
|
|
EnumeratingIterator(TIdx idx_, TIterator base_) noexcept : idx(idx_), base(base_) {}
|
|
EnumeratingIterator(const EnumeratingIterator&) noexcept = default;
|
|
|
|
EnumeratingIterator& operator=(const EnumeratingIterator&) noexcept = default;
|
|
|
|
auto operator*() const noexcept
|
|
{
|
|
return std::tie(idx, *base);
|
|
}
|
|
|
|
EnumeratingIterator& operator++() noexcept
|
|
{
|
|
++idx;
|
|
++base;
|
|
return *this;
|
|
}
|
|
|
|
EnumeratingIterator operator++(int) noexcept
|
|
{
|
|
EnumeratingIterator copy(*this);
|
|
++(*this);
|
|
return copy;
|
|
}
|
|
|
|
EnumeratingIterator& operator--() noexcept
|
|
{
|
|
--idx;
|
|
--base;
|
|
return *this;
|
|
}
|
|
|
|
EnumeratingIterator operator--(int) noexcept
|
|
{
|
|
EnumeratingIterator copy(*this);
|
|
--(*this);
|
|
return copy;
|
|
}
|
|
|
|
bool operator==(const EnumeratingIterator& other) const noexcept
|
|
{
|
|
return base == other.base; // note: ignoring idx so we don't have to find it out for end()
|
|
}
|
|
|
|
bool operator!=(const EnumeratingIterator& other) const noexcept
|
|
{
|
|
return base != other.base; // note: ignoring idx so we don't have to find it out for end()
|
|
}
|
|
};
|
|
template<typename TIdx, typename TIterator>
|
|
EnumeratingIterator(TIdx, TIterator) -> EnumeratingIterator<TIdx, TIterator>;
|
|
|
|
template<typename TIdx, typename TIterable>
|
|
struct Enumeratable
|
|
{
|
|
TIterable& base;
|
|
|
|
auto begin() const noexcept
|
|
{
|
|
return EnumeratingIterator(TIdx(0), base.begin());
|
|
}
|
|
|
|
auto end() const noexcept
|
|
{
|
|
return EnumeratingIterator(TIdx(0), base.end());
|
|
}
|
|
};
|
|
|
|
template<typename TIdx = std::size_t, typename TIterable>
|
|
Enumeratable<TIdx, TIterable> enumerate(TIterable& iterable)
|
|
{
|
|
return {iterable};
|
|
}
|
|
} // namespace mijin
|
|
|
|
#endif // MIJIN_UTIL_ITERATORS_HPP_INCLUDED
|