#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "revng/Support/Assert.h" template class RandomAccessIterator : public std::iterator { private: using iterator = typename std::iterator; using type = RandomAccessIterator; using it_ref = typename iterator::reference; template using conditional = std::conditional; public: using iterator_category = std::random_access_iterator_tag; using value_type = typename iterator::value_type; using difference_type = typename iterator::difference_type; using reference = typename conditional::type; using pointer = typename iterator::pointer; private: const Derived &constThisDerived() const { return *static_cast(this); } Derived &thisDerived() { return *static_cast(this); } reference get(unsigned Index) const { return constThisDerived().get(Index); } Derived clone(unsigned NewIndex) const { return Derived(constThisDerived(), NewIndex); } void assertCompatibility(const type &r) const { revng_assert(constThisDerived().isCompatible(r.constThisDerived())); } protected: RandomAccessIterator() : Index(0) {} RandomAccessIterator(unsigned Index) : Index(Index) {} RandomAccessIterator(const type &r) : Index(r.Index) {} Derived &operator=(const type &r) { assertCompatibility(r); Index = r.Index; return thisDerived(); } public: Derived &operator++() { ++Index; return thisDerived(); } Derived &operator--() { --Index; return thisDerived(); } Derived operator++(int) { return clone(Index++); } Derived operator--(int) { return clone(Index--); } Derived operator+(const difference_type &n) const { return clone(Index + n); } Derived &operator+=(difference_type n) { Index += n; return thisDerived(); } Derived operator-(const difference_type &n) const { return clone(Index - n); } Derived &operator-=(const difference_type &n) { Index -= n; return thisDerived(); } reference operator*() const { return get(Index); } pointer operator->() const { return &get(Index); } reference operator[](const difference_type &n) const { return get(Index + n); } bool operator==(const type &r2) const { assertCompatibility(r2); return Index == r2.Index; } bool operator!=(const type &r2) { assertCompatibility(r2); return Index != r2.Index; } bool operator<(const type &r2) { assertCompatibility(r2); return Index < r2.Index; } bool operator>(const type &r2) { assertCompatibility(r2); return Index > r2.Index; } bool operator<=(const type &r2) { assertCompatibility(r2); return Index <= r2.Index; } bool operator>=(const type &r2) { assertCompatibility(r2); return Index >= r2.Index; } template Derived operator+(const RandomAccessIterator &r2) { assertCompatibility(r2); return clone(Index + r2.Index); } template difference_type operator-(const RandomAccessIterator &r2) const { assertCompatibility(r2); return Index - r2.Index; } private: unsigned Index; };