1 // Copyright 2009-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #define _CRT_SECURE_NO_WARNINGS
7 
8 #include <stdint.h>
9 #include <cassert>
10 #include <cstddef>
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 #include <fstream>
15 #include <iomanip>
16 #include <iostream>
17 #include <memory>
18 #include <sstream>
19 #include <stdexcept>
20 #include <string>
21 
22 #ifdef _WIN32
23 #include <intrin.h>
24 #include <windows.h>
25 #endif
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 /// Macros
29 ////////////////////////////////////////////////////////////////////////////////
30 
31 #ifdef _WIN32
32 #undef __noinline
33 #define __noinline __declspec(noinline)
34 //#define __forceinline        __forceinline
35 //#define __restrict           __restrict
36 #ifdef __INTEL_COMPILER
37 #define __restrict__ __restrict
38 #else
39 #define __restrict__  //__restrict // causes issues with MSVC
40 #endif
41 #define __thread __declspec(thread)
42 #define __aligned(...) __declspec(align(__VA_ARGS__))
43 //#define __FUNCTION__           __FUNCTION__
44 #define debugbreak() __debugbreak()
45 
46 #else
47 #undef __noinline
48 #undef __forceinline
49 #define __noinline __attribute__((noinline))
50 #define __forceinline inline __attribute__((always_inline))
51 //#define __restrict             __restrict
52 //#define __thread               __thread
53 #define __aligned(...) __attribute__((aligned(__VA_ARGS__)))
54 #define __FUNCTION__ __PRETTY_FUNCTION__
55 #define debugbreak() asm("int $3")
56 #endif
57 
58 #ifdef __GNUC__
59 #define MAYBE_UNUSED __attribute__((unused))
60 #else
61 #define MAYBE_UNUSED
62 #endif
63 
64 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
65 #define likely(expr) (expr)
66 #define unlikely(expr) (expr)
67 #else
68 #define likely(expr) __builtin_expect((bool)(expr), true)
69 #define unlikely(expr) __builtin_expect((bool)(expr), false)
70 #endif
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Error handling and debugging
74 ////////////////////////////////////////////////////////////////////////////////
75 
76 /* debug printing macros */
77 #define STRING(x) #x
78 #define TOSTRING(x) STRING(x)
79 #define CODE_LOCATION __FILE__ " (" TOSTRING(__LINE__) ")"
80 #define PING                                                   \
81   {                                                            \
82     std::stringstream msg;                                     \
83     msg << CODE_LOCATION << ": " << __FUNCTION__ << std::endl; \
84     std::cout << msg.str();                                    \
85   }
86 #define PRINT(x)                                   \
87   {                                                \
88     std::stringstream msg;                         \
89     msg << STRING(x) << " = " << (x) << std::endl; \
90     std::cout << msg.str();                        \
91   }
92 #define PRINT2(x, y)                                                      \
93   {                                                                       \
94     std::stringstream msg;                                                \
95     msg << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) \
96         << std::endl;                                                     \
97     std::cout << msg.str();                                               \
98   }
99 #define PRINT3(x, y, z)                                                   \
100   {                                                                       \
101     std::stringstream msg;                                                \
102     msg << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) \
103         << ", " << STRING(z) << " = " << (z) << std::endl;                \
104     std::cout << msg.str();                                               \
105   }
106 #define PRINT4(x, y, z, w)                                                 \
107   {                                                                        \
108     std::stringstream msg;                                                 \
109     msg << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y)  \
110         << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " \
111         << (w) << std::endl;                                               \
112     std::cout << msg.str();                                                \
113   }
114 
115 #define THROW_RUNTIME_ERROR(str)                                 \
116   throw std::runtime_error(std::string(__FILE__) + " (" +        \
117                            std::to_string((long long)__LINE__) + \
118                            "): " + std::string(str))
119 #define FATAL(x) THROW_RUNTIME_ERROR(x)
120 #define WARNING(x) std::cerr << "Warning:" << std::string(x) << std::endl
121 
122 #define NOT_IMPLEMENTED FATAL(std::string(__FUNCTION__) + " not implemented")
123 
124 // NOTE(jda) - These macros are used to construct the last UNUSED(...) macro,
125 //             used to mark a variable number of arguments as unused so the
126 //             compiler doesn't warn when -Wextra (gcc/clang/icc) is used. Only
127 //             works with 1 to 5 passed arguments.
128 #define UNUSED_1(x) (void)x
129 #define UNUSED_2(x, y) \
130   UNUSED_1(x);         \
131   UNUSED_1(y)
132 #define UNUSED_3(x, ...) UNUSED_2(x, UNUSED_2(__VA_ARGS__))
133 #define UNUSED_4(x, ...) UNUSED_2(x, UNUSED_3(__VA_ARGS__))
134 #define UNUSED_5(x, ...) UNUSED_2(x, UNUSED_4(__VA_ARGS__))
135 
136 // NUM_ARGS(...) evaluates to the literal number of the passed-in arguments.
137 #define _NUM_ARGS2(X, X5, X4, X3, X2, X1, N, ...) N
138 #define NUM_ARGS(...) _NUM_ARGS2(0, __VA_ARGS__, 5, 4, 3, 2, 1, 0)
139 
140 #define _UNUSED_N3(N, ...) UNUSED_##N(__VA_ARGS__)
141 #define _UNUSED_N2(N, ...) _UNUSED_N3(N, __VA_ARGS__)
142 #define UNUSED(...) _UNUSED_N2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__)
143 
144 #if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
145 #define __X86_64__
146 #endif
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// Basic Types
150 ////////////////////////////////////////////////////////////////////////////////
151 
152 /* windows does not have ssize_t */
153 #ifdef __WIN32
154 #ifdef __X86_64__
155 typedef int64_t ssize_t;
156 #else
157 typedef int32_t ssize_t;
158 #endif
159 #endif
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Disable some compiler warnings
163 ////////////////////////////////////////////////////////////////////////////////
164 
165 #if defined(__INTEL_COMPILER)
166 #pragma warning( \
167     disable : 265)  // floating-point operation result is out of range
168 #pragma warning( \
169     disable : 383)  // value copied to temporary, reference to temporary used
170 #pragma warning(disable : 869)  // parameter was never referenced
171 #pragma warning(disable : 981)  // operands are evaluated in unspecified order
172 #pragma warning( \
173     disable : 1418)  // external function definition with no prior declaration
174 #pragma warning(disable : 1419)  // external declaration in primary source file
175 #pragma warning(disable : 1572)  // floating-point equality and inequality
176                                  // comparisons are unreliable
177 #pragma warning(disable : 94)  // the size of an array must be greater than zero
178 #pragma warning(disable : 1599)  // declaration hides parameter
179 #pragma warning(disable : 424)   // extra ";" ignored
180 #pragma warning(disable : 2196)  // routine is both "inline" and "noinline"
181 #pragma warning(disable : 177)   // label was declared but never referenced
182 #pragma warning(disable : 114)   // function was referenced but not defined
183 #endif
184 
185 #if defined(_MSC_VER)
186 #pragma warning(disable : 4200)  // nonstandard extension used : zero-sized
187                                  // array in struct/union
188 #pragma warning(disable : 4800)  // forcing value to bool 'true' or 'false'
189                                  // (performance warning)
190 #pragma warning(disable : 4267)  // '=' : conversion from 'size_t' to 'unsigned
191                                  // long', possible loss of data
192 #pragma warning(disable : 4244)  // 'argument' : conversion from 'ssize_t' to
193                                  // 'unsigned int', possible loss of data
194 #pragma warning( \
195     disable : 4355)             // 'this' : used in base member initializer list
196 #pragma warning(disable : 391)  // '<=' : signed / unsigned mismatch
197 #pragma warning(disable : 4018)  // '<' : signed / unsigned mismatch
198 #pragma warning( \
199     disable : 4305)  // 'initializing' : truncation from 'double' to 'float'
200 #pragma warning(disable : 4068)  // unknown pragma
201 #pragma warning(disable : 4146)  // unary minus operator applied to unsigned
202                                  // type, result still unsigned
203 #pragma warning(disable : 4838)  // conversion from 'unsigned int' to 'const
204                                  // int' requires a narrowing conversion)
205 #pragma warning( \
206     disable : 4227)  // anachronism used : qualifiers on reference are ignored
207 #endif
208 
209 #if defined(__clang__) && !defined(__INTEL_COMPILER)
210 #pragma clang diagnostic ignored "-Wunknown-pragmas"
211 #pragma clang diagnostic ignored "-Wunused-variable"
212 #pragma clang diagnostic ignored "-Wreorder"
213 #pragma clang diagnostic ignored "-Wmicrosoft"
214 #pragma clang diagnostic ignored "-Wunused-private-field"
215 #pragma clang diagnostic ignored "-Wunused-local-typedef"
216 #pragma clang diagnostic ignored "-Wunused-function"
217 #endif
218