iterator_t (iterator wrapper) class
This commit is contained in:
parent
292f0f4886
commit
b872cc940b
|
@ -37,6 +37,149 @@ class Range {
|
||||||
auto end() const -> const Iterator { return m_end; }
|
auto end() const -> const Iterator { return m_end; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <class C>
|
||||||
|
requires requires(const C &c) { c.read(); }
|
||||||
|
using reference_t = decltype(std::declval<const C &>().read());
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <class C> struct deduced_value_t {
|
||||||
|
template <class T> static auto deduce(int) -> typename T::value_type;
|
||||||
|
template <class T> static auto deduce(...) -> std::decay_t<reference_t<T>>;
|
||||||
|
|
||||||
|
using type = decltype(deduce<C>(0));
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class C>
|
||||||
|
requires std::same_as<typename detail::deduced_value_t<C>::type,
|
||||||
|
std::decay_t<typename detail::deduced_value_t<C>::type>>
|
||||||
|
using value_type_t = typename detail::deduced_value_t<C>::type;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <class C> struct deduced_difference_t {
|
||||||
|
template <class T> static auto deduce(int) -> typename T::difference_type;
|
||||||
|
template <class T>
|
||||||
|
static auto deduce(long) -> decltype(std::declval<const T &>().distance_to(
|
||||||
|
std::declval<const T &>()));
|
||||||
|
template <class T> static auto deduce(...) -> std::ptrdiff_t;
|
||||||
|
|
||||||
|
using type = decltype(deduce<C>(0));
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class C>
|
||||||
|
using difference_type_t = typename detail::deduced_difference_t<C>::type;
|
||||||
|
|
||||||
|
template <typename I> struct iterator_traits {
|
||||||
|
using difference_type = difference_type_t<I>;
|
||||||
|
using value_type = value_type_t<I>;
|
||||||
|
using reference = reference_t<I>;
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename I> struct iterator_t {
|
||||||
|
private:
|
||||||
|
I base_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
iterator_t() requires(std::is_default_constructible_v<I>) : base_({}) {}
|
||||||
|
iterator_t(const I &base) : base_(base) {}
|
||||||
|
iterator_t(I &&base) : base_(std::move(base)) {}
|
||||||
|
|
||||||
|
auto constexpr base() const -> const I & { return base_; }
|
||||||
|
auto constexpr base() -> I & { return base_; }
|
||||||
|
|
||||||
|
// input_or_output_iterator
|
||||||
|
auto constexpr operator++(int) -> iterator_t
|
||||||
|
requires(std::input_or_output_iterator<I>) {
|
||||||
|
const auto ret = *this;
|
||||||
|
base()++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
auto constexpr operator++()
|
||||||
|
-> iterator_t &requires(std::input_or_output_iterator<I>) {
|
||||||
|
this ++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// input_iterator
|
||||||
|
auto constexpr operator*() const -> const std::iter_reference_t<I>
|
||||||
|
requires(std::input_iterator<I>) { return *base(); }
|
||||||
|
|
||||||
|
// output_iterator
|
||||||
|
template <typename T = decltype(*base_)>
|
||||||
|
auto constexpr operator*() -> std::iter_reference_t<I>
|
||||||
|
requires(std::output_iterator<I, T>) { return *base(); }
|
||||||
|
|
||||||
|
// forward_iterator
|
||||||
|
auto constexpr operator==(const iterator_t &rhs) const
|
||||||
|
-> bool requires(std::forward_iterator<I>) {
|
||||||
|
return base() == rhs.base();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::sentinel_for<I> S>
|
||||||
|
auto constexpr operator==(const S &rhs) const
|
||||||
|
-> bool requires(std::forward_iterator<I>) {
|
||||||
|
return base() == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bidirectional_iterator
|
||||||
|
auto constexpr operator--(int) -> iterator_t
|
||||||
|
requires(std::bidirectional_iterator<I>) {
|
||||||
|
const auto ret = *this;
|
||||||
|
base()--;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
auto constexpr operator--()
|
||||||
|
-> iterator_t &requires(std::bidirectional_iterator<I>) {
|
||||||
|
base()--;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// random_access_iterator
|
||||||
|
auto constexpr operator<=>(const iterator_t &rhs) const
|
||||||
|
-> std::strong_ordering {
|
||||||
|
return base() <=> rhs.base();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto constexpr operator-(const iterator_t &rhs) const
|
||||||
|
-> std::iter_difference_t<I> {
|
||||||
|
return base() - rhs.base();
|
||||||
|
}
|
||||||
|
auto constexpr operator+(const std::iter_difference_t<I> &n) const
|
||||||
|
-> iterator_t {
|
||||||
|
return iterator_t(base() + n);
|
||||||
|
}
|
||||||
|
friend auto constexpr operator+(const std::iter_difference_t<I> &n,
|
||||||
|
const iterator_t &rhs) -> iterator_t {
|
||||||
|
return rhs + n;
|
||||||
|
}
|
||||||
|
auto constexpr operator-(const std::iter_difference_t<I> &n) const
|
||||||
|
-> iterator_t {
|
||||||
|
return iterator_t(base() - n);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator+=(const std::iter_difference_t<I> &n) -> iterator_t & {
|
||||||
|
*this = iterator_t(base() + n);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
auto operator-=(const std::iter_difference_t<I> &n) -> iterator_t & {
|
||||||
|
*this = iterator_t(base() - n);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto constexpr operator[](const std::iter_difference_t<I> &n) const
|
||||||
|
-> const std::iter_reference_t<I> {
|
||||||
|
return base()[n];
|
||||||
|
}
|
||||||
|
auto operator[](const std::iter_difference_t<I> &n)
|
||||||
|
-> std::iter_reference_t<I> {
|
||||||
|
return base()[n];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename V, typename I = V *> struct BaseIterator {
|
template <typename V, typename I = V *> struct BaseIterator {
|
||||||
using value_type = V;
|
using value_type = V;
|
||||||
using reference = V &;
|
using reference = V &;
|
||||||
|
@ -184,3 +327,8 @@ template <std::ranges::range R>
|
||||||
using RangeIterator = Iterator<std::ranges::iterator_t<R>>;
|
using RangeIterator = Iterator<std::ranges::iterator_t<R>>;
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <typename I>
|
||||||
|
struct iterator_traits<util::iterator_t<I>> : public iterator_traits<I> {};
|
||||||
|
} // namespace std
|
Loading…
Reference in a new issue