#pragma once #define ITERABLE_ENUM_BEGIN(name) enum class name : int { #define ITERABLE_ENUM_END ,end, begin = 0 } template class Iterable { public: Iterable(T value = T::begin) : mValue(value) {} Iterable(const Iterable& other) : mValue(other.mValue) {} Iterable& operator++() { assert(mValue >= T::begin && mValue < T::end); mValue = static_cast(static_cast(mValue) + 1); return *this; } Iterable operator++(int) { Iterable prev = *this; mValue = static_cast(static_cast(mValue) + 1); return prev; } Iterable& operator--() { assert(mValue >= T::end && mValue < T::begin); mValue = static_cast(static_cast(mValue) - 1); return *this; } Iterable operator--(int) { Iterable prev = *this; mValue = static_cast(static_cast(mValue) - 1); return prev; } Iterable operator+(int i) { return static_cast(static_cast(mValue) + i); } Iterable operator+(T i) { return static_cast(static_cast(mValue) + static_cast(i)); } Iterable operator-(int i) { return static_cast(static_cast(mValue) - i); } Iterable operator-(T i) { return static_cast(static_cast(mValue) - static_cast(i)); } bool operator >(const T& other) const { return static_cast(mValue) > static_cast(other); } bool operator >=(const T& other) const { return static_cast(mValue) >= static_cast(other); } bool operator <(const T& other) const { return static_cast(mValue) < static_cast(other); } bool operator <=(const T& other) const { return static_cast(mValue) <= static_cast(other); } bool operator ==(const T& other) const { return static_cast(mValue) == static_cast(other); } bool valid() const { return mValue != T::end; } operator T() const { return mValue; } operator T&() { return mValue; } T val() const { return mValue; } private: T mValue; };