#pragma once // enum.hpp - Safe building blocks for enumerated types. // // Copyright © 2012-2014 Ben Longbons // // This file is part of The Mana World (Athena server) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "fwd.hpp" #include #include #include #include #include "../compat/iter.hpp" #include "array.hpp" namespace tmwa { // part moved to fwd.hpp template class eptr { constexpr static size_t size() { return static_cast(max); } T *_data; public: eptr(std::nullptr_t=nullptr) : _data(nullptr) {} eptr(earray& arr) : _data(arr.data) {} T& operator [](E v) const { auto i = static_cast(v); assert (i < size()); return _data[i]; } explicit operator bool() { return _data; } bool operator not() { return not _data; } }; // std::underlying_type isn't supported until gcc 4.7 // this is a poor man's emulation // TODO I'm depending on GCC 4.7 now, this can go away 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; }; template::value> struct remove_enum { typedef E type; }; template struct remove_enum { typedef typename underlying_type::type type; }; // This really should just go in a namespace // that's how I use it anyway ... #define ENUM_BITWISE_OPERATORS(E) \ inline \ E operator & (E l, E r) \ { \ typedef underlying_type::type U; \ return E(U(l) & U(r)); \ } \ inline \ E operator | (E l, E r) \ { \ typedef underlying_type::type U; \ return E(U(l) | U(r)); \ } \ inline \ E operator ^ (E l, E r) \ { \ typedef underlying_type::type U; \ return E(U(l) ^ U(r)); \ } \ inline \ E& operator &= (E& l, E r) \ { \ return l = l & r; \ } \ inline \ E& operator |= (E& l, E r) \ { \ return l = l | r; \ } \ inline \ E& operator ^= (E& l, E r) \ { \ return l = l ^ r; \ } \ inline \ E operator ~ (E r) \ { \ return E(-1) ^ r; \ } template class EnumMath { typedef typename underlying_type::type U; public: static E inced(E v) { return static_cast(static_cast(v) + 1); } }; template IteratorPair>> erange(E b, E e) { return {b, e}; } } // namespace tmwa