enumerator wrapper types
This commit is contained in:
parent
250dd20a6a
commit
89de73e36a
|
@ -1,6 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <compare>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <xutility>
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
|
@ -32,4 +37,150 @@ class Range {
|
||||||
auto end() const -> const Iterator { return m_end; }
|
auto end() const -> const Iterator { return m_end; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *> struct BaseIterator {
|
||||||
|
using value_type = V;
|
||||||
|
using reference = V &;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
I base_iter;
|
||||||
|
|
||||||
|
BaseIterator(const I &iter) : base_iter(iter) {}
|
||||||
|
BaseIterator(I &&iter) : base_iter(std::move(iter)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *>
|
||||||
|
struct InputOrOutputIterator : public BaseIterator<V, I> {
|
||||||
|
InputOrOutputIterator(const I &iter) : BaseIterator<V, I>(iter) {}
|
||||||
|
InputOrOutputIterator(I &&iter) : BaseIterator<V, I>(std::move(iter)) {}
|
||||||
|
|
||||||
|
auto constexpr operator*() const -> void {}
|
||||||
|
|
||||||
|
auto constexpr operator++(int) -> InputOrOutputIterator {
|
||||||
|
const auto ret = *this;
|
||||||
|
this->base_iter++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
auto constexpr operator++() -> InputOrOutputIterator & {
|
||||||
|
this ++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *>
|
||||||
|
struct InputIterator : public InputOrOutputIterator<V, I>,
|
||||||
|
public std::input_iterator_tag {
|
||||||
|
InputIterator(const I &iter) : BaseIterator<V, I>(iter) {}
|
||||||
|
InputIterator(I &&iter) : BaseIterator<V, I>(std::move(iter)) {}
|
||||||
|
|
||||||
|
auto constexpr operator*() const -> const V & { return *this->base_iter; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *>
|
||||||
|
struct OutputIterator : public InputOrOutputIterator<V, I>,
|
||||||
|
public std::output_iterator_tag {
|
||||||
|
OutputIterator(const I &iter) : BaseIterator<V, I>(iter) {}
|
||||||
|
OutputIterator(I &&iter) : BaseIterator<V, I>(std::move(iter)) {}
|
||||||
|
|
||||||
|
auto constexpr operator*() -> V & { return *this->base_iter; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *>
|
||||||
|
struct ForwardIterator : public InputIterator<V, I>,
|
||||||
|
public std::forward_iterator_tag {
|
||||||
|
ForwardIterator(const I &iter) : BaseIterator<V, I>(iter) {}
|
||||||
|
ForwardIterator(I &&iter) : BaseIterator<V, I>(std::move(iter)) {}
|
||||||
|
|
||||||
|
auto constexpr operator==(const ForwardIterator &rhs) const -> bool {
|
||||||
|
return this->base_iter == rhs.base_iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *>
|
||||||
|
struct BidirectionalIterator : public ForwardIterator<V, I>,
|
||||||
|
public std::bidirectional_iterator_tag {
|
||||||
|
BidirectionalIterator(const I &iter) : BaseIterator<V, I>(iter) {}
|
||||||
|
BidirectionalIterator(I &&iter) : BaseIterator<V, I>(std::move(iter)) {}
|
||||||
|
|
||||||
|
auto constexpr operator--(int) -> BidirectionalIterator {
|
||||||
|
const auto ret = *this;
|
||||||
|
this->base_iter--;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
auto constexpr operator--() -> BidirectionalIterator & {
|
||||||
|
this --;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename V, typename I = V *>
|
||||||
|
struct RandomAccessIterator : public BidirectionalIterator<V, I>,
|
||||||
|
public std::random_access_iterator_tag {
|
||||||
|
using difference_type = typename BaseIterator<V, I>::difference_type;
|
||||||
|
|
||||||
|
RandomAccessIterator(const I &iter) : BaseIterator<V, I>(iter) {}
|
||||||
|
RandomAccessIterator(I &&iter) : BaseIterator<V, I>(std::move(iter)) {}
|
||||||
|
|
||||||
|
auto constexpr operator<=>(const RandomAccessIterator &rhs) const
|
||||||
|
-> std::strong_ordering {
|
||||||
|
return this->base_iter <=> rhs.base_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto constexpr operator-(const RandomAccessIterator &rhs) const
|
||||||
|
-> difference_type {
|
||||||
|
return this->base_iter - rhs.base_iter;
|
||||||
|
}
|
||||||
|
auto constexpr operator+(const difference_type &n) const
|
||||||
|
-> RandomAccessIterator {
|
||||||
|
return RandomAccessIterator(this->base_iter + n);
|
||||||
|
}
|
||||||
|
friend auto constexpr operator+(const difference_type &n,
|
||||||
|
const RandomAccessIterator &rhs)
|
||||||
|
-> RandomAccessIterator {
|
||||||
|
return rhs + n;
|
||||||
|
}
|
||||||
|
auto constexpr operator-(const difference_type &n) const
|
||||||
|
-> RandomAccessIterator {
|
||||||
|
return RandomAccessIterator(this->base_iter - n);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator+=(const difference_type &n) -> RandomAccessIterator & {
|
||||||
|
*this = RandomAccessIterator(this->base_iter + n);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
auto operator-=(const difference_type &n) -> RandomAccessIterator & {
|
||||||
|
*this = RandomAccessIterator(this->base_iter - n);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto constexpr operator[](const difference_type &n) const -> const V & {
|
||||||
|
return this->base_iter[n];
|
||||||
|
}
|
||||||
|
auto operator[](const difference_type &n) -> V & {
|
||||||
|
return this->base_iter[n];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
using Iterator = std::conditional_t<
|
||||||
|
std::random_access_iterator<I>,
|
||||||
|
RandomAccessIterator<std::iter_value_t<I>, I>,
|
||||||
|
std::conditional_t<
|
||||||
|
std::bidirectional_iterator<I>,
|
||||||
|
BidirectionalIterator<std::iter_value_t<I>, I>,
|
||||||
|
std::conditional_t<
|
||||||
|
std::forward_iterator<I>, ForwardIterator<std::iter_value_t<I>, I>,
|
||||||
|
std::conditional_t<
|
||||||
|
std::output_iterator<I, decltype(*std::declval<I>())>,
|
||||||
|
OutputIterator<std::iter_value_t<I>, I>,
|
||||||
|
std::conditional_t<
|
||||||
|
std::input_iterator<I>,
|
||||||
|
InputIterator<std::iter_value_t<I>, I>,
|
||||||
|
std::conditional_t<
|
||||||
|
std::input_or_output_iterator<I>,
|
||||||
|
InputOrOutputIterator<std::iter_value_t<I>, I>,
|
||||||
|
RandomAccessIterator<I, I *>>>>>>>;
|
||||||
|
|
||||||
|
template <std::ranges::range R>
|
||||||
|
using RangeIterator = Iterator<std::ranges::iterator_t<R>>;
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
Loading…
Reference in a new issue