Cuberite
A lightweight, fast and extensible game server for Minecraft
Globals.h
Go to the documentation of this file.
1 
2 // Globals.h
3 
4 // This file gets included from every module in the project, so that global symbols may be introduced easily
5 // Also used for precompiled header generation in MSVC environments
6 
7 
8 
9 
10 
11 #pragma once
12 
13 
14 
15 
16 
17 // Compiler-dependent stuff:
18 #if defined(_MSC_VER)
19  // Use non-standard defines in <cmath>
20  #define _USE_MATH_DEFINES
21 
22  #ifndef NDEBUG
23  // Override the "new" operator to include file and line specification for debugging memory leaks
24  // Ref.: https://social.msdn.microsoft.com/Forums/en-US/ebc7dd7a-f3c6-49f1-8a60-e381052f21b6/debugging-memory-leaks?forum=vcgeneral#53f0cc89-62fe-45e8-bbf0-56b89f2a1901
25  // This causes MSVC Debug runs to produce a report upon program exit, that contains memory-leaks
26  // together with the file:line information about where the memory was allocated.
27  // Note that this doesn't work with placement-new, which needs to temporarily #undef the macro
28  // (See AllocationPool.h for an example).
29  #define _CRTDBG_MAP_ALLOC
30  #include <stdlib.h>
31  #include <crtdbg.h>
32  #define DEBUG_CLIENTBLOCK new(_CLIENT_BLOCK, __FILE__, __LINE__)
33  #define new DEBUG_CLIENTBLOCK
34  // For some reason this works magically - each "new X" gets replaced as "new(_CLIENT_BLOCK, "file", line) X"
35  // The CRT has a definition for this operator new that stores the debugging info for leak-finding later.
36  #endif
37 
38  #define UNREACHABLE_INTRINSIC __assume(false)
39 
40 #elif defined(__GNUC__)
41 
42  // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
43  #define abstract
44 
45  #define UNREACHABLE_INTRINSIC __builtin_unreachable()
46 
47 #else
48 
49  #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
50 
51 #endif
52 
53 
54 
55 
56 
57 // A macro to disallow the copy constructor and operator = functions
58 // This should be used in the declarations for any class that shouldn't allow copying itself
59 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
60  TypeName(const TypeName &) = delete; \
61  TypeName & operator =(const TypeName &) = delete
62 
63 // A macro that is used to mark unused local variables, to avoid pedantic warnings in gcc / clang / MSVC
64 // Note that in MSVC it requires the full type of X to be known
65 #define UNUSED_VAR(X) (void)(X)
66 
67 // A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc
68 // Written so that the full type of param needn't be known
69 #ifdef _MSC_VER
70  #define UNUSED(X)
71 #else
72  #define UNUSED UNUSED_VAR
73 #endif
74 
75 
76 
77 
78 
79 // OS-dependent stuff:
80 #ifdef _WIN32
81  #define NOMINMAX // Windows SDK defines min and max macros, messing up with our std::min and std::max usage.
82  #define WIN32_LEAN_AND_MEAN
83  #define _WIN32_WINNT 0x0501 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher.
84 
85  // Use CryptoAPI primitives when targeting a version that supports encrypting with AES-CFB8 smaller than a full block at a time.
86  #define PLATFORM_CRYPTOGRAPHY (_WIN32_WINNT >= 0x0602)
87 
88  #include <Windows.h>
89  #include <winsock2.h>
90  #include <Ws2tcpip.h> // IPv6 stuff
91 
92  // Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant:
93  #ifdef GetFreeSpace
94  #undef GetFreeSpace
95  #endif // GetFreeSpace
96 #else
97  #define PLATFORM_CRYPTOGRAPHY 0
98 
99  #include <arpa/inet.h>
100  #include <unistd.h>
101 #endif
102 
103 
104 
105 
106 
107 // CRT stuff:
108 #include <cassert>
109 #include <cstdio>
110 #include <cmath>
111 #include <cstdarg>
112 #include <cstddef>
113 
114 
115 
116 
117 
118 // STL stuff:
119 #include <algorithm>
120 #include <array>
121 #include <atomic>
122 #include <chrono>
123 #include <condition_variable>
124 #include <deque>
125 #include <fstream>
126 #include <limits>
127 #include <list>
128 #include <map>
129 #include <memory>
130 #include <mutex>
131 #include <queue>
132 #include <random>
133 #include <set>
134 #include <string>
135 #include <thread>
136 #include <type_traits>
137 #include <unordered_map>
138 #include <unordered_set>
139 #include <utility>
140 #include <vector>
141 #include <variant>
142 
143 
144 
145 
146 
147 // Integral types with predefined sizes:
148 typedef signed long long Int64;
149 typedef signed int Int32;
150 typedef signed short Int16;
151 typedef signed char Int8;
152 
153 typedef unsigned long long UInt64;
154 typedef unsigned int UInt32;
155 typedef unsigned short UInt16;
156 typedef unsigned char UInt8;
157 
158 typedef unsigned char Byte;
159 typedef Byte ColourID;
160 
161 
162 template <typename T, size_t Size>
164 {
165  static_assert(sizeof(T) == Size, "Check the size of integral types");
166 };
167 
168 template class SizeChecker<Int64, 8>;
169 template class SizeChecker<Int32, 4>;
170 template class SizeChecker<Int16, 2>;
171 template class SizeChecker<Int8, 1>;
172 
173 template class SizeChecker<UInt64, 8>;
174 template class SizeChecker<UInt32, 4>;
175 template class SizeChecker<UInt16, 2>;
176 template class SizeChecker<UInt8, 1>;
177 
178 // Common headers (part 1, without macros):
179 #include "fmt.h"
180 #include "StringUtils.h"
181 #include "LoggerSimple.h"
183 #include "OSSupport/Event.h"
184 #include "OSSupport/File.h"
185 #include "OSSupport/StackTrace.h"
186 
187 #ifdef TEST_GLOBALS
188 
189  // Basic logging function implementations
190  namespace Logger
191  {
192 
193  inline void LogFormat(
194  std::string_view a_Format, eLogLevel, fmt::format_args a_ArgList
195  )
196  {
197  fmt::vprint(a_Format, a_ArgList);
198  putchar('\n');
199  fflush(stdout);
200  }
201 
202  inline void LogPrintf(
203  std::string_view a_Format, eLogLevel, fmt::printf_args a_ArgList
204  )
205  {
206  fmt::vprintf(a_Format, a_ArgList);
207  putchar('\n');
208  fflush(stdout);
209  }
210 
211  inline void LogSimple(std::string_view a_Message, eLogLevel)
212  {
213  fmt::print("{}\n", a_Message);
214  fflush(stdout);
215  }
216 
217  } // namespace Logger
218 
219 #endif
220 
221 
222 
223 
224 
225 // Common definitions:
226 
228 #define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
229 
231 #define KiB * 1024
232 #define MiB * 1024 * 1024
233 
235 #define FAST_FLOOR_DIV(x, div) (((x) - (((x) < 0) ? ((div) - 1) : 0)) / (div))
236 
237 // Own version of ASSERT() that plays nicely with the testing framework
238 #ifdef TEST_GLOBALS
239 
240  class cAssertFailure
241  {
242  AString mExpression;
243  AString mFileName;
244  int mLineNumber;
245 
246  public:
247  cAssertFailure(const AString & aExpression, const AString & aFileName, int aLineNumber):
248  mExpression(aExpression),
249  mFileName(aFileName),
250  mLineNumber(aLineNumber)
251  {
252  }
253 
254  const AString & expression() const { return mExpression; }
255  const AString & fileName() const { return mFileName; }
256  int lineNumber() const { return mLineNumber; }
257  };
258 
259  #ifdef NDEBUG
260  #define ASSERT(x)
261  #else
262  #define ASSERT(x) do { if (!(x)) { throw cAssertFailure(#x, __FILE__, __LINE__);} } while (0)
263  #endif
264 
265  // Pretty much the same as ASSERT() but stays in Release builds
266  #define VERIFY(x) (!!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), std::abort(), 0))
267 
268 #else // TEST_GLOBALS
269 
270  #ifdef NDEBUG
271  #define ASSERT(x)
272  #else
273  #define ASSERT(x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), std::abort(), 0))
274  #endif
275 
276  // Pretty much the same as ASSERT() but stays in Release builds
277  #define VERIFY(x) (!!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), std::abort(), 0))
278 
279 #endif // else TEST_GLOBALS
280 
281 // Use to mark code that should be impossible to reach.
282 #ifdef NDEBUG
283  #define UNREACHABLE(x) UNREACHABLE_INTRINSIC
284 #else
285  #define UNREACHABLE(x) ( FLOGERROR("Hit unreachable code: {0}, file {1}, line {2}", #x, __FILE__, __LINE__), std::abort(), 0)
286 #endif
287 
288 
289 
290 
291 
292 namespace cpp20
293 {
294  template <class T>
295  std::enable_if_t<std::is_array_v<T> && (std::extent_v<T> == 0), std::unique_ptr<T>> make_unique_for_overwrite(std::size_t a_Size)
296  {
297  return std::unique_ptr<T>(new std::remove_extent_t<T>[a_Size]);
298  }
299 
300  template <class T>
301  std::enable_if_t<!std::is_array_v<T>, std::unique_ptr<T>> make_unique_for_overwrite()
302  {
303  return std::unique_ptr<T>(new T);
304  }
305 }
306 
307 
308 
309 
310 
324 template<class... Ts> struct OverloadedVariantAccess : Ts... { using Ts::operator()...; };
325 template<class... Ts> OverloadedVariantAccess(Ts...)->OverloadedVariantAccess<Ts...>;
326 
327 
328 
329 
330 
332 template <typename T>
333 T Clamp(T a_Value, T a_Min, T a_Max)
334 {
335  return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
336 }
337 
338 
339 
340 
341 
343 template <typename C = int, typename T>
344 typename std::enable_if<std::is_arithmetic<T>::value, C>::type FloorC(T a_Value)
345 {
346  return static_cast<C>(std::floor(a_Value));
347 }
348 
350 template <typename C = int, typename T>
351 typename std::enable_if<std::is_arithmetic<T>::value, C>::type CeilC(T a_Value)
352 {
353  return static_cast<C>(std::ceil(a_Value));
354 }
355 
356 
357 
358 
359 
360 // A time duration representing a Minecraft tick (50 ms), capable of storing at least 32'767 ticks.
361 using cTickTime = std::chrono::duration<signed int, std::ratio_multiply<std::chrono::milliseconds::period, std::ratio<50>>>;
362 
363 // A time duration representing a Minecraft tick (50 ms), capable of storing at least a 64 bit signed duration.
364 using cTickTimeLong = std::chrono::duration<signed long long int, cTickTime::period>;
365 
367 constexpr cTickTimeLong operator ""_tick(const unsigned long long a_Ticks)
368 {
369  return cTickTimeLong(a_Ticks);
370 }
371 
372 using ContiguousByteBuffer = std::basic_string<std::byte>;
373 using ContiguousByteBufferView = std::basic_string_view<std::byte>;
374 
375 #ifndef TOLUA_TEMPLATE_BIND
376  #define TOLUA_TEMPLATE_BIND(x)
377 #endif
378 
379 #ifdef TOLUA_EXPOSITION
380  #error TOLUA_EXPOSITION should never actually be defined
381 #endif
382 
383 template <typename T>
384 auto ToUnsigned(T a_Val)
385 {
386  ASSERT(a_Val >= 0);
387  return static_cast<std::make_unsigned_t<T>>(a_Val);
388 }
389 
390 
391 
392 
393 
394 // Common headers (part 2, with macros):
395 #include "Vector3.h"
FloorC
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:344
Logger::LogSimple
void LogSimple(std::string_view a_Message, eLogLevel a_LogLevel)
Definition: Logger.cpp:169
ContiguousByteBuffer
std::basic_string< std::byte > ContiguousByteBuffer
Definition: Globals.h:372
Logger::LogFormat
void LogFormat(std::string_view a_Format, eLogLevel a_LogLevel, fmt::format_args a_ArgList)
Definition: Logger.cpp:151
ToUnsigned
auto ToUnsigned(T a_Val)
Definition: Globals.h:384
cpp20
Definition: Globals.h:292
CriticalSection.h
UInt16
unsigned short UInt16
Definition: Globals.h:155
OverloadedVariantAccess
You can use this struct to use in std::visit example: std::visit( OverloadedVariantAccess { [&] (cFir...
Definition: Globals.h:324
ColourID
Byte ColourID
Definition: Globals.h:159
fmt.h
UInt32
unsigned int UInt32
Definition: Globals.h:154
ASSERT
#define ASSERT(x)
Definition: Globals.h:273
Vector3.h
Clamp
T Clamp(T a_Value, T a_Min, T a_Max)
Clamp X to the specified range.
Definition: Globals.h:333
CeilC
std::enable_if< std::is_arithmetic< T >::value, C >::type CeilC(T a_Value)
Ceils a value, then casts it to C (an int by default).
Definition: Globals.h:351
ContiguousByteBufferView
std::basic_string_view< std::byte > ContiguousByteBufferView
Definition: Globals.h:373
StringUtils.h
Int32
signed int Int32
Definition: Globals.h:149
Event.h
cTickTime
std::chrono::duration< signed int, std::ratio_multiply< std::chrono::milliseconds::period, std::ratio< 50 > >> cTickTime
Definition: Globals.h:361
Byte
unsigned char Byte
Definition: Globals.h:158
Int8
signed char Int8
Definition: Globals.h:151
SizeChecker
Definition: Globals.h:163
LoggerSimple.h
Int64
signed long long Int64
Definition: Globals.h:148
File.h
StackTrace.h
cTickTimeLong
std::chrono::duration< signed long long int, cTickTime::period > cTickTimeLong
Definition: Globals.h:364
UInt8
unsigned char UInt8
Definition: Globals.h:156
Logger::LogPrintf
void LogPrintf(std::string_view a_Format, eLogLevel a_LogLevel, fmt::printf_args a_ArgList)
Definition: Logger.cpp:160
AString
std::string AString
Definition: StringUtils.h:11
eLogLevel
eLogLevel
Definition: LoggerSimple.h:5
UInt64
unsigned long long UInt64
Definition: Globals.h:153
Int16
signed short Int16
Definition: Globals.h:150
OverloadedVariantAccess
OverloadedVariantAccess(Ts...) -> OverloadedVariantAccess< Ts... >
cpp20::make_unique_for_overwrite
std::enable_if_t<!std::is_array_v< T >, std::unique_ptr< T > > make_unique_for_overwrite()
Definition: Globals.h:301
Logger
Definition: LoggerSimple.h:13