67 using iterator_category = std::input_iterator_tag;
68 using difference_type = std::ptrdiff_t;
70 template<ranges::input_range Rng,
typename Iterator>
71 iterator(Rng&& rng, Iterator&& it): mImpl(rttify(std::forward<Rng>(rng), std::forward<Iterator>(it))) {
74 iterator(iterator&& rhs)
noexcept =
default;
75 iterator& operator=(iterator&& rhs)
noexcept =
default;
79 iterator(iterator& rhs) {
82 iterator(
const iterator& rhs) {
85 iterator& operator=(
const iterator& rhs) {
90 mImpl = rhs.mImpl->clone();
95 iterator& operator++() {
100 iterator& operator++(
int) {
105 iterator& operator--() {
110 iterator& operator--(
int) {
115 T operator*()
const {
116 return mImpl->value();
119 bool operator==(
const iterator& rhs)
const {
120 return mImpl->isEquals(rhs.mImpl.get());
123 bool operator!=(
const iterator& rhs)
const {
124 return !mImpl->isEquals(rhs.mImpl.get());
129 virtual ~iface() =
default;
130 virtual void prev() = 0;
131 virtual void next() = 0;
132 virtual T value() = 0;
133 virtual std::unique_ptr<iface> clone() = 0;
134 virtual bool isEquals(iface* rhs) = 0;
136 std::unique_ptr<iface> mImpl;
138 template<ranges::input_range Rng,
typename Iterator>
139 std::unique_ptr<iface> rttify(Rng&& rng, Iterator&& it) {
140 struct rttified: iface {
141 rttified(std::remove_reference_t<Rng>& rng, std::decay_t<Iterator> it): rng(rng), it(std::move(it)) {}
142 ~rttified() =
default;
144 void prev()
override {
145 if constexpr (
requires { --it; }) {
152 void next()
override {
157 if constexpr (std::is_copy_constructible_v<T>) {
163 std::unique_ptr<iface> clone()
override {
164 return std::make_unique<rttified>(rng, it);
167 bool isEquals(iface* rhs)
override {
168 if (rhs ==
nullptr) {
170 return it == ranges::end(rng);
172 if (
auto t =
dynamic_cast<rttified*
>(rhs)) {
179 std::decay_t<Iterator> it;
180 std::remove_reference_t<Rng>& rng;
183 return std::make_unique<rttified>(rng, it);