ZeroErr
Loading...
Searching...
No Matches
config.h
Go to the documentation of this file.
1#pragma once
2
3#define ZEROERR_VERSION_MAJOR 0
4#define ZEROERR_VERSION_MINOR 3
5#define ZEROERR_VERSION_PATCH 0
6#define ZEROERR_VERSION \
7 (ZEROERR_VERSION_MAJOR * 10000 + ZEROERR_VERSION_MINOR * 100 + ZEROERR_VERSION_PATCH)
8
9#define ZEROERR_STR(x) #x
10
11#define ZEROERR_VERSION_STR_BUILDER(a, b, c) ZEROERR_STR(a) "." ZEROERR_STR(b) "." ZEROERR_STR(c)
12#define ZEROERR_VERSION_STR \
13 ZEROERR_VERSION_STR_BUILDER(ZEROERR_VERSION_MAJOR, ZEROERR_VERSION_MINOR, ZEROERR_VERSION_PATCH)
14
15// If you just wish to use the color without dynamic
16// enable or disable it, you can uncomment the following line
17// #define ZEROERR_ALWAYS_COLORFUL
18// #define ZEROERR_DISABLE_COLORFUL
19
20// If you wish to use the whole library without thread safety, uncomment the following line
21// #define ZEROERR_NO_THREAD_SAFE
22
23// When embedding zeroerr as a library into another binary that provides its own main,
24// define ZEROERR_NO_MAIN (e.g. target_compile_definitions(zeroerr PUBLIC ZEROERR_NO_MAIN)).
25// #define ZEROERR_NO_MAIN
26
27// If you wish to disable auto initialization of the system
28// #define ZEROERR_DISABLE_AUTO_INIT
29
30// If you didn't wish override operator<< for ostream, we can disable it
31// #define ZEROERR_DISABLE_OSTREAM_OVERRIDE
32
33// If you wish to disable AND, OR macro
34// #define ZEROERR_DISABLE_COMPLEX_AND_OR
35
36// If you wish ot disable BDD style macros
37// #define ZEROERR_DISABLE_BDD
38
39// Detect C++ standard with a cross-platform way
40
41#ifdef _MSC_VER
42#define ZEROERR_CPLUSPLUS _MSVC_LANG
43#else
44#define ZEROERR_CPLUSPLUS __cplusplus
45#endif
46
47#if ZEROERR_CPLUSPLUS >= 202300L
48#define ZEROERR_CXX_STANDARD 23
49#elif ZEROERR_CPLUSPLUS >= 202002L
50#define ZEROERR_CXX_STANDARD 20
51#elif ZEROERR_CPLUSPLUS >= 201703L
52#define ZEROERR_CXX_STANDARD 17
53#elif ZEROERR_CPLUSPLUS >= 201402L
54#define ZEROERR_CXX_STANDARD 14
55#elif ZEROERR_CPLUSPLUS >= 201103L
56#define ZEROERR_CXX_STANDARD 11
57#else
58#error "Unsupported C++ standard detected. ZeroErr requires C++11 or later."
59#endif
60
61#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
62#define ZEROERR_OS_UNIX
63#if defined(__linux__)
64#define ZEROERR_OS_LINUX
65#endif
66#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
67#define ZEROERR_OS_WINDOWS
68#else
69#define ZEROERR_OS_UNKNOWN
70#endif
71
72
73#if defined(NDEBUG) && !defined(ZEROERR_ALWAYS_ASSERT)
74// FIXME: we should safely remove the assert in IF statement
75// #define ZEROERR_NO_ASSERT
76#endif
77
78// This is used for generating a unique name based on the file name and line number
79#define ZEROERR_CAT_IMPL(s1, s2) s1##s2
80#define ZEROERR_CAT(x, s) ZEROERR_CAT_IMPL(x, s)
81
82// The following macros are used to check the arguments is empty or not
83// from: https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
84#define ZEROERR_ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15
85#define ZEROERR_HAS_COMMA(...) \
86 ZEROERR_ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
87#define ZEROERR_TRIGGER_PARENTHESIS_(...) ,
88
89#define ZEROERR_ISEMPTY(...) \
90 ZEROERR_SUPPRESS_VARIADIC_MACRO \
91 _ZEROERR_ISEMPTY(/* test if there is just one argument, eventually an empty \
92 one */ \
93 ZEROERR_HAS_COMMA(__VA_ARGS__), /* test if ZEROERR_TRIGGER_PARENTHESIS_ \
94 together with the argument adds a comma */ \
95 ZEROERR_HAS_COMMA(ZEROERR_TRIGGER_PARENTHESIS_ \
96 __VA_ARGS__), /* test if the argument together with \
97 a parenthesis adds a comma */ \
98 ZEROERR_HAS_COMMA(__VA_ARGS__( \
99 /*empty*/)), /* test if placing it between ZEROERR_TRIGGER_PARENTHESIS_ \
100 and the parenthesis adds a comma */ \
101 ZEROERR_HAS_COMMA(ZEROERR_TRIGGER_PARENTHESIS_ __VA_ARGS__(/*empty*/))) \
102 ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
104#define ZEROERR_PASTE5(_0, _1, _2, _3, _4) _0##_1##_2##_3##_4
105#define _ZEROERR_ISEMPTY(_0, _1, _2, _3) \
106 ZEROERR_HAS_COMMA(ZEROERR_PASTE5(_IS_EMPTY_CASE_, _0, _1, _2, _3))
107#define _IS_EMPTY_CASE_0001 ,
108
109
110// The counter is used to generate a unique name
111#ifdef __COUNTER__
112#define ZEROERR_NAMEGEN(x) ZEROERR_CAT(x, __COUNTER__)
113#else // __COUNTER__
114#define ZEROERR_NAMEGEN(x) ZEROERR_CAT(x, __LINE__)
115#endif // __COUNTER__
116
117#ifdef ZEROERR_OS_LINUX
118#define ZEROERR_PERF
119#endif
120
121#ifdef ZEROERR_DISABLE_ASSERTS_RETURN_VALUES
122#define ZEROERR_FUNC_SCOPE_BEGIN do
123#define ZEROERR_FUNC_SCOPE_END while (0)
124#define ZEROERR_FUNC_SCOPE_RET(v) (void)0
125#else
126#define ZEROERR_FUNC_SCOPE_BEGIN [&]
127#define ZEROERR_FUNC_SCOPE_END ()
128#define ZEROERR_FUNC_SCOPE_RET(v) return v
129#endif
130
131#ifndef ZEROERR_NO_SHORT_LOG_MACRO
132#define ZEROERR_USE_SHORT_LOG_MACRO
133#endif
134
135#define ZEROERR_EXPAND(x) x
136
137
138// =================================================================================================
139// == COMPILER Detector ============================================================================
140// =================================================================================================
141
142#define ZEROERR_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR) * 10000000 + (MINOR) * 100000 + (PATCH))
143
144// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl...
145#if defined(_MSC_VER) && defined(_MSC_FULL_VER)
146#if _MSC_VER == _MSC_FULL_VER / 10000
147#define ZEROERR_MSVC ZEROERR_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
148#else // MSVC
149#define ZEROERR_MSVC \
150 ZEROERR_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
151#endif // MSVC
152#endif // MSVC
153#if defined(__clang__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
154#define ZEROERR_CLANG ZEROERR_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)
155#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \
156 !defined(__INTEL_COMPILER)
157#define ZEROERR_GCC ZEROERR_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
158#endif // GCC
159#if defined(__INTEL_COMPILER)
160#define ZEROERR_ICC ZEROERR_COMPILER(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
161#endif // ICC
162
163#ifndef ZEROERR_MSVC
164#define ZEROERR_MSVC 0
165#endif // ZEROERR_MSVC
166#ifndef ZEROERR_CLANG
167#define ZEROERR_CLANG 0
168#endif // ZEROERR_CLANG
169#ifndef ZEROERR_GCC
170#define ZEROERR_GCC 0
171#endif // ZEROERR_GCC
172#ifndef ZEROERR_ICC
173#define ZEROERR_ICC 0
174#endif // ZEROERR_ICC
175
176
177// =================================================================================================
178// == COMPILER WARNINGS HELPERS ====================================================================
179// =================================================================================================
180
181#if ZEROERR_CLANG && !ZEROERR_ICC
182#define ZEROERR_PRAGMA_TO_STR(x) _Pragma(#x)
183#define ZEROERR_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push")
184#define ZEROERR_CLANG_SUPPRESS_WARNING(w) ZEROERR_PRAGMA_TO_STR(clang diagnostic ignored w)
185#define ZEROERR_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop")
186#define ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \
187 ZEROERR_CLANG_SUPPRESS_WARNING_PUSH ZEROERR_CLANG_SUPPRESS_WARNING(w)
188#else // ZEROERR_CLANG
189#define ZEROERR_CLANG_SUPPRESS_WARNING_PUSH
190#define ZEROERR_CLANG_SUPPRESS_WARNING(w)
191#define ZEROERR_CLANG_SUPPRESS_WARNING_POP
192#define ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
193#endif // ZEROERR_CLANG
194
195#if ZEROERR_GCC
196#define ZEROERR_PRAGMA_TO_STR(x) _Pragma(#x)
197#define ZEROERR_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push")
198#define ZEROERR_GCC_SUPPRESS_WARNING(w) ZEROERR_PRAGMA_TO_STR(GCC diagnostic ignored w)
199#define ZEROERR_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop")
200#define ZEROERR_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \
201 ZEROERR_GCC_SUPPRESS_WARNING_PUSH ZEROERR_GCC_SUPPRESS_WARNING(w)
202#else // ZEROERR_GCC
203#define ZEROERR_GCC_SUPPRESS_WARNING_PUSH
204#define ZEROERR_GCC_SUPPRESS_WARNING(w)
205#define ZEROERR_GCC_SUPPRESS_WARNING_POP
206#define ZEROERR_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
207#endif // ZEROERR_GCC
208
209#if ZEROERR_MSVC
210#define ZEROERR_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))
211#define ZEROERR_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))
212#define ZEROERR_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))
213#define ZEROERR_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \
214 ZEROERR_MSVC_SUPPRESS_WARNING_PUSH ZEROERR_MSVC_SUPPRESS_WARNING(w)
215#else // ZEROERR_MSVC
216#define ZEROERR_MSVC_SUPPRESS_WARNING_PUSH
217#define ZEROERR_MSVC_SUPPRESS_WARNING(w)
218#define ZEROERR_MSVC_SUPPRESS_WARNING_POP
219#define ZEROERR_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
220#endif // ZEROERR_MSVC
221
222// =================================================================================================
223// == COMPILER WARNINGS ============================================================================
224// =================================================================================================
225
226// both the header and the implementation suppress all of these,
227// so it only makes sense to aggregate them like so
228#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH \
229 ZEROERR_CLANG_SUPPRESS_WARNING_PUSH \
230 ZEROERR_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \
231 ZEROERR_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \
232 ZEROERR_CLANG_SUPPRESS_WARNING("-Wpadded") \
233 ZEROERR_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \
234 ZEROERR_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \
235 ZEROERR_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \
236 ZEROERR_CLANG_SUPPRESS_WARNING("-Wvariadic-macro-arguments-omitted") \
237 \
238 ZEROERR_GCC_SUPPRESS_WARNING_PUSH \
239 ZEROERR_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \
240 ZEROERR_GCC_SUPPRESS_WARNING("-Wpragmas") \
241 ZEROERR_GCC_SUPPRESS_WARNING("-Weffc++") \
242 ZEROERR_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \
243 ZEROERR_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \
244 ZEROERR_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \
245 ZEROERR_GCC_SUPPRESS_WARNING("-Wuseless-cast") \
246 ZEROERR_GCC_SUPPRESS_WARNING("-Wnoexcept") \
247 \
248 ZEROERR_MSVC_SUPPRESS_WARNING_PUSH \
249 /* these 4 also disabled globally via cmake: */ \
250 ZEROERR_MSVC_SUPPRESS_WARNING(4514) /* unreferenced inline function has been removed */ \
251 ZEROERR_MSVC_SUPPRESS_WARNING(4571) /* SEH related */ \
252 ZEROERR_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */ \
253 ZEROERR_MSVC_SUPPRESS_WARNING(4711) /* function selected for inline expansion*/ \
254 /* common ones */ \
255 ZEROERR_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */ \
256 ZEROERR_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */ \
257 ZEROERR_MSVC_SUPPRESS_WARNING(4996) /* The compiler encountered a deprecated declaration */ \
258 ZEROERR_MSVC_SUPPRESS_WARNING(4706) /* assignment within conditional expression */ \
259 ZEROERR_MSVC_SUPPRESS_WARNING(4512) /* 'class' : assignment operator could not be generated */ \
260 ZEROERR_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */ \
261 ZEROERR_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
262 ZEROERR_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
263 ZEROERR_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
264 ZEROERR_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
265 ZEROERR_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
266 ZEROERR_MSVC_SUPPRESS_WARNING(4640) /* construction of local static object not thread-safe */ \
267 ZEROERR_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
268 ZEROERR_MSVC_SUPPRESS_WARNING(5264) /* 'variable-name': 'const' variable is not used */ \
269 /* static analysis */ \
270 ZEROERR_MSVC_SUPPRESS_WARNING(26439) /* Function may not throw. Declare it 'noexcept' */ \
271 ZEROERR_MSVC_SUPPRESS_WARNING(26495) /* Always initialize a member variable */ \
272 ZEROERR_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */ \
273 ZEROERR_MSVC_SUPPRESS_WARNING(26444) /* Avoid unnamed objects with custom ctor and dtor... */ \
274 ZEROERR_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */
275
276#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP \
277 ZEROERR_CLANG_SUPPRESS_WARNING_POP \
278 ZEROERR_GCC_SUPPRESS_WARNING_POP \
279 ZEROERR_MSVC_SUPPRESS_WARNING_POP
280
281
282#define ZEROERR_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \
283 ZEROERR_MSVC_SUPPRESS_WARNING_PUSH \
284 ZEROERR_MSVC_SUPPRESS_WARNING(4548) /* before comma no effect; expected side - effect */ \
285 ZEROERR_MSVC_SUPPRESS_WARNING(4265) /* virtual functions, but destructor is not virtual */ \
286 ZEROERR_MSVC_SUPPRESS_WARNING(4986) /* exception specification does not match previous */ \
287 ZEROERR_MSVC_SUPPRESS_WARNING(4350) /* 'member1' called instead of 'member2' */ \
288 ZEROERR_MSVC_SUPPRESS_WARNING(4668) /* not defined as a preprocessor macro */ \
289 ZEROERR_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */ \
290 ZEROERR_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */ \
291 ZEROERR_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
292 ZEROERR_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
293 ZEROERR_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
294 ZEROERR_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
295 ZEROERR_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
296 ZEROERR_MSVC_SUPPRESS_WARNING(4623) /* default constructor was implicitly deleted */ \
297 ZEROERR_MSVC_SUPPRESS_WARNING(5039) /* pointer to pot. throwing function passed to extern C */ \
298 ZEROERR_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
299 ZEROERR_MSVC_SUPPRESS_WARNING(5105) /* macro producing 'defined' has undefined behavior */ \
300 ZEROERR_MSVC_SUPPRESS_WARNING(4738) /* storing float result in memory, loss of performance */ \
301 ZEROERR_MSVC_SUPPRESS_WARNING(5262) /* implicit fall-through */
302
303#define ZEROERR_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END ZEROERR_MSVC_SUPPRESS_WARNING_POP
304
305#define ZEROERR_SUPPRESS_VARIADIC_MACRO \
306 ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wgnu-zero-variadic-macro-arguments") \
307 ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wvariadic-macro-arguments-omitted")
308
309#define ZEROERR_SUPPRESS_VARIADIC_MACRO_POP ZEROERR_CLANG_SUPPRESS_WARNING_POP
310
311#define ZEROERR_SUPPRESS_COMPARE \
312 ZEROERR_CLANG_SUPPRESS_WARNING_PUSH \
313 ZEROERR_CLANG_SUPPRESS_WARNING("-Wsign-conversion") \
314 ZEROERR_CLANG_SUPPRESS_WARNING("-Wsign-compare") \
315 ZEROERR_CLANG_SUPPRESS_WARNING("-Wgnu-zero-variadic-macro-arguments") \
316 ZEROERR_GCC_SUPPRESS_WARNING_PUSH \
317 ZEROERR_GCC_SUPPRESS_WARNING("-Wsign-conversion") \
318 ZEROERR_GCC_SUPPRESS_WARNING("-Wsign-compare") \
319 ZEROERR_MSVC_SUPPRESS_WARNING_PUSH \
320 ZEROERR_MSVC_SUPPRESS_WARNING(4388) \
321 ZEROERR_MSVC_SUPPRESS_WARNING(4389) \
322 ZEROERR_MSVC_SUPPRESS_WARNING(4018)
323
324#define ZEROERR_SUPPRESS_COMPARE_POP \
325 ZEROERR_CLANG_SUPPRESS_WARNING_POP ZEROERR_GCC_SUPPRESS_WARNING_POP \
326 ZEROERR_MSVC_SUPPRESS_WARNING_POP
327
345#if ZEROERR_CLANG || ZEROERR_GCC
346#define ZEROERR_UNUSED(x) x __attribute__((unused))
347#elif defined(__LCLINT__)
348#define ZEROERR_UNUSED(x) /*@unused@*/ x
349#elif ZEROERR_MSVC
350#define ZEROERR_UNUSED(x) \
351 ZEROERR_MSVC_SUPPRESS_WARNING_WITH_PUSH(4100) x ZEROERR_MSVC_SUPPRESS_WARNING_POP
352#else
353#define ZEROERR_UNUSED(x) x
354#endif