1 /*
2 * This file is part of the Simutrans project under the artistic license.
3 * (see license.txt)
4 */
5
6 #ifndef SIMTYPES_H
7 #define SIMTYPES_H
8
9 #include "utils/for.h"
10 #include <limits.h>
11
12 #ifndef PATH_MAX
13 #ifdef MAX_PATH
14 #define PATH_MAX (MAX_PATH)
15 #else
16 #define PATH_MAX 1024
17 #endif
18 #endif
19
20 #if defined _MSC_VER
21 # if _MSC_VER <= 1200
22 # error "Simutrans cannot be compiled with Visual C++ 6.0 or earlier."
23 # endif
24 #
25 # include <malloc.h>
26 # define ALLOCA(type, name, count) type* name = static_cast<type*>(alloca(sizeof(type) * (count)))
27 #elif defined __clang__
28 # include <stdlib.h>
29 # define ALLOCA(type, name, count) type* name = static_cast<type*>(alloca(sizeof(type) * (count)))
30 #else
31 # define ALLOCA(type, name, count) type name[count]
32 #endif
33
34 #if defined DEBUG
35 # include <stdlib.h>
36 # define NOT_REACHED abort();
37 #else
38 # define NOT_REACHED
39 #endif
40
41 #if defined (__GNUC__)
42 # define GNUC_DEFINED 1
43 #else
44 # define GNUC_DEFINED 0
45 #endif
46 #if defined (__GXX_EXPERIMENTAL_CXX0X__)
47 # define GXXEXP_DEFINED 1
48 #else
49 # define GXXEXP_DEFINED 0
50 #endif
51 #if defined (_MSC_VER)
52 # define MSC_DEFINED 1
53 #else
54 # define MSC_DEFINED 0
55 #endif
56
57 #define GCC_ATLEAST(major, minor) (GNUC_DEFINED && (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
58
59 #define CXX11(gcc_major, gcc_minor, msc_ver) ( \
60 __cplusplus >= 201103L || \
61 (GXXEXP_DEFINED && GCC_ATLEAST((gcc_major), (gcc_minor))) || \
62 (MSC_DEFINED && (msc_ver) != 0 && _MSC_VER >= (msc_ver)) \
63 )
64
65 #if CXX11(4, 4, 0)
66 # define DELETED = delete
67 #else
68 # define DELETED
69 #endif
70
71 #if CXX11(4, 7, 1400)
72 # define OVERRIDE override
73 #else
74 # define OVERRIDE
75 #endif
76
77 #define ENUM_BITSET(T) \
78 static inline T operator ~ (T a) { return (T)~(unsigned)a; } \
79 static inline T operator & (T a, T b) { return (T)((unsigned)a & (unsigned)b); } \
80 static inline T operator &= (T& a, T b) { return a = (T)((unsigned)a & (unsigned)b); } \
81 static inline T operator | (T a, T b) { return (T)((unsigned)a | (unsigned)b); } \
82 static inline T operator |= (T& a, T b) { return a = (T)((unsigned)a | (unsigned)b); }
83
84 /* divers enums:
85 * better defined here than scattered in thousand files ...
86 */
87 enum climate
88 {
89 water_climate = 0,
90 desert_climate,
91 tropic_climate,
92 mediterran_climate,
93 temperate_climate,
94 tundra_climate,
95 rocky_climate,
96 arctic_climate,
97 MAX_CLIMATES
98 };
99
100 enum climate_bits
101 {
102 water_climate_bit = 1 << water_climate,
103 desert_climate_bit = 1 << desert_climate,
104 tropic_climate_bit = 1 << tropic_climate,
105 mediterran_climate_bit = 1 << mediterran_climate,
106 temperate_climate_bit = 1 << temperate_climate,
107 tundra_climate_bit = 1 << tundra_climate,
108 rocky_climatebit = 1 << rocky_climate,
109 arctic_climate_bit = 1 << arctic_climate,
110 ALL_CLIMATES = (1 << MAX_CLIMATES) - 1,
111 all_but_water_climate = ALL_CLIMATES & ~water_climate_bit,
112 all_but_arctic_climate = ALL_CLIMATES & ~arctic_climate_bit
113 };
114
115 /**
116 * Vordefinierte Wegtypen.
117 * @author Hj. Malthaner
118 */
119 enum waytype_t {
120 invalid_wt = -1,
121 ignore_wt = 0,
122 road_wt = 1,
123 track_wt = 2,
124 water_wt = 3,
125 overheadlines_wt = 4,
126 monorail_wt = 5,
127 maglev_wt = 6,
128 tram_wt = 7,
129 narrowgauge_wt = 8,
130 air_wt = 16,
131 powerline_wt = 128,
132 any_wt = 255
133 };
134
135 /**
136 * System types for ways
137 */
138 enum systemtype_t {
139 type_flat = 0, ///< flat track
140 type_elevated = 1, ///< flag for elevated ways
141 type_runway = 1, ///< flag for runway (only aircrafts)
142 type_tram = 7, ///< tram track (waytype = track_wt)
143 type_river = 255, ///< flag for river
144 type_all = 255, ///< special ?
145 };
146
147
148 // makros are not very safe: thus use these macro like functions
149 // otherwise things may fail or functions are called uneccessarily twice
150
151 #define CLIP(wert,mini,maxi) min(max((wert),(mini)),(maxi))
152
153 // Hajo: define machine independent types
154 typedef unsigned int uint;
155 typedef signed char sint8;
156 typedef unsigned char uint8;
157 typedef signed short sint16;
158 typedef unsigned short uint16;
159 #ifndef __BEOS__
160 typedef signed int sint32;
161 #ifndef NO_UINT32_TYPES
162 typedef unsigned int uint32;
163 #endif
164 #else
165 // BeOS: int!=long (even though both 32 bit)
166 typedef signed long sint32;
167 #ifndef NO_UINT32_TYPES
168 typedef unsigned long uint32;
169 #endif
170 #endif
171 typedef signed long long sint64;
172 #ifndef NO_UINT64_TYPES
173 typedef unsigned long long uint64;
174 #endif
175 #ifdef _MSC_VER
176 # define GCC_PACKED
177 # define GCC_ALIGN(a)
178 # define MSVC_ALIGN(a) __declspec(align(a))
179 # define NORETURN __declspec(noreturn)
180 # pragma warning(disable: 4200 4311 4800 4996)
181 #else
182 # define GCC_PACKED __attribute__ ((__packed__))
183 # define GCC_ALIGN(a) __attribute__ ((aligned (a)))
184 # define MSVC_ALIGN(a)
185 # define NORETURN __attribute__ ((noreturn))
186 #endif
187
sgn(T x)188 template<typename T> static inline int sgn(T x)
189 {
190 if (x < 0) return -1;
191 if (x > 0) return 1;
192 return 0;
193 }
194
min(const int a,const int b)195 static inline int min(const int a, const int b)
196 {
197 return a < b ? a : b;
198 }
199
max(const int a,const int b)200 static inline int max(const int a, const int b)
201 {
202 return a > b ? a : b;
203 }
204
205 // endian conversion routines
206
endian(uint16 v)207 static inline uint16 endian(uint16 v)
208 {
209 #ifdef SIM_BIG_ENDIAN
210 v = (v << 8) | (v >> 8); // 0x0011
211 #endif
212 return v;
213 }
214
endian(uint32 v)215 static inline uint32 endian(uint32 v)
216 {
217 #ifdef SIM_BIG_ENDIAN
218 v = (v << 16) | (v >> 16); // 0x22330011
219 v = ( (v << 8) & 0xFF00FF00 ) | ( (v >> 8) & 0x00FF00FF ); // 0x33221100
220 #endif
221 return v;
222 }
223
endian(uint64 v)224 static inline uint64 endian(uint64 v)
225 {
226 #ifdef SIM_BIG_ENDIAN
227 v = (v << 32) | (v >> 32); // 0x4455667700112233
228 v = ( (v << 16) & 0xFFFF0000FFFF0000ULL ) | ( (v >> 16) & 0x0000FFFF0000FFFFULL ); // 0x6677445522330011
229 v = ( (v << 8) & 0xFF00FF00FF00FF00ULL ) | ( (v >> 8) & 0x00FF00FF00FF00FFULL ); // 0x7766554433221100
230 #endif
231 return v;
232 }
233
endian(sint16 const v)234 static inline sint16 endian(sint16 const v) { return sint16(endian(uint16(v))); }
endian(sint32 const v)235 static inline sint32 endian(sint32 const v) { return sint32(endian(uint32(v))); }
endian(sint64 const v)236 static inline sint64 endian(sint64 const v) { return sint64(endian(uint64(v))); }
237
238
239 /**
240 * Sometimes we need to pass pointers as well as integers through a
241 * standardized interface (i.e. via a function pointer). This union is used as
242 * a helper type to avoid cast operations. This isn't very clean, but if used
243 * with care it seems better than using "long" and casting to a pointer type.
244 * In all cases it ensures that no bits are lost.
245 * @author Hj. Malthaner
246 */
247 union value_t
248 {
value_t()249 value_t() : p(0) {}
value_t(long itg)250 value_t(long itg) : i(itg) {}
value_t(const void * ptr)251 value_t(const void* ptr) : p(ptr) {}
252
253 const void* p;
254 long i;
255 };
256
257 #endif
258