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