Translations update
[openttd/fttd.git] / src / core / enum_type.hpp
blob35a0cb2926c768e702f75936d1528f166cddc0d5
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file enum_type.hpp Type (helpers) for enums */
12 #ifndef ENUM_TYPE_HPP
13 #define ENUM_TYPE_HPP
15 /** Some enums need to have allowed incrementing (i.e. StationClassID) */
16 #define DECLARE_POSTFIX_INCREMENT(type) \
17 inline type operator ++(type& e, int) \
18 { \
19 type e_org = e; \
20 e = (type)((int)e + 1); \
21 return e_org; \
22 } \
23 inline type operator --(type& e, int) \
24 { \
25 type e_org = e; \
26 e = (type)((int)e - 1); \
27 return e_org; \
32 /** Operators to allow to work with enum as with type safe bit set in C++ */
33 # define DECLARE_ENUM_AS_BIT_SET(mask_t) \
34 inline mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((int)m1 | m2);} \
35 inline mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((int)m1 & m2);} \
36 inline mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((int)m1 ^ m2);} \
37 inline mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \
38 inline mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \
39 inline mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \
40 inline mask_t operator ~(mask_t m) {return (mask_t)(~(int)m);}
43 /**
44 * Informative template class exposing basic enumeration properties used by several
45 * other templates below. Here we have only forward declaration. For each enum type
46 * we will create specialization derived from MakeEnumPropsT<>.
47 * i.e.:
48 * template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {};
49 * followed by:
50 * typedef TinyEnumT<Track> TrackByte;
52 template <typename Tenum_t> struct EnumPropsT;
54 /**
55 * Helper template class that makes basic properties of given enumeration type visible
56 * from outsize. It is used as base class of several EnumPropsT specializations each
57 * dedicated to one of commonly used enumeration types.
58 * @param Tenum_t enumeration type that you want to describe
59 * @param Tstorage_t what storage type would be sufficient (i.e. byte)
60 * @param Tbegin first valid value from the contiguous range (i.e. TRACK_BEGIN)
61 * @param Tend one past the last valid value from the contiguous range (i.e. TRACK_END)
62 * @param Tinvalid value used as invalid value marker (i.e. INVALID_TRACK)
63 * @param Tnum_bits Number of bits for storing the enum in command parameters
65 template <typename Tenum_t, typename Tstorage_t, Tenum_t Tbegin, Tenum_t Tend, Tenum_t Tinvalid, uint Tnum_bits = 8 * sizeof(Tstorage_t)>
66 struct MakeEnumPropsT {
67 typedef Tenum_t type; ///< enum type (i.e. Trackdir)
68 typedef Tstorage_t storage; ///< storage type (i.e. byte)
69 static const Tenum_t begin = Tbegin; ///< lowest valid value (i.e. TRACKDIR_BEGIN)
70 static const Tenum_t end = Tend; ///< one after the last valid value (i.e. TRACKDIR_END)
71 static const Tenum_t invalid = Tinvalid; ///< what value is used as invalid value (i.e. INVALID_TRACKDIR)
72 static const uint num_bits = Tnum_bits; ///< Number of bits for storing the enum in command parameters
77 /**
78 * In some cases we use byte or uint16 to store values that are defined as enum. It is
79 * necessary in order to control the sizeof() such values. Some compilers make enum
80 * the same size as int (4 or 8 bytes instead of 1 or 2). As a consequence the strict
81 * compiler type - checking causes errors like:
82 * 'HasPowerOnRail' : cannot convert parameter 1 from 'byte' to 'RailType' when
83 * u->u.rail.railtype is passed as argument or type RailType. In such cases it is better
84 * to teach the compiler that u->u.rail.railtype is to be treated as RailType.
86 template <typename Tenum_t> struct TinyEnumT;
88 /** The general declaration of TinyEnumT<> (above) */
89 template <typename Tenum_t>
90 struct TinyEnumT {
91 typedef Tenum_t enum_type; ///< expose our enumeration type (i.e. Trackdir) to outside
92 typedef EnumPropsT<Tenum_t> Props; ///< make easier access to our enumeration properties
93 typedef typename Props::storage storage_type; ///< small storage type
94 static const enum_type begin = Props::begin; ///< enum beginning (i.e. TRACKDIR_BEGIN)
95 static const enum_type end = Props::end; ///< enum end (i.e. TRACKDIR_END)
96 static const enum_type invalid = Props::invalid;///< invalid value (i.e. INVALID_TRACKDIR)
98 storage_type m_val; ///< here we hold the actual value in small (i.e. byte) form
100 /** Cast operator - invoked then the value is assigned to the Tenum_t type */
101 inline operator enum_type () const
103 return (enum_type)m_val;
106 /** Assignment operator (from Tenum_t type) */
107 inline TinyEnumT& operator = (enum_type e)
109 m_val = (storage_type)e;
110 return *this;
113 /** Assignment operator (from Tenum_t type) */
114 inline TinyEnumT& operator = (uint u)
116 m_val = (storage_type)u;
117 return *this;
120 /** postfix ++ operator on tiny type */
121 inline TinyEnumT operator ++ (int)
123 TinyEnumT org = *this;
124 if (++m_val >= end) m_val -= (storage_type)(end - begin);
125 return org;
128 /** prefix ++ operator on tiny type */
129 inline TinyEnumT& operator ++ ()
131 if (++m_val >= end) m_val -= (storage_type)(end - begin);
132 return *this;
137 /** Template of struct holding enum types (on most archs, enums are stored in an int32). No math operators are provided. */
138 template <typename enum_type, typename storage_type>
139 struct SimpleTinyEnumT {
140 storage_type m_val; ///< here we hold the actual value in small (i.e. byte) form
142 /** Cast operator - invoked then the value is assigned to the storage_type */
143 inline operator enum_type () const
145 return (enum_type)this->m_val;
148 /** Assignment operator (from enum_type) */
149 inline SimpleTinyEnumT &operator = (enum_type e)
151 this->m_val = (storage_type)e;
152 return *this;
155 /** Assignment operator (from general uint) */
156 inline SimpleTinyEnumT &operator = (uint u)
158 this->m_val = (storage_type)u;
159 return *this;
162 /** Bit math (or) assignment operator (from enum_type) */
163 inline SimpleTinyEnumT &operator |= (enum_type e)
165 this->m_val = (storage_type)((enum_type)this->m_val | e);
166 return *this;
169 /** Bit math (and) assignment operator (from enum_type) */
170 inline SimpleTinyEnumT &operator &= (enum_type e)
172 this->m_val = (storage_type)((enum_type)this->m_val & e);
173 return *this;
177 #endif /* ENUM_TYPE_HPP */