1 /* 2 * This file is part of OpenTTD. 3 * OpenTTD 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, version 2. 4 * OpenTTD 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. 5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. 6 */ 7 8 /** @file enum_type.hpp Type (helpers) for enums */ 9 10 #ifndef ENUM_TYPE_HPP 11 #define ENUM_TYPE_HPP 12 13 /** Some enums need to have allowed incrementing (i.e. StationClassID) */ 14 #define DECLARE_POSTFIX_INCREMENT(enum_type) \ 15 inline enum_type operator ++(enum_type& e, int) \ 16 { \ 17 enum_type e_org = e; \ 18 e = (enum_type)((std::underlying_type<enum_type>::type)e + 1); \ 19 return e_org; \ 20 } \ 21 inline enum_type operator --(enum_type& e, int) \ 22 { \ 23 enum_type e_org = e; \ 24 e = (enum_type)((std::underlying_type<enum_type>::type)e - 1); \ 25 return e_org; \ 26 } 27 28 29 30 /** Operators to allow to work with enum as with type safe bit set in C++ */ 31 # define DECLARE_ENUM_AS_BIT_SET(mask_t) \ 32 inline mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 | m2);} \ 33 inline mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 & m2);} \ 34 inline mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type<mask_t>::type)m1 ^ m2);} \ 35 inline mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \ 36 inline mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \ 37 inline mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \ 38 inline mask_t operator ~(mask_t m) {return (mask_t)(~(std::underlying_type<mask_t>::type)m);} 39 40 41 /** 42 * Informative template class exposing basic enumeration properties used by several 43 * other templates below. Here we have only forward declaration. For each enum type 44 * we will create specialization derived from MakeEnumPropsT<>. 45 * i.e.: 46 * template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {}; 47 */ 48 template <typename Tenum_t> struct EnumPropsT; 49 50 /** 51 * Helper template class that makes basic properties of given enumeration type visible 52 * from outsize. It is used as base class of several EnumPropsT specializations each 53 * dedicated to one of commonly used enumeration types. 54 * @param Tenum_t enumeration type that you want to describe 55 * @param Tstorage_t what storage type would be sufficient (i.e. byte) 56 * @param Tbegin first valid value from the contiguous range (i.e. TRACK_BEGIN) 57 * @param Tend one past the last valid value from the contiguous range (i.e. TRACK_END) 58 * @param Tinvalid value used as invalid value marker (i.e. INVALID_TRACK) 59 * @param Tnum_bits Number of bits for storing the enum in command parameters 60 */ 61 template <typename Tenum_t, typename Tstorage_t, Tenum_t Tbegin, Tenum_t Tend, Tenum_t Tinvalid, uint Tnum_bits = 8 * sizeof(Tstorage_t)> 62 struct MakeEnumPropsT { 63 typedef Tenum_t type; ///< enum type (i.e. Trackdir) 64 typedef Tstorage_t storage; ///< storage type (i.e. byte) 65 static const Tenum_t begin = Tbegin; ///< lowest valid value (i.e. TRACKDIR_BEGIN) 66 static const Tenum_t end = Tend; ///< one after the last valid value (i.e. TRACKDIR_END) 67 static const Tenum_t invalid = Tinvalid; ///< what value is used as invalid value (i.e. INVALID_TRACKDIR) 68 static const uint num_bits = Tnum_bits; ///< Number of bits for storing the enum in command parameters 69 }; 70 71 #endif /* ENUM_TYPE_HPP */ 72