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/>.
10 /** @file enum_type.hpp Type (helpers) for enums */
15 /** Some enums need to have allowed incrementing (i.e. StationClassID) */
16 #define DECLARE_POSTFIX_INCREMENT(type) \
17 inline type operator ++(type& e, int) \
20 e = (type)((int)e + 1); \
23 inline type operator --(type& e, int) \
26 e = (type)((int)e - 1); \
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);}
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<>.
48 * template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {};
50 * typedef TinyEnumT<Track> TrackByte;
52 template <typename Tenum_t
> struct EnumPropsT
;
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
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
>
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
;
113 /** Assignment operator (from Tenum_t type) */
114 inline TinyEnumT
& operator = (uint u
)
116 m_val
= (storage_type
)u
;
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
);
128 /** prefix ++ operator on tiny type */
129 inline TinyEnumT
& operator ++ ()
131 if (++m_val
>= end
) m_val
-= (storage_type
)(end
- begin
);
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
;
155 /** Assignment operator (from general uint) */
156 inline SimpleTinyEnumT
&operator = (uint u
)
158 this->m_val
= (storage_type
)u
;
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
);
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
);
177 #endif /* ENUM_TYPE_HPP */