#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "revng/Support/Assert.h" template class RandomAccessIterator { private: using type = RandomAccessIterator; template using conditional = std::conditional; public: using iterator_category = std::random_access_iterator_tag; using value_type = TypeT; using difference_type = std::ptrdiff_t; using reference = typename conditional::type; using const_reference = TypeT &; using pointer = TypeT *; 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; };