// included by utils.hpp as a porting aid. // Eventually it will be promoted to one or more normal headers. #include #include template struct earray { // no ctor/dtor and one public member variable for easy initialization T _data[size_t(max)]; T& operator[](E v) { return _data[size_t(v)]; } const T& operator[](E v) const { return _data[size_t(v)]; } T *begin() { return _data; } T *end() { return _data + size_t(max); } }; template class eptr { T *_data; public: eptr(decltype(nullptr)=nullptr) : _data(nullptr) {} template eptr(earray& arr) : _data(arr._data) {} T& operator [](E v) { return _data[size_t(v)]; } explicit operator bool() { return _data; } bool operator not() { return not _data; } }; template class IteratorPair { It b, e; public: IteratorPair(It b, It e) : b(b), e(e) {} It begin() { return b; } It end() { return e; } }; template IteratorPair iterator_pair(It b, It e) { return {b, e}; } #ifndef HAVE_STD_UNDERLYING_TYPE // Note: you *must* correctly define/not define this - it conflicts! namespace std { template struct underlying_type { static_assert(std::is_enum::value, "Only enums have underlying type!"); typedef typename std::conditional< std::is_signed::value, typename std::make_signed::type, typename std::make_unsigned::type >::type type; }; } #endif // HAVE_STD_UNDERLYING_TYPE template class EnumValueIterator { typedef typename std::underlying_type::type U; E value; public: EnumValueIterator(E v) : value(v) {} E operator *() { return value; } EnumValueIterator& operator++ () { value = E(U(value) + 1); return *this; } EnumValueIterator& operator-- () { value = E(U(value) - 1); return *this; } friend bool operator == (EnumValueIterator l, EnumValueIterator r) { return l.value == r.value; } friend bool operator != (EnumValueIterator l, EnumValueIterator r) { return !(l == r); } }; template IteratorPair> erange(E b, E e) { return {b, e}; }