mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
137 lines
3.2 KiB
C++
137 lines
3.2 KiB
C++
#pragma once
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include <iterator>
|
|
|
|
#include "revng/Support/Assert.h"
|
|
|
|
template<typename TypeT, typename Derived, bool Reference = true>
|
|
class RandomAccessIterator {
|
|
|
|
private:
|
|
using type = RandomAccessIterator<TypeT, Derived, Reference>;
|
|
template<bool C, typename A, typename B>
|
|
using conditional = std::conditional<C, A, B>;
|
|
|
|
public:
|
|
using iterator_category = std::random_access_iterator_tag;
|
|
using value_type = TypeT;
|
|
using difference_type = std::ptrdiff_t;
|
|
using reference = typename conditional<Reference, TypeT &, value_type>::type;
|
|
using const_reference = TypeT &;
|
|
using pointer = TypeT *;
|
|
|
|
private:
|
|
const Derived &constThisDerived() const {
|
|
return *static_cast<const Derived *>(this);
|
|
}
|
|
|
|
Derived &thisDerived() { return *static_cast<Derived *>(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<typename T, typename D, bool R>
|
|
Derived operator+(const RandomAccessIterator<T, D, R> &R2) {
|
|
assertCompatibility(R2);
|
|
return clone(Index + R2.Index);
|
|
}
|
|
|
|
template<typename T, typename D, bool R>
|
|
difference_type operator-(const RandomAccessIterator<T, D, R> &R2) const {
|
|
assertCompatibility(R2);
|
|
return Index - R2.Index;
|
|
}
|
|
|
|
private:
|
|
unsigned Index;
|
|
};
|