refactoredCPPNeuronMesher
doctest.h
Go to the documentation of this file.
1 // ====================================================================== lgtm [cpp/missing-header-guard]
2 // == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! ==
3 // ======================================================================
4 //
5 // doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
6 //
7 // Copyright (c) 2016-2023 Viktor Kirilov
8 //
9 // Distributed under the MIT Software License
10 // See accompanying file LICENSE.txt or copy at
11 // https://opensource.org/licenses/MIT
12 //
13 // The documentation can be found at the library's page:
14 // https://github.com/doctest/doctest/blob/master/doc/markdown/readme.md
15 //
16 // =================================================================================================
17 // =================================================================================================
18 // =================================================================================================
19 //
20 // The library is heavily influenced by Catch - https://github.com/catchorg/Catch2
21 // which uses the Boost Software License - Version 1.0
22 // see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt
23 //
24 // The concept of subcases (sections in Catch) and expression decomposition are from there.
25 // Some parts of the code are taken directly:
26 // - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<>
27 // - the Approx() helper class for floating point comparison
28 // - colors in the console
29 // - breaking into a debugger
30 // - signal / SEH handling
31 // - timer
32 // - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste)
33 //
34 // The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest
35 // which uses the Boost Software License - Version 1.0
36 // see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt
37 //
38 // =================================================================================================
39 // =================================================================================================
40 // =================================================================================================
41 
42 #ifndef DOCTEST_LIBRARY_INCLUDED
43 #define DOCTEST_LIBRARY_INCLUDED
44 
45 // =================================================================================================
46 // == VERSION ======================================================================================
47 // =================================================================================================
48 
49 #define DOCTEST_VERSION_MAJOR 2
50 #define DOCTEST_VERSION_MINOR 4
51 #define DOCTEST_VERSION_PATCH 12
52 
53 // util we need here
54 #define DOCTEST_TOSTR_IMPL(x) #x
55 #define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)
56 
57 #define DOCTEST_VERSION_STR \
58  DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) "." \
59  DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "." \
60  DOCTEST_TOSTR(DOCTEST_VERSION_PATCH)
61 
62 #define DOCTEST_VERSION \
63  (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
64 
65 // =================================================================================================
66 // == COMPILER VERSION =============================================================================
67 // =================================================================================================
68 
69 // ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect
70 
71 #ifdef _MSC_VER
72 #define DOCTEST_CPLUSPLUS _MSVC_LANG
73 #else
74 #define DOCTEST_CPLUSPLUS __cplusplus
75 #endif
76 
77 #define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH))
78 
79 // GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl...
80 #if defined(_MSC_VER) && defined(_MSC_FULL_VER)
81 #if _MSC_VER == _MSC_FULL_VER / 10000
82 #define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
83 #else // MSVC
84 #define DOCTEST_MSVC \
85  DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
86 #endif // MSVC
87 #endif // MSVC
88 #if defined(__clang__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
89 #define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)
90 #elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \
91  !defined(__INTEL_COMPILER)
92 #define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
93 #endif // GCC
94 #if defined(__INTEL_COMPILER)
95 #define DOCTEST_ICC DOCTEST_COMPILER(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
96 #endif // ICC
97 
98 #ifndef DOCTEST_MSVC
99 #define DOCTEST_MSVC 0
100 #endif // DOCTEST_MSVC
101 #ifndef DOCTEST_CLANG
102 #define DOCTEST_CLANG 0
103 #endif // DOCTEST_CLANG
104 #ifndef DOCTEST_GCC
105 #define DOCTEST_GCC 0
106 #endif // DOCTEST_GCC
107 #ifndef DOCTEST_ICC
108 #define DOCTEST_ICC 0
109 #endif // DOCTEST_ICC
110 
111 // =================================================================================================
112 // == COMPILER WARNINGS HELPERS ====================================================================
113 // =================================================================================================
114 
115 #if DOCTEST_CLANG && !DOCTEST_ICC
116 #define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
117 #define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push")
118 #define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w)
119 #define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop")
120 #define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \
121  DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w)
122 #else // DOCTEST_CLANG
123 #define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
124 #define DOCTEST_CLANG_SUPPRESS_WARNING(w)
125 #define DOCTEST_CLANG_SUPPRESS_WARNING_POP
126 #define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
127 #endif // DOCTEST_CLANG
128 
129 #if DOCTEST_GCC
130 #define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
131 #define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push")
132 #define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w)
133 #define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop")
134 #define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \
135  DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w)
136 #else // DOCTEST_GCC
137 #define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
138 #define DOCTEST_GCC_SUPPRESS_WARNING(w)
139 #define DOCTEST_GCC_SUPPRESS_WARNING_POP
140 #define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
141 #endif // DOCTEST_GCC
142 
143 #if DOCTEST_MSVC
144 #define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))
145 #define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))
146 #define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))
147 #define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \
148  DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w)
149 #else // DOCTEST_MSVC
150 #define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
151 #define DOCTEST_MSVC_SUPPRESS_WARNING(w)
152 #define DOCTEST_MSVC_SUPPRESS_WARNING_POP
153 #define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
154 #endif // DOCTEST_MSVC
155 
156 // =================================================================================================
157 // == COMPILER WARNINGS ============================================================================
158 // =================================================================================================
159 
160 // both the header and the implementation suppress all of these,
161 // so it only makes sense to aggregate them like so
162 #define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH \
163  DOCTEST_CLANG_SUPPRESS_WARNING_PUSH \
164  DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \
165  DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \
166  DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") \
167  DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \
168  DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \
169  DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \
170  \
171  DOCTEST_GCC_SUPPRESS_WARNING_PUSH \
172  DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \
173  DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") \
174  DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") \
175  DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \
176  DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \
177  DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \
178  DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") \
179  DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") \
180  \
181  DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
182  /* these 4 also disabled globally via cmake: */ \
183  DOCTEST_MSVC_SUPPRESS_WARNING(4514) /* unreferenced inline function has been removed */ \
184  DOCTEST_MSVC_SUPPRESS_WARNING(4571) /* SEH related */ \
185  DOCTEST_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */ \
186  DOCTEST_MSVC_SUPPRESS_WARNING(4711) /* function selected for inline expansion*/ \
187  /* common ones */ \
188  DOCTEST_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */ \
189  DOCTEST_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */ \
190  DOCTEST_MSVC_SUPPRESS_WARNING(4996) /* The compiler encountered a deprecated declaration */ \
191  DOCTEST_MSVC_SUPPRESS_WARNING(4706) /* assignment within conditional expression */ \
192  DOCTEST_MSVC_SUPPRESS_WARNING(4512) /* 'class' : assignment operator could not be generated */ \
193  DOCTEST_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */ \
194  DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
195  DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
196  DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
197  DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
198  DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
199  DOCTEST_MSVC_SUPPRESS_WARNING(4640) /* construction of local static object not thread-safe */ \
200  DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
201  DOCTEST_MSVC_SUPPRESS_WARNING(5264) /* 'variable-name': 'const' variable is not used */ \
202  /* static analysis */ \
203  DOCTEST_MSVC_SUPPRESS_WARNING(26439) /* Function may not throw. Declare it 'noexcept' */ \
204  DOCTEST_MSVC_SUPPRESS_WARNING(26495) /* Always initialize a member variable */ \
205  DOCTEST_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */ \
206  DOCTEST_MSVC_SUPPRESS_WARNING(26444) /* Avoid unnamed objects with custom ctor and dtor... */ \
207  DOCTEST_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */
208 
209 #define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP \
210  DOCTEST_CLANG_SUPPRESS_WARNING_POP \
211  DOCTEST_GCC_SUPPRESS_WARNING_POP \
212  DOCTEST_MSVC_SUPPRESS_WARNING_POP
213 
215 
217 DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor")
218 DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated")
219 
221 DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy")
222 DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor")
223 DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo")
224 
226 DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted
227 
228 #define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \
229  DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
230  DOCTEST_MSVC_SUPPRESS_WARNING(4548) /* before comma no effect; expected side - effect */ \
231  DOCTEST_MSVC_SUPPRESS_WARNING(4265) /* virtual functions, but destructor is not virtual */ \
232  DOCTEST_MSVC_SUPPRESS_WARNING(4986) /* exception specification does not match previous */ \
233  DOCTEST_MSVC_SUPPRESS_WARNING(4350) /* 'member1' called instead of 'member2' */ \
234  DOCTEST_MSVC_SUPPRESS_WARNING(4668) /* not defined as a preprocessor macro */ \
235  DOCTEST_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */ \
236  DOCTEST_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */ \
237  DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
238  DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
239  DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
240  DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
241  DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
242  DOCTEST_MSVC_SUPPRESS_WARNING(4623) /* default constructor was implicitly deleted */ \
243  DOCTEST_MSVC_SUPPRESS_WARNING(5039) /* pointer to pot. throwing function passed to extern C */ \
244  DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
245  DOCTEST_MSVC_SUPPRESS_WARNING(5105) /* macro producing 'defined' has undefined behavior */ \
246  DOCTEST_MSVC_SUPPRESS_WARNING(4738) /* storing float result in memory, loss of performance */ \
247  DOCTEST_MSVC_SUPPRESS_WARNING(5262) /* implicit fall-through */
248 
249 #define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP
250 
251 // =================================================================================================
252 // == FEATURE DETECTION ============================================================================
253 // =================================================================================================
254 
255 // general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support
256 // MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx
257 // GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html
258 // MSVC version table:
259 // https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering
260 // MSVC++ 14.3 (17) _MSC_VER == 1930 (Visual Studio 2022)
261 // MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019)
262 // MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017)
263 // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
264 // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
265 // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
266 // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
267 // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
268 // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
269 
270 // Universal Windows Platform support
271 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
272 #define DOCTEST_CONFIG_NO_WINDOWS_SEH
273 #endif // WINAPI_FAMILY
274 #if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
275 #define DOCTEST_CONFIG_WINDOWS_SEH
276 #endif // MSVC
277 #if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH)
278 #undef DOCTEST_CONFIG_WINDOWS_SEH
279 #endif // DOCTEST_CONFIG_NO_WINDOWS_SEH
280 
281 #if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \
282  !defined(__EMSCRIPTEN__) && !defined(__wasi__)
283 #define DOCTEST_CONFIG_POSIX_SIGNALS
284 #endif // _WIN32
285 #if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS)
286 #undef DOCTEST_CONFIG_POSIX_SIGNALS
287 #endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS
288 
289 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
290 #if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) \
291  || defined(__wasi__)
292 #define DOCTEST_CONFIG_NO_EXCEPTIONS
293 #endif // no exceptions
294 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
295 
296 #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
297 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
298 #define DOCTEST_CONFIG_NO_EXCEPTIONS
299 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
300 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
301 
302 #if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS)
303 #define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
304 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
305 
306 #ifdef __wasi__
307 #define DOCTEST_CONFIG_NO_MULTITHREADING
308 #endif
309 
310 #if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT)
311 #define DOCTEST_CONFIG_IMPLEMENT
312 #endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
313 
314 #if defined(_WIN32) || defined(__CYGWIN__)
315 #if DOCTEST_MSVC
316 #define DOCTEST_SYMBOL_EXPORT __declspec(dllexport)
317 #define DOCTEST_SYMBOL_IMPORT __declspec(dllimport)
318 #else // MSVC
319 #define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport))
320 #define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport))
321 #endif // MSVC
322 #else // _WIN32
323 #define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default")))
324 #define DOCTEST_SYMBOL_IMPORT
325 #endif // _WIN32
326 
327 #ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
328 #ifdef DOCTEST_CONFIG_IMPLEMENT
329 #define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT
330 #else // DOCTEST_CONFIG_IMPLEMENT
331 #define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT
332 #endif // DOCTEST_CONFIG_IMPLEMENT
333 #else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
334 #define DOCTEST_INTERFACE
335 #endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
336 
337 // needed for extern template instantiations
338 // see https://github.com/fmtlib/fmt/issues/2228
339 #if DOCTEST_MSVC
340 #define DOCTEST_INTERFACE_DECL
341 #define DOCTEST_INTERFACE_DEF DOCTEST_INTERFACE
342 #else // DOCTEST_MSVC
343 #define DOCTEST_INTERFACE_DECL DOCTEST_INTERFACE
344 #define DOCTEST_INTERFACE_DEF
345 #endif // DOCTEST_MSVC
346 
347 #define DOCTEST_EMPTY
348 
349 #if DOCTEST_MSVC
350 #define DOCTEST_NOINLINE __declspec(noinline)
351 #define DOCTEST_UNUSED
352 #define DOCTEST_ALIGNMENT(x)
353 #elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
354 #define DOCTEST_NOINLINE
355 #define DOCTEST_UNUSED
356 #define DOCTEST_ALIGNMENT(x)
357 #else
358 #define DOCTEST_NOINLINE __attribute__((noinline))
359 #define DOCTEST_UNUSED __attribute__((unused))
360 #define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
361 #endif
362 
363 #ifdef DOCTEST_CONFIG_NO_CONTRADICTING_INLINE
364 #define DOCTEST_INLINE_NOINLINE inline
365 #else
366 #define DOCTEST_INLINE_NOINLINE inline DOCTEST_NOINLINE
367 #endif
368 
369 #ifndef DOCTEST_NORETURN
370 #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
371 #define DOCTEST_NORETURN
372 #else // DOCTEST_MSVC
373 #define DOCTEST_NORETURN [[noreturn]]
374 #endif // DOCTEST_MSVC
375 #endif // DOCTEST_NORETURN
376 
377 #ifndef DOCTEST_NOEXCEPT
378 #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
379 #define DOCTEST_NOEXCEPT
380 #else // DOCTEST_MSVC
381 #define DOCTEST_NOEXCEPT noexcept
382 #endif // DOCTEST_MSVC
383 #endif // DOCTEST_NOEXCEPT
384 
385 #ifndef DOCTEST_CONSTEXPR
386 #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
387 #define DOCTEST_CONSTEXPR const
388 #define DOCTEST_CONSTEXPR_FUNC inline
389 #else // DOCTEST_MSVC
390 #define DOCTEST_CONSTEXPR constexpr
391 #define DOCTEST_CONSTEXPR_FUNC constexpr
392 #endif // DOCTEST_MSVC
393 #endif // DOCTEST_CONSTEXPR
394 
395 #ifndef DOCTEST_NO_SANITIZE_INTEGER
396 #if DOCTEST_CLANG >= DOCTEST_COMPILER(3, 7, 0)
397 #define DOCTEST_NO_SANITIZE_INTEGER __attribute__((no_sanitize("integer")))
398 #else
399 #define DOCTEST_NO_SANITIZE_INTEGER
400 #endif
401 #endif // DOCTEST_NO_SANITIZE_INTEGER
402 
403 // =================================================================================================
404 // == FEATURE DETECTION END ========================================================================
405 // =================================================================================================
406 
407 #define DOCTEST_DECLARE_INTERFACE(name) \
408  virtual ~name(); \
409  name() = default; \
410  name(const name&) = delete; \
411  name(name&&) = delete; \
412  name& operator=(const name&) = delete; \
413  name& operator=(name&&) = delete;
414 
415 #define DOCTEST_DEFINE_INTERFACE(name) \
416  name::~name() = default;
417 
418 // internal macros for string concatenation and anonymous variable name generation
419 #define DOCTEST_CAT_IMPL(s1, s2) s1##s2
420 #define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2)
421 #ifdef __COUNTER__ // not standard and may be missing for some compilers
422 #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__)
423 #else // __COUNTER__
424 #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__)
425 #endif // __COUNTER__
426 
427 #ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
428 #define DOCTEST_REF_WRAP(x) x&
429 #else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
430 #define DOCTEST_REF_WRAP(x) x
431 #endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
432 
433 // not using __APPLE__ because... this is how Catch does it
434 #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
435 #define DOCTEST_PLATFORM_MAC
436 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
437 #define DOCTEST_PLATFORM_IPHONE
438 #elif defined(_WIN32)
439 #define DOCTEST_PLATFORM_WINDOWS
440 #elif defined(__wasi__)
441 #define DOCTEST_PLATFORM_WASI
442 #else // DOCTEST_PLATFORM
443 #define DOCTEST_PLATFORM_LINUX
444 #endif // DOCTEST_PLATFORM
445 
446 namespace doctest { namespace detail {
447  static DOCTEST_CONSTEXPR int consume(const int*, int) noexcept { return 0; }
448 }}
449 
450 #define DOCTEST_GLOBAL_NO_WARNINGS(var, ...) \
451  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \
452  static const int var = doctest::detail::consume(&var, __VA_ARGS__); \
453  DOCTEST_CLANG_SUPPRESS_WARNING_POP
454 
455 #ifndef DOCTEST_BREAK_INTO_DEBUGGER
456 // should probably take a look at https://github.com/scottt/debugbreak
457 #ifdef DOCTEST_PLATFORM_LINUX
458 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
459 // Break at the location of the failing check if possible
460 #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler)
461 #else
462 #include <signal.h>
463 #define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
464 #endif
465 #elif defined(DOCTEST_PLATFORM_MAC)
466 #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
467 #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler)
468 #elif defined(__ppc__) || defined(__ppc64__)
469 // https://www.cocoawithlove.com/2008/03/break-into-debugger.html
470 #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n": : : "memory","r0","r3","r4") // NOLINT(hicpp-no-assembler)
471 #else
472 #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT(hicpp-no-assembler)
473 #endif
474 #elif DOCTEST_MSVC
475 #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
476 #elif defined(__MINGW32__)
477 DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls")
478 extern "C" __declspec(dllimport) void __stdcall DebugBreak();
480 #define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
481 #else // linux
482 #define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
483 #endif // linux
484 #endif // DOCTEST_BREAK_INTO_DEBUGGER
485 
486 // this is kept here for backwards compatibility since the config option was changed
487 #ifdef DOCTEST_CONFIG_USE_IOSFWD
488 #ifndef DOCTEST_CONFIG_USE_STD_HEADERS
489 #define DOCTEST_CONFIG_USE_STD_HEADERS
490 #endif
491 #endif // DOCTEST_CONFIG_USE_IOSFWD
492 
493 // for clang - always include ciso646 (which drags some std stuff) because
494 // we want to check if we are using libc++ with the _LIBCPP_VERSION macro in
495 // which case we don't want to forward declare stuff from std - for reference:
496 // https://github.com/doctest/doctest/issues/126
497 // https://github.com/doctest/doctest/issues/356
498 #if DOCTEST_CLANG
499 #include <ciso646>
500 #endif // clang
501 
502 #ifdef _LIBCPP_VERSION
503 #ifndef DOCTEST_CONFIG_USE_STD_HEADERS
504 #define DOCTEST_CONFIG_USE_STD_HEADERS
505 #endif
506 #endif // _LIBCPP_VERSION
507 
508 #ifdef DOCTEST_CONFIG_USE_STD_HEADERS
509 #ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
510 #define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
511 #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
513 #include <cstddef>
514 #include <ostream>
515 #include <istream>
517 #else // DOCTEST_CONFIG_USE_STD_HEADERS
518 
519 // Forward declaring 'X' in namespace std is not permitted by the C++ Standard.
521 
522 namespace std { // NOLINT(cert-dcl58-cpp)
523 typedef decltype(nullptr) nullptr_t; // NOLINT(modernize-use-using)
524 typedef decltype(sizeof(void*)) size_t; // NOLINT(modernize-use-using)
525 template <class charT>
526 struct char_traits;
527 template <>
528 struct char_traits<char>;
529 template <class charT, class traits>
530 class basic_ostream; // NOLINT(fuchsia-virtual-inheritance)
531 typedef basic_ostream<char, char_traits<char>> ostream; // NOLINT(modernize-use-using)
532 template<class traits>
533 // NOLINTNEXTLINE
534 basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);
535 template <class charT, class traits>
537 typedef basic_istream<char, char_traits<char>> istream; // NOLINT(modernize-use-using)
538 template <class... Types>
539 class tuple;
540 #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
541 // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
542 template <class Ty>
543 class allocator;
544 template <class Elem, class Traits, class Alloc>
545 class basic_string;
546 using string = basic_string<char, char_traits<char>, allocator<char>>;
547 #endif // VS 2019
548 } // namespace std
549 
551 
552 #endif // DOCTEST_CONFIG_USE_STD_HEADERS
553 
554 #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
555 #include <type_traits>
556 #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
557 
558 namespace doctest {
559 
560 using std::size_t;
561 
563 
564 #ifndef DOCTEST_CONFIG_STRING_SIZE_TYPE
565 #define DOCTEST_CONFIG_STRING_SIZE_TYPE unsigned
566 #endif
567 
568 // A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length
569 // of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for:
570 // - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128)
571 // - if small - capacity left before going on the heap - using the lowest 5 bits
572 // - if small - 2 bits are left unused - the second and third highest ones
573 // - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator)
574 // and the "is small" bit remains "0" ("as well as the capacity left") so its OK
575 // Idea taken from this lecture about the string implementation of facebook/folly - fbstring
576 // https://www.youtube.com/watch?v=kPR8h4-qZdk
577 // TODO:
578 // - optimizations - like not deleting memory unnecessarily in operator= and etc.
579 // - resize/reserve/clear
580 // - replace
581 // - back/front
582 // - iterator stuff
583 // - find & friends
584 // - push_back/pop_back
585 // - assign/insert/erase
586 // - relational operators as free functions - taking const char* as one of the params
588 {
589 public:
591 
592 private:
593  static DOCTEST_CONSTEXPR size_type len = 24;
594  static DOCTEST_CONSTEXPR size_type last = len - 1;
595 
596  struct view // len should be more than sizeof(view) - because of the final byte for flags
597  {
598  char* ptr;
601  };
602 
603  union
604  {
605  char buf[len]; // NOLINT(*-avoid-c-arrays)
607  };
608 
609  char* allocate(size_type sz);
610 
611  bool isOnStack() const noexcept { return (buf[last] & 128) == 0; }
612  void setOnHeap() noexcept;
613  void setLast(size_type in = last) noexcept;
614  void setSize(size_type sz) noexcept;
615 
616  void copy(const String& other);
617 
618 public:
619  static DOCTEST_CONSTEXPR size_type npos = static_cast<size_type>(-1);
620 
621  String() noexcept;
622  ~String();
623 
624  // cppcheck-suppress noExplicitConstructor
625  String(const char* in);
626  String(const char* in, size_type in_size);
627 
628  String(std::istream& in, size_type in_size);
629 
630  String(const String& other);
631  String& operator=(const String& other);
632 
633  String& operator+=(const String& other);
634 
635  String(String&& other) noexcept;
636  String& operator=(String&& other) noexcept;
637 
638  char operator[](size_type i) const;
639  char& operator[](size_type i);
640 
641  // the only functions I'm willing to leave in the interface - available for inlining
642  const char* c_str() const { return const_cast<String*>(this)->c_str(); } // NOLINT
643  char* c_str() {
644  if (isOnStack()) {
645  return reinterpret_cast<char*>(buf);
646  }
647  return data.ptr;
648  }
649 
650  size_type size() const;
652 
653  String substr(size_type pos, size_type cnt = npos) &&;
654  String substr(size_type pos, size_type cnt = npos) const &;
655 
656  size_type find(char ch, size_type pos = 0) const;
657  size_type rfind(char ch, size_type pos = npos) const;
658 
659  int compare(const char* other, bool no_case = false) const;
660  int compare(const String& other, bool no_case = false) const;
661 
663 };
664 
666 
667 DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs);
668 DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs);
669 DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs);
670 DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs);
671 DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs);
672 DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs);
673 
675 public:
676  explicit Contains(const String& string);
677 
678  bool checkWith(const String& other) const;
679 
681 };
682 
684 
685 DOCTEST_INTERFACE bool operator==(const String& lhs, const Contains& rhs);
686 DOCTEST_INTERFACE bool operator==(const Contains& lhs, const String& rhs);
687 DOCTEST_INTERFACE bool operator!=(const String& lhs, const Contains& rhs);
688 DOCTEST_INTERFACE bool operator!=(const Contains& lhs, const String& rhs);
689 
690 namespace Color {
691  enum Enum
692  {
693  None = 0,
701 
702  Bright = 0x10,
703 
708  };
709 
711 } // namespace Color
712 
713 namespace assertType {
714  enum Enum
715  {
716  // macro traits
717 
718  is_warn = 1,
721 
727 
729  is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types
730 
732  is_ne = 2 * is_eq,
733 
734  is_lt = 2 * is_ne,
735  is_gt = 2 * is_lt,
736 
737  is_ge = 2 * is_gt,
738  is_le = 2 * is_ge,
739 
740  // macro types
741 
745 
749 
753 
757 
761 
765 
769 
773 
777 
781 
785 
789 
793 
797 
801  };
802 } // namespace assertType
803 
806 DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
807 
809 {
810  String m_file; // the file in which the test was registered (using String - see #350)
811  unsigned m_line; // the line where the test was registered
812  const char* m_name; // name of the test case
813  const char* m_test_suite; // the test suite in which the test was added
814  const char* m_description;
815  bool m_skip;
821  double m_timeout;
822 };
823 
825 {
826  // common - for all asserts
829  const char* m_file;
830  int m_line;
831  const char* m_expr;
832  bool m_failed;
833 
834  // exception-related - for all asserts
835  bool m_threw;
837 
838  // for normal asserts
840 
841  // for specific exception-related asserts
843  const char* m_exception_type;
844 
846  private:
849 
850  public:
851  StringContains(const String& str) : content(str), isContains(false) { }
852  StringContains(Contains cntn) : content(static_cast<Contains&&>(cntn)), isContains(true) { }
853 
854  bool check(const String& str) { return isContains ? (content == str) : (content.string == str); }
855 
856  operator const String&() const { return content.string; }
857 
858  const char* c_str() const { return content.string.c_str(); }
859  } m_exception_string;
860 
861  AssertData(assertType::Enum at, const char* file, int line, const char* expr,
862  const char* exception_type, const StringContains& exception_string);
863 };
864 
866 {
868  const char* m_file;
869  int m_line;
871 };
872 
874 {
876  const char* m_file;
877  int m_line;
878 
879  bool operator==(const SubcaseSignature& other) const;
880  bool operator<(const SubcaseSignature& other) const;
881 };
882 
884 {
886  virtual void stringify(std::ostream*) const = 0;
887 };
888 
889 namespace detail {
890  struct DOCTEST_INTERFACE TestCase;
891 } // namespace detail
892 
894 {
895  std::ostream* cout = nullptr; // stdout stream
896  String binary_name; // the test binary name
897 
898  const detail::TestCase* currentTest = nullptr;
899 
900  // == parameters from the command line
901  String out; // output filename
902  String order_by; // how tests should be ordered
903  unsigned rand_seed; // the seed for rand ordering
904 
905  unsigned first; // the first (matching) test to be executed
906  unsigned last; // the last (matching) test to be executed
907 
908  int abort_after; // stop tests after this many failed assertions
909  int subcase_filter_levels; // apply the subcase filters for the first N levels
910 
911  bool success; // include successful assertions in output
912  bool case_sensitive; // if filtering should be case sensitive
913  bool exit; // if the program should be exited after the tests are ran/whatever
914  bool duration; // print the time duration of each test case
915  bool minimal; // minimal console output (only test failures)
916  bool quiet; // no console output
917  bool no_throw; // to skip exceptions-related assertion macros
918  bool no_exitcode; // if the framework should return 0 as the exitcode
919  bool no_run; // to not run the tests at all (can be done with an "*" exclude)
920  bool no_intro; // to not print the intro of the framework
921  bool no_version; // to not print the version of the framework
922  bool no_colors; // if output to the console should be colorized
923  bool force_colors; // forces the use of colors even when a tty cannot be detected
924  bool no_breaks; // to not break into the debugger
925  bool no_skip; // don't skip test cases which are marked to be skipped
926  bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x):
927  bool no_path_in_filenames; // if the path to files should be removed from the output
928  String strip_file_prefixes;// remove the longest matching one of these prefixes from any file paths in the output
929  bool no_line_numbers; // if source code line numbers should be omitted from the output
930  bool no_debug_output; // no output in the debug console when a debugger is attached
931  bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
932  bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
933 
934  bool help; // to print the help
935  bool version; // to print the version
936  bool count; // if only the count of matching tests is to be retrieved
937  bool list_test_cases; // to list all tests matching the filters
938  bool list_test_suites; // to list all suites matching the filters
939  bool list_reporters; // lists all registered reporters
940 };
941 
942 namespace detail {
943  namespace types {
944 #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
945  using namespace std;
946 #else
947  template <bool COND, typename T = void>
948  struct enable_if { };
949 
950  template <typename T>
951  struct enable_if<true, T> { using type = T; };
952 
953  struct true_type { static DOCTEST_CONSTEXPR bool value = true; };
954  struct false_type { static DOCTEST_CONSTEXPR bool value = false; };
955 
956  template <typename T> struct remove_reference { using type = T; };
957  template <typename T> struct remove_reference<T&> { using type = T; };
958  template <typename T> struct remove_reference<T&&> { using type = T; };
959 
960  template <typename T> struct is_rvalue_reference : false_type { };
961  template <typename T> struct is_rvalue_reference<T&&> : true_type { };
962 
963  template<typename T> struct remove_const { using type = T; };
964  template <typename T> struct remove_const<const T> { using type = T; };
965 
966  // Compiler intrinsics
967  template <typename T> struct is_enum { static DOCTEST_CONSTEXPR bool value = __is_enum(T); };
968  template <typename T> struct underlying_type { using type = __underlying_type(T); };
969 
970  template <typename T> struct is_pointer : false_type { };
971  template <typename T> struct is_pointer<T*> : true_type { };
972 
973  template <typename T> struct is_array : false_type { };
974  // NOLINTNEXTLINE(*-avoid-c-arrays)
975  template <typename T, size_t SIZE> struct is_array<T[SIZE]> : true_type { };
976 #endif
977  }
978 
979  // <utility>
980  template <typename T>
981  T&& declval();
982 
983  template <class T>
985  return static_cast<T&&>(t);
986  }
987 
988  template <class T>
990  return static_cast<T&&>(t);
991  }
992 
993  template <typename T>
995 
996 // MSVS 2015 :(
997 #if !DOCTEST_CLANG && defined(_MSC_VER) && _MSC_VER <= 1900
998  template <typename T, typename = void>
999  struct has_global_insertion_operator : types::false_type { };
1000 
1001  template <typename T>
1002  struct has_global_insertion_operator<T, decltype(::operator<<(declval<std::ostream&>(), declval<const T&>()), void())> : types::true_type { };
1003 
1004  template <typename T, typename = void>
1005  struct has_insertion_operator { static DOCTEST_CONSTEXPR bool value = has_global_insertion_operator<T>::value; };
1006 
1007  template <typename T, bool global>
1008  struct insert_hack;
1009 
1010  template <typename T>
1011  struct insert_hack<T, true> {
1012  static void insert(std::ostream& os, const T& t) { ::operator<<(os, t); }
1013  };
1014 
1015  template <typename T>
1016  struct insert_hack<T, false> {
1017  static void insert(std::ostream& os, const T& t) { operator<<(os, t); }
1018  };
1019 
1020  template <typename T>
1021  using insert_hack_t = insert_hack<T, has_global_insertion_operator<T>::value>;
1022 #else
1023  template <typename T, typename = void>
1025 #endif
1026 
1027  template <typename T>
1028  struct has_insertion_operator<T, decltype(operator<<(declval<std::ostream&>(), declval<const T&>()), void())> : types::true_type { };
1029 
1030  template <typename T>
1033  };
1034 
1037 
1038  template <bool C>
1040  template <typename T>
1041  static String convert(const DOCTEST_REF_WRAP(T)) {
1042 #ifdef DOCTEST_CONFIG_REQUIRE_STRINGIFICATION_FOR_ALL_USED_TYPES
1043  static_assert(deferred_false<T>::value, "No stringification detected for type T. See string conversion manual");
1044 #endif
1045  return "{?}";
1046  }
1047  };
1048 
1049  template <typename T>
1050  struct filldata;
1051 
1052  template <typename T>
1053  void filloss(std::ostream* stream, const T& in) {
1054  filldata<T>::fill(stream, in);
1055  }
1056 
1057  template <typename T, size_t N>
1058  void filloss(std::ostream* stream, const T (&in)[N]) { // NOLINT(*-avoid-c-arrays)
1059  // T[N], T(&)[N], T(&&)[N] have same behaviour.
1060  // Hence remove reference.
1061  filloss<typename types::remove_reference<decltype(in)>::type>(stream, in);
1062  }
1063 
1064  template <typename T>
1065  String toStream(const T& in) {
1066  std::ostream* stream = tlssPush();
1067  filloss(stream, in);
1068  return tlssPop();
1069  }
1070 
1071  template <>
1072  struct StringMakerBase<true> {
1073  template <typename T>
1074  static String convert(const DOCTEST_REF_WRAP(T) in) {
1075  return toStream(in);
1076  }
1077  };
1078 } // namespace detail
1079 
1080 template <typename T>
1082  detail::has_insertion_operator<T>::value || detail::types::is_pointer<T>::value || detail::types::is_array<T>::value>
1083 {};
1084 
1085 #ifndef DOCTEST_STRINGIFY
1086 #ifdef DOCTEST_CONFIG_DOUBLE_STRINGIFY
1087 #define DOCTEST_STRINGIFY(...) toString(toString(__VA_ARGS__))
1088 #else
1089 #define DOCTEST_STRINGIFY(...) toString(__VA_ARGS__)
1090 #endif
1091 #endif
1092 
1093 template <typename T>
1095 #if DOCTEST_CLANG == 0 && DOCTEST_GCC == 0 && DOCTEST_ICC == 0
1096  String ret = __FUNCSIG__; // class doctest::String __cdecl doctest::toString<TYPE>(void)
1097  String::size_type beginPos = ret.find('<');
1098  return ret.substr(beginPos + 1, ret.size() - beginPos - static_cast<String::size_type>(sizeof(">(void)")));
1099 #else
1100  String ret = __PRETTY_FUNCTION__; // doctest::String toString() [with T = TYPE]
1101  String::size_type begin = ret.find('=') + 2;
1102  return ret.substr(begin, ret.size() - begin - 1);
1103 #endif
1104 }
1105 
1106 template <typename T, typename detail::types::enable_if<!detail::should_stringify_as_underlying_type<T>::value, bool>::type = true>
1108  return StringMaker<T>::convert(value);
1109 }
1110 
1111 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1112 DOCTEST_INTERFACE String toString(const char* in);
1113 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1114 
1115 #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
1116 // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
1117 DOCTEST_INTERFACE String toString(const std::string& in);
1118 #endif // VS 2019
1119 
1121 
1123 
1125 
1129 
1134 DOCTEST_INTERFACE String toString(short unsigned in);
1140 DOCTEST_INTERFACE String toString(long long unsigned in);
1141 
1142 template <typename T, typename detail::types::enable_if<detail::should_stringify_as_underlying_type<T>::value, bool>::type = true>
1143 String toString(const DOCTEST_REF_WRAP(T) value) {
1144  using UT = typename detail::types::underlying_type<T>::type;
1145  return (DOCTEST_STRINGIFY(static_cast<UT>(value)));
1146 }
1147 
1148 namespace detail {
1149  template <typename T>
1150  struct filldata
1151  {
1152  static void fill(std::ostream* stream, const T& in) {
1153 #if defined(_MSC_VER) && _MSC_VER <= 1900
1154  insert_hack_t<T>::insert(*stream, in);
1155 #else
1156  operator<<(*stream, in);
1157 #endif
1158  }
1159  };
1160 
1162 // NOLINTBEGIN(*-avoid-c-arrays)
1163  template <typename T, size_t N>
1164  struct filldata<T[N]> {
1165  static void fill(std::ostream* stream, const T(&in)[N]) {
1166  *stream << "[";
1167  for (size_t i = 0; i < N; i++) {
1168  if (i != 0) { *stream << ", "; }
1169  *stream << (DOCTEST_STRINGIFY(in[i]));
1170  }
1171  *stream << "]";
1172  }
1173  };
1174 // NOLINTEND(*-avoid-c-arrays)
1176 
1177  // Specialized since we don't want the terminating null byte!
1178 // NOLINTBEGIN(*-avoid-c-arrays)
1179  template <size_t N>
1180  struct filldata<const char[N]> {
1181  static void fill(std::ostream* stream, const char (&in)[N]) {
1182  *stream << String(in, in[N - 1] ? N : N - 1);
1183  } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
1184  };
1185 // NOLINTEND(*-avoid-c-arrays)
1186 
1187  template <>
1188  struct filldata<const void*> {
1189  static void fill(std::ostream* stream, const void* in);
1190  };
1191 
1192  template <typename T>
1193  struct filldata<T*> {
1195  static void fill(std::ostream* stream, const T* in) {
1197 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wmicrosoft-cast")
1199 #if DOCTEST_GCC == 0 || DOCTEST_GCC >= DOCTEST_COMPILER(4, 9, 0)
1200  reinterpret_cast<const void*>(in)
1201 #else
1202  *reinterpret_cast<const void* const*>(&in)
1203 #endif
1204  );
1206  }
1207  };
1208 }
1209 
1211 {
1212  Approx(double value);
1213 
1214  Approx operator()(double value) const;
1215 
1216 #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1217  template <typename T>
1218  explicit Approx(const T& value,
1219  typename detail::types::enable_if<std::is_constructible<double, T>::value>::type* =
1220  static_cast<T*>(nullptr)) {
1221  *this = static_cast<double>(value);
1222  }
1223 #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1224 
1225  Approx& epsilon(double newEpsilon);
1226 
1227 #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1228  template <typename T>
1229  typename std::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon(
1230  const T& newEpsilon) {
1231  m_epsilon = static_cast<double>(newEpsilon);
1232  return *this;
1233  }
1234 #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1235 
1236  Approx& scale(double newScale);
1237 
1238 #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1239  template <typename T>
1240  typename std::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale(
1241  const T& newScale) {
1242  m_scale = static_cast<double>(newScale);
1243  return *this;
1244  }
1245 #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1246 
1247  // clang-format off
1248  DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs);
1249  DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs);
1250  DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs);
1251  DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs);
1252  DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs);
1253  DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs);
1254  DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs);
1255  DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs);
1256  DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs);
1257  DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs);
1258  DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs);
1259  DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs);
1260 
1261 #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1262 #define DOCTEST_APPROX_PREFIX \
1263  template <typename T> friend typename std::enable_if<std::is_constructible<double, T>::value, bool>::type
1264 
1265  DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(static_cast<double>(lhs), rhs); }
1266  DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); }
1267  DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
1268  DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); }
1269  DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; }
1270  DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; }
1271  DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; }
1272  DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast<double>(rhs) || lhs == rhs; }
1273  DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) < rhs.m_value && lhs != rhs; }
1274  DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast<double>(rhs) && lhs != rhs; }
1275  DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return static_cast<double>(lhs) > rhs.m_value && lhs != rhs; }
1276  DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast<double>(rhs) && lhs != rhs; }
1277 #undef DOCTEST_APPROX_PREFIX
1278 #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
1279 
1280  // clang-format on
1281 
1282  double m_epsilon;
1283  double m_scale;
1284  double m_value;
1285 };
1286 
1288 
1290 
1291 template <typename F>
1293 {
1294  F value; bool flipped;
1295  IsNaN(F f, bool flip = false) : value(f), flipped(flip) { }
1296  IsNaN<F> operator!() const { return { value, !flipped }; }
1297  operator bool() const;
1298 };
1299 #ifndef __MINGW32__
1300 extern template struct DOCTEST_INTERFACE_DECL IsNaN<float>;
1301 extern template struct DOCTEST_INTERFACE_DECL IsNaN<double>;
1302 extern template struct DOCTEST_INTERFACE_DECL IsNaN<long double>;
1303 #endif
1307 
1308 #ifndef DOCTEST_CONFIG_DISABLE
1309 
1310 namespace detail {
1311  // clang-format off
1312 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1313  template<class T> struct decay_array { using type = T; };
1314  template<class T, unsigned N> struct decay_array<T[N]> { using type = T*; };
1315  template<class T> struct decay_array<T[]> { using type = T*; };
1316 
1317  template<class T> struct not_char_pointer { static DOCTEST_CONSTEXPR int value = 1; };
1318  template<> struct not_char_pointer<char*> { static DOCTEST_CONSTEXPR int value = 0; };
1319  template<> struct not_char_pointer<const char*> { static DOCTEST_CONSTEXPR int value = 0; };
1320 
1321  template<class T> struct can_use_op : public not_char_pointer<typename decay_array<T>::type> {};
1322 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1323  // clang-format on
1324 
1326  {
1327  };
1328 
1330 
1331 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
1333 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
1335 
1337  {
1339  bool m_entered = false;
1340 
1341  Subcase(const String& name, const char* file, int line);
1342  Subcase(const Subcase&) = delete;
1343  Subcase(Subcase&&) = delete;
1344  Subcase& operator=(const Subcase&) = delete;
1345  Subcase& operator=(Subcase&&) = delete;
1347 
1348  operator bool() const;
1349 
1350  private:
1352  };
1353 
1354  template <typename L, typename R>
1355  String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
1356  const DOCTEST_REF_WRAP(R) rhs) {
1357  return (DOCTEST_STRINGIFY(lhs)) + op + (DOCTEST_STRINGIFY(rhs));
1358  }
1359 
1360 #if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
1361 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
1362 #endif
1363 
1364 // This will check if there is any way it could find a operator like member or friend and uses it.
1365 // If not it doesn't find the operator or if the operator at global scope is defined after
1366 // this template, the template won't be instantiated due to SFINAE. Once the template is not
1367 // instantiated it can look for global operator using normal conversions.
1368 #ifdef __NVCC__
1369 #define SFINAE_OP(ret,op) ret
1370 #else
1371 #define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval<L>() op doctest::detail::declval<R>()),ret{})
1372 #endif
1373 
1374 #define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \
1375  template <typename R> \
1376  DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \
1377  bool res = op_macro(doctest::detail::forward<const L>(lhs), doctest::detail::forward<R>(rhs)); \
1378  if(m_at & assertType::is_false) \
1379  res = !res; \
1380  if(!res || doctest::getContextOptions()->success) \
1381  return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \
1382  return Result(res); \
1383  }
1384 
1385  // more checks could be added - like in Catch:
1386  // https://github.com/catchorg/Catch2/pull/1480/files
1387  // https://github.com/catchorg/Catch2/pull/1481/files
1388 #define DOCTEST_FORBIT_EXPRESSION(rt, op) \
1389  template <typename R> \
1390  rt& operator op(const R&) { \
1391  static_assert(deferred_false<R>::value, \
1392  "Expression Too Complex Please Rewrite As Binary Comparison!"); \
1393  return *this; \
1394  }
1395 
1396  struct DOCTEST_INTERFACE Result // NOLINT(*-member-init)
1397  {
1398  bool m_passed;
1400 
1401  Result() = default; // TODO: Why do we need this? (To remove NOLINT)
1402  Result(bool passed, const String& decomposition = String());
1403 
1404  // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
1427  };
1428 
1429 #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
1430 
1432  DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
1433  DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare")
1434  //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion")
1435  //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion")
1436  //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal")
1437 
1439  DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
1440  DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare")
1441  //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion")
1442  //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
1443  //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
1444 
1446  // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389
1447  DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch
1448  DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch
1449  DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch
1450  //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation
1451 
1452 #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
1453 
1454  // clang-format off
1455 #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1456 #define DOCTEST_COMPARISON_RETURN_TYPE bool
1457 #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1458 #define DOCTEST_COMPARISON_RETURN_TYPE typename types::enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
1459  inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
1460  inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
1461  inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
1462  inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); }
1463  inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }
1464  inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }
1465 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1466  // clang-format on
1467 
1468 #define DOCTEST_RELATIONAL_OP(name, op) \
1469  template <typename L, typename R> \
1470  DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \
1471  const DOCTEST_REF_WRAP(R) rhs) { \
1472  return lhs op rhs; \
1473  }
1474 
1481 
1482 #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1483 #define DOCTEST_CMP_EQ(l, r) l == r
1484 #define DOCTEST_CMP_NE(l, r) l != r
1485 #define DOCTEST_CMP_GT(l, r) l > r
1486 #define DOCTEST_CMP_LT(l, r) l < r
1487 #define DOCTEST_CMP_GE(l, r) l >= r
1488 #define DOCTEST_CMP_LE(l, r) l <= r
1489 #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1490 #define DOCTEST_CMP_EQ(l, r) eq(l, r)
1491 #define DOCTEST_CMP_NE(l, r) ne(l, r)
1492 #define DOCTEST_CMP_GT(l, r) gt(l, r)
1493 #define DOCTEST_CMP_LT(l, r) lt(l, r)
1494 #define DOCTEST_CMP_GE(l, r) ge(l, r)
1495 #define DOCTEST_CMP_LE(l, r) le(l, r)
1496 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
1497 
1498  template <typename L>
1499  // cppcheck-suppress copyCtorAndEqOperator
1501  {
1502  L lhs;
1504 
1505  explicit Expression_lhs(L&& in, assertType::Enum at)
1506  : lhs(static_cast<L&&>(in))
1507  , m_at(at) {}
1508 
1510 // this is needed only for MSVC 2015
1511 DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool
1512  bool res = static_cast<bool>(lhs);
1514  if(m_at & assertType::is_false) {
1515  res = !res;
1516  }
1517 
1518  if(!res || getContextOptions()->success) {
1519  return { res, (DOCTEST_STRINGIFY(lhs)) };
1520  }
1521  return { res };
1522  }
1523 
1524  /* This is required for user-defined conversions from Expression_lhs to L */
1525  operator L() const { return lhs; }
1526 
1527  // clang-format off
1534  // clang-format on
1535 
1536  // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
1553  // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the
1554  // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression...
1557  };
1558 
1559 #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
1560 
1564 
1565 #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
1566 
1567 #if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
1569 #endif
1570 
1572  {
1574 
1576 
1577  // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table)
1578  // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now...
1579  // https://github.com/catchorg/Catch2/issues/870
1580  // https://github.com/catchorg/Catch2/issues/565
1581  template <typename L>
1582  Expression_lhs<const L&&> operator<<(const L&& operand) { //bitfields bind to universal ref but not const rvalue ref
1583  return Expression_lhs<const L&&>(static_cast<const L&&>(operand), m_at);
1584  }
1585 
1586  template <typename L,typename types::enable_if<!doctest::detail::types::is_rvalue_reference<L>::value,void >::type* = nullptr>
1587  Expression_lhs<const L&> operator<<(const L &operand) {
1588  return Expression_lhs<const L&>(operand, m_at);
1589  }
1590  };
1591 
1593  {
1594  const char* m_test_suite = nullptr;
1595  const char* m_description = nullptr;
1596  bool m_skip = false;
1597  bool m_no_breaks = false;
1598  bool m_no_output = false;
1599  bool m_may_fail = false;
1600  bool m_should_fail = false;
1601  int m_expected_failures = 0;
1602  double m_timeout = 0;
1603 
1604  TestSuite& operator*(const char* in);
1605 
1606  template <typename T>
1607  TestSuite& operator*(const T& in) {
1608  in.fill(*this);
1609  return *this;
1610  }
1611  };
1612 
1613  using funcType = void (*)();
1614 
1616  {
1617  funcType m_test; // a function pointer to the test case
1618 
1619  String m_type; // for templated test cases - gets appended to the real name
1620  int m_template_id; // an ID used to distinguish between the different versions of a templated test case
1621  String m_full_name; // contains the name (only for templated test cases!) + the template type
1622 
1623  TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
1624  const String& type = String(), int template_id = -1);
1625 
1626  TestCase(const TestCase& other);
1627  TestCase(TestCase&&) = delete;
1628 
1629  DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
1630  TestCase& operator=(const TestCase& other);
1632 
1633  TestCase& operator=(TestCase&&) = delete;
1634 
1635  TestCase& operator*(const char* in);
1636 
1637  template <typename T>
1638  TestCase& operator*(const T& in) {
1639  in.fill(*this);
1640  return *this;
1641  }
1642 
1643  bool operator<(const TestCase& other) const;
1644 
1645  ~TestCase() = default;
1646  };
1647 
1648  // forward declarations of functions used by the macros
1652 
1653  template<typename T>
1654  int instantiationHelper(const T&) { return 0; }
1655 
1656  namespace binaryAssertComparison {
1657  enum Enum
1658  {
1659  eq = 0,
1664  le
1665  };
1666  } // namespace binaryAssertComparison
1667 
1668  // clang-format off
1669  template <int, class L, class R> struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } };
1670 
1671 #define DOCTEST_BINARY_RELATIONAL_OP(n, op) \
1672  template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };
1673  // clang-format on
1674 
1681 
1683  {
1684  ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
1685  const char* exception_type = "", const String& exception_string = "");
1686 
1687  ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
1688  const char* exception_type, const Contains& exception_string);
1689 
1690  void setResult(const Result& res);
1691 
1692  template <int comparison, typename L, typename R>
1693  DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs,
1694  const DOCTEST_REF_WRAP(R) rhs) {
1695  m_failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
1696  if (m_failed || getContextOptions()->success) {
1697  m_decomp = stringifyBinaryExpr(lhs, ", ", rhs);
1698  }
1699  return !m_failed;
1700  }
1701 
1702  template <typename L>
1703  DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val) {
1704  m_failed = !val;
1705 
1706  if (m_at & assertType::is_false) {
1707  m_failed = !m_failed;
1708  }
1709 
1710  if (m_failed || getContextOptions()->success) {
1711  m_decomp = (DOCTEST_STRINGIFY(val));
1712  }
1713 
1714  return !m_failed;
1715  }
1716 
1718 
1719  bool log();
1720  void react() const;
1721  };
1722 
1723  namespace assertAction {
1724  enum Enum
1725  {
1726  nothing = 0,
1728  shouldthrow = 2
1729  };
1730  } // namespace assertAction
1731 
1733 
1734  DOCTEST_INTERFACE bool decomp_assert(assertType::Enum at, const char* file, int line,
1735  const char* expr, const Result& result);
1736 
1737 #define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \
1738  do { \
1739  if(!is_running_in_test) { \
1740  if(failed) { \
1741  ResultBuilder rb(at, file, line, expr); \
1742  rb.m_failed = failed; \
1743  rb.m_decomp = decomp; \
1744  failed_out_of_a_testing_context(rb); \
1745  if(isDebuggerActive() && !getContextOptions()->no_breaks) \
1746  DOCTEST_BREAK_INTO_DEBUGGER(); \
1747  if(checkIfShouldThrow(at)) \
1748  throwException(); \
1749  } \
1750  return !failed; \
1751  } \
1752  } while(false)
1753 
1754 #define DOCTEST_ASSERT_IN_TESTS(decomp) \
1755  ResultBuilder rb(at, file, line, expr); \
1756  rb.m_failed = failed; \
1757  if(rb.m_failed || getContextOptions()->success) \
1758  rb.m_decomp = decomp; \
1759  if(rb.log()) \
1760  DOCTEST_BREAK_INTO_DEBUGGER(); \
1761  if(rb.m_failed && checkIfShouldThrow(at)) \
1762  throwException()
1763 
1764  template <int comparison, typename L, typename R>
1765  DOCTEST_NOINLINE bool binary_assert(assertType::Enum at, const char* file, int line,
1766  const char* expr, const DOCTEST_REF_WRAP(L) lhs,
1767  const DOCTEST_REF_WRAP(R) rhs) {
1768  bool failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
1769 
1770  // ###################################################################################
1771  // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
1772  // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
1773  // ###################################################################################
1776  return !failed;
1777  }
1778 
1779  template <typename L>
1780  DOCTEST_NOINLINE bool unary_assert(assertType::Enum at, const char* file, int line,
1781  const char* expr, const DOCTEST_REF_WRAP(L) val) {
1782  bool failed = !val;
1783 
1784  if(at & assertType::is_false)
1785  failed = !failed;
1786 
1787  // ###################################################################################
1788  // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
1789  // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
1790  // ###################################################################################
1793  return !failed;
1794  }
1795 
1797  {
1799  virtual bool translate(String&) const = 0;
1800  };
1801 
1802  template <typename T>
1804  {
1805  public:
1806  explicit ExceptionTranslator(String (*translateFunction)(T))
1807  : m_translateFunction(translateFunction) {}
1808 
1809  bool translate(String& res) const override {
1810 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
1811  try {
1812  throw; // lgtm [cpp/rethrow-no-exception]
1813  // cppcheck-suppress catchExceptionByValue
1814  } catch(const T& ex) {
1815  res = m_translateFunction(ex);
1816  return true;
1817  } catch(...) {}
1818 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
1819  static_cast<void>(res); // to silence -Wunused-parameter
1820  return false;
1821  }
1822 
1823  private:
1824  String (*m_translateFunction)(T);
1825  };
1826 
1828 
1829  // ContextScope base class used to allow implementing methods of ContextScope
1830  // that don't depend on the template parameter in doctest.cpp.
1833 
1836 
1837  ~ContextScopeBase() override = default;
1838 
1839  protected:
1842 
1843  void destroy();
1844  bool need_to_destroy{true};
1845  };
1846 
1847  template <typename L> class ContextScope : public ContextScopeBase
1848  {
1850 
1851  public:
1852  explicit ContextScope(const L &lambda) : lambda_(lambda) {}
1853  explicit ContextScope(L&& lambda) : lambda_(static_cast<L&&>(lambda)) { }
1854 
1855  ContextScope(const ContextScope&) = delete;
1856  ContextScope(ContextScope&&) noexcept = default;
1857 
1858  ContextScope& operator=(const ContextScope&) = delete;
1859  ContextScope& operator=(ContextScope&&) = delete;
1860 
1861  void stringify(std::ostream* s) const override { lambda_(s); }
1862 
1863  ~ContextScope() override {
1864  if (need_to_destroy) {
1865  destroy();
1866  }
1867  }
1868  };
1869 
1871  {
1873  bool logged = false;
1874 
1875  MessageBuilder(const char* file, int line, assertType::Enum severity);
1876 
1877  MessageBuilder(const MessageBuilder&) = delete;
1879 
1882 
1884 
1885  // the preferred way of chaining parameters for stringification
1887  template <typename T>
1888  MessageBuilder& operator,(const T& in) {
1889  *m_stream << (DOCTEST_STRINGIFY(in));
1890  return *this;
1891  }
1893 
1894  // kept here just for backwards-compatibility - the comma operator should be preferred now
1895  template <typename T>
1896  MessageBuilder& operator<<(const T& in) { return this->operator,(in); }
1897 
1898  // the `,` operator has the lowest operator precedence - if `<<` is used by the user then
1899  // the `,` operator will be called last which is not what we want and thus the `*` operator
1900  // is used first (has higher operator precedence compared to `<<`) so that we guarantee that
1901  // an operator of the MessageBuilder class is called first before the rest of the parameters
1902  template <typename T>
1903  MessageBuilder& operator*(const T& in) { return this->operator,(in); }
1904 
1905  bool log();
1906  void react();
1907  };
1908 
1909  template <typename L>
1911  return ContextScope<L>(lambda);
1912  }
1913 } // namespace detail
1914 
1915 #define DOCTEST_DEFINE_DECORATOR(name, type, def) \
1916  struct name \
1917  { \
1918  type data; \
1919  name(type in = def) \
1920  : data(in) {} \
1921  void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \
1922  void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \
1923  }
1924 
1934 
1935 template <typename T>
1936 int registerExceptionTranslator(String (*translateFunction)(T)) {
1937  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors")
1938  static detail::ExceptionTranslator<T> exceptionTranslator(translateFunction);
1940  detail::registerExceptionTranslatorImpl(&exceptionTranslator);
1941  return 0;
1942 }
1943 
1944 } // namespace doctest
1945 
1946 // in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro
1947 // introduces an anonymous namespace in which getCurrentTestSuite gets overridden
1950 } // namespace doctest_detail_test_suite_ns
1951 
1952 namespace doctest {
1953 #else // DOCTEST_CONFIG_DISABLE
1954 template <typename T>
1955 int registerExceptionTranslator(String (*)(T)) {
1956  return 0;
1957 }
1958 #endif // DOCTEST_CONFIG_DISABLE
1959 
1960 namespace detail {
1961  using assert_handler = void (*)(const AssertData&);
1962  struct ContextState;
1963 } // namespace detail
1964 
1966 {
1967  detail::ContextState* p;
1968 
1969  void parseArgs(int argc, const char* const* argv, bool withDefaults = false);
1970 
1971 public:
1972  explicit Context(int argc = 0, const char* const* argv = nullptr);
1973 
1974  Context(const Context&) = delete;
1975  Context(Context&&) = delete;
1976 
1977  Context& operator=(const Context&) = delete;
1978  Context& operator=(Context&&) = delete;
1979 
1980  ~Context(); // NOLINT(performance-trivially-destructible)
1981 
1982  void applyCommandLine(int argc, const char* const* argv);
1983 
1984  void addFilter(const char* filter, const char* value);
1986  void setOption(const char* option, bool value);
1987  void setOption(const char* option, int value);
1988  void setOption(const char* option, const char* value);
1989 
1990  bool shouldExit();
1991 
1993 
1995 
1996  void setCout(std::ostream* out);
1997 
1998  int run();
1999 };
2000 
2001 namespace TestCaseFailureReason {
2002  enum Enum
2003  {
2004  None = 0,
2005  AssertFailure = 1, // an assertion has failed in the test case
2006  Exception = 2, // test case threw an exception
2007  Crash = 4, // a crash...
2008  TooManyFailedAsserts = 8, // the abort-after option
2009  Timeout = 16, // see the timeout decorator
2010  ShouldHaveFailedButDidnt = 32, // see the should_fail decorator
2011  ShouldHaveFailedAndDid = 64, // see the should_fail decorator
2012  DidntFailExactlyNumTimes = 128, // see the expected_failures decorator
2013  FailedExactlyNumTimes = 256, // see the expected_failures decorator
2014  CouldHaveFailedAndDid = 512 // see the may_fail decorator
2015  };
2016 } // namespace TestCaseFailureReason
2017 
2019 {
2022  double seconds;
2023  int failure_flags; // use TestCaseFailureReason::Enum
2025 };
2026 
2028 {
2030  bool is_crash;
2031 };
2032 
2034 {
2035  unsigned numTestCases;
2041 };
2042 
2044 {
2045  const TestRunStats* run_stats = nullptr;
2046  const TestCaseData** data = nullptr;
2047  unsigned num_data = 0;
2048 };
2049 
2051 {
2052  // The constructor has to accept "const ContextOptions&" as a single argument
2053  // which has most of the options for the run + a pointer to the stdout stream
2054  // Reporter(const ContextOptions& in)
2055 
2056  // called when a query should be reported (listing test cases, printing the version, etc.)
2057  virtual void report_query(const QueryData&) = 0;
2058 
2059  // called when the whole test run starts
2060  virtual void test_run_start() = 0;
2061  // called when the whole test run ends (caching a pointer to the input doesn't make sense here)
2062  virtual void test_run_end(const TestRunStats&) = 0;
2063 
2064  // called when a test case is started (safe to cache a pointer to the input)
2065  virtual void test_case_start(const TestCaseData&) = 0;
2066  // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input)
2067  virtual void test_case_reenter(const TestCaseData&) = 0;
2068  // called when a test case has ended
2069  virtual void test_case_end(const CurrentTestCaseStats&) = 0;
2070 
2071  // called when an exception is thrown from the test case (or it crashes)
2072  virtual void test_case_exception(const TestCaseException&) = 0;
2073 
2074  // called whenever a subcase is entered (don't cache pointers to the input)
2075  virtual void subcase_start(const SubcaseSignature&) = 0;
2076  // called whenever a subcase is exited (don't cache pointers to the input)
2077  virtual void subcase_end() = 0;
2078 
2079  // called for each assert (don't cache pointers to the input)
2080  virtual void log_assert(const AssertData&) = 0;
2081  // called for each message (don't cache pointers to the input)
2082  virtual void log_message(const MessageData&) = 0;
2083 
2084  // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator
2085  // or isn't in the execution range (between first and last) (safe to cache a pointer to the input)
2086  virtual void test_case_skipped(const TestCaseData&) = 0;
2087 
2089 
2090  // can obtain all currently active contexts and stringify them if one wishes to do so
2091  static int get_num_active_contexts();
2092  static const IContextScope* const* get_active_contexts();
2093 
2094  // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown
2095  static int get_num_stringified_contexts();
2096  static const String* get_stringified_contexts();
2097 };
2098 
2099 namespace detail {
2101 
2102  DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter);
2103 
2104  template <typename Reporter>
2106  return new Reporter(o);
2107  }
2108 } // namespace detail
2109 
2110 template <typename Reporter>
2111 int registerReporter(const char* name, int priority, bool isReporter) {
2112  detail::registerReporterImpl(name, priority, detail::reporterCreator<Reporter>, isReporter);
2113  return 0;
2114 }
2115 } // namespace doctest
2116 
2117 #ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES
2118 #define DOCTEST_FUNC_EMPTY [] { return false; }()
2119 #else
2120 #define DOCTEST_FUNC_EMPTY (void)0
2121 #endif
2122 
2123 // if registering is not disabled
2124 #ifndef DOCTEST_CONFIG_DISABLE
2125 
2126 #ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES
2127 #define DOCTEST_FUNC_SCOPE_BEGIN [&]
2128 #define DOCTEST_FUNC_SCOPE_END ()
2129 #define DOCTEST_FUNC_SCOPE_RET(v) return v
2130 #else
2131 #define DOCTEST_FUNC_SCOPE_BEGIN do
2132 #define DOCTEST_FUNC_SCOPE_END while(false)
2133 #define DOCTEST_FUNC_SCOPE_RET(v) (void)0
2134 #endif
2135 
2136 // common code in asserts - for convenience
2137 #define DOCTEST_ASSERT_LOG_REACT_RETURN(b) \
2138  if(b.log()) DOCTEST_BREAK_INTO_DEBUGGER(); \
2139  b.react(); \
2140  DOCTEST_FUNC_SCOPE_RET(!b.m_failed)
2141 
2142 #ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
2143 #define DOCTEST_WRAP_IN_TRY(x) x;
2144 #else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
2145 #define DOCTEST_WRAP_IN_TRY(x) \
2146  try { \
2147  x; \
2148  } catch(...) { DOCTEST_RB.translateException(); }
2149 #endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
2150 
2151 #ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
2152 #define DOCTEST_CAST_TO_VOID(...) \
2153  DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \
2154  static_cast<void>(__VA_ARGS__); \
2155  DOCTEST_GCC_SUPPRESS_WARNING_POP
2156 #else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
2157 #define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;
2158 #endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
2159 
2160 // registers the test by initializing a dummy var with a function
2161 #define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \
2162  global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT */ \
2163  doctest::detail::regTest( \
2164  doctest::detail::TestCase( \
2165  f, __FILE__, __LINE__, \
2166  doctest_detail_test_suite_ns::getCurrentTestSuite()) * \
2167  decorators))
2168 
2169 #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \
2170  namespace { /* NOLINT */ \
2171  struct der : public base \
2172  { \
2173  void f(); \
2174  }; \
2175  static DOCTEST_INLINE_NOINLINE void func() { \
2176  der v; \
2177  v.f(); \
2178  } \
2179  DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \
2180  } \
2181  DOCTEST_INLINE_NOINLINE void der::f() // NOLINT(misc-definitions-in-headers)
2182 
2183 #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \
2184  static void f(); \
2185  DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \
2186  static void f()
2187 
2188 #define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \
2189  static doctest::detail::funcType proxy() { return f; } \
2190  DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators) \
2191  static void f()
2192 
2193 // for registering tests
2194 #define DOCTEST_TEST_CASE(decorators) \
2195  DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
2196 
2197 // for registering tests in classes - requires C++17 for inline variables!
2198 #if DOCTEST_CPLUSPLUS >= 201703L
2199 #define DOCTEST_TEST_CASE_CLASS(decorators) \
2200  DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \
2201  DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \
2202  decorators)
2203 #else // DOCTEST_TEST_CASE_CLASS
2204 #define DOCTEST_TEST_CASE_CLASS(...) \
2205  TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER
2206 #endif // DOCTEST_TEST_CASE_CLASS
2207 
2208 // for registering tests with a fixture
2209 #define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \
2210  DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c, \
2211  DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
2212 
2213 // for converting types to strings without the <typeinfo> header and demangling
2214 #define DOCTEST_TYPE_TO_STRING_AS(str, ...) \
2215  namespace doctest { \
2216  template <> \
2217  inline String toString<__VA_ARGS__>() { \
2218  return str; \
2219  } \
2220  } \
2221  static_assert(true, "")
2222 
2223 #define DOCTEST_TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING_AS(#__VA_ARGS__, __VA_ARGS__)
2224 
2225 #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \
2226  template <typename T> \
2227  static void func(); \
2228  namespace { /* NOLINT */ \
2229  template <typename Tuple> \
2230  struct iter; \
2231  template <typename Type, typename... Rest> \
2232  struct iter<std::tuple<Type, Rest...>> \
2233  { \
2234  iter(const char* file, unsigned line, int index) { \
2235  doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line, \
2236  doctest_detail_test_suite_ns::getCurrentTestSuite(), \
2237  doctest::toString<Type>(), \
2238  int(line) * 1000 + index) \
2239  * dec); \
2240  iter<std::tuple<Rest...>>(file, line, index + 1); \
2241  } \
2242  }; \
2243  template <> \
2244  struct iter<std::tuple<>> \
2245  { \
2246  iter(const char*, unsigned, int) {} \
2247  }; \
2248  } \
2249  template <typename T> \
2250  static void func()
2251 
2252 #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \
2253  DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \
2254  DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_))
2255 
2256 #define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \
2257  DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY), /* NOLINT(cert-err58-cpp, fuchsia-statically-constructed-objects) */ \
2258  doctest::detail::instantiationHelper( \
2259  DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0)))
2260 
2261 #define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \
2262  DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
2263  static_assert(true, "")
2264 
2265 #define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \
2266  DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \
2267  static_assert(true, "")
2268 
2269 #define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \
2270  DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \
2271  DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \
2272  template <typename T> \
2273  static void anon()
2274 
2275 #define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \
2276  DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__)
2277 
2278 // for subcases
2279 #define DOCTEST_SUBCASE(name) \
2280  if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \
2281  doctest::detail::Subcase(name, __FILE__, __LINE__))
2282 
2283 // for grouping tests in test suites by using code blocks
2284 #define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \
2285  namespace ns_name { namespace doctest_detail_test_suite_ns { \
2286  static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() noexcept { \
2287  DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \
2288  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \
2289  DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \
2290  static doctest::detail::TestSuite data{}; \
2291  static bool inited = false; \
2292  DOCTEST_MSVC_SUPPRESS_WARNING_POP \
2293  DOCTEST_CLANG_SUPPRESS_WARNING_POP \
2294  DOCTEST_GCC_SUPPRESS_WARNING_POP \
2295  if(!inited) { \
2296  data* decorators; \
2297  inited = true; \
2298  } \
2299  return data; \
2300  } \
2301  } \
2302  } \
2303  namespace ns_name
2304 
2305 #define DOCTEST_TEST_SUITE(decorators) \
2306  DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_))
2307 
2308 // for starting a testsuite block
2309 #define DOCTEST_TEST_SUITE_BEGIN(decorators) \
2310  DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \
2311  doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators)) \
2312  static_assert(true, "")
2313 
2314 // for ending a testsuite block
2315 #define DOCTEST_TEST_SUITE_END \
2316  DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \
2317  doctest::detail::setTestSuite(doctest::detail::TestSuite() * "")) \
2318  using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int
2319 
2320 // for registering exception translators
2321 #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \
2322  inline doctest::String translatorName(signature); \
2323  DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), /* NOLINT(cert-err58-cpp) */ \
2324  doctest::registerExceptionTranslator(translatorName)) \
2325  doctest::String translatorName(signature)
2326 
2327 #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
2328  DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \
2329  signature)
2330 
2331 // for registering reporters
2332 #define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \
2333  DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \
2334  doctest::registerReporter<reporter>(name, priority, true)) \
2335  static_assert(true, "")
2336 
2337 // for registering listeners
2338 #define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \
2339  DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \
2340  doctest::registerReporter<reporter>(name, priority, false)) \
2341  static_assert(true, "")
2342 
2343 // clang-format off
2344 // for logging - disabling formatting because it's important to have these on 2 separate lines - see PR #557
2345 #define DOCTEST_INFO(...) \
2346  DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_), \
2347  DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_), \
2348  __VA_ARGS__)
2349 // clang-format on
2350 
2351 #define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \
2352  auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \
2353  [&](std::ostream* s_name) { \
2354  doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
2355  mb_name.m_stream = s_name; \
2356  mb_name * __VA_ARGS__; \
2357  })
2358 
2359 #define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
2360 
2361 #define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
2362  DOCTEST_FUNC_SCOPE_BEGIN { \
2363  doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
2364  mb * __VA_ARGS__; \
2365  if(mb.log()) \
2366  DOCTEST_BREAK_INTO_DEBUGGER(); \
2367  mb.react(); \
2368  } DOCTEST_FUNC_SCOPE_END
2369 
2370 // clang-format off
2371 #define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
2372 #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
2373 #define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
2374 // clang-format on
2375 
2376 #define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
2377 #define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
2378 #define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
2379 
2380 #define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.
2381 
2382 #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
2383 
2384 #define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \
2385  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
2386  /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \
2387  doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2388  __LINE__, #__VA_ARGS__); \
2389  DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult( \
2390  doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
2391  << __VA_ARGS__)) /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \
2392  DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB) \
2393  DOCTEST_CLANG_SUPPRESS_WARNING_POP
2394 
2395 #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
2396  DOCTEST_FUNC_SCOPE_BEGIN { \
2397  DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \
2398  } DOCTEST_FUNC_SCOPE_END // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
2399 
2400 #define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \
2401  DOCTEST_FUNC_SCOPE_BEGIN { \
2402  doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2403  __LINE__, #__VA_ARGS__); \
2404  DOCTEST_WRAP_IN_TRY( \
2405  DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \
2406  __VA_ARGS__)) \
2407  DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2408  } DOCTEST_FUNC_SCOPE_END
2409 
2410 #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
2411  DOCTEST_FUNC_SCOPE_BEGIN { \
2412  doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2413  __LINE__, #__VA_ARGS__); \
2414  DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__)) \
2415  DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2416  } DOCTEST_FUNC_SCOPE_END
2417 
2418 #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
2419 
2420 // necessary for <ASSERT>_MESSAGE
2421 #define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1
2422 
2423 #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
2424  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
2425  doctest::detail::decomp_assert( \
2426  doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \
2427  doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
2428  << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP
2429 
2430 #define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \
2431  doctest::detail::binary_assert<doctest::detail::binaryAssertComparison::comparison>( \
2432  doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__)
2433 
2434 #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
2435  doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \
2436  #__VA_ARGS__, __VA_ARGS__)
2437 
2438 #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
2439 
2440 #define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__)
2441 #define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__)
2442 #define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__)
2443 #define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__)
2444 #define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__)
2445 #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
2446 
2447 // clang-format off
2448 #define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } DOCTEST_FUNC_SCOPE_END
2449 #define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } DOCTEST_FUNC_SCOPE_END
2450 #define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } DOCTEST_FUNC_SCOPE_END
2451 #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
2452 #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
2453 #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } DOCTEST_FUNC_SCOPE_END
2454 // clang-format on
2455 
2456 #define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__)
2457 #define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__)
2458 #define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__)
2459 #define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__)
2460 #define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__)
2461 #define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__)
2462 #define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__)
2463 #define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__)
2464 #define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__)
2465 #define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__)
2466 #define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__)
2467 #define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__)
2468 #define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__)
2469 #define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__)
2470 #define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__)
2471 #define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__)
2472 #define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__)
2473 #define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__)
2474 
2475 #define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__)
2476 #define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__)
2477 #define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__)
2478 #define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__)
2479 #define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__)
2480 #define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__)
2481 
2482 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
2483 
2484 #define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
2485  DOCTEST_FUNC_SCOPE_BEGIN { \
2486  if(!doctest::getContextOptions()->no_throw) { \
2487  doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2488  __LINE__, #expr, #__VA_ARGS__, message); \
2489  try { \
2490  DOCTEST_CAST_TO_VOID(expr) \
2491  } catch(const typename doctest::detail::types::remove_const< \
2492  typename doctest::detail::types::remove_reference<__VA_ARGS__>::type>::type&) {\
2493  DOCTEST_RB.translateException(); \
2494  DOCTEST_RB.m_threw_as = true; \
2495  } catch(...) { DOCTEST_RB.translateException(); } \
2496  DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2497  } else { /* NOLINT(*-else-after-return) */ \
2498  DOCTEST_FUNC_SCOPE_RET(false); \
2499  } \
2500  } DOCTEST_FUNC_SCOPE_END
2501 
2502 #define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \
2503  DOCTEST_FUNC_SCOPE_BEGIN { \
2504  if(!doctest::getContextOptions()->no_throw) { \
2505  doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2506  __LINE__, expr_str, "", __VA_ARGS__); \
2507  try { \
2508  DOCTEST_CAST_TO_VOID(expr) \
2509  } catch(...) { DOCTEST_RB.translateException(); } \
2510  DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2511  } else { /* NOLINT(*-else-after-return) */ \
2512  DOCTEST_FUNC_SCOPE_RET(false); \
2513  } \
2514  } DOCTEST_FUNC_SCOPE_END
2515 
2516 #define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \
2517  DOCTEST_FUNC_SCOPE_BEGIN { \
2518  doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
2519  __LINE__, #__VA_ARGS__); \
2520  try { \
2521  DOCTEST_CAST_TO_VOID(__VA_ARGS__) \
2522  } catch(...) { DOCTEST_RB.translateException(); } \
2523  DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
2524  } DOCTEST_FUNC_SCOPE_END
2525 
2526 // clang-format off
2527 #define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
2528 #define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "")
2529 #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "")
2530 
2531 #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__)
2532 #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__)
2533 #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__)
2534 
2535 #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)
2536 #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)
2537 #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)
2538 
2539 #define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)
2540 #define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)
2541 #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)
2542 
2543 #define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
2544 #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
2545 #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
2546 
2547 #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
2548 #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
2549 #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } DOCTEST_FUNC_SCOPE_END
2550 #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
2551 #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
2552 #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END
2553 #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
2554 #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
2555 #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END
2556 #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
2557 #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
2558 #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END
2559 #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
2560 #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
2561 #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END
2562 // clang-format on
2563 
2564 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
2565 
2566 // =================================================================================================
2567 // == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! ==
2568 // == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! ==
2569 // =================================================================================================
2570 #else // DOCTEST_CONFIG_DISABLE
2571 
2572 #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
2573  namespace /* NOLINT */ { \
2574  template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2575  struct der : public base \
2576  { void f(); }; \
2577  } \
2578  template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2579  inline void der<DOCTEST_UNUSED_TEMPLATE_TYPE>::f()
2580 
2581 #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
2582  template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2583  static inline void f()
2584 
2585 // for registering tests
2586 #define DOCTEST_TEST_CASE(name) \
2587  DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
2588 
2589 // for registering tests in classes
2590 #define DOCTEST_TEST_CASE_CLASS(name) \
2591  DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
2592 
2593 // for registering tests with a fixture
2594 #define DOCTEST_TEST_CASE_FIXTURE(x, name) \
2595  DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x, \
2596  DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
2597 
2598 // for converting types to strings without the <typeinfo> header and demangling
2599 #define DOCTEST_TYPE_TO_STRING_AS(str, ...) static_assert(true, "")
2600 #define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "")
2601 
2602 // for typed tests
2603 #define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \
2604  template <typename type> \
2605  inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
2606 
2607 #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \
2608  template <typename type> \
2609  inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
2610 
2611 #define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "")
2612 #define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "")
2613 
2614 // for subcases
2615 #define DOCTEST_SUBCASE(name)
2616 
2617 // for a testsuite block
2618 #define DOCTEST_TEST_SUITE(name) namespace // NOLINT
2619 
2620 // for starting a testsuite block
2621 #define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "")
2622 
2623 // for ending a testsuite block
2624 #define DOCTEST_TEST_SUITE_END using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int
2625 
2626 #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
2627  template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
2628  static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature)
2629 
2630 #define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
2631 #define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
2632 
2633 #define DOCTEST_INFO(...) (static_cast<void>(0))
2634 #define DOCTEST_CAPTURE(x) (static_cast<void>(0))
2635 #define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
2636 #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
2637 #define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
2638 #define DOCTEST_MESSAGE(...) (static_cast<void>(0))
2639 #define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
2640 #define DOCTEST_FAIL(...) (static_cast<void>(0))
2641 
2642 #if defined(DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED) \
2643  && defined(DOCTEST_CONFIG_ASSERTS_RETURN_VALUES)
2644 
2645 #define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }()
2646 #define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }()
2647 #define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }()
2648 #define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }()
2649 #define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }()
2650 #define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }()
2651 
2652 #define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }()
2653 #define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }()
2654 #define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }()
2655 #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
2656 #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
2657 #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
2658 
2659 namespace doctest {
2660 namespace detail {
2661 #define DOCTEST_RELATIONAL_OP(name, op) \
2662  template <typename L, typename R> \
2663  bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs op rhs; }
2664 
2671 } // namespace detail
2672 } // namespace doctest
2673 
2674 #define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
2675 #define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
2676 #define DOCTEST_REQUIRE_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
2677 #define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
2678 #define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
2679 #define DOCTEST_REQUIRE_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
2680 #define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
2681 #define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
2682 #define DOCTEST_REQUIRE_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
2683 #define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
2684 #define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
2685 #define DOCTEST_REQUIRE_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
2686 #define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
2687 #define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
2688 #define DOCTEST_REQUIRE_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
2689 #define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
2690 #define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
2691 #define DOCTEST_REQUIRE_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
2692 #define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }()
2693 #define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }()
2694 #define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }()
2695 #define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
2696 #define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
2697 #define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
2698 
2699 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
2700 
2701 #define DOCTEST_WARN_THROWS_WITH(expr, with, ...) [] { static_assert(false, "Exception translation is not available when doctest is disabled."); return false; }()
2702 #define DOCTEST_CHECK_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2703 #define DOCTEST_REQUIRE_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2704 #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2705 #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2706 #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2707 
2708 #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2709 #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2710 #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,)
2711 #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2712 #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2713 #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,)
2714 
2715 #define DOCTEST_WARN_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2716 #define DOCTEST_CHECK_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2717 #define DOCTEST_REQUIRE_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2718 #define DOCTEST_WARN_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2719 #define DOCTEST_CHECK_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2720 #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2721 #define DOCTEST_WARN_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2722 #define DOCTEST_CHECK_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2723 #define DOCTEST_REQUIRE_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2724 
2725 #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2726 #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2727 #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }()
2728 #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2729 #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2730 #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }()
2731 #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2732 #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2733 #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }()
2734 
2735 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
2736 
2737 #else // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
2738 
2739 #define DOCTEST_WARN(...) DOCTEST_FUNC_EMPTY
2740 #define DOCTEST_CHECK(...) DOCTEST_FUNC_EMPTY
2741 #define DOCTEST_REQUIRE(...) DOCTEST_FUNC_EMPTY
2742 #define DOCTEST_WARN_FALSE(...) DOCTEST_FUNC_EMPTY
2743 #define DOCTEST_CHECK_FALSE(...) DOCTEST_FUNC_EMPTY
2744 #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_FUNC_EMPTY
2745 
2746 #define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2747 #define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2748 #define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2749 #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2750 #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2751 #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY
2752 
2753 #define DOCTEST_WARN_EQ(...) DOCTEST_FUNC_EMPTY
2754 #define DOCTEST_CHECK_EQ(...) DOCTEST_FUNC_EMPTY
2755 #define DOCTEST_REQUIRE_EQ(...) DOCTEST_FUNC_EMPTY
2756 #define DOCTEST_WARN_NE(...) DOCTEST_FUNC_EMPTY
2757 #define DOCTEST_CHECK_NE(...) DOCTEST_FUNC_EMPTY
2758 #define DOCTEST_REQUIRE_NE(...) DOCTEST_FUNC_EMPTY
2759 #define DOCTEST_WARN_GT(...) DOCTEST_FUNC_EMPTY
2760 #define DOCTEST_CHECK_GT(...) DOCTEST_FUNC_EMPTY
2761 #define DOCTEST_REQUIRE_GT(...) DOCTEST_FUNC_EMPTY
2762 #define DOCTEST_WARN_LT(...) DOCTEST_FUNC_EMPTY
2763 #define DOCTEST_CHECK_LT(...) DOCTEST_FUNC_EMPTY
2764 #define DOCTEST_REQUIRE_LT(...) DOCTEST_FUNC_EMPTY
2765 #define DOCTEST_WARN_GE(...) DOCTEST_FUNC_EMPTY
2766 #define DOCTEST_CHECK_GE(...) DOCTEST_FUNC_EMPTY
2767 #define DOCTEST_REQUIRE_GE(...) DOCTEST_FUNC_EMPTY
2768 #define DOCTEST_WARN_LE(...) DOCTEST_FUNC_EMPTY
2769 #define DOCTEST_CHECK_LE(...) DOCTEST_FUNC_EMPTY
2770 #define DOCTEST_REQUIRE_LE(...) DOCTEST_FUNC_EMPTY
2771 
2772 #define DOCTEST_WARN_UNARY(...) DOCTEST_FUNC_EMPTY
2773 #define DOCTEST_CHECK_UNARY(...) DOCTEST_FUNC_EMPTY
2774 #define DOCTEST_REQUIRE_UNARY(...) DOCTEST_FUNC_EMPTY
2775 #define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
2776 #define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
2777 #define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY
2778 
2779 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
2780 
2781 #define DOCTEST_WARN_THROWS(...) DOCTEST_FUNC_EMPTY
2782 #define DOCTEST_CHECK_THROWS(...) DOCTEST_FUNC_EMPTY
2783 #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_FUNC_EMPTY
2784 #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
2785 #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
2786 #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY
2787 #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
2788 #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
2789 #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY
2790 #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
2791 #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
2792 #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY
2793 #define DOCTEST_WARN_NOTHROW(...) DOCTEST_FUNC_EMPTY
2794 #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_FUNC_EMPTY
2795 #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_FUNC_EMPTY
2796 
2797 #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2798 #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2799 #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2800 #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
2801 #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
2802 #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY
2803 #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
2804 #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
2805 #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY
2806 #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
2807 #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
2808 #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY
2809 #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2810 #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2811 #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY
2812 
2813 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
2814 
2815 #endif // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
2816 
2817 #endif // DOCTEST_CONFIG_DISABLE
2818 
2819 #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS
2820 
2821 #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
2822 #define DOCTEST_EXCEPTION_EMPTY_FUNC DOCTEST_FUNC_EMPTY
2823 #else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
2824 #define DOCTEST_EXCEPTION_EMPTY_FUNC [] { static_assert(false, "Exceptions are disabled! " \
2825  "Use DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS if you want to compile with exceptions disabled."); return false; }()
2826 
2827 #undef DOCTEST_REQUIRE
2828 #undef DOCTEST_REQUIRE_FALSE
2829 #undef DOCTEST_REQUIRE_MESSAGE
2830 #undef DOCTEST_REQUIRE_FALSE_MESSAGE
2831 #undef DOCTEST_REQUIRE_EQ
2832 #undef DOCTEST_REQUIRE_NE
2833 #undef DOCTEST_REQUIRE_GT
2834 #undef DOCTEST_REQUIRE_LT
2835 #undef DOCTEST_REQUIRE_GE
2836 #undef DOCTEST_REQUIRE_LE
2837 #undef DOCTEST_REQUIRE_UNARY
2838 #undef DOCTEST_REQUIRE_UNARY_FALSE
2839 
2840 #define DOCTEST_REQUIRE DOCTEST_EXCEPTION_EMPTY_FUNC
2841 #define DOCTEST_REQUIRE_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC
2842 #define DOCTEST_REQUIRE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC
2843 #define DOCTEST_REQUIRE_FALSE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC
2844 #define DOCTEST_REQUIRE_EQ DOCTEST_EXCEPTION_EMPTY_FUNC
2845 #define DOCTEST_REQUIRE_NE DOCTEST_EXCEPTION_EMPTY_FUNC
2846 #define DOCTEST_REQUIRE_GT DOCTEST_EXCEPTION_EMPTY_FUNC
2847 #define DOCTEST_REQUIRE_LT DOCTEST_EXCEPTION_EMPTY_FUNC
2848 #define DOCTEST_REQUIRE_GE DOCTEST_EXCEPTION_EMPTY_FUNC
2849 #define DOCTEST_REQUIRE_LE DOCTEST_EXCEPTION_EMPTY_FUNC
2850 #define DOCTEST_REQUIRE_UNARY DOCTEST_EXCEPTION_EMPTY_FUNC
2851 #define DOCTEST_REQUIRE_UNARY_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC
2852 
2853 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
2854 
2855 #define DOCTEST_WARN_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2856 #define DOCTEST_CHECK_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2857 #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2858 #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2859 #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2860 #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2861 #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2862 #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2863 #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2864 #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2865 #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2866 #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2867 #define DOCTEST_WARN_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2868 #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2869 #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC
2870 
2871 #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2872 #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2873 #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2874 #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2875 #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2876 #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2877 #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2878 #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2879 #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2880 #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2881 #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2882 #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2883 #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2884 #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2885 #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC
2886 
2887 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
2888 
2889 // clang-format off
2890 // KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS
2891 #define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ
2892 #define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ
2893 #define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ
2894 #define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE
2895 #define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE
2896 #define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE
2897 #define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT
2898 #define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT
2899 #define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT
2900 #define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT
2901 #define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT
2902 #define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT
2903 #define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE
2904 #define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE
2905 #define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE
2906 #define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE
2907 #define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE
2908 #define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE
2909 
2910 #define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY
2911 #define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY
2912 #define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY
2913 #define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE
2914 #define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE
2915 #define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE
2916 
2917 #define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
2918 // clang-format on
2919 
2920 // BDD style macros
2921 // clang-format off
2922 #define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name)
2923 #define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name)
2924 #define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__)
2925 #define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id)
2926 
2927 #define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name)
2928 #define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name)
2929 #define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name)
2930 #define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name)
2931 #define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name)
2932 // clang-format on
2933 
2934 // == SHORT VERSIONS OF THE MACROS
2935 #ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
2936 
2937 #define TEST_CASE(name) DOCTEST_TEST_CASE(name)
2938 #define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name)
2939 #define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
2940 #define TYPE_TO_STRING_AS(str, ...) DOCTEST_TYPE_TO_STRING_AS(str, __VA_ARGS__)
2941 #define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
2942 #define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
2943 #define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
2944 #define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
2945 #define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
2946 #define SUBCASE(name) DOCTEST_SUBCASE(name)
2947 #define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators)
2948 #define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name)
2949 #define TEST_SUITE_END DOCTEST_TEST_SUITE_END
2950 #define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
2951 #define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
2952 #define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
2953 #define INFO(...) DOCTEST_INFO(__VA_ARGS__)
2954 #define CAPTURE(x) DOCTEST_CAPTURE(x)
2955 #define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
2956 #define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
2957 #define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
2958 #define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__)
2959 #define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
2960 #define FAIL(...) DOCTEST_FAIL(__VA_ARGS__)
2961 #define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__)
2962 
2963 #define WARN(...) DOCTEST_WARN(__VA_ARGS__)
2964 #define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
2965 #define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
2966 #define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
2967 #define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
2968 #define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
2969 #define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
2970 #define CHECK(...) DOCTEST_CHECK(__VA_ARGS__)
2971 #define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
2972 #define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
2973 #define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
2974 #define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
2975 #define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
2976 #define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
2977 #define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__)
2978 #define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
2979 #define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
2980 #define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
2981 #define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
2982 #define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
2983 #define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)
2984 
2985 #define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
2986 #define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
2987 #define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
2988 #define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
2989 #define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
2990 #define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
2991 #define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
2992 #define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
2993 #define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
2994 #define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
2995 #define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
2996 #define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
2997 #define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
2998 #define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
2999 #define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
3000 #define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
3001 #define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
3002 #define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
3003 #define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
3004 #define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
3005 #define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)
3006 
3007 #define SCENARIO(name) DOCTEST_SCENARIO(name)
3008 #define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name)
3009 #define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
3010 #define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
3011 #define GIVEN(name) DOCTEST_GIVEN(name)
3012 #define WHEN(name) DOCTEST_WHEN(name)
3013 #define AND_WHEN(name) DOCTEST_AND_WHEN(name)
3014 #define THEN(name) DOCTEST_THEN(name)
3015 #define AND_THEN(name) DOCTEST_AND_THEN(name)
3016 
3017 #define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__)
3018 #define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
3019 #define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
3020 #define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__)
3021 #define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__)
3022 #define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
3023 #define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__)
3024 #define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__)
3025 #define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
3026 #define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__)
3027 #define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__)
3028 #define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
3029 #define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__)
3030 #define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__)
3031 #define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
3032 #define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__)
3033 #define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__)
3034 #define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
3035 #define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
3036 #define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
3037 #define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
3038 #define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
3039 #define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
3040 #define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
3041 
3042 // KEPT FOR BACKWARDS COMPATIBILITY
3043 #define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
3044 #define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
3045 #define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
3046 #define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
3047 #define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
3048 #define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
3049 #define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
3050 #define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
3051 #define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
3052 #define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
3053 #define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
3054 #define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
3055 #define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
3056 #define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
3057 #define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
3058 #define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
3059 #define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
3060 #define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)
3061 
3062 #define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
3063 #define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
3064 #define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
3065 #define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
3066 #define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
3067 #define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
3068 
3069 #define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)
3070 
3071 #endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
3072 
3073 #ifndef DOCTEST_CONFIG_DISABLE
3074 
3075 // this is here to clear the 'current test suite' for the current translation unit - at the top
3077 
3078 #endif // DOCTEST_CONFIG_DISABLE
3079 
3083 
3085 
3086 #endif // DOCTEST_LIBRARY_INCLUDED
3087 
3088 #ifndef DOCTEST_SINGLE_HEADER
3089 #define DOCTEST_SINGLE_HEADER
3090 #endif // DOCTEST_SINGLE_HEADER
3091 
3092 #if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER)
3093 
3094 #ifndef DOCTEST_SINGLE_HEADER
3095 #include "doctest_fwd.h"
3096 #endif // DOCTEST_SINGLE_HEADER
3097 
3099 
3100 #ifndef DOCTEST_LIBRARY_IMPLEMENTATION
3101 #define DOCTEST_LIBRARY_IMPLEMENTATION
3102 
3104 
3106 
3108 DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors")
3109 DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
3110 DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
3111 DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32")
3112 DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations")
3114 DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum")
3115 DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default")
3116 DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn")
3117 DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion")
3118 DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces")
3119 DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers")
3120 DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function")
3121 DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path")
3122 
3124 DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
3125 DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
3126 DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers")
3127 DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces")
3128 DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch")
3129 DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum")
3130 DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default")
3131 DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations")
3132 DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast")
3133 DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function")
3134 DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance")
3135 DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute")
3136 
3138 DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data
3139 DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled
3140 DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified
3141 DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal
3142 DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch
3143 DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C
3144 DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning)
3145 DOCTEST_MSVC_SUPPRESS_WARNING(5245) // unreferenced function with internal linkage has been removed
3146 
3148 
3149 // required includes - will go only in one translation unit!
3150 #include <ctime>
3151 #include <cmath>
3152 #include <climits>
3153 // borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/doctest/doctest/pull/37
3154 #ifdef __BORLANDC__
3155 #include <math.h>
3156 #endif // __BORLANDC__
3157 #include <new>
3158 #include <cstdio>
3159 #include <cstdlib>
3160 #include <cstring>
3161 #include <limits>
3162 #include <utility>
3163 #include <fstream>
3164 #include <sstream>
3165 #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
3166 #include <iostream>
3167 #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
3168 #include <algorithm>
3169 #include <iomanip>
3170 #include <vector>
3171 #ifndef DOCTEST_CONFIG_NO_MULTITHREADING
3172 #include <atomic>
3173 #include <mutex>
3174 #define DOCTEST_DECLARE_MUTEX(name) std::mutex name;
3175 #define DOCTEST_DECLARE_STATIC_MUTEX(name) static DOCTEST_DECLARE_MUTEX(name)
3176 #define DOCTEST_LOCK_MUTEX(name) std::lock_guard<std::mutex> DOCTEST_ANONYMOUS(DOCTEST_ANON_LOCK_)(name);
3177 #else // DOCTEST_CONFIG_NO_MULTITHREADING
3178 #define DOCTEST_DECLARE_MUTEX(name)
3179 #define DOCTEST_DECLARE_STATIC_MUTEX(name)
3180 #define DOCTEST_LOCK_MUTEX(name)
3181 #endif // DOCTEST_CONFIG_NO_MULTITHREADING
3182 #include <set>
3183 #include <map>
3184 #include <unordered_set>
3185 #include <exception>
3186 #include <stdexcept>
3187 #include <csignal>
3188 #include <cfloat>
3189 #include <cctype>
3190 #include <cstdint>
3191 #include <string>
3192 
3193 #ifdef DOCTEST_PLATFORM_MAC
3194 #include <sys/types.h>
3195 #include <unistd.h>
3196 #include <sys/sysctl.h>
3197 #endif // DOCTEST_PLATFORM_MAC
3198 
3199 #ifdef DOCTEST_PLATFORM_WINDOWS
3200 
3201 // defines for a leaner windows.h
3202 #ifndef WIN32_LEAN_AND_MEAN
3203 #define WIN32_LEAN_AND_MEAN
3204 #define DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
3205 #endif // WIN32_LEAN_AND_MEAN
3206 #ifndef NOMINMAX
3207 #define NOMINMAX
3208 #define DOCTEST_UNDEF_NOMINMAX
3209 #endif // NOMINMAX
3210 
3211 // not sure what AfxWin.h is for - here I do what Catch does
3212 #ifdef __AFXDLL
3213 #include <AfxWin.h>
3214 #else
3215 #include <windows.h>
3216 #endif
3217 #include <io.h>
3218 
3219 #else // DOCTEST_PLATFORM_WINDOWS
3220 
3221 #include <sys/time.h>
3222 #include <unistd.h>
3223 
3224 #endif // DOCTEST_PLATFORM_WINDOWS
3225 
3226 // this is a fix for https://github.com/doctest/doctest/issues/348
3227 // https://mail.gnome.org/archives/xml/2012-January/msg00000.html
3228 #if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)
3229 #define STDOUT_FILENO fileno(stdout)
3230 #endif // HAVE_UNISTD_H
3231 
3233 
3234 // counts the number of elements in a C array
3235 #define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
3236 
3237 #ifdef DOCTEST_CONFIG_DISABLE
3238 #define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled
3239 #else // DOCTEST_CONFIG_DISABLE
3240 #define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled
3241 #endif // DOCTEST_CONFIG_DISABLE
3242 
3243 #ifndef DOCTEST_CONFIG_OPTIONS_PREFIX
3244 #define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-"
3245 #endif
3246 
3247 #ifndef DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR
3248 #define DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR ':'
3249 #endif
3250 
3251 #ifndef DOCTEST_THREAD_LOCAL
3252 #if defined(DOCTEST_CONFIG_NO_MULTITHREADING) || DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
3253 #define DOCTEST_THREAD_LOCAL
3254 #else // DOCTEST_MSVC
3255 #define DOCTEST_THREAD_LOCAL thread_local
3256 #endif // DOCTEST_MSVC
3257 #endif // DOCTEST_THREAD_LOCAL
3258 
3259 #ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
3260 #define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
3261 #endif
3262 
3263 #ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
3264 #define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
3265 #endif
3266 
3267 #ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
3268 #define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
3269 #else
3270 #define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
3271 #endif
3272 
3273 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
3274 #define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
3275 #endif
3276 
3277 #ifndef DOCTEST_CDECL
3278 #define DOCTEST_CDECL __cdecl
3279 #endif
3280 
3281 namespace doctest {
3282 
3283 bool is_running_in_test = false;
3284 
3285 namespace {
3286  using namespace detail;
3287 
3288  template <typename Ex>
3289  DOCTEST_NORETURN void throw_exception(Ex const& e) {
3290 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
3291  throw e;
3292 #else // DOCTEST_CONFIG_NO_EXCEPTIONS
3293 #ifdef DOCTEST_CONFIG_HANDLE_EXCEPTION
3294  DOCTEST_CONFIG_HANDLE_EXCEPTION(e);
3295 #else // DOCTEST_CONFIG_HANDLE_EXCEPTION
3296 #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
3297  std::cerr << "doctest will terminate because it needed to throw an exception.\n"
3298  << "The message was: " << e.what() << '\n';
3299 #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
3300 #endif // DOCTEST_CONFIG_HANDLE_EXCEPTION
3301  std::terminate();
3302 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
3303  }
3304 
3305 #ifndef DOCTEST_INTERNAL_ERROR
3306 #define DOCTEST_INTERNAL_ERROR(msg) \
3307  throw_exception(std::logic_error( \
3308  __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
3309 #endif // DOCTEST_INTERNAL_ERROR
3310 
3311  // case insensitive strcmp
3312  int stricmp(const char* a, const char* b) {
3313  for(;; a++, b++) {
3314  const int d = tolower(*a) - tolower(*b);
3315  if(d != 0 || !*a)
3316  return d;
3317  }
3318  }
3319 
3320  struct Endianness
3321  {
3322  enum Arch
3323  {
3324  Big,
3325  Little
3326  };
3327 
3328  static Arch which() {
3329  int x = 1;
3330  // casting any data pointer to char* is allowed
3331  auto ptr = reinterpret_cast<char*>(&x);
3332  if(*ptr)
3333  return Little;
3334  return Big;
3335  }
3336  };
3337 } // namespace
3338 
3339 namespace detail {
3340  DOCTEST_THREAD_LOCAL class
3341  {
3342  std::vector<std::streampos> stack;
3343  std::stringstream ss;
3344 
3345  public:
3346  std::ostream* push() {
3347  stack.push_back(ss.tellp());
3348  return &ss;
3349  }
3350 
3351  String pop() {
3352  if (stack.empty())
3353  DOCTEST_INTERNAL_ERROR("TLSS was empty when trying to pop!");
3354 
3355  std::streampos pos = stack.back();
3356  stack.pop_back();
3357  unsigned sz = static_cast<unsigned>(ss.tellp() - pos);
3358  ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out);
3359  return String(ss, sz);
3360  }
3361  } g_oss;
3362 
3363  std::ostream* tlssPush() {
3364  return g_oss.push();
3365  }
3366 
3367  String tlssPop() {
3368  return g_oss.pop();
3369  }
3370 
3371 #ifndef DOCTEST_CONFIG_DISABLE
3372 
3373 namespace timer_large_integer
3374 {
3375 
3376 #if defined(DOCTEST_PLATFORM_WINDOWS)
3377  using type = ULONGLONG;
3378 #else // DOCTEST_PLATFORM_WINDOWS
3379  using type = std::uint64_t;
3380 #endif // DOCTEST_PLATFORM_WINDOWS
3381 }
3382 
3383 using ticks_t = timer_large_integer::type;
3384 
3385 #ifdef DOCTEST_CONFIG_GETCURRENTTICKS
3386  ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
3387 #elif defined(DOCTEST_PLATFORM_WINDOWS)
3388  ticks_t getCurrentTicks() {
3389  static LARGE_INTEGER hz = { {0} }, hzo = { {0} };
3390  if(!hz.QuadPart) {
3391  QueryPerformanceFrequency(&hz);
3392  QueryPerformanceCounter(&hzo);
3393  }
3394  LARGE_INTEGER t;
3395  QueryPerformanceCounter(&t);
3396  return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;
3397  }
3398 #else // DOCTEST_PLATFORM_WINDOWS
3399  ticks_t getCurrentTicks() {
3400  timeval t;
3401  gettimeofday(&t, nullptr);
3402  return static_cast<ticks_t>(t.tv_sec) * 1000000 + static_cast<ticks_t>(t.tv_usec);
3403  }
3404 #endif // DOCTEST_PLATFORM_WINDOWS
3405 
3406  struct Timer
3407  {
3408  void start() { m_ticks = getCurrentTicks(); }
3409  unsigned int getElapsedMicroseconds() const {
3410  return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
3411  }
3412  //unsigned int getElapsedMilliseconds() const {
3413  // return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
3414  //}
3415  double getElapsedSeconds() const { return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }
3416 
3417  private:
3418  ticks_t m_ticks = 0;
3419  };
3420 
3421 #ifdef DOCTEST_CONFIG_NO_MULTITHREADING
3422  template <typename T>
3423  using Atomic = T;
3424 #else // DOCTEST_CONFIG_NO_MULTITHREADING
3425  template <typename T>
3426  using Atomic = std::atomic<T>;
3427 #endif // DOCTEST_CONFIG_NO_MULTITHREADING
3428 
3429 #if defined(DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) || defined(DOCTEST_CONFIG_NO_MULTITHREADING)
3430  template <typename T>
3431  using MultiLaneAtomic = Atomic<T>;
3432 #else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
3433  // Provides a multilane implementation of an atomic variable that supports add, sub, load,
3434  // store. Instead of using a single atomic variable, this splits up into multiple ones,
3435  // each sitting on a separate cache line. The goal is to provide a speedup when most
3436  // operations are modifying. It achieves this with two properties:
3437  //
3438  // * Multiple atomics are used, so chance of congestion from the same atomic is reduced.
3439  // * Each atomic sits on a separate cache line, so false sharing is reduced.
3440  //
3441  // The disadvantage is that there is a small overhead due to the use of TLS, and load/store
3442  // is slower because all atomics have to be accessed.
3443  template <typename T>
3444  class MultiLaneAtomic
3445  {
3446  struct CacheLineAlignedAtomic
3447  {
3448  Atomic<T> atomic{};
3449  char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(Atomic<T>)];
3450  };
3451  CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];
3452 
3453  static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,
3454  "guarantee one atomic takes exactly one cache line");
3455 
3456  public:
3457  T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; }
3458 
3459  T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); }
3460 
3461  T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
3462  return myAtomic().fetch_add(arg, order);
3463  }
3464 
3465  T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
3466  return myAtomic().fetch_sub(arg, order);
3467  }
3468 
3469  operator T() const DOCTEST_NOEXCEPT { return load(); }
3470 
3471  T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT {
3472  auto result = T();
3473  for(auto const& c : m_atomics) {
3474  result += c.atomic.load(order);
3475  }
3476  return result;
3477  }
3478 
3479  T operator=(T desired) DOCTEST_NOEXCEPT { // lgtm [cpp/assignment-does-not-return-this]
3480  store(desired);
3481  return desired;
3482  }
3483 
3484  void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
3485  // first value becomes desired", all others become 0.
3486  for(auto& c : m_atomics) {
3487  c.atomic.store(desired, order);
3488  desired = {};
3489  }
3490  }
3491 
3492  private:
3493  // Each thread has a different atomic that it operates on. If more than NumLanes threads
3494  // use this, some will use the same atomic. So performance will degrade a bit, but still
3495  // everything will work.
3496  //
3497  // The logic here is a bit tricky. The call should be as fast as possible, so that there
3498  // is minimal to no overhead in determining the correct atomic for the current thread.
3499  //
3500  // 1. A global static counter laneCounter counts continuously up.
3501  // 2. Each successive thread will use modulo operation of that counter so it gets an atomic
3502  // assigned in a round-robin fashion.
3503  // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with
3504  // little overhead.
3505  Atomic<T>& myAtomic() DOCTEST_NOEXCEPT {
3506  static Atomic<size_t> laneCounter;
3507  DOCTEST_THREAD_LOCAL size_t tlsLaneIdx =
3508  laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;
3509 
3510  return m_atomics[tlsLaneIdx].atomic;
3511  }
3512  };
3513 #endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
3514 
3515  // this holds both parameters from the command line and runtime data for tests
3516  struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats
3517  {
3518  MultiLaneAtomic<int> numAssertsCurrentTest_atomic;
3519  MultiLaneAtomic<int> numAssertsFailedCurrentTest_atomic;
3520 
3521  std::vector<std::vector<String>> filters = decltype(filters)(9); // 9 different filters
3522 
3523  std::vector<IReporter*> reporters_currently_used;
3524 
3525  assert_handler ah = nullptr;
3526 
3527  Timer timer;
3528 
3529  std::vector<String> stringifiedContexts; // logging from INFO() due to an exception
3530 
3531  // stuff for subcases
3532  bool reachedLeaf;
3533  std::vector<SubcaseSignature> subcaseStack;
3534  std::vector<SubcaseSignature> nextSubcaseStack;
3535  std::unordered_set<unsigned long long> fullyTraversedSubcases;
3536  size_t currentSubcaseDepth;
3537  Atomic<bool> shouldLogCurrentException;
3538 
3539  void resetRunData() {
3540  numTestCases = 0;
3541  numTestCasesPassingFilters = 0;
3542  numTestSuitesPassingFilters = 0;
3543  numTestCasesFailed = 0;
3544  numAsserts = 0;
3545  numAssertsFailed = 0;
3546  numAssertsCurrentTest = 0;
3547  numAssertsFailedCurrentTest = 0;
3548  }
3549 
3550  void finalizeTestCaseData() {
3551  seconds = timer.getElapsedSeconds();
3552 
3553  // update the non-atomic counters
3554  numAsserts += numAssertsCurrentTest_atomic;
3555  numAssertsFailed += numAssertsFailedCurrentTest_atomic;
3556  numAssertsCurrentTest = numAssertsCurrentTest_atomic;
3557  numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic;
3558 
3559  if(numAssertsFailedCurrentTest)
3560  failure_flags |= TestCaseFailureReason::AssertFailure;
3561 
3562  if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 &&
3563  Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout)
3564  failure_flags |= TestCaseFailureReason::Timeout;
3565 
3566  if(currentTest->m_should_fail) {
3567  if(failure_flags) {
3569  } else {
3571  }
3572  } else if(failure_flags && currentTest->m_may_fail) {
3574  } else if(currentTest->m_expected_failures > 0) {
3575  if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) {
3577  } else {
3579  }
3580  }
3581 
3582  bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) ||
3585 
3586  // if any subcase has failed - the whole test case has failed
3587  testCaseSuccess = !(failure_flags && !ok_to_fail);
3588  if(!testCaseSuccess)
3589  numTestCasesFailed++;
3590  }
3591  };
3592 
3593  ContextState* g_cs = nullptr;
3594 
3595  // used to avoid locks for the debug output
3596  // TODO: figure out if this is indeed necessary/correct - seems like either there still
3597  // could be a race or that there wouldn't be a race even if using the context directly
3598  DOCTEST_THREAD_LOCAL bool g_no_colors;
3599 
3600 #endif // DOCTEST_CONFIG_DISABLE
3601 } // namespace detail
3602 
3603 char* String::allocate(size_type sz) {
3604  if (sz <= last) {
3605  buf[sz] = '\0';
3606  setLast(last - sz);
3607  return buf;
3608  } else {
3609  setOnHeap();
3610  data.size = sz;
3611  data.capacity = data.size + 1;
3612  data.ptr = new char[data.capacity];
3613  data.ptr[sz] = '\0';
3614  return data.ptr;
3615  }
3616 }
3617 
3618 void String::setOnHeap() noexcept { *reinterpret_cast<unsigned char*>(&buf[last]) = 128; }
3619 void String::setLast(size_type in) noexcept { buf[last] = char(in); }
3620 void String::setSize(size_type sz) noexcept {
3621  if (isOnStack()) { buf[sz] = '\0'; setLast(last - sz); }
3622  else { data.ptr[sz] = '\0'; data.size = sz; }
3623 }
3624 
3625 void String::copy(const String& other) {
3626  if(other.isOnStack()) {
3627  memcpy(buf, other.buf, len);
3628  } else {
3629  memcpy(allocate(other.data.size), other.data.ptr, other.data.size);
3630  }
3631 }
3632 
3633 String::String() noexcept {
3634  buf[0] = '\0';
3635  setLast();
3636 }
3637 
3638 String::~String() {
3639  if(!isOnStack())
3640  delete[] data.ptr;
3641 } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
3642 
3643 String::String(const char* in)
3644  : String(in, strlen(in)) {}
3645 
3646 String::String(const char* in, size_type in_size) {
3647  memcpy(allocate(in_size), in, in_size);
3648 }
3649 
3650 String::String(std::istream& in, size_type in_size) {
3651  in.read(allocate(in_size), in_size);
3652 }
3653 
3654 String::String(const String& other) { copy(other); }
3655 
3656 String& String::operator=(const String& other) {
3657  if(this != &other) {
3658  if(!isOnStack())
3659  delete[] data.ptr;
3660 
3661  copy(other);
3662  }
3663 
3664  return *this;
3665 }
3666 
3667 String& String::operator+=(const String& other) {
3668  const size_type my_old_size = size();
3669  const size_type other_size = other.size();
3670  const size_type total_size = my_old_size + other_size;
3671  if(isOnStack()) {
3672  if(total_size < len) {
3673  // append to the current stack space
3674  memcpy(buf + my_old_size, other.c_str(), other_size + 1);
3675  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
3676  setLast(last - total_size);
3677  } else {
3678  // alloc new chunk
3679  char* temp = new char[total_size + 1];
3680  // copy current data to new location before writing in the union
3681  memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed
3682  // update data in union
3683  setOnHeap();
3684  data.size = total_size;
3685  data.capacity = data.size + 1;
3686  data.ptr = temp;
3687  // transfer the rest of the data
3688  memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
3689  }
3690  } else {
3691  if(data.capacity > total_size) {
3692  // append to the current heap block
3693  data.size = total_size;
3694  memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
3695  } else {
3696  // resize
3697  data.capacity *= 2;
3698  if(data.capacity <= total_size)
3699  data.capacity = total_size + 1;
3700  // alloc new chunk
3701  char* temp = new char[data.capacity];
3702  // copy current data to new location before releasing it
3703  memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed
3704  // release old chunk
3705  delete[] data.ptr;
3706  // update the rest of the union members
3707  data.size = total_size;
3708  data.ptr = temp;
3709  // transfer the rest of the data
3710  memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
3711  }
3712  }
3713 
3714  return *this;
3715 }
3716 
3717 String::String(String&& other) noexcept {
3718  memcpy(buf, other.buf, len);
3719  other.buf[0] = '\0';
3720  other.setLast();
3721 }
3722 
3723 String& String::operator=(String&& other) noexcept {
3724  if(this != &other) {
3725  if(!isOnStack())
3726  delete[] data.ptr;
3727  memcpy(buf, other.buf, len);
3728  other.buf[0] = '\0';
3729  other.setLast();
3730  }
3731  return *this;
3732 }
3733 
3734 char String::operator[](size_type i) const {
3735  return const_cast<String*>(this)->operator[](i);
3736 }
3737 
3738 char& String::operator[](size_type i) {
3739  if(isOnStack())
3740  return reinterpret_cast<char*>(buf)[i];
3741  return data.ptr[i];
3742 }
3743 
3744 DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized")
3746  if(isOnStack())
3747  return last - (size_type(buf[last]) & 31); // using "last" would work only if "len" is 32
3748  return data.size;
3749 }
3751 
3753  if(isOnStack())
3754  return len;
3755  return data.capacity;
3756 }
3757 
3758 String String::substr(size_type pos, size_type cnt) && {
3759  cnt = std::min(cnt, size() - pos);
3760  char* cptr = c_str();
3761  memmove(cptr, cptr + pos, cnt);
3762  setSize(cnt);
3763  return std::move(*this);
3764 }
3765 
3766 String String::substr(size_type pos, size_type cnt) const & {
3767  cnt = std::min(cnt, size() - pos);
3768  return String{ c_str() + pos, cnt };
3769 }
3770 
3771 String::size_type String::find(char ch, size_type pos) const {
3772  const char* begin = c_str();
3773  const char* end = begin + size();
3774  const char* it = begin + pos;
3775  for (; it < end && *it != ch; it++);
3776  if (it < end) { return static_cast<size_type>(it - begin); }
3777  else { return npos; }
3778 }
3779 
3780 String::size_type String::rfind(char ch, size_type pos) const {
3781  const char* begin = c_str();
3782  const char* it = begin + std::min(pos, size() - 1);
3783  for (; it >= begin && *it != ch; it--);
3784  if (it >= begin) { return static_cast<size_type>(it - begin); }
3785  else { return npos; }
3786 }
3787 
3788 int String::compare(const char* other, bool no_case) const {
3789  if(no_case)
3790  return doctest::stricmp(c_str(), other);
3791  return std::strcmp(c_str(), other);
3792 }
3793 
3794 int String::compare(const String& other, bool no_case) const {
3795  return compare(other.c_str(), no_case);
3796 }
3797 
3798 String operator+(const String& lhs, const String& rhs) { return String(lhs) += rhs; }
3799 
3800 bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
3801 bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
3802 bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
3803 bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
3804 bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }
3805 bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }
3806 
3807 std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); }
3808 
3809 Contains::Contains(const String& str) : string(str) { }
3810 
3811 bool Contains::checkWith(const String& other) const {
3812  return strstr(other.c_str(), string.c_str()) != nullptr;
3813 }
3814 
3815 String toString(const Contains& in) {
3816  return "Contains( " + in.string + " )";
3817 }
3818 
3819 bool operator==(const String& lhs, const Contains& rhs) { return rhs.checkWith(lhs); }
3820 bool operator==(const Contains& lhs, const String& rhs) { return lhs.checkWith(rhs); }
3821 bool operator!=(const String& lhs, const Contains& rhs) { return !rhs.checkWith(lhs); }
3822 bool operator!=(const Contains& lhs, const String& rhs) { return !lhs.checkWith(rhs); }
3823 
3824 namespace {
3825  void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;)
3826 } // namespace
3827 
3828 namespace Color {
3830  color_to_stream(s, code);
3831  return s;
3832  }
3833 } // namespace Color
3834 
3835 // clang-format off
3836 const char* assertString(assertType::Enum at) {
3837  DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4061) // enum 'x' in switch of enum 'y' is not explicitly handled
3838  #define DOCTEST_GENERATE_ASSERT_TYPE_CASE(assert_type) case assertType::DT_ ## assert_type: return #assert_type
3839  #define DOCTEST_GENERATE_ASSERT_TYPE_CASES(assert_type) \
3840  DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN_ ## assert_type); \
3841  DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK_ ## assert_type); \
3842  DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE_ ## assert_type)
3843  switch(at) {
3844  DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN);
3845  DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK);
3846  DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE);
3847 
3848  DOCTEST_GENERATE_ASSERT_TYPE_CASES(FALSE);
3849 
3850  DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS);
3851 
3852  DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_AS);
3853 
3854  DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH);
3855 
3856  DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH_AS);
3857 
3858  DOCTEST_GENERATE_ASSERT_TYPE_CASES(NOTHROW);
3859 
3860  DOCTEST_GENERATE_ASSERT_TYPE_CASES(EQ);
3861  DOCTEST_GENERATE_ASSERT_TYPE_CASES(NE);
3862  DOCTEST_GENERATE_ASSERT_TYPE_CASES(GT);
3863  DOCTEST_GENERATE_ASSERT_TYPE_CASES(LT);
3864  DOCTEST_GENERATE_ASSERT_TYPE_CASES(GE);
3865  DOCTEST_GENERATE_ASSERT_TYPE_CASES(LE);
3866 
3867  DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY);
3868  DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY_FALSE);
3869 
3870  default: DOCTEST_INTERNAL_ERROR("Tried stringifying invalid assert type!");
3871  }
3873 }
3874 // clang-format on
3875 
3876 const char* failureString(assertType::Enum at) {
3877  if(at & assertType::is_warn)
3878  return "WARNING";
3879  if(at & assertType::is_check)
3880  return "ERROR";
3881  if(at & assertType::is_require)
3882  return "FATAL ERROR";
3883  return "";
3884 }
3885 
3886 DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
3887 DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
3888 // depending on the current options this will remove the path of filenames
3889 const char* skipPathFromFilename(const char* file) {
3890 #ifndef DOCTEST_CONFIG_DISABLE
3891  if(getContextOptions()->no_path_in_filenames) {
3892  auto back = std::strrchr(file, '\\');
3893  auto forward = std::strrchr(file, '/');
3894  if(back || forward) {
3895  if(back > forward)
3896  forward = back;
3897  return forward + 1;
3898  }
3899  } else {
3900  const auto prefixes = getContextOptions()->strip_file_prefixes;
3901  const char separator = DOCTEST_CONFIG_OPTIONS_FILE_PREFIX_SEPARATOR;
3902  String::size_type longest_match = 0U;
3903  for(String::size_type pos = 0U; pos < prefixes.size(); ++pos)
3904  {
3905  const auto prefix_start = pos;
3906  pos = std::min(prefixes.find(separator, prefix_start), prefixes.size());
3907 
3908  const auto prefix_size = pos - prefix_start;
3909  if(prefix_size > longest_match)
3910  {
3911  // TODO under DOCTEST_MSVC: does the comparison need strnicmp() to work with drive letter capitalization?
3912  if(0 == std::strncmp(prefixes.c_str() + prefix_start, file, prefix_size))
3913  {
3914  longest_match = prefix_size;
3915  }
3916  }
3917  }
3918  return &file[longest_match];
3919  }
3920 #endif // DOCTEST_CONFIG_DISABLE
3921  return file;
3922 }
3925 
3926 bool SubcaseSignature::operator==(const SubcaseSignature& other) const {
3927  return m_line == other.m_line
3928  && std::strcmp(m_file, other.m_file) == 0
3929  && m_name == other.m_name;
3930 }
3931 
3932 bool SubcaseSignature::operator<(const SubcaseSignature& other) const {
3933  if(m_line != other.m_line)
3934  return m_line < other.m_line;
3935  if(std::strcmp(m_file, other.m_file) != 0)
3936  return std::strcmp(m_file, other.m_file) < 0;
3937  return m_name.compare(other.m_name) < 0;
3938 }
3939 
3940 DOCTEST_DEFINE_INTERFACE(IContextScope)
3941 
3942 namespace detail {
3943  void filldata<const void*>::fill(std::ostream* stream, const void* in) {
3944  if (in) { *stream << in; }
3945  else { *stream << "nullptr"; }
3946  }
3947 
3948  template <typename T>
3949  String toStreamLit(T t) {
3950  std::ostream* os = tlssPush();
3951  os->operator<<(t);
3952  return tlssPop();
3953  }
3954 }
3955 
3956 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
3957 String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
3958 #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
3959 
3960 #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
3961 // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
3962 String toString(const std::string& in) { return in.c_str(); }
3963 #endif // VS 2019
3964 
3965 String toString(String in) { return in; }
3966 
3967 String toString(std::nullptr_t) { return "nullptr"; }
3968 
3969 String toString(bool in) { return in ? "true" : "false"; }
3970 
3971 String toString(float in) { return toStreamLit(in); }
3972 String toString(double in) { return toStreamLit(in); }
3973 String toString(double long in) { return toStreamLit(in); }
3974 
3975 String toString(char in) { return toStreamLit(static_cast<signed>(in)); }
3976 String toString(char signed in) { return toStreamLit(static_cast<signed>(in)); }
3977 String toString(char unsigned in) { return toStreamLit(static_cast<unsigned>(in)); }
3978 String toString(short in) { return toStreamLit(in); }
3979 String toString(short unsigned in) { return toStreamLit(in); }
3980 String toString(signed in) { return toStreamLit(in); }
3981 String toString(unsigned in) { return toStreamLit(in); }
3982 String toString(long in) { return toStreamLit(in); }
3983 String toString(long unsigned in) { return toStreamLit(in); }
3984 String toString(long long in) { return toStreamLit(in); }
3985 String toString(long long unsigned in) { return toStreamLit(in); }
3986 
3987 Approx::Approx(double value)
3988  : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
3989  , m_scale(1.0)
3990  , m_value(value) {}
3991 
3992 Approx Approx::operator()(double value) const {
3993  Approx approx(value);
3994  approx.epsilon(m_epsilon);
3995  approx.scale(m_scale);
3996  return approx;
3997 }
3998 
3999 Approx& Approx::epsilon(double newEpsilon) {
4000  m_epsilon = newEpsilon;
4001  return *this;
4002 }
4003 Approx& Approx::scale(double newScale) {
4004  m_scale = newScale;
4005  return *this;
4006 }
4007 
4008 bool operator==(double lhs, const Approx& rhs) {
4009  // Thanks to Richard Harris for his help refining this formula
4010  return std::fabs(lhs - rhs.m_value) <
4011  rhs.m_epsilon * (rhs.m_scale + std::max<double>(std::fabs(lhs), std::fabs(rhs.m_value)));
4012 }
4013 bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }
4014 bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
4015 bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); }
4016 bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; }
4017 bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; }
4018 bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; }
4019 bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; }
4020 bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; }
4021 bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; }
4022 bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; }
4023 bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
4024 
4025 String toString(const Approx& in) {
4026  return "Approx( " + doctest::toString(in.m_value) + " )";
4027 }
4028 const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
4029 
4031 template <typename F>
4032 IsNaN<F>::operator bool() const {
4033  return std::isnan(value) ^ flipped;
4034 }
4036 template struct DOCTEST_INTERFACE_DEF IsNaN<float>;
4037 template struct DOCTEST_INTERFACE_DEF IsNaN<double>;
4038 template struct DOCTEST_INTERFACE_DEF IsNaN<long double>;
4039 template <typename F>
4040 String toString(IsNaN<F> in) { return String(in.flipped ? "! " : "") + "IsNaN( " + doctest::toString(in.value) + " )"; }
4041 String toString(IsNaN<float> in) { return toString<float>(in); }
4042 String toString(IsNaN<double> in) { return toString<double>(in); }
4043 String toString(IsNaN<double long> in) { return toString<double long>(in); }
4044 
4045 } // namespace doctest
4046 
4047 #ifdef DOCTEST_CONFIG_DISABLE
4048 namespace doctest {
4049 Context::Context(int, const char* const*) {}
4050 Context::~Context() = default;
4051 void Context::applyCommandLine(int, const char* const*) {}
4052 void Context::addFilter(const char*, const char*) {}
4053 void Context::clearFilters() {}
4054 void Context::setOption(const char*, bool) {}
4055 void Context::setOption(const char*, int) {}
4056 void Context::setOption(const char*, const char*) {}
4057 bool Context::shouldExit() { return false; }
4061 int Context::run() { return 0; }
4062 
4063 int IReporter::get_num_active_contexts() { return 0; }
4064 const IContextScope* const* IReporter::get_active_contexts() { return nullptr; }
4065 int IReporter::get_num_stringified_contexts() { return 0; }
4066 const String* IReporter::get_stringified_contexts() { return nullptr; }
4067 
4068 int registerReporter(const char*, int, IReporter*) { return 0; }
4069 
4070 } // namespace doctest
4071 #else // DOCTEST_CONFIG_DISABLE
4072 
4073 #if !defined(DOCTEST_CONFIG_COLORS_NONE)
4074 #if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
4075 #ifdef DOCTEST_PLATFORM_WINDOWS
4076 #define DOCTEST_CONFIG_COLORS_WINDOWS
4077 #else // linux
4078 #define DOCTEST_CONFIG_COLORS_ANSI
4079 #endif // platform
4080 #endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI
4081 #endif // DOCTEST_CONFIG_COLORS_NONE
4082 
4083 namespace doctest_detail_test_suite_ns {
4084 // holds the current test suite
4086  static doctest::detail::TestSuite data{};
4087  return data;
4088 }
4089 } // namespace doctest_detail_test_suite_ns
4090 
4091 namespace doctest {
4092 namespace {
4093  // the int (priority) is part of the key for automatic sorting - sadly one can register a
4094  // reporter with a duplicate name and a different priority but hopefully that won't happen often :|
4095  using reporterMap = std::map<std::pair<int, String>, reporterCreatorFunc>;
4096 
4097  reporterMap& getReporters() {
4098  static reporterMap data;
4099  return data;
4100  }
4101  reporterMap& getListeners() {
4102  static reporterMap data;
4103  return data;
4104  }
4105 } // namespace
4106 namespace detail {
4107 #define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \
4108  for(auto& curr_rep : g_cs->reporters_currently_used) \
4109  curr_rep->function(__VA_ARGS__)
4110 
4112  if(at & assertType::is_require)
4113  return true;
4114 
4115  if((at & assertType::is_check)
4116  && getContextOptions()->abort_after > 0 &&
4117  (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >=
4118  getContextOptions()->abort_after)
4119  return true;
4120 
4121  return false;
4122  }
4123 
4124 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
4126  g_cs->shouldLogCurrentException = false;
4127  throw TestFailureException(); // NOLINT(hicpp-exception-baseclass)
4128  }
4129 #else // DOCTEST_CONFIG_NO_EXCEPTIONS
4130  void throwException() {}
4131 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
4132 } // namespace detail
4133 
4134 namespace {
4135  using namespace detail;
4136  // matching of a string against a wildcard mask (case sensitivity configurable) taken from
4137  // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing
4138  int wildcmp(const char* str, const char* wild, bool caseSensitive) {
4139  const char* cp = str;
4140  const char* mp = wild;
4141 
4142  while((*str) && (*wild != '*')) {
4143  if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
4144  (*wild != '?')) {
4145  return 0;
4146  }
4147  wild++;
4148  str++;
4149  }
4150 
4151  while(*str) {
4152  if(*wild == '*') {
4153  if(!*++wild) {
4154  return 1;
4155  }
4156  mp = wild;
4157  cp = str + 1;
4158  } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
4159  (*wild == '?')) {
4160  wild++;
4161  str++;
4162  } else {
4163  wild = mp;
4164  str = cp++;
4165  }
4166  }
4167 
4168  while(*wild == '*') {
4169  wild++;
4170  }
4171  return !*wild;
4172  }
4173 
4174  // checks if the name matches any of the filters (and can be configured what to do when empty)
4175  bool matchesAny(const char* name, const std::vector<String>& filters, bool matchEmpty,
4176  bool caseSensitive) {
4177  if (filters.empty() && matchEmpty)
4178  return true;
4179  for (auto& curr : filters)
4180  if (wildcmp(name, curr.c_str(), caseSensitive))
4181  return true;
4182  return false;
4183  }
4184 
4186  unsigned long long hash(unsigned long long a, unsigned long long b) {
4187  return (a << 5) + b;
4188  }
4189 
4190  // C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html
4192  unsigned long long hash(const char* str) {
4193  unsigned long long hash = 5381;
4194  char c;
4195  while ((c = *str++))
4196  hash = ((hash << 5) + hash) + c; // hash * 33 + c
4197  return hash;
4198  }
4199 
4200  unsigned long long hash(const SubcaseSignature& sig) {
4201  return hash(hash(hash(sig.m_file), hash(sig.m_name.c_str())), sig.m_line);
4202  }
4203 
4204  unsigned long long hash(const std::vector<SubcaseSignature>& sigs, size_t count) {
4205  unsigned long long running = 0;
4206  auto end = sigs.begin() + count;
4207  for (auto it = sigs.begin(); it != end; it++) {
4208  running = hash(running, hash(*it));
4209  }
4210  return running;
4211  }
4212 
4213  unsigned long long hash(const std::vector<SubcaseSignature>& sigs) {
4214  unsigned long long running = 0;
4215  for (const SubcaseSignature& sig : sigs) {
4216  running = hash(running, hash(sig));
4217  }
4218  return running;
4219  }
4220 } // namespace
4221 namespace detail {
4222  bool Subcase::checkFilters() {
4223  if (g_cs->subcaseStack.size() < size_t(g_cs->subcase_filter_levels)) {
4224  if (!matchesAny(m_signature.m_name.c_str(), g_cs->filters[6], true, g_cs->case_sensitive))
4225  return true;
4226  if (matchesAny(m_signature.m_name.c_str(), g_cs->filters[7], false, g_cs->case_sensitive))
4227  return true;
4228  }
4229  return false;
4230  }
4231 
4232  Subcase::Subcase(const String& name, const char* file, int line)
4233  : m_signature({name, file, line}) {
4234  if (!g_cs->reachedLeaf) {
4235  if (g_cs->nextSubcaseStack.size() <= g_cs->subcaseStack.size()
4236  || g_cs->nextSubcaseStack[g_cs->subcaseStack.size()] == m_signature) {
4237  // Going down.
4238  if (checkFilters()) { return; }
4239 
4240  g_cs->subcaseStack.push_back(m_signature);
4241  g_cs->currentSubcaseDepth++;
4242  m_entered = true;
4243  DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
4244  }
4245  } else {
4246  if (g_cs->subcaseStack[g_cs->currentSubcaseDepth] == m_signature) {
4247  // This subcase is reentered via control flow.
4248  g_cs->currentSubcaseDepth++;
4249  m_entered = true;
4250  DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
4251  } else if (g_cs->nextSubcaseStack.size() <= g_cs->currentSubcaseDepth
4252  && g_cs->fullyTraversedSubcases.find(hash(hash(g_cs->subcaseStack, g_cs->currentSubcaseDepth), hash(m_signature)))
4253  == g_cs->fullyTraversedSubcases.end()) {
4254  if (checkFilters()) { return; }
4255  // This subcase is part of the one to be executed next.
4256  g_cs->nextSubcaseStack.clear();
4257  g_cs->nextSubcaseStack.insert(g_cs->nextSubcaseStack.end(),
4258  g_cs->subcaseStack.begin(), g_cs->subcaseStack.begin() + g_cs->currentSubcaseDepth);
4259  g_cs->nextSubcaseStack.push_back(m_signature);
4260  }
4261  }
4262  }
4263 
4264  DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
4265  DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
4266  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
4267 
4268  Subcase::~Subcase() {
4269  if (m_entered) {
4270  g_cs->currentSubcaseDepth--;
4271 
4272  if (!g_cs->reachedLeaf) {
4273  // Leaf.
4274  g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack));
4275  g_cs->nextSubcaseStack.clear();
4276  g_cs->reachedLeaf = true;
4277  } else if (g_cs->nextSubcaseStack.empty()) {
4278  // All children are finished.
4279  g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack));
4280  }
4281 
4282 #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
4283  if(std::uncaught_exceptions() > 0
4284 #else
4285  if(std::uncaught_exception()
4286 #endif
4287  && g_cs->shouldLogCurrentException) {
4288  DOCTEST_ITERATE_THROUGH_REPORTERS(
4289  test_case_exception, {"exception thrown in subcase - will translate later "
4290  "when the whole test case has been exited (cannot "
4291  "translate while there is an active exception)",
4292  false});
4293  g_cs->shouldLogCurrentException = false;
4294  }
4295 
4296  DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
4297  }
4298  }
4299 
4303 
4304  Subcase::operator bool() const { return m_entered; }
4305 
4306  Result::Result(bool passed, const String& decomposition)
4307  : m_passed(passed)
4308  , m_decomp(decomposition) {}
4309 
4310  ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at)
4311  : m_at(at) {}
4312 
4313  TestSuite& TestSuite::operator*(const char* in) {
4314  m_test_suite = in;
4315  return *this;
4316  }
4317 
4318  TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
4319  const String& type, int template_id) {
4320  m_file = file;
4321  m_line = line;
4322  m_name = nullptr; // will be later overridden in operator*
4323  m_test_suite = test_suite.m_test_suite;
4324  m_description = test_suite.m_description;
4325  m_skip = test_suite.m_skip;
4326  m_no_breaks = test_suite.m_no_breaks;
4327  m_no_output = test_suite.m_no_output;
4328  m_may_fail = test_suite.m_may_fail;
4329  m_should_fail = test_suite.m_should_fail;
4330  m_expected_failures = test_suite.m_expected_failures;
4331  m_timeout = test_suite.m_timeout;
4332 
4333  m_test = test;
4334  m_type = type;
4335  m_template_id = template_id;
4336  }
4337 
4338  TestCase::TestCase(const TestCase& other)
4339  : TestCaseData() {
4340  *this = other;
4341  }
4342 
4343  DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
4344  TestCase& TestCase::operator=(const TestCase& other) {
4345  TestCaseData::operator=(other);
4346  m_test = other.m_test;
4347  m_type = other.m_type;
4348  m_template_id = other.m_template_id;
4349  m_full_name = other.m_full_name;
4350 
4351  if(m_template_id != -1)
4352  m_name = m_full_name.c_str();
4353  return *this;
4354  }
4356 
4357  TestCase& TestCase::operator*(const char* in) {
4358  m_name = in;
4359  // make a new name with an appended type for templated test case
4360  if(m_template_id != -1) {
4361  m_full_name = String(m_name) + "<" + m_type + ">";
4362  // redirect the name to point to the newly constructed full name
4363  m_name = m_full_name.c_str();
4364  }
4365  return *this;
4366  }
4367 
4368  bool TestCase::operator<(const TestCase& other) const {
4369  // this will be used only to differentiate between test cases - not relevant for sorting
4370  if(m_line != other.m_line)
4371  return m_line < other.m_line;
4372  const int name_cmp = strcmp(m_name, other.m_name);
4373  if(name_cmp != 0)
4374  return name_cmp < 0;
4375  const int file_cmp = m_file.compare(other.m_file);
4376  if(file_cmp != 0)
4377  return file_cmp < 0;
4378  return m_template_id < other.m_template_id;
4379  }
4380 
4381  // all the registered tests
4382  std::set<TestCase>& getRegisteredTests() {
4383  static std::set<TestCase> data;
4384  return data;
4385  }
4386 } // namespace detail
4387 namespace {
4388  using namespace detail;
4389  // for sorting tests by file/line
4390  bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
4391  // this is needed because MSVC gives different case for drive letters
4392  // for __FILE__ when evaluated in a header and a source file
4393  const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));
4394  if(res != 0)
4395  return res < 0;
4396  if(lhs->m_line != rhs->m_line)
4397  return lhs->m_line < rhs->m_line;
4398  return lhs->m_template_id < rhs->m_template_id;
4399  }
4400 
4401  // for sorting tests by suite/file/line
4402  bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) {
4403  const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
4404  if(res != 0)
4405  return res < 0;
4406  return fileOrderComparator(lhs, rhs);
4407  }
4408 
4409  // for sorting tests by name/suite/file/line
4410  bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) {
4411  const int res = std::strcmp(lhs->m_name, rhs->m_name);
4412  if(res != 0)
4413  return res < 0;
4414  return suiteOrderComparator(lhs, rhs);
4415  }
4416 
4417  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
4418  void color_to_stream(std::ostream& s, Color::Enum code) {
4419  static_cast<void>(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
4420  static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE
4421 #ifdef DOCTEST_CONFIG_COLORS_ANSI
4422  if(g_no_colors ||
4423  (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))
4424  return;
4425 
4426  auto col = "";
4427  // clang-format off
4428  switch(code) {
4429  case Color::Red: col = "[0;31m"; break;
4430  case Color::Green: col = "[0;32m"; break;
4431  case Color::Blue: col = "[0;34m"; break;
4432  case Color::Cyan: col = "[0;36m"; break;
4433  case Color::Yellow: col = "[0;33m"; break;
4434  case Color::Grey: col = "[1;30m"; break;
4435  case Color::LightGrey: col = "[0;37m"; break;
4436  case Color::BrightRed: col = "[1;31m"; break;
4437  case Color::BrightGreen: col = "[1;32m"; break;
4438  case Color::BrightWhite: col = "[1;37m"; break;
4439  case Color::Bright: // invalid
4440  case Color::None:
4441  case Color::White:
4442  default: col = "[0m";
4443  }
4444  // clang-format on
4445  s << "\033" << col;
4446 #endif // DOCTEST_CONFIG_COLORS_ANSI
4447 
4448 #ifdef DOCTEST_CONFIG_COLORS_WINDOWS
4449  if(g_no_colors ||
4450  (_isatty(_fileno(stdout)) == false && getContextOptions()->force_colors == false))
4451  return;
4452 
4453  static struct ConsoleHelper {
4454  HANDLE stdoutHandle;
4455  WORD origFgAttrs;
4456  WORD origBgAttrs;
4457 
4458  ConsoleHelper() {
4459  stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
4460  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
4461  GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
4462  origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED |
4463  BACKGROUND_BLUE | BACKGROUND_INTENSITY);
4464  origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED |
4465  FOREGROUND_BLUE | FOREGROUND_INTENSITY);
4466  }
4467  } ch;
4468 
4469 #define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(ch.stdoutHandle, x | ch.origBgAttrs)
4470 
4471  // clang-format off
4472  switch (code) {
4473  case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
4474  case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break;
4475  case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break;
4476  case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break;
4477  case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break;
4478  case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break;
4479  case Color::Grey: DOCTEST_SET_ATTR(0); break;
4480  case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break;
4481  case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break;
4482  case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break;
4483  case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
4484  case Color::None:
4485  case Color::Bright: // invalid
4486  default: DOCTEST_SET_ATTR(ch.origFgAttrs);
4487  }
4488  // clang-format on
4489 #endif // DOCTEST_CONFIG_COLORS_WINDOWS
4490  }
4492 
4493  std::vector<const IExceptionTranslator*>& getExceptionTranslators() {
4494  static std::vector<const IExceptionTranslator*> data;
4495  return data;
4496  }
4497 
4498  String translateActiveException() {
4499 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
4500  String res;
4501  auto& translators = getExceptionTranslators();
4502  for(auto& curr : translators)
4503  if(curr->translate(res))
4504  return res;
4505  // clang-format off
4507  try {
4508  throw;
4509  } catch(std::exception& ex) {
4510  return ex.what();
4511  } catch(std::string& msg) {
4512  return msg.c_str();
4513  } catch(const char* msg) {
4514  return msg;
4515  } catch(...) {
4516  return "unknown exception";
4517  }
4519 // clang-format on
4520 #else // DOCTEST_CONFIG_NO_EXCEPTIONS
4521  return "";
4522 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
4523  }
4524 } // namespace
4525 
4526 namespace detail {
4527  // used by the macros for registering tests
4528  int regTest(const TestCase& tc) {
4529  getRegisteredTests().insert(tc);
4530  return 0;
4531  }
4532 
4533  // sets the current test suite
4534  int setTestSuite(const TestSuite& ts) {
4536  return 0;
4537  }
4538 
4539 #ifdef DOCTEST_IS_DEBUGGER_ACTIVE
4540  bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); }
4541 #else // DOCTEST_IS_DEBUGGER_ACTIVE
4542 #ifdef DOCTEST_PLATFORM_LINUX
4543  class ErrnoGuard {
4544  public:
4545  ErrnoGuard() : m_oldErrno(errno) {}
4546  ~ErrnoGuard() { errno = m_oldErrno; }
4547  private:
4548  int m_oldErrno;
4549  };
4550  // See the comments in Catch2 for the reasoning behind this implementation:
4551  // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102
4552  bool isDebuggerActive() {
4553  ErrnoGuard guard;
4554  std::ifstream in("/proc/self/status");
4555  for(std::string line; std::getline(in, line);) {
4556  static const int PREFIX_LEN = 11;
4557  if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
4558  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
4559  }
4560  }
4561  return false;
4562  }
4563 #elif defined(DOCTEST_PLATFORM_MAC)
4564  // The following function is taken directly from the following technical note:
4565  // https://developer.apple.com/library/archive/qa/qa1361/_index.html
4566  // Returns true if the current process is being debugged (either
4567  // running under the debugger or has a debugger attached post facto).
4568  bool isDebuggerActive() {
4569  int mib[4];
4570  kinfo_proc info;
4571  size_t size;
4572  // Initialize the flags so that, if sysctl fails for some bizarre
4573  // reason, we get a predictable result.
4574  info.kp_proc.p_flag = 0;
4575  // Initialize mib, which tells sysctl the info we want, in this case
4576  // we're looking for information about a specific process ID.
4577  mib[0] = CTL_KERN;
4578  mib[1] = KERN_PROC;
4579  mib[2] = KERN_PROC_PID;
4580  mib[3] = getpid();
4581  // Call sysctl.
4582  size = sizeof(info);
4583  if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) {
4584  std::cerr << "\nCall to sysctl failed - unable to determine if debugger is active **\n";
4585  return false;
4586  }
4587  // We're being debugged if the P_TRACED flag is set.
4588  return ((info.kp_proc.p_flag & P_TRACED) != 0);
4589  }
4590 #elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__)
4591  bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
4592 #else
4593  bool isDebuggerActive() { return false; }
4594 #endif // Platform
4595 #endif // DOCTEST_IS_DEBUGGER_ACTIVE
4596 
4597  void registerExceptionTranslatorImpl(const IExceptionTranslator* et) {
4598  if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) ==
4599  getExceptionTranslators().end())
4600  getExceptionTranslators().push_back(et);
4601  }
4602 
4603  DOCTEST_THREAD_LOCAL std::vector<IContextScope*> g_infoContexts; // for logging with INFO()
4604 
4605  ContextScopeBase::ContextScopeBase() {
4606  g_infoContexts.push_back(this);
4607  }
4608 
4609  ContextScopeBase::ContextScopeBase(ContextScopeBase&& other) noexcept {
4610  if (other.need_to_destroy) {
4611  other.destroy();
4612  }
4613  other.need_to_destroy = false;
4614  g_infoContexts.push_back(this);
4615  }
4616 
4617  DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
4618  DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
4619  DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
4620 
4621  // destroy cannot be inlined into the destructor because that would mean calling stringify after
4622  // ContextScope has been destroyed (base class destructors run after derived class destructors).
4623  // Instead, ContextScope calls this method directly from its destructor.
4624  void ContextScopeBase::destroy() {
4625 #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
4626  if(std::uncaught_exceptions() > 0) {
4627 #else
4628  if(std::uncaught_exception()) {
4629 #endif
4630  std::ostringstream s;
4631  this->stringify(&s);
4632  g_cs->stringifiedContexts.push_back(s.str().c_str());
4633  }
4634  g_infoContexts.pop_back();
4635  }
4636 
4640 } // namespace detail
4641 namespace {
4642  using namespace detail;
4643 
4644 #if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
4645  struct FatalConditionHandler
4646  {
4647  static void reset() {}
4648  static void allocateAltStackMem() {}
4649  static void freeAltStackMem() {}
4650  };
4651 #else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
4652 
4653  void reportFatal(const std::string&);
4654 
4655 #ifdef DOCTEST_PLATFORM_WINDOWS
4656 
4657  struct SignalDefs
4658  {
4659  DWORD id;
4660  const char* name;
4661  };
4662  // There is no 1-1 mapping between signals and windows exceptions.
4663  // Windows can easily distinguish between SO and SigSegV,
4664  // but SigInt, SigTerm, etc are handled differently.
4665  SignalDefs signalDefs[] = {
4666  {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),
4667  "SIGILL - Illegal instruction signal"},
4668  {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
4669  {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),
4670  "SIGSEGV - Segmentation violation signal"},
4671  {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
4672  };
4673 
4674  struct FatalConditionHandler
4675  {
4676  static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
4677  // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the
4678  // console just once no matter how many threads have crashed.
4679  DOCTEST_DECLARE_STATIC_MUTEX(mutex)
4680  static bool execute = true;
4681  {
4682  DOCTEST_LOCK_MUTEX(mutex)
4683  if(execute) {
4684  bool reported = false;
4685  for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4686  if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
4687  reportFatal(signalDefs[i].name);
4688  reported = true;
4689  break;
4690  }
4691  }
4692  if(reported == false)
4693  reportFatal("Unhandled SEH exception caught");
4694  if(isDebuggerActive() && !g_cs->no_breaks)
4696  }
4697  execute = false;
4698  }
4699  std::exit(EXIT_FAILURE);
4700  }
4701 
4702  static void allocateAltStackMem() {}
4703  static void freeAltStackMem() {}
4704 
4705  FatalConditionHandler() {
4706  isSet = true;
4707  // 32k seems enough for doctest to handle stack overflow,
4708  // but the value was found experimentally, so there is no strong guarantee
4709  guaranteeSize = 32 * 1024;
4710  // Register an unhandled exception filter
4711  previousTop = SetUnhandledExceptionFilter(handleException);
4712  // Pass in guarantee size to be filled
4713  SetThreadStackGuarantee(&guaranteeSize);
4714 
4715  // On Windows uncaught exceptions from another thread, exceptions from
4716  // destructors, or calls to std::terminate are not a SEH exception
4717 
4718  // The terminal handler gets called when:
4719  // - std::terminate is called FROM THE TEST RUNNER THREAD
4720  // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
4721  original_terminate_handler = std::get_terminate();
4722  std::set_terminate([]() DOCTEST_NOEXCEPT {
4723  reportFatal("Terminate handler called");
4724  if(isDebuggerActive() && !g_cs->no_breaks)
4726  std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well
4727  });
4728 
4729  // SIGABRT is raised when:
4730  // - std::terminate is called FROM A DIFFERENT THREAD
4731  // - an exception is thrown from a destructor FROM A DIFFERENT THREAD
4732  // - an uncaught exception is thrown FROM A DIFFERENT THREAD
4733  prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT {
4734  if(signal == SIGABRT) {
4735  reportFatal("SIGABRT - Abort (abnormal termination) signal");
4736  if(isDebuggerActive() && !g_cs->no_breaks)
4738  std::exit(EXIT_FAILURE);
4739  }
4740  });
4741 
4742  // The following settings are taken from google test, and more
4743  // specifically from UnitTest::Run() inside of gtest.cc
4744 
4745  // the user does not want to see pop-up dialogs about crashes
4746  prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
4747  SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
4748  // This forces the abort message to go to stderr in all circumstances.
4749  prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);
4750  // In the debug version, Visual Studio pops up a separate dialog
4751  // offering a choice to debug the aborted program - we want to disable that.
4752  prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
4753  // In debug mode, the Windows CRT can crash with an assertion over invalid
4754  // input (e.g. passing an invalid file descriptor). The default handling
4755  // for these assertions is to pop up a dialog and wait for user input.
4756  // Instead ask the CRT to dump such assertions to stderr non-interactively.
4757  prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
4758  prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
4759  }
4760 
4761  static void reset() {
4762  if(isSet) {
4763  // Unregister handler and restore the old guarantee
4764  SetUnhandledExceptionFilter(previousTop);
4765  SetThreadStackGuarantee(&guaranteeSize);
4766  std::set_terminate(original_terminate_handler);
4767  std::signal(SIGABRT, prev_sigabrt_handler);
4768  SetErrorMode(prev_error_mode_1);
4769  _set_error_mode(prev_error_mode_2);
4770  _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
4771  static_cast<void>(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode));
4772  static_cast<void>(_CrtSetReportFile(_CRT_ASSERT, prev_report_file));
4773  isSet = false;
4774  }
4775  }
4776 
4777  ~FatalConditionHandler() { reset(); }
4778 
4779  private:
4780  static UINT prev_error_mode_1;
4781  static int prev_error_mode_2;
4782  static unsigned int prev_abort_behavior;
4783  static int prev_report_mode;
4784  static _HFILE prev_report_file;
4785  static void (DOCTEST_CDECL *prev_sigabrt_handler)(int);
4786  static std::terminate_handler original_terminate_handler;
4787  static bool isSet;
4788  static ULONG guaranteeSize;
4789  static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
4790  };
4791 
4792  UINT FatalConditionHandler::prev_error_mode_1;
4793  int FatalConditionHandler::prev_error_mode_2;
4794  unsigned int FatalConditionHandler::prev_abort_behavior;
4795  int FatalConditionHandler::prev_report_mode;
4796  _HFILE FatalConditionHandler::prev_report_file;
4797  void (DOCTEST_CDECL *FatalConditionHandler::prev_sigabrt_handler)(int);
4798  std::terminate_handler FatalConditionHandler::original_terminate_handler;
4799  bool FatalConditionHandler::isSet = false;
4800  ULONG FatalConditionHandler::guaranteeSize = 0;
4801  LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
4802 
4803 #else // DOCTEST_PLATFORM_WINDOWS
4804 
4805  struct SignalDefs
4806  {
4807  int id;
4808  const char* name;
4809  };
4810  SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"},
4811  {SIGILL, "SIGILL - Illegal instruction signal"},
4812  {SIGFPE, "SIGFPE - Floating point error signal"},
4813  {SIGSEGV, "SIGSEGV - Segmentation violation signal"},
4814  {SIGTERM, "SIGTERM - Termination request signal"},
4815  {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
4816 
4817  struct FatalConditionHandler
4818  {
4819  static bool isSet;
4820  static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)];
4821  static stack_t oldSigStack;
4822  static size_t altStackSize;
4823  static char* altStackMem;
4824 
4825  static void handleSignal(int sig) {
4826  const char* name = "<unknown signal>";
4827  for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4828  SignalDefs& def = signalDefs[i];
4829  if(sig == def.id) {
4830  name = def.name;
4831  break;
4832  }
4833  }
4834  reset();
4835  reportFatal(name);
4836  raise(sig);
4837  }
4838 
4839  static void allocateAltStackMem() {
4840  altStackMem = new char[altStackSize];
4841  }
4842 
4843  static void freeAltStackMem() {
4844  delete[] altStackMem;
4845  }
4846 
4847  FatalConditionHandler() {
4848  isSet = true;
4849  stack_t sigStack;
4850  sigStack.ss_sp = altStackMem;
4851  sigStack.ss_size = altStackSize;
4852  sigStack.ss_flags = 0;
4853  sigaltstack(&sigStack, &oldSigStack);
4854  struct sigaction sa = {};
4855  sa.sa_handler = handleSignal;
4856  sa.sa_flags = SA_ONSTACK;
4857  for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4858  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
4859  }
4860  }
4861 
4862  ~FatalConditionHandler() { reset(); }
4863  static void reset() {
4864  if(isSet) {
4865  // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
4866  for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
4867  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
4868  }
4869  // Return the old stack
4870  sigaltstack(&oldSigStack, nullptr);
4871  isSet = false;
4872  }
4873  }
4874  };
4875 
4876  bool FatalConditionHandler::isSet = false;
4877  struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {};
4878  stack_t FatalConditionHandler::oldSigStack = {};
4879  size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ;
4880  char* FatalConditionHandler::altStackMem = nullptr;
4881 
4882 #endif // DOCTEST_PLATFORM_WINDOWS
4883 #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
4884 
4885 } // namespace
4886 
4887 namespace {
4888  using namespace detail;
4889 
4890 #ifdef DOCTEST_PLATFORM_WINDOWS
4891 #define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text)
4892 #else
4893  // TODO: integration with XCode and other IDEs
4894 #define DOCTEST_OUTPUT_DEBUG_STRING(text)
4895 #endif // Platform
4896 
4897  void addAssert(assertType::Enum at) {
4898  if((at & assertType::is_warn) == 0)
4899  g_cs->numAssertsCurrentTest_atomic++;
4900  }
4901 
4902  void addFailedAssert(assertType::Enum at) {
4903  if((at & assertType::is_warn) == 0)
4904  g_cs->numAssertsFailedCurrentTest_atomic++;
4905  }
4906 
4907 #if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH)
4908  void reportFatal(const std::string& message) {
4909  g_cs->failure_flags |= TestCaseFailureReason::Crash;
4910 
4911  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true});
4912 
4913  while (g_cs->subcaseStack.size()) {
4914  g_cs->subcaseStack.pop_back();
4915  DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
4916  }
4917 
4918  g_cs->finalizeTestCaseData();
4919 
4920  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
4921 
4922  DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
4923  }
4924 #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
4925 } // namespace
4926 
4927 AssertData::AssertData(assertType::Enum at, const char* file, int line, const char* expr,
4928  const char* exception_type, const StringContains& exception_string)
4929  : m_test_case(g_cs->currentTest), m_at(at), m_file(file), m_line(line), m_expr(expr),
4930  m_failed(true), m_threw(false), m_threw_as(false), m_exception_type(exception_type),
4931  m_exception_string(exception_string) {
4932 #if DOCTEST_MSVC
4933  if (m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC
4934  ++m_expr;
4935 #endif // MSVC
4936 }
4937 
4938 namespace detail {
4939  ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
4940  const char* exception_type, const String& exception_string)
4941  : AssertData(at, file, line, expr, exception_type, exception_string) { }
4942 
4943  ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
4944  const char* exception_type, const Contains& exception_string)
4945  : AssertData(at, file, line, expr, exception_type, exception_string) { }
4946 
4947  void ResultBuilder::setResult(const Result& res) {
4948  m_decomp = res.m_decomp;
4949  m_failed = !res.m_passed;
4950  }
4951 
4952  void ResultBuilder::translateException() {
4953  m_threw = true;
4954  m_exception = translateActiveException();
4955  }
4956 
4957  bool ResultBuilder::log() {
4958  if(m_at & assertType::is_throws) {
4959  m_failed = !m_threw;
4960  } else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) {
4961  m_failed = !m_threw_as || !m_exception_string.check(m_exception);
4962  } else if(m_at & assertType::is_throws_as) {
4963  m_failed = !m_threw_as;
4964  } else if(m_at & assertType::is_throws_with) {
4965  m_failed = !m_exception_string.check(m_exception);
4966  } else if(m_at & assertType::is_nothrow) {
4967  m_failed = m_threw;
4968  }
4969 
4970  if(m_exception.size())
4971  m_exception = "\"" + m_exception + "\"";
4972 
4973  if(is_running_in_test) {
4974  addAssert(m_at);
4975  DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this);
4976 
4977  if(m_failed)
4978  addFailedAssert(m_at);
4979  } else if(m_failed) {
4981  }
4982 
4983  return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks &&
4984  (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
4985  }
4986 
4987  void ResultBuilder::react() const {
4988  if(m_failed && checkIfShouldThrow(m_at))
4989  throwException();
4990  }
4991 
4992  void failed_out_of_a_testing_context(const AssertData& ad) {
4993  if(g_cs->ah)
4994  g_cs->ah(ad);
4995  else
4996  std::abort();
4997  }
4998 
4999  bool decomp_assert(assertType::Enum at, const char* file, int line, const char* expr,
5000  const Result& result) {
5001  bool failed = !result.m_passed;
5002 
5003  // ###################################################################################
5004  // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
5005  // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
5006  // ###################################################################################
5007  DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);
5008  DOCTEST_ASSERT_IN_TESTS(result.m_decomp);
5009  return !failed;
5010  }
5011 
5012  MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {
5013  m_stream = tlssPush();
5014  m_file = file;
5015  m_line = line;
5016  m_severity = severity;
5017  }
5018 
5019  MessageBuilder::~MessageBuilder() {
5020  if (!logged)
5021  tlssPop();
5022  }
5023 
5024  DOCTEST_DEFINE_INTERFACE(IExceptionTranslator)
5025 
5026  bool MessageBuilder::log() {
5027  if (!logged) {
5028  m_string = tlssPop();
5029  logged = true;
5030  }
5031 
5032  DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this);
5033 
5034  const bool isWarn = m_severity & assertType::is_warn;
5035 
5036  // warn is just a message in this context so we don't treat it as an assert
5037  if(!isWarn) {
5038  addAssert(m_severity);
5039  addFailedAssert(m_severity);
5040  }
5041 
5042  return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn &&
5043  (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
5044  }
5045 
5046  void MessageBuilder::react() {
5047  if(m_severity & assertType::is_require)
5048  throwException();
5049  }
5050 } // namespace detail
5051 namespace {
5052  using namespace detail;
5053 
5054  // clang-format off
5055 
5056 // =================================================================================================
5057 // The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp
5058 // This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.
5059 // =================================================================================================
5060 
5061  class XmlEncode {
5062  public:
5063  enum ForWhat { ForTextNodes, ForAttributes };
5064 
5065  XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
5066 
5067  void encodeTo( std::ostream& os ) const;
5068 
5069  friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
5070 
5071  private:
5072  std::string m_str;
5073  ForWhat m_forWhat;
5074  };
5075 
5076  class XmlWriter {
5077  public:
5078 
5079  class ScopedElement {
5080  public:
5081  ScopedElement( XmlWriter* writer );
5082 
5083  ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT;
5084  ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT;
5085 
5086  ~ScopedElement();
5087 
5088  ScopedElement& writeText( std::string const& text, bool indent = true );
5089 
5090  template<typename T>
5091  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
5092  m_writer->writeAttribute( name, attribute );
5093  return *this;
5094  }
5095 
5096  private:
5097  mutable XmlWriter* m_writer = nullptr;
5098  };
5099 
5100 #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
5101  XmlWriter( std::ostream& os = std::cout );
5102 #else // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
5103  XmlWriter( std::ostream& os );
5104 #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
5105  ~XmlWriter();
5106 
5107  XmlWriter( XmlWriter const& ) = delete;
5108  XmlWriter& operator=( XmlWriter const& ) = delete;
5109 
5110  XmlWriter& startElement( std::string const& name );
5111 
5112  ScopedElement scopedElement( std::string const& name );
5113 
5114  XmlWriter& endElement();
5115 
5116  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
5117 
5118  XmlWriter& writeAttribute( std::string const& name, const char* attribute );
5119 
5120  XmlWriter& writeAttribute( std::string const& name, bool attribute );
5121 
5122  template<typename T>
5123  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
5124  std::stringstream rss;
5125  rss << attribute;
5126  return writeAttribute( name, rss.str() );
5127  }
5128 
5129  XmlWriter& writeText( std::string const& text, bool indent = true );
5130 
5131  //XmlWriter& writeComment( std::string const& text );
5132 
5133  //void writeStylesheetRef( std::string const& url );
5134 
5135  //XmlWriter& writeBlankLine();
5136 
5137  void ensureTagClosed();
5138 
5139  void writeDeclaration();
5140 
5141  private:
5142 
5143  void newlineIfNecessary();
5144 
5145  bool m_tagIsOpen = false;
5146  bool m_needsNewline = false;
5147  std::vector<std::string> m_tags;
5148  std::string m_indent;
5149  std::ostream& m_os;
5150  };
5151 
5152 // =================================================================================================
5153 // The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp
5154 // This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.
5155 // =================================================================================================
5156 
5157 using uchar = unsigned char;
5158 
5159 namespace {
5160 
5161  size_t trailingBytes(unsigned char c) {
5162  if ((c & 0xE0) == 0xC0) {
5163  return 2;
5164  }
5165  if ((c & 0xF0) == 0xE0) {
5166  return 3;
5167  }
5168  if ((c & 0xF8) == 0xF0) {
5169  return 4;
5170  }
5171  DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
5172  }
5173 
5174  uint32_t headerValue(unsigned char c) {
5175  if ((c & 0xE0) == 0xC0) {
5176  return c & 0x1F;
5177  }
5178  if ((c & 0xF0) == 0xE0) {
5179  return c & 0x0F;
5180  }
5181  if ((c & 0xF8) == 0xF0) {
5182  return c & 0x07;
5183  }
5184  DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
5185  }
5186 
5187  void hexEscapeChar(std::ostream& os, unsigned char c) {
5188  std::ios_base::fmtflags f(os.flags());
5189  os << "\\x"
5190  << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
5191  << static_cast<int>(c);
5192  os.flags(f);
5193  }
5194 
5195 } // anonymous namespace
5196 
5197  XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
5198  : m_str( str ),
5199  m_forWhat( forWhat )
5200  {}
5201 
5202  void XmlEncode::encodeTo( std::ostream& os ) const {
5203  // Apostrophe escaping not necessary if we always use " to write attributes
5204  // (see: https://www.w3.org/TR/xml/#syntax)
5205 
5206  for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
5207  uchar c = m_str[idx];
5208  switch (c) {
5209  case '<': os << "&lt;"; break;
5210  case '&': os << "&amp;"; break;
5211 
5212  case '>':
5213  // See: https://www.w3.org/TR/xml/#syntax
5214  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
5215  os << "&gt;";
5216  else
5217  os << c;
5218  break;
5219 
5220  case '\"':
5221  if (m_forWhat == ForAttributes)
5222  os << "&quot;";
5223  else
5224  os << c;
5225  break;
5226 
5227  default:
5228  // Check for control characters and invalid utf-8
5229 
5230  // Escape control characters in standard ascii
5231  // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
5232  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
5233  hexEscapeChar(os, c);
5234  break;
5235  }
5236 
5237  // Plain ASCII: Write it to stream
5238  if (c < 0x7F) {
5239  os << c;
5240  break;
5241  }
5242 
5243  // UTF-8 territory
5244  // Check if the encoding is valid and if it is not, hex escape bytes.
5245  // Important: We do not check the exact decoded values for validity, only the encoding format
5246  // First check that this bytes is a valid lead byte:
5247  // This means that it is not encoded as 1111 1XXX
5248  // Or as 10XX XXXX
5249  if (c < 0xC0 ||
5250  c >= 0xF8) {
5251  hexEscapeChar(os, c);
5252  break;
5253  }
5254 
5255  auto encBytes = trailingBytes(c);
5256  // Are there enough bytes left to avoid accessing out-of-bounds memory?
5257  if (idx + encBytes - 1 >= m_str.size()) {
5258  hexEscapeChar(os, c);
5259  break;
5260  }
5261  // The header is valid, check data
5262  // The next encBytes bytes must together be a valid utf-8
5263  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
5264  bool valid = true;
5265  uint32_t value = headerValue(c);
5266  for (std::size_t n = 1; n < encBytes; ++n) {
5267  uchar nc = m_str[idx + n];
5268  valid &= ((nc & 0xC0) == 0x80);
5269  value = (value << 6) | (nc & 0x3F);
5270  }
5271 
5272  if (
5273  // Wrong bit pattern of following bytes
5274  (!valid) ||
5275  // Overlong encodings
5276  (value < 0x80) ||
5277  ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant
5278  (0x800 < value && value < 0x10000 && encBytes > 3) ||
5279  // Encoded value out of range
5280  (value >= 0x110000)
5281  ) {
5282  hexEscapeChar(os, c);
5283  break;
5284  }
5285 
5286  // If we got here, this is in fact a valid(ish) utf-8 sequence
5287  for (std::size_t n = 0; n < encBytes; ++n) {
5288  os << m_str[idx + n];
5289  }
5290  idx += encBytes - 1;
5291  break;
5292  }
5293  }
5294  }
5295 
5296  std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
5297  xmlEncode.encodeTo( os );
5298  return os;
5299  }
5300 
5301  XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
5302  : m_writer( writer )
5303  {}
5304 
5305  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT
5306  : m_writer( other.m_writer ){
5307  other.m_writer = nullptr;
5308  }
5309  XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT {
5310  if ( m_writer ) {
5311  m_writer->endElement();
5312  }
5313  m_writer = other.m_writer;
5314  other.m_writer = nullptr;
5315  return *this;
5316  }
5317 
5318 
5319  XmlWriter::ScopedElement::~ScopedElement() {
5320  if( m_writer )
5321  m_writer->endElement();
5322  }
5323 
5324  XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
5325  m_writer->writeText( text, indent );
5326  return *this;
5327  }
5328 
5329  XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
5330  {
5331  // writeDeclaration(); // called explicitly by the reporters that use the writer class - see issue #627
5332  }
5333 
5334  XmlWriter::~XmlWriter() {
5335  while( !m_tags.empty() )
5336  endElement();
5337  }
5338 
5339  XmlWriter& XmlWriter::startElement( std::string const& name ) {
5340  ensureTagClosed();
5341  newlineIfNecessary();
5342  m_os << m_indent << '<' << name;
5343  m_tags.push_back( name );
5344  m_indent += " ";
5345  m_tagIsOpen = true;
5346  return *this;
5347  }
5348 
5349  XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
5350  ScopedElement scoped( this );
5351  startElement( name );
5352  return scoped;
5353  }
5354 
5355  XmlWriter& XmlWriter::endElement() {
5356  newlineIfNecessary();
5357  m_indent = m_indent.substr( 0, m_indent.size()-2 );
5358  if( m_tagIsOpen ) {
5359  m_os << "/>";
5360  m_tagIsOpen = false;
5361  }
5362  else {
5363  m_os << m_indent << "</" << m_tags.back() << ">";
5364  }
5365  m_os << std::endl;
5366  m_tags.pop_back();
5367  return *this;
5368  }
5369 
5370  XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
5371  if( !name.empty() && !attribute.empty() )
5372  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
5373  return *this;
5374  }
5375 
5376  XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) {
5377  if( !name.empty() && attribute && attribute[0] != '\0' )
5378  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
5379  return *this;
5380  }
5381 
5382  XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
5383  m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
5384  return *this;
5385  }
5386 
5387  XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
5388  if( !text.empty() ){
5389  bool tagWasOpen = m_tagIsOpen;
5390  ensureTagClosed();
5391  if( tagWasOpen && indent )
5392  m_os << m_indent;
5393  m_os << XmlEncode( text );
5394  m_needsNewline = true;
5395  }
5396  return *this;
5397  }
5398 
5399  //XmlWriter& XmlWriter::writeComment( std::string const& text ) {
5400  // ensureTagClosed();
5401  // m_os << m_indent << "<!--" << text << "-->";
5402  // m_needsNewline = true;
5403  // return *this;
5404  //}
5405 
5406  //void XmlWriter::writeStylesheetRef( std::string const& url ) {
5407  // m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
5408  //}
5409 
5410  //XmlWriter& XmlWriter::writeBlankLine() {
5411  // ensureTagClosed();
5412  // m_os << '\n';
5413  // return *this;
5414  //}
5415 
5416  void XmlWriter::ensureTagClosed() {
5417  if( m_tagIsOpen ) {
5418  m_os << ">" << std::endl;
5419  m_tagIsOpen = false;
5420  }
5421  }
5422 
5423  void XmlWriter::writeDeclaration() {
5424  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
5425  }
5426 
5427  void XmlWriter::newlineIfNecessary() {
5428  if( m_needsNewline ) {
5429  m_os << std::endl;
5430  m_needsNewline = false;
5431  }
5432  }
5433 
5434 // =================================================================================================
5435 // End of copy-pasted code from Catch
5436 // =================================================================================================
5437 
5438  // clang-format on
5439 
5440  struct XmlReporter : public IReporter
5441  {
5442  XmlWriter xml;
5443  DOCTEST_DECLARE_MUTEX(mutex)
5444 
5445  // caching pointers/references to objects of these types - safe to do
5446  const ContextOptions& opt;
5447  const TestCaseData* tc = nullptr;
5448 
5449  XmlReporter(const ContextOptions& co)
5450  : xml(*co.cout)
5451  , opt(co) {}
5452 
5453  void log_contexts() {
5454  int num_contexts = get_num_active_contexts();
5455  if(num_contexts) {
5456  auto contexts = get_active_contexts();
5457  std::stringstream ss;
5458  for(int i = 0; i < num_contexts; ++i) {
5459  contexts[i]->stringify(&ss);
5460  xml.scopedElement("Info").writeText(ss.str());
5461  ss.str("");
5462  }
5463  }
5464  }
5465 
5466  unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
5467 
5468  void test_case_start_impl(const TestCaseData& in) {
5469  bool open_ts_tag = false;
5470  if(tc != nullptr) { // we have already opened a test suite
5471  if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) {
5472  xml.endElement();
5473  open_ts_tag = true;
5474  }
5475  }
5476  else {
5477  open_ts_tag = true; // first test case ==> first test suite
5478  }
5479 
5480  if(open_ts_tag) {
5481  xml.startElement("TestSuite");
5482  xml.writeAttribute("name", in.m_test_suite);
5483  }
5484 
5485  tc = &in;
5486  xml.startElement("TestCase")
5487  .writeAttribute("name", in.m_name)
5488  .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str()))
5489  .writeAttribute("line", line(in.m_line))
5490  .writeAttribute("description", in.m_description);
5491 
5492  if(Approx(in.m_timeout) != 0)
5493  xml.writeAttribute("timeout", in.m_timeout);
5494  if(in.m_may_fail)
5495  xml.writeAttribute("may_fail", true);
5496  if(in.m_should_fail)
5497  xml.writeAttribute("should_fail", true);
5498  }
5499 
5500  // =========================================================================================
5501  // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
5502  // =========================================================================================
5503 
5504  void report_query(const QueryData& in) override {
5505  test_run_start();
5506  if(opt.list_reporters) {
5507  for(auto& curr : getListeners())
5508  xml.scopedElement("Listener")
5509  .writeAttribute("priority", curr.first.first)
5510  .writeAttribute("name", curr.first.second);
5511  for(auto& curr : getReporters())
5512  xml.scopedElement("Reporter")
5513  .writeAttribute("priority", curr.first.first)
5514  .writeAttribute("name", curr.first.second);
5515  } else if(opt.count || opt.list_test_cases) {
5516  for(unsigned i = 0; i < in.num_data; ++i) {
5517  xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name)
5518  .writeAttribute("testsuite", in.data[i]->m_test_suite)
5519  .writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file.c_str()))
5520  .writeAttribute("line", line(in.data[i]->m_line))
5521  .writeAttribute("skipped", in.data[i]->m_skip);
5522  }
5523  xml.scopedElement("OverallResultsTestCases")
5524  .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
5525  } else if(opt.list_test_suites) {
5526  for(unsigned i = 0; i < in.num_data; ++i)
5527  xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]->m_test_suite);
5528  xml.scopedElement("OverallResultsTestCases")
5529  .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
5530  xml.scopedElement("OverallResultsTestSuites")
5531  .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters);
5532  }
5533  xml.endElement();
5534  }
5535 
5536  void test_run_start() override {
5537  xml.writeDeclaration();
5538 
5539  // remove .exe extension - mainly to have the same output on UNIX and Windows
5540  std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
5541 #ifdef DOCTEST_PLATFORM_WINDOWS
5542  if(binary_name.rfind(".exe") != std::string::npos)
5543  binary_name = binary_name.substr(0, binary_name.length() - 4);
5544 #endif // DOCTEST_PLATFORM_WINDOWS
5545 
5546  xml.startElement("doctest").writeAttribute("binary", binary_name);
5547  if(opt.no_version == false)
5548  xml.writeAttribute("version", DOCTEST_VERSION_STR);
5549 
5550  // only the consequential ones (TODO: filters)
5551  xml.scopedElement("Options")
5552  .writeAttribute("order_by", opt.order_by.c_str())
5553  .writeAttribute("rand_seed", opt.rand_seed)
5554  .writeAttribute("first", opt.first)
5555  .writeAttribute("last", opt.last)
5556  .writeAttribute("abort_after", opt.abort_after)
5557  .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels)
5558  .writeAttribute("case_sensitive", opt.case_sensitive)
5559  .writeAttribute("no_throw", opt.no_throw)
5560  .writeAttribute("no_skip", opt.no_skip);
5561  }
5562 
5563  void test_run_end(const TestRunStats& p) override {
5564  if(tc) // the TestSuite tag - only if there has been at least 1 test case
5565  xml.endElement();
5566 
5567  xml.scopedElement("OverallResultsAsserts")
5568  .writeAttribute("successes", p.numAsserts - p.numAssertsFailed)
5569  .writeAttribute("failures", p.numAssertsFailed);
5570 
5571  xml.startElement("OverallResultsTestCases")
5572  .writeAttribute("successes",
5573  p.numTestCasesPassingFilters - p.numTestCasesFailed)
5574  .writeAttribute("failures", p.numTestCasesFailed);
5575  if(opt.no_skipped_summary == false)
5576  xml.writeAttribute("skipped", p.numTestCases - p.numTestCasesPassingFilters);
5577  xml.endElement();
5578 
5579  xml.endElement();
5580  }
5581 
5582  void test_case_start(const TestCaseData& in) override {
5583  test_case_start_impl(in);
5584  xml.ensureTagClosed();
5585  }
5586 
5587  void test_case_reenter(const TestCaseData&) override {}
5588 
5589  void test_case_end(const CurrentTestCaseStats& st) override {
5590  xml.startElement("OverallResultsAsserts")
5591  .writeAttribute("successes",
5592  st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest)
5593  .writeAttribute("failures", st.numAssertsFailedCurrentTest)
5594  .writeAttribute("test_case_success", st.testCaseSuccess);
5595  if(opt.duration)
5596  xml.writeAttribute("duration", st.seconds);
5597  if(tc->m_expected_failures)
5598  xml.writeAttribute("expected_failures", tc->m_expected_failures);
5599  xml.endElement();
5600 
5601  xml.endElement();
5602  }
5603 
5604  void test_case_exception(const TestCaseException& e) override {
5605  DOCTEST_LOCK_MUTEX(mutex)
5606 
5607  xml.scopedElement("Exception")
5608  .writeAttribute("crash", e.is_crash)
5609  .writeText(e.error_string.c_str());
5610  }
5611 
5612  void subcase_start(const SubcaseSignature& in) override {
5613  xml.startElement("SubCase")
5614  .writeAttribute("name", in.m_name)
5615  .writeAttribute("filename", skipPathFromFilename(in.m_file))
5616  .writeAttribute("line", line(in.m_line));
5617  xml.ensureTagClosed();
5618  }
5619 
5620  void subcase_end() override { xml.endElement(); }
5621 
5622  void log_assert(const AssertData& rb) override {
5623  if(!rb.m_failed && !opt.success)
5624  return;
5625 
5626  DOCTEST_LOCK_MUTEX(mutex)
5627 
5628  xml.startElement("Expression")
5629  .writeAttribute("success", !rb.m_failed)
5630  .writeAttribute("type", assertString(rb.m_at))
5631  .writeAttribute("filename", skipPathFromFilename(rb.m_file))
5632  .writeAttribute("line", line(rb.m_line));
5633 
5634  xml.scopedElement("Original").writeText(rb.m_expr);
5635 
5636  if(rb.m_threw)
5637  xml.scopedElement("Exception").writeText(rb.m_exception.c_str());
5638 
5639  if(rb.m_at & assertType::is_throws_as)
5640  xml.scopedElement("ExpectedException").writeText(rb.m_exception_type);
5641  if(rb.m_at & assertType::is_throws_with)
5642  xml.scopedElement("ExpectedExceptionString").writeText(rb.m_exception_string.c_str());
5643  if((rb.m_at & assertType::is_normal) && !rb.m_threw)
5644  xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str());
5645 
5646  log_contexts();
5647 
5648  xml.endElement();
5649  }
5650 
5651  void log_message(const MessageData& mb) override {
5652  DOCTEST_LOCK_MUTEX(mutex)
5653 
5654  xml.startElement("Message")
5655  .writeAttribute("type", failureString(mb.m_severity))
5656  .writeAttribute("filename", skipPathFromFilename(mb.m_file))
5657  .writeAttribute("line", line(mb.m_line));
5658 
5659  xml.scopedElement("Text").writeText(mb.m_string.c_str());
5660 
5661  log_contexts();
5662 
5663  xml.endElement();
5664  }
5665 
5666  void test_case_skipped(const TestCaseData& in) override {
5667  if(opt.no_skipped_summary == false) {
5668  test_case_start_impl(in);
5669  xml.writeAttribute("skipped", "true");
5670  xml.endElement();
5671  }
5672  }
5673  };
5674 
5675  DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter);
5676 
5677  void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) {
5679  0)
5680  s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) "
5681  << Color::None;
5682 
5683  if(rb.m_at & assertType::is_throws) {
5684  s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n";
5685  } else if((rb.m_at & assertType::is_throws_as) &&
5686  (rb.m_at & assertType::is_throws_with)) {
5687  s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
5688  << rb.m_exception_string.c_str()
5689  << "\", " << rb.m_exception_type << " ) " << Color::None;
5690  if(rb.m_threw) {
5691  if(!rb.m_failed) {
5692  s << "threw as expected!\n";
5693  } else {
5694  s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n";
5695  }
5696  } else {
5697  s << "did NOT throw at all!\n";
5698  }
5699  } else if(rb.m_at &
5701  s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", "
5702  << rb.m_exception_type << " ) " << Color::None
5703  << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" :
5704  "threw a DIFFERENT exception: ") :
5705  "did NOT throw at all!")
5706  << Color::Cyan << rb.m_exception << "\n";
5707  } else if(rb.m_at &
5709  s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
5710  << rb.m_exception_string.c_str()
5711  << "\" ) " << Color::None
5712  << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" :
5713  "threw a DIFFERENT exception: ") :
5714  "did NOT throw at all!")
5715  << Color::Cyan << rb.m_exception << "\n";
5716  } else if(rb.m_at & assertType::is_nothrow) {
5717  s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan
5718  << rb.m_exception << "\n";
5719  } else {
5720  s << (rb.m_threw ? "THREW exception: " :
5721  (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n"));
5722  if(rb.m_threw)
5723  s << rb.m_exception << "\n";
5724  else
5725  s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n";
5726  }
5727  }
5728 
5729  // TODO:
5730  // - log_message()
5731  // - respond to queries
5732  // - honor remaining options
5733  // - more attributes in tags
5734  struct JUnitReporter : public IReporter
5735  {
5736  XmlWriter xml;
5737  DOCTEST_DECLARE_MUTEX(mutex)
5738  Timer timer;
5739  std::vector<String> deepestSubcaseStackNames;
5740 
5741  struct JUnitTestCaseData
5742  {
5743  static std::string getCurrentTimestamp() {
5744  // Beware, this is not reentrant because of backward compatibility issues
5745  // Also, UTC only, again because of backward compatibility (%z is C++11)
5746  time_t rawtime;
5747  std::time(&rawtime);
5748  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
5749 
5750  std::tm timeInfo;
5751 #ifdef DOCTEST_PLATFORM_WINDOWS
5752  gmtime_s(&timeInfo, &rawtime);
5753 #else // DOCTEST_PLATFORM_WINDOWS
5754  gmtime_r(&rawtime, &timeInfo);
5755 #endif // DOCTEST_PLATFORM_WINDOWS
5756 
5757  char timeStamp[timeStampSize];
5758  const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
5759 
5760  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
5761  return std::string(timeStamp);
5762  }
5763 
5764  struct JUnitTestMessage
5765  {
5766  JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details)
5767  : message(_message), type(_type), details(_details) {}
5768 
5769  JUnitTestMessage(const std::string& _message, const std::string& _details)
5770  : message(_message), type(), details(_details) {}
5771 
5772  std::string message, type, details;
5773  };
5774 
5775  struct JUnitTestCase
5776  {
5777  JUnitTestCase(const std::string& _classname, const std::string& _name)
5778  : classname(_classname), name(_name), time(0), failures() {}
5779 
5780  std::string classname, name;
5781  double time;
5782  std::vector<JUnitTestMessage> failures, errors;
5783  };
5784 
5785  void add(const std::string& classname, const std::string& name) {
5786  testcases.emplace_back(classname, name);
5787  }
5788 
5789  void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {
5790  for(auto& curr: nameStack)
5791  if(curr.size())
5792  testcases.back().name += std::string("/") + curr.c_str();
5793  }
5794 
5795  void addTime(double time) {
5796  if(time < 1e-4)
5797  time = 0;
5798  testcases.back().time = time;
5799  totalSeconds += time;
5800  }
5801 
5802  void addFailure(const std::string& message, const std::string& type, const std::string& details) {
5803  testcases.back().failures.emplace_back(message, type, details);
5804  ++totalFailures;
5805  }
5806 
5807  void addError(const std::string& message, const std::string& details) {
5808  testcases.back().errors.emplace_back(message, details);
5809  ++totalErrors;
5810  }
5811 
5812  std::vector<JUnitTestCase> testcases;
5813  double totalSeconds = 0;
5814  int totalErrors = 0, totalFailures = 0;
5815  };
5816 
5817  JUnitTestCaseData testCaseData;
5818 
5819  // caching pointers/references to objects of these types - safe to do
5820  const ContextOptions& opt;
5821  const TestCaseData* tc = nullptr;
5822 
5823  JUnitReporter(const ContextOptions& co)
5824  : xml(*co.cout)
5825  , opt(co) {}
5826 
5827  unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
5828 
5829  // =========================================================================================
5830  // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
5831  // =========================================================================================
5832 
5833  void report_query(const QueryData&) override {
5834  xml.writeDeclaration();
5835  }
5836 
5837  void test_run_start() override {
5838  xml.writeDeclaration();
5839  }
5840 
5841  void test_run_end(const TestRunStats& p) override {
5842  // remove .exe extension - mainly to have the same output on UNIX and Windows
5843  std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
5844 #ifdef DOCTEST_PLATFORM_WINDOWS
5845  if(binary_name.rfind(".exe") != std::string::npos)
5846  binary_name = binary_name.substr(0, binary_name.length() - 4);
5847 #endif // DOCTEST_PLATFORM_WINDOWS
5848  xml.startElement("testsuites");
5849  xml.startElement("testsuite").writeAttribute("name", binary_name)
5850  .writeAttribute("errors", testCaseData.totalErrors)
5851  .writeAttribute("failures", testCaseData.totalFailures)
5852  .writeAttribute("tests", p.numAsserts);
5853  if(opt.no_time_in_output == false) {
5854  xml.writeAttribute("time", testCaseData.totalSeconds);
5855  xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp());
5856  }
5857  if(opt.no_version == false)
5858  xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR);
5859 
5860  for(const auto& testCase : testCaseData.testcases) {
5861  xml.startElement("testcase")
5862  .writeAttribute("classname", testCase.classname)
5863  .writeAttribute("name", testCase.name);
5864  if(opt.no_time_in_output == false)
5865  xml.writeAttribute("time", testCase.time);
5866  // This is not ideal, but it should be enough to mimic gtest's junit output.
5867  xml.writeAttribute("status", "run");
5868 
5869  for(const auto& failure : testCase.failures) {
5870  xml.scopedElement("failure")
5871  .writeAttribute("message", failure.message)
5872  .writeAttribute("type", failure.type)
5873  .writeText(failure.details, false);
5874  }
5875 
5876  for(const auto& error : testCase.errors) {
5877  xml.scopedElement("error")
5878  .writeAttribute("message", error.message)
5879  .writeText(error.details);
5880  }
5881 
5882  xml.endElement();
5883  }
5884  xml.endElement();
5885  xml.endElement();
5886  }
5887 
5888  void test_case_start(const TestCaseData& in) override {
5889  testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
5890  timer.start();
5891  }
5892 
5893  void test_case_reenter(const TestCaseData& in) override {
5894  testCaseData.addTime(timer.getElapsedSeconds());
5895  testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
5896  deepestSubcaseStackNames.clear();
5897 
5898  timer.start();
5899  testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
5900  }
5901 
5902  void test_case_end(const CurrentTestCaseStats&) override {
5903  testCaseData.addTime(timer.getElapsedSeconds());
5904  testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
5905  deepestSubcaseStackNames.clear();
5906  }
5907 
5908  void test_case_exception(const TestCaseException& e) override {
5909  DOCTEST_LOCK_MUTEX(mutex)
5910  testCaseData.addError("exception", e.error_string.c_str());
5911  }
5912 
5913  void subcase_start(const SubcaseSignature& in) override {
5914  deepestSubcaseStackNames.push_back(in.m_name);
5915  }
5916 
5917  void subcase_end() override {}
5918 
5919  void log_assert(const AssertData& rb) override {
5920  if(!rb.m_failed) // report only failures & ignore the `success` option
5921  return;
5922 
5923  DOCTEST_LOCK_MUTEX(mutex)
5924 
5925  std::ostringstream os;
5926  os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(")
5927  << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
5928 
5929  fulltext_log_assert_to_stream(os, rb);
5930  log_contexts(os);
5931  testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());
5932  }
5933 
5934  void log_message(const MessageData& mb) override {
5935  if(mb.m_severity & assertType::is_warn) // report only failures
5936  return;
5937 
5938  DOCTEST_LOCK_MUTEX(mutex)
5939 
5940  std::ostringstream os;
5941  os << skipPathFromFilename(mb.m_file) << (opt.gnu_file_line ? ":" : "(")
5942  << line(mb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
5943 
5944  os << mb.m_string.c_str() << "\n";
5945  log_contexts(os);
5946 
5947  testCaseData.addFailure(mb.m_string.c_str(),
5948  mb.m_severity & assertType::is_check ? "FAIL_CHECK" : "FAIL", os.str());
5949  }
5950 
5951  void test_case_skipped(const TestCaseData&) override {}
5952 
5953  void log_contexts(std::ostringstream& s) {
5954  int num_contexts = get_num_active_contexts();
5955  if(num_contexts) {
5956  auto contexts = get_active_contexts();
5957 
5958  s << " logged: ";
5959  for(int i = 0; i < num_contexts; ++i) {
5960  s << (i == 0 ? "" : " ");
5961  contexts[i]->stringify(&s);
5962  s << std::endl;
5963  }
5964  }
5965  }
5966  };
5967 
5968  DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
5969 
5970  struct Whitespace
5971  {
5972  int nrSpaces;
5973  explicit Whitespace(int nr)
5974  : nrSpaces(nr) {}
5975  };
5976 
5977  std::ostream& operator<<(std::ostream& out, const Whitespace& ws) {
5978  if(ws.nrSpaces != 0)
5979  out << std::setw(ws.nrSpaces) << ' ';
5980  return out;
5981  }
5982 
5983  struct ConsoleReporter : public IReporter
5984  {
5985  std::ostream& s;
5986  bool hasLoggedCurrentTestStart;
5987  std::vector<SubcaseSignature> subcasesStack;
5988  size_t currentSubcaseLevel;
5989  DOCTEST_DECLARE_MUTEX(mutex)
5990 
5991  // caching pointers/references to objects of these types - safe to do
5992  const ContextOptions& opt;
5993  const TestCaseData* tc;
5994 
5995  ConsoleReporter(const ContextOptions& co)
5996  : s(*co.cout)
5997  , opt(co) {}
5998 
5999  ConsoleReporter(const ContextOptions& co, std::ostream& ostr)
6000  : s(ostr)
6001  , opt(co) {}
6002 
6003  // =========================================================================================
6004  // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE
6005  // =========================================================================================
6006 
6007  void separator_to_stream() {
6008  s << Color::Yellow
6009  << "==============================================================================="
6010  "\n";
6011  }
6012 
6013  const char* getSuccessOrFailString(bool success, assertType::Enum at,
6014  const char* success_str) {
6015  if(success)
6016  return success_str;
6017  return failureString(at);
6018  }
6019 
6020  Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) {
6021  return success ? Color::BrightGreen :
6023  }
6024 
6025  void successOrFailColoredStringToStream(bool success, assertType::Enum at,
6026  const char* success_str = "SUCCESS") {
6027  s << getSuccessOrFailColor(success, at)
6028  << getSuccessOrFailString(success, at, success_str) << ": ";
6029  }
6030 
6031  void log_contexts() {
6032  int num_contexts = get_num_active_contexts();
6033  if(num_contexts) {
6034  auto contexts = get_active_contexts();
6035 
6036  s << Color::None << " logged: ";
6037  for(int i = 0; i < num_contexts; ++i) {
6038  s << (i == 0 ? "" : " ");
6039  contexts[i]->stringify(&s);
6040  s << "\n";
6041  }
6042  }
6043 
6044  s << "\n";
6045  }
6046 
6047  // this was requested to be made virtual so users could override it
6048  virtual void file_line_to_stream(const char* file, int line,
6049  const char* tail = "") {
6050  s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? ":" : "(")
6051  << (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option
6052  << (opt.gnu_file_line ? ":" : "):") << tail;
6053  }
6054 
6055  void logTestStart() {
6056  if(hasLoggedCurrentTestStart)
6057  return;
6058 
6059  separator_to_stream();
6060  file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n");
6061  if(tc->m_description)
6062  s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n";
6063  if(tc->m_test_suite && tc->m_test_suite[0] != '\0')
6064  s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n";
6065  if(strncmp(tc->m_name, " Scenario:", 11) != 0)
6066  s << Color::Yellow << "TEST CASE: ";
6067  s << Color::None << tc->m_name << "\n";
6068 
6069  for(size_t i = 0; i < currentSubcaseLevel; ++i) {
6070  if(subcasesStack[i].m_name[0] != '\0')
6071  s << " " << subcasesStack[i].m_name << "\n";
6072  }
6073 
6074  if(currentSubcaseLevel != subcasesStack.size()) {
6075  s << Color::Yellow << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None;
6076  for(size_t i = 0; i < subcasesStack.size(); ++i) {
6077  if(subcasesStack[i].m_name[0] != '\0')
6078  s << " " << subcasesStack[i].m_name << "\n";
6079  }
6080  }
6081 
6082  s << "\n";
6083 
6084  hasLoggedCurrentTestStart = true;
6085  }
6086 
6087  void printVersion() {
6088  if(opt.no_version == false)
6089  s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \""
6090  << DOCTEST_VERSION_STR << "\"\n";
6091  }
6092 
6093  void printIntro() {
6094  if(opt.no_intro == false) {
6095  printVersion();
6096  s << Color::Cyan << "[doctest] " << Color::None
6097  << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for options\n";
6098  }
6099  }
6100 
6101  void printHelp() {
6102  int sizePrefixDisplay = static_cast<int>(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY));
6103  printVersion();
6104  // clang-format off
6105  s << Color::Cyan << "[doctest]\n" << Color::None;
6106  s << Color::Cyan << "[doctest] " << Color::None;
6107  s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n";
6108  s << Color::Cyan << "[doctest] " << Color::None;
6109  s << "filter values: \"str1,str2,str3\" (comma separated strings)\n";
6110  s << Color::Cyan << "[doctest]\n" << Color::None;
6111  s << Color::Cyan << "[doctest] " << Color::None;
6112  s << "filters use wildcards for matching strings\n";
6113  s << Color::Cyan << "[doctest] " << Color::None;
6114  s << "something passes a filter if any of the strings in a filter matches\n";
6115 #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
6116  s << Color::Cyan << "[doctest]\n" << Color::None;
6117  s << Color::Cyan << "[doctest] " << Color::None;
6118  s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n";
6119 #endif
6120  s << Color::Cyan << "[doctest]\n" << Color::None;
6121  s << Color::Cyan << "[doctest] " << Color::None;
6122  s << "Query flags - the program quits after them. Available:\n\n";
6123  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h "
6124  << Whitespace(sizePrefixDisplay*0) << "prints this message\n";
6125  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version "
6126  << Whitespace(sizePrefixDisplay*1) << "prints the version\n";
6127  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count "
6128  << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n";
6129  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases "
6130  << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n";
6131  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites "
6132  << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n";
6133  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters "
6134  << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n";
6135  // ================================================================================== << 79
6136  s << Color::Cyan << "[doctest] " << Color::None;
6137  s << "The available <int>/<string> options/filters are:\n\n";
6138  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case=<filters> "
6139  << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n";
6140  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude=<filters> "
6141  << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n";
6142  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file=<filters> "
6143  << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n";
6144  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude=<filters> "
6145  << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n";
6146  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite=<filters> "
6147  << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n";
6148  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude=<filters> "
6149  << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n";
6150  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase=<filters> "
6151  << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n";
6152  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude=<filters> "
6153  << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n";
6154  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters=<filters> "
6155  << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n";
6156  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out=<string> "
6157  << Whitespace(sizePrefixDisplay*1) << "output filename\n";
6158  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by=<string> "
6159  << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n";
6160  s << Whitespace(sizePrefixDisplay*3) << " <string> - [file/suite/name/rand/none]\n";
6161  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed=<int> "
6162  << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n";
6163  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first=<int> "
6164  << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n";
6165  s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n";
6166  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last=<int> "
6167  << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n";
6168  s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n";
6169  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after=<int> "
6170  << Whitespace(sizePrefixDisplay*1) << "stop after <int> failed assertions\n";
6171  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels=<int> "
6172  << Whitespace(sizePrefixDisplay*1) << "apply filters for the first <int> levels\n";
6173  s << Color::Cyan << "\n[doctest] " << Color::None;
6174  s << "Bool options - can be used like flags and true is assumed. Available:\n\n";
6175  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success=<bool> "
6176  << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n";
6177  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive=<bool> "
6178  << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n";
6179  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit=<bool> "
6180  << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n";
6181  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration=<bool> "
6182  << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n";
6183  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "m, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "minimal=<bool> "
6184  << Whitespace(sizePrefixDisplay*1) << "minimal console output (only failures)\n";
6185  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "q, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "quiet=<bool> "
6186  << Whitespace(sizePrefixDisplay*1) << "no console output\n";
6187  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw=<bool> "
6188  << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n";
6189  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode=<bool> "
6190  << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n";
6191  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run=<bool> "
6192  << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n";
6193  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ni, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-intro=<bool> "
6194  << Whitespace(sizePrefixDisplay*1) << "omit the framework intro in the output\n";
6195  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version=<bool> "
6196  << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n";
6197  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors=<bool> "
6198  << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n";
6199  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors=<bool> "
6200  << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n";
6201  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks=<bool> "
6202  << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n";
6203  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip=<bool> "
6204  << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n";
6205  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line=<bool> "
6206  << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n";
6207  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames=<bool> "
6208  << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n";
6209  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "spp, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "skip-path-prefixes=<p1:p2> "
6210  << Whitespace(sizePrefixDisplay*1) << "whenever file paths start with this prefix, remove it from the output\n";
6211  s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers=<bool> "
6212  << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n";
6213  // ================================================================================== << 79
6214  // clang-format on
6215 
6216  s << Color::Cyan << "\n[doctest] " << Color::None;
6217  s << "for more information visit the project documentation\n\n";
6218  }
6219 
6220  void printRegisteredReporters() {
6221  printVersion();
6222  auto printReporters = [this] (const reporterMap& reporters, const char* type) {
6223  if(reporters.size()) {
6224  s << Color::Cyan << "[doctest] " << Color::None << "listing all registered " << type << "\n";
6225  for(auto& curr : reporters)
6226  s << "priority: " << std::setw(5) << curr.first.first
6227  << " name: " << curr.first.second << "\n";
6228  }
6229  };
6230  printReporters(getListeners(), "listeners");
6231  printReporters(getReporters(), "reporters");
6232  }
6233 
6234  // =========================================================================================
6235  // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
6236  // =========================================================================================
6237 
6238  void report_query(const QueryData& in) override {
6239  if(opt.version) {
6240  printVersion();
6241  } else if(opt.help) {
6242  printHelp();
6243  } else if(opt.list_reporters) {
6244  printRegisteredReporters();
6245  } else if(opt.count || opt.list_test_cases) {
6246  if(opt.list_test_cases) {
6247  s << Color::Cyan << "[doctest] " << Color::None
6248  << "listing all test case names\n";
6249  separator_to_stream();
6250  }
6251 
6252  for(unsigned i = 0; i < in.num_data; ++i)
6253  s << Color::None << in.data[i]->m_name << "\n";
6254 
6255  separator_to_stream();
6256 
6257  s << Color::Cyan << "[doctest] " << Color::None
6258  << "unskipped test cases passing the current filters: "
6259  << g_cs->numTestCasesPassingFilters << "\n";
6260 
6261  } else if(opt.list_test_suites) {
6262  s << Color::Cyan << "[doctest] " << Color::None << "listing all test suites\n";
6263  separator_to_stream();
6264 
6265  for(unsigned i = 0; i < in.num_data; ++i)
6266  s << Color::None << in.data[i]->m_test_suite << "\n";
6267 
6268  separator_to_stream();
6269 
6270  s << Color::Cyan << "[doctest] " << Color::None
6271  << "unskipped test cases passing the current filters: "
6272  << g_cs->numTestCasesPassingFilters << "\n";
6273  s << Color::Cyan << "[doctest] " << Color::None
6274  << "test suites with unskipped test cases passing the current filters: "
6275  << g_cs->numTestSuitesPassingFilters << "\n";
6276  }
6277  }
6278 
6279  void test_run_start() override {
6280  if(!opt.minimal)
6281  printIntro();
6282  }
6283 
6284  void test_run_end(const TestRunStats& p) override {
6285  if(opt.minimal && p.numTestCasesFailed == 0)
6286  return;
6287 
6288  separator_to_stream();
6289  s << std::dec;
6290 
6291  auto totwidth = int(std::ceil(log10(static_cast<double>(std::max(p.numTestCasesPassingFilters, static_cast<unsigned>(p.numAsserts))) + 1)));
6292  auto passwidth = int(std::ceil(log10(static_cast<double>(std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));
6293  auto failwidth = int(std::ceil(log10(static_cast<double>(std::max(p.numTestCasesFailed, static_cast<unsigned>(p.numAssertsFailed))) + 1)));
6294  const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
6295  s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth)
6296  << p.numTestCasesPassingFilters << " | "
6297  << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :
6298  Color::Green)
6299  << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed"
6300  << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None)
6301  << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |";
6302  if(opt.no_skipped_summary == false) {
6303  const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;
6304  s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped
6305  << " skipped" << Color::None;
6306  }
6307  s << "\n";
6308  s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth)
6309  << p.numAsserts << " | "
6310  << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green)
6311  << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
6312  << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)
6313  << p.numAssertsFailed << " failed" << Color::None << " |\n";
6314  s << Color::Cyan << "[doctest] " << Color::None
6315  << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
6316  << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None << std::endl;
6317  }
6318 
6319  void test_case_start(const TestCaseData& in) override {
6320  hasLoggedCurrentTestStart = false;
6321  tc = &in;
6322  subcasesStack.clear();
6323  currentSubcaseLevel = 0;
6324  }
6325 
6326  void test_case_reenter(const TestCaseData&) override {
6327  subcasesStack.clear();
6328  }
6329 
6330  void test_case_end(const CurrentTestCaseStats& st) override {
6331  if(tc->m_no_output)
6332  return;
6333 
6334  // log the preamble of the test case only if there is something
6335  // else to print - something other than that an assert has failed
6336  if(opt.duration ||
6337  (st.failure_flags && st.failure_flags != static_cast<int>(TestCaseFailureReason::AssertFailure)))
6338  logTestStart();
6339 
6340  if(opt.duration)
6341  s << Color::None << std::setprecision(6) << std::fixed << st.seconds
6342  << " s: " << tc->m_name << "\n";
6343 
6344  if(st.failure_flags & TestCaseFailureReason::Timeout)
6345  s << Color::Red << "Test case exceeded time limit of " << std::setprecision(6)
6346  << std::fixed << tc->m_timeout << "!\n";
6347 
6348  if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) {
6349  s << Color::Red << "Should have failed but didn't! Marking it as failed!\n";
6350  } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) {
6351  s << Color::Yellow << "Failed as expected so marking it as not failed\n";
6352  } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) {
6353  s << Color::Yellow << "Allowed to fail so marking it as not failed\n";
6354  } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) {
6355  s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures
6356  << " times so marking it as failed!\n";
6357  } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) {
6358  s << Color::Yellow << "Failed exactly " << tc->m_expected_failures
6359  << " times as expected so marking it as not failed!\n";
6360  }
6361  if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) {
6362  s << Color::Red << "Aborting - too many failed asserts!\n";
6363  }
6364  s << Color::None; // lgtm [cpp/useless-expression]
6365  }
6366 
6367  void test_case_exception(const TestCaseException& e) override {
6368  DOCTEST_LOCK_MUTEX(mutex)
6369  if(tc->m_no_output)
6370  return;
6371 
6372  logTestStart();
6373 
6374  file_line_to_stream(tc->m_file.c_str(), tc->m_line, " ");
6375  successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require :
6377  s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ")
6378  << Color::Cyan << e.error_string << "\n";
6379 
6380  int num_stringified_contexts = get_num_stringified_contexts();
6381  if(num_stringified_contexts) {
6382  auto stringified_contexts = get_stringified_contexts();
6383  s << Color::None << " logged: ";
6384  for(int i = num_stringified_contexts; i > 0; --i) {
6385  s << (i == num_stringified_contexts ? "" : " ")
6386  << stringified_contexts[i - 1] << "\n";
6387  }
6388  }
6389  s << "\n" << Color::None;
6390  }
6391 
6392  void subcase_start(const SubcaseSignature& subc) override {
6393  subcasesStack.push_back(subc);
6394  ++currentSubcaseLevel;
6395  hasLoggedCurrentTestStart = false;
6396  }
6397 
6398  void subcase_end() override {
6399  --currentSubcaseLevel;
6400  hasLoggedCurrentTestStart = false;
6401  }
6402 
6403  void log_assert(const AssertData& rb) override {
6404  if((!rb.m_failed && !opt.success) || tc->m_no_output)
6405  return;
6406 
6407  DOCTEST_LOCK_MUTEX(mutex)
6408 
6409  logTestStart();
6410 
6411  file_line_to_stream(rb.m_file, rb.m_line, " ");
6412  successOrFailColoredStringToStream(!rb.m_failed, rb.m_at);
6413 
6414  fulltext_log_assert_to_stream(s, rb);
6415 
6416  log_contexts();
6417  }
6418 
6419  void log_message(const MessageData& mb) override {
6420  if(tc->m_no_output)
6421  return;
6422 
6423  DOCTEST_LOCK_MUTEX(mutex)
6424 
6425  logTestStart();
6426 
6427  file_line_to_stream(mb.m_file, mb.m_line, " ");
6428  s << getSuccessOrFailColor(false, mb.m_severity)
6429  << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,
6430  "MESSAGE") << ": ";
6431  s << Color::None << mb.m_string << "\n";
6432  log_contexts();
6433  }
6434 
6435  void test_case_skipped(const TestCaseData&) override {}
6436  };
6437 
6438  DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter);
6439 
6440 #ifdef DOCTEST_PLATFORM_WINDOWS
6441  struct DebugOutputWindowReporter : public ConsoleReporter
6442  {
6443  DOCTEST_THREAD_LOCAL static std::ostringstream oss;
6444 
6445  DebugOutputWindowReporter(const ContextOptions& co)
6446  : ConsoleReporter(co, oss) {}
6447 
6448 #define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \
6449  void func(type arg) override { \
6450  bool with_col = g_no_colors; \
6451  g_no_colors = false; \
6452  ConsoleReporter::func(arg); \
6453  if(oss.tellp() != std::streampos{}) { \
6454  DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
6455  oss.str(""); \
6456  } \
6457  g_no_colors = with_col; \
6458  }
6459 
6460  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY)
6461  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in)
6462  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in)
6463  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, const TestCaseData&, in)
6464  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in)
6465  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in)
6466  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in)
6467  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY)
6468  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in)
6469  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in)
6470  DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in)
6471  };
6472 
6473  DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss;
6474 #endif // DOCTEST_PLATFORM_WINDOWS
6475 
6476  // the implementation of parseOption()
6477  bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String* value) {
6478  // going from the end to the beginning and stopping on the first occurrence from the end
6479  for(int i = argc; i > 0; --i) {
6480  auto index = i - 1;
6481  auto temp = std::strstr(argv[index], pattern);
6482  if(temp && (value || strlen(temp) == strlen(pattern))) {
6483  // eliminate matches in which the chars before the option are not '-'
6484  bool noBadCharsFound = true;
6485  auto curr = argv[index];
6486  while(curr != temp) {
6487  if(*curr++ != '-') {
6488  noBadCharsFound = false;
6489  break;
6490  }
6491  }
6492  if(noBadCharsFound && argv[index][0] == '-') {
6493  if(value) {
6494  // parsing the value of an option
6495  temp += strlen(pattern);
6496  const unsigned len = strlen(temp);
6497  if(len) {
6498  *value = temp;
6499  return true;
6500  }
6501  } else {
6502  // just a flag - no value
6503  return true;
6504  }
6505  }
6506  }
6507  }
6508  return false;
6509  }
6510 
6511  // parses an option and returns the string after the '=' character
6512  bool parseOption(int argc, const char* const* argv, const char* pattern, String* value = nullptr,
6513  const String& defaultVal = String()) {
6514  if(value)
6515  *value = defaultVal;
6516 #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
6517  // offset (normally 3 for "dt-") to skip prefix
6518  if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value))
6519  return true;
6520 #endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
6521  return parseOptionImpl(argc, argv, pattern, value);
6522  }
6523 
6524  // locates a flag on the command line
6525  bool parseFlag(int argc, const char* const* argv, const char* pattern) {
6526  return parseOption(argc, argv, pattern);
6527  }
6528 
6529  // parses a comma separated list of words after a pattern in one of the arguments in argv
6530  bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern,
6531  std::vector<String>& res) {
6532  String filtersString;
6533  if(parseOption(argc, argv, pattern, &filtersString)) {
6534  // tokenize with "," as a separator, unless escaped with backslash
6535  std::ostringstream s;
6536  auto flush = [&s, &res]() {
6537  auto string = s.str();
6538  if(string.size() > 0) {
6539  res.push_back(string.c_str());
6540  }
6541  s.str("");
6542  };
6543 
6544  bool seenBackslash = false;
6545  const char* current = filtersString.c_str();
6546  const char* end = current + strlen(current);
6547  while(current != end) {
6548  char character = *current++;
6549  if(seenBackslash) {
6550  seenBackslash = false;
6551  if(character == ',' || character == '\\') {
6552  s.put(character);
6553  continue;
6554  }
6555  s.put('\\');
6556  }
6557  if(character == '\\') {
6558  seenBackslash = true;
6559  } else if(character == ',') {
6560  flush();
6561  } else {
6562  s.put(character);
6563  }
6564  }
6565 
6566  if(seenBackslash) {
6567  s.put('\\');
6568  }
6569  flush();
6570  return true;
6571  }
6572  return false;
6573  }
6574 
6575  enum optionType
6576  {
6577  option_bool,
6578  option_int
6579  };
6580 
6581  // parses an int/bool option from the command line
6582  bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type,
6583  int& res) {
6584  String parsedValue;
6585  if(!parseOption(argc, argv, pattern, &parsedValue))
6586  return false;
6587 
6588  if(type) {
6589  // integer
6590  // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse...
6591  int theInt = std::atoi(parsedValue.c_str());
6592  if (theInt != 0) {
6593  res = theInt;
6594  return true;
6595  }
6596  } else {
6597  // boolean
6598  const char positive[][5] = { "1", "true", "on", "yes" }; // 5 - strlen("true") + 1
6599  const char negative[][6] = { "0", "false", "off", "no" }; // 6 - strlen("false") + 1
6600 
6601  // if the value matches any of the positive/negative possibilities
6602  for (unsigned i = 0; i < 4; i++) {
6603  if (parsedValue.compare(positive[i], true) == 0) {
6604  res = 1;
6605  return true;
6606  }
6607  if (parsedValue.compare(negative[i], true) == 0) {
6608  res = 0;
6609  return true;
6610  }
6611  }
6612  }
6613  return false;
6614  }
6615 } // namespace
6616 
6617 Context::Context(int argc, const char* const* argv)
6618  : p(new detail::ContextState) {
6619  parseArgs(argc, argv, true);
6620  if(argc)
6621  p->binary_name = argv[0];
6622 }
6623 
6624 Context::~Context() {
6625  if(g_cs == p)
6626  g_cs = nullptr;
6627  delete p;
6628 }
6629 
6630 void Context::applyCommandLine(int argc, const char* const* argv) {
6631  parseArgs(argc, argv);
6632  if(argc)
6633  p->binary_name = argv[0];
6634 }
6635 
6636 // parses args
6637 void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
6638  using namespace detail;
6639 
6640  // clang-format off
6641  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]);
6642  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]);
6643  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]);
6644  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]);
6645  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]);
6646  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]);
6647  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]);
6648  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]);
6649  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]);
6650  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]);
6651  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]);
6652  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]);
6653  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]);
6654  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]);
6655  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]);
6656  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]);
6657  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]);
6658  parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]);
6659  // clang-format on
6660 
6661  int intRes = 0;
6662  String strRes;
6663 
6664 #define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
6665  if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \
6666  parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \
6667  p->var = static_cast<bool>(intRes); \
6668  else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \
6669  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \
6670  p->var = true; \
6671  else if(withDefaults) \
6672  p->var = default
6673 
6674 #define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \
6675  if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \
6676  parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \
6677  p->var = intRes; \
6678  else if(withDefaults) \
6679  p->var = default
6680 
6681 #define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \
6682  if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", &strRes, default) || \
6683  parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", &strRes, default) || \
6684  withDefaults) \
6685  p->var = strRes
6686 
6687  // clang-format off
6688  DOCTEST_PARSE_STR_OPTION("out", "o", out, "");
6689  DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file");
6690  DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0);
6691 
6692  DOCTEST_PARSE_INT_OPTION("first", "f", first, 0);
6693  DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX);
6694 
6695  DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0);
6696  DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX);
6697 
6698  DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false);
6699  DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false);
6700  DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false);
6701  DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false);
6702  DOCTEST_PARSE_AS_BOOL_OR_FLAG("minimal", "m", minimal, false);
6703  DOCTEST_PARSE_AS_BOOL_OR_FLAG("quiet", "q", quiet, false);
6704  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false);
6705  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false);
6706  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false);
6707  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-intro", "ni", no_intro, false);
6708  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false);
6709  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false);
6710  DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false);
6711  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false);
6712  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false);
6713  DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC));
6714  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false);
6715  DOCTEST_PARSE_STR_OPTION("strip-file-prefixes", "sfp", strip_file_prefixes, "");
6716  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false);
6717  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false);
6718  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false);
6719  DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false);
6720  // clang-format on
6721 
6722  if(withDefaults) {
6723  p->help = false;
6724  p->version = false;
6725  p->count = false;
6726  p->list_test_cases = false;
6727  p->list_test_suites = false;
6728  p->list_reporters = false;
6729  }
6730  if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") ||
6731  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") ||
6732  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) {
6733  p->help = true;
6734  p->exit = true;
6735  }
6736  if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") ||
6737  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) {
6738  p->version = true;
6739  p->exit = true;
6740  }
6741  if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") ||
6742  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) {
6743  p->count = true;
6744  p->exit = true;
6745  }
6746  if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") ||
6747  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) {
6748  p->list_test_cases = true;
6749  p->exit = true;
6750  }
6751  if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") ||
6752  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) {
6753  p->list_test_suites = true;
6754  p->exit = true;
6755  }
6756  if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") ||
6757  parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) {
6758  p->list_reporters = true;
6759  p->exit = true;
6760  }
6761 }
6762 
6763 // allows the user to add procedurally to the filters from the command line
6764 void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); }
6765 
6766 // allows the user to clear all filters from the command line
6767 void Context::clearFilters() {
6768  for(auto& curr : p->filters)
6769  curr.clear();
6770 }
6771 
6772 // allows the user to override procedurally the bool options from the command line
6773 void Context::setOption(const char* option, bool value) {
6774  setOption(option, value ? "true" : "false");
6775 }
6776 
6777 // allows the user to override procedurally the int options from the command line
6778 void Context::setOption(const char* option, int value) {
6779  setOption(option, toString(value).c_str());
6780 }
6781 
6782 // allows the user to override procedurally the string options from the command line
6783 void Context::setOption(const char* option, const char* value) {
6784  auto argv = String("-") + option + "=" + value;
6785  auto lvalue = argv.c_str();
6786  parseArgs(1, &lvalue);
6787 }
6788 
6789 // users should query this in their main() and exit the program if true
6790 bool Context::shouldExit() { return p->exit; }
6791 
6792 void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; }
6793 
6794 void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; }
6795 
6796 void Context::setCout(std::ostream* out) { p->cout = out; }
6797 
6798 static class DiscardOStream : public std::ostream
6799 {
6800 private:
6801  class : public std::streambuf
6802  {
6803  private:
6804  // allowing some buffering decreases the amount of calls to overflow
6805  char buf[1024];
6806 
6807  protected:
6808  std::streamsize xsputn(const char_type*, std::streamsize count) override { return count; }
6809 
6810  int_type overflow(int_type ch) override {
6811  setp(std::begin(buf), std::end(buf));
6812  return traits_type::not_eof(ch);
6813  }
6814  } discardBuf;
6815 
6816 public:
6817  DiscardOStream()
6818  : std::ostream(&discardBuf) {}
6819 } discardOut;
6820 
6821 // the main function that does all the filtering and test running
6822 int Context::run() {
6823  using namespace detail;
6824 
6825  // save the old context state in case such was setup - for using asserts out of a testing context
6826  auto old_cs = g_cs;
6827  // this is the current contest
6828  g_cs = p;
6829  is_running_in_test = true;
6830 
6831  g_no_colors = p->no_colors;
6832  p->resetRunData();
6833 
6834  std::fstream fstr;
6835  if(p->cout == nullptr) {
6836  if(p->quiet) {
6837  p->cout = &discardOut;
6838  } else if(p->out.size()) {
6839  // to a file if specified
6840  fstr.open(p->out.c_str(), std::fstream::out);
6841  p->cout = &fstr;
6842  } else {
6843 #ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
6844  // stdout by default
6845  p->cout = &std::cout;
6846 #else // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
6847  return EXIT_FAILURE;
6848 #endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
6849  }
6850  }
6851 
6852  FatalConditionHandler::allocateAltStackMem();
6853 
6854  auto cleanup_and_return = [&]() {
6855  FatalConditionHandler::freeAltStackMem();
6856 
6857  if(fstr.is_open())
6858  fstr.close();
6859 
6860  // restore context
6861  g_cs = old_cs;
6862  is_running_in_test = false;
6863 
6864  // we have to free the reporters which were allocated when the run started
6865  for(auto& curr : p->reporters_currently_used)
6866  delete curr;
6867  p->reporters_currently_used.clear();
6868 
6869  if(p->numTestCasesFailed && !p->no_exitcode)
6870  return EXIT_FAILURE;
6871  return EXIT_SUCCESS;
6872  };
6873 
6874  // setup default reporter if none is given through the command line
6875  if(p->filters[8].empty())
6876  p->filters[8].push_back("console");
6877 
6878  // check to see if any of the registered reporters has been selected
6879  for(auto& curr : getReporters()) {
6880  if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive))
6881  p->reporters_currently_used.push_back(curr.second(*g_cs));
6882  }
6883 
6884  // TODO: check if there is nothing in reporters_currently_used
6885 
6886  // prepend all listeners
6887  for(auto& curr : getListeners())
6888  p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
6889 
6890 #ifdef DOCTEST_PLATFORM_WINDOWS
6891  if(isDebuggerActive() && p->no_debug_output == false)
6892  p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));
6893 #endif // DOCTEST_PLATFORM_WINDOWS
6894 
6895  // handle version, help and no_run
6896  if(p->no_run || p->version || p->help || p->list_reporters) {
6897  DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData());
6898 
6899  return cleanup_and_return();
6900  }
6901 
6902  std::vector<const TestCase*> testArray;
6903  for(auto& curr : getRegisteredTests())
6904  testArray.push_back(&curr);
6905  p->numTestCases = testArray.size();
6906 
6907  // sort the collected records
6908  if(!testArray.empty()) {
6909  if(p->order_by.compare("file", true) == 0) {
6910  std::sort(testArray.begin(), testArray.end(), fileOrderComparator);
6911  } else if(p->order_by.compare("suite", true) == 0) {
6912  std::sort(testArray.begin(), testArray.end(), suiteOrderComparator);
6913  } else if(p->order_by.compare("name", true) == 0) {
6914  std::sort(testArray.begin(), testArray.end(), nameOrderComparator);
6915  } else if(p->order_by.compare("rand", true) == 0) {
6916  std::srand(p->rand_seed);
6917 
6918  // random_shuffle implementation
6919  const auto first = &testArray[0];
6920  for(size_t i = testArray.size() - 1; i > 0; --i) {
6921  int idxToSwap = std::rand() % (i + 1);
6922 
6923  const auto temp = first[i];
6924 
6925  first[i] = first[idxToSwap];
6926  first[idxToSwap] = temp;
6927  }
6928  } else if(p->order_by.compare("none", true) == 0) {
6929  // means no sorting - beneficial for death tests which call into the executable
6930  // with a specific test case in mind - we don't want to slow down the startup times
6931  }
6932  }
6933 
6934  std::set<String> testSuitesPassingFilt;
6935 
6936  bool query_mode = p->count || p->list_test_cases || p->list_test_suites;
6937  std::vector<const TestCaseData*> queryResults;
6938 
6939  if(!query_mode)
6940  DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY);
6941 
6942  // invoke the registered functions if they match the filter criteria (or just count them)
6943  for(auto& curr : testArray) {
6944  const auto& tc = *curr;
6945 
6946  bool skip_me = false;
6947  if(tc.m_skip && !p->no_skip)
6948  skip_me = true;
6949 
6950  if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive))
6951  skip_me = true;
6952  if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive))
6953  skip_me = true;
6954  if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive))
6955  skip_me = true;
6956  if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive))
6957  skip_me = true;
6958  if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive))
6959  skip_me = true;
6960  if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive))
6961  skip_me = true;
6962 
6963  if(!skip_me)
6964  p->numTestCasesPassingFilters++;
6965 
6966  // skip the test if it is not in the execution range
6967  if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) ||
6968  (p->first > p->numTestCasesPassingFilters))
6969  skip_me = true;
6970 
6971  if(skip_me) {
6972  if(!query_mode)
6973  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc);
6974  continue;
6975  }
6976 
6977  // do not execute the test if we are to only count the number of filter passing tests
6978  if(p->count)
6979  continue;
6980 
6981  // print the name of the test and don't execute it
6982  if(p->list_test_cases) {
6983  queryResults.push_back(&tc);
6984  continue;
6985  }
6986 
6987  // print the name of the test suite if not done already and don't execute it
6988  if(p->list_test_suites) {
6989  if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') {
6990  queryResults.push_back(&tc);
6991  testSuitesPassingFilt.insert(tc.m_test_suite);
6992  p->numTestSuitesPassingFilters++;
6993  }
6994  continue;
6995  }
6996 
6997  // execute the test if it passes all the filtering
6998  {
6999  p->currentTest = &tc;
7000 
7001  p->failure_flags = TestCaseFailureReason::None;
7002  p->seconds = 0;
7003 
7004  // reset atomic counters
7005  p->numAssertsFailedCurrentTest_atomic = 0;
7006  p->numAssertsCurrentTest_atomic = 0;
7007 
7008  p->fullyTraversedSubcases.clear();
7009 
7010  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc);
7011 
7012  p->timer.start();
7013 
7014  bool run_test = true;
7015 
7016  do {
7017  // reset some of the fields for subcases (except for the set of fully passed ones)
7018  p->reachedLeaf = false;
7019  // May not be empty if previous subcase exited via exception.
7020  p->subcaseStack.clear();
7021  p->currentSubcaseDepth = 0;
7022 
7023  p->shouldLogCurrentException = true;
7024 
7025  // reset stuff for logging with INFO()
7026  p->stringifiedContexts.clear();
7027 
7028 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
7029  try {
7030 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
7031 // MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method)
7032 DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable
7033  FatalConditionHandler fatalConditionHandler; // Handle signals
7034  // execute the test
7035  tc.m_test();
7036  fatalConditionHandler.reset();
7038 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
7039  } catch(const TestFailureException&) {
7040  p->failure_flags |= TestCaseFailureReason::AssertFailure;
7041  } catch(...) {
7042  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception,
7043  {translateActiveException(), false});
7044  p->failure_flags |= TestCaseFailureReason::Exception;
7045  }
7046 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
7047 
7048  // exit this loop if enough assertions have failed - even if there are more subcases
7049  if(p->abort_after > 0 &&
7050  p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) {
7051  run_test = false;
7052  p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts;
7053  }
7054 
7055  if(!p->nextSubcaseStack.empty() && run_test)
7056  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc);
7057  if(p->nextSubcaseStack.empty())
7058  run_test = false;
7059  } while(run_test);
7060 
7061  p->finalizeTestCaseData();
7062 
7063  DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
7064 
7065  p->currentTest = nullptr;
7066 
7067  // stop executing tests if enough assertions have failed
7068  if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after)
7069  break;
7070  }
7071  }
7072 
7073  if(!query_mode) {
7074  DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
7075  } else {
7076  QueryData qdata;
7077  qdata.run_stats = g_cs;
7078  qdata.data = queryResults.data();
7079  qdata.num_data = unsigned(queryResults.size());
7080  DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata);
7081  }
7082 
7083  return cleanup_and_return();
7084 }
7085 
7086 DOCTEST_DEFINE_INTERFACE(IReporter)
7087 
7088 int IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); }
7089 const IContextScope* const* IReporter::get_active_contexts() {
7090  return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr;
7091 }
7092 
7093 int IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); }
7094 const String* IReporter::get_stringified_contexts() {
7095  return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr;
7096 }
7097 
7098 namespace detail {
7099  void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c, bool isReporter) {
7100  if(isReporter)
7101  getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));
7102  else
7103  getListeners().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));
7104  }
7105 } // namespace detail
7106 
7107 } // namespace doctest
7108 
7109 #endif // DOCTEST_CONFIG_DISABLE
7110 
7111 #ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
7112 DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182
7113 int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
7115 #endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
7116 
7120 
7122 
7123 #endif // DOCTEST_LIBRARY_IMPLEMENTATION
7124 #endif // DOCTEST_CONFIG_IMPLEMENT
7125 
7126 #ifdef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
7127 #undef WIN32_LEAN_AND_MEAN
7128 #undef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
7129 #endif // DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN
7130 
7131 #ifdef DOCTEST_UNDEF_NOMINMAX
7132 #undef NOMINMAX
7133 #undef DOCTEST_UNDEF_NOMINMAX
7134 #endif // DOCTEST_UNDEF_NOMINMAX
Definition: doctest.h:845
Contains content
Definition: doctest.h:847
StringContains(const String &str)
Definition: doctest.h:851
bool isContains
Definition: doctest.h:848
StringContains(Contains cntn)
Definition: doctest.h:852
const char * c_str() const
Definition: doctest.h:858
bool check(const String &str)
Definition: doctest.h:854
Definition: doctest.h:674
bool checkWith(const String &other) const
String string
Definition: doctest.h:680
Contains(const String &string)
Definition: doctest.h:1966
Context & operator=(const Context &)=delete
Context(const Context &)=delete
detail::ContextState * p
Definition: doctest.h:1967
Context(Context &&)=delete
void setOption(const char *option, const char *value)
void setCout(std::ostream *out)
void addFilter(const char *filter, const char *value)
void setAssertHandler(detail::assert_handler ah)
void setOption(const char *option, bool value)
Context(int argc=0, const char *const *argv=nullptr)
void parseArgs(int argc, const char *const *argv, bool withDefaults=false)
void setOption(const char *option, int value)
Context & operator=(Context &&)=delete
void applyCommandLine(int argc, const char *const *argv)
void setAsDefaultForAssertsOutOfTestCases()
Definition: doctest.h:588
char operator[](size_type i) const
size_type capacity() const
String & operator=(const String &other)
char * c_str()
Definition: doctest.h:643
bool isOnStack() const noexcept
Definition: doctest.h:611
view data
Definition: doctest.h:606
const char * c_str() const
Definition: doctest.h:642
void setLast(size_type in=last) noexcept
size_type rfind(char ch, size_type pos=npos) const
char * allocate(size_type sz)
String substr(size_type pos, size_type cnt=npos) &&
void setSize(size_type sz) noexcept
friend std::ostream & operator<<(std::ostream &s, const String &in)
void copy(const String &other)
size_type find(char ch, size_type pos=0) const
String() noexcept
size_type size() const
String substr(size_type pos, size_type cnt=npos) const &
String & operator+=(const String &other)
int compare(const String &other, bool no_case=false) const
void setOnHeap() noexcept
int compare(const char *other, bool no_case=false) const
unsigned size_type
Definition: doctest.h:590
Definition: doctest.h:1848
~ContextScope() override
Definition: doctest.h:1863
ContextScope(const L &lambda)
Definition: doctest.h:1852
ContextScope(const ContextScope &)=delete
ContextScope(ContextScope &&) noexcept=default
L lambda_
Definition: doctest.h:1849
ContextScope(L &&lambda)
Definition: doctest.h:1853
OCLINT destructor of virtual class.
Definition: doctest.h:1804
ExceptionTranslator(String(*translateFunction)(T))
Definition: doctest.h:1806
bool translate(String &res) const override
Definition: doctest.h:1809
Definition: doctest.h:536
Definition: doctest.h:530
Definition: doctest.h:539
#define DOCTEST_FORBIT_EXPRESSION(rt, op)
Definition: doctest.h:1388
#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH)
Definition: doctest.h:77
#define DOCTEST_NOEXCEPT
Definition: doctest.h:381
#define DOCTEST_STRINGIFY(...)
Definition: doctest.h:1089
#define DOCTEST_BREAK_INTO_DEBUGGER()
Definition: doctest.h:463
#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
Definition: doctest.h:153
#define DOCTEST_GCC
Definition: doctest.h:105
#define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP
Definition: doctest.h:209
#define DOCTEST_VERSION_STR
Definition: doctest.h:57
#define DOCTEST_RELATIONAL_OP(name, op)
Definition: doctest.h:1468
#define DOCTEST_CMP_LE(l, r)
Definition: doctest.h:1488
#define DOCTEST_GCC_SUPPRESS_WARNING(w)
Definition: doctest.h:138
#define DOCTEST_INTERFACE_DECL
Definition: doctest.h:343
#define DOCTEST_NOINLINE
Definition: doctest.h:358
#define DOCTEST_CMP_NE(l, r)
Definition: doctest.h:1484
#define DOCTEST_DEFINE_INTERFACE(name)
Definition: doctest.h:415
#define DOCTEST_NORETURN
Definition: doctest.h:373
#define DOCTEST_MSVC_SUPPRESS_WARNING_POP
Definition: doctest.h:152
#define DOCTEST_CLANG_SUPPRESS_WARNING_POP
Definition: doctest.h:125
#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
Definition: doctest.h:123
#define DOCTEST_GCC_SUPPRESS_WARNING_POP
Definition: doctest.h:139
#define DOCTEST_CMP_GT(l, r)
Definition: doctest.h:1485
#define DOCTEST_BINARY_RELATIONAL_OP(n, op)
Definition: doctest.h:1671
#define DOCTEST_DEFINE_DECORATOR(name, type, def)
Definition: doctest.h:1915
#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
Definition: doctest.h:137
#define CHECK(...)
Definition: doctest.h:2970
#define DOCTEST_CMP_GE(l, r)
Definition: doctest.h:1487
#define WARN(...)
Definition: doctest.h:2963
#define DOCTEST_ASSERT_IN_TESTS(decomp)
Definition: doctest.h:1754
#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro)
Definition: doctest.h:1374
#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
Definition: doctest.h:140
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
Definition: doctest.h:2332
#define DOCTEST_INTERFACE
Definition: doctest.h:334
#define DOCTEST_CONFIG_STRING_SIZE_TYPE
Definition: doctest.h:565
#define DOCTEST_DECLARE_INTERFACE(name)
Definition: doctest.h:407
#define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH
Definition: doctest.h:162
#define DOCTEST_TEST_SUITE_END
Definition: doctest.h:2315
#define DOCTEST_EMPTY
Definition: doctest.h:347
#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp)
Definition: doctest.h:1737
#define DOCTEST_CONSTEXPR
Definition: doctest.h:390
#define DOCTEST_NO_SANITIZE_INTEGER
Definition: doctest.h:399
#define DOCTEST_CLANG_SUPPRESS_WARNING(w)
Definition: doctest.h:124
#define DOCTEST_MSVC
Definition: doctest.h:99
#define DOCTEST_MSVC_SUPPRESS_WARNING(w)
Definition: doctest.h:151
#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
Definition: doctest.h:249
#define DOCTEST_CMP_LT(l, r)
Definition: doctest.h:1486
#define DOCTEST_INTERFACE_DEF
Definition: doctest.h:344
#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
Definition: doctest.h:228
#define REQUIRE(...)
Definition: doctest.h:2977
#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
Definition: doctest.h:150
#define DOCTEST_CONSTEXPR_FUNC
Definition: doctest.h:391
#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
Definition: doctest.h:126
#define DOCTEST_REF_WRAP(x)
Definition: doctest.h:428
#define DOCTEST_CMP_EQ(l, r)
Definition: doctest.h:1483
Enum
Definition: doctest.h:692
@ BrightGreen
Definition: doctest.h:705
@ White
Definition: doctest.h:694
@ Green
Definition: doctest.h:696
@ BrightRed
Definition: doctest.h:704
@ LightGrey
Definition: doctest.h:706
@ BrightWhite
Definition: doctest.h:707
@ Yellow
Definition: doctest.h:699
@ Red
Definition: doctest.h:695
@ Bright
Definition: doctest.h:702
@ None
Definition: doctest.h:693
@ Grey
Definition: doctest.h:700
@ Blue
Definition: doctest.h:697
@ Cyan
Definition: doctest.h:698
std::ostream & operator<<(std::ostream &s, Color::Enum code)
Enum
Definition: doctest.h:2003
@ Exception
Definition: doctest.h:2006
@ AssertFailure
Definition: doctest.h:2005
@ ShouldHaveFailedAndDid
Definition: doctest.h:2011
@ ShouldHaveFailedButDidnt
Definition: doctest.h:2010
@ Crash
Definition: doctest.h:2007
@ None
Definition: doctest.h:2004
@ Timeout
Definition: doctest.h:2009
@ CouldHaveFailedAndDid
Definition: doctest.h:2014
@ DidntFailExactlyNumTimes
Definition: doctest.h:2012
@ FailedExactlyNumTimes
Definition: doctest.h:2013
@ TooManyFailedAsserts
Definition: doctest.h:2008
Enum
Definition: doctest.h:715
@ is_nothrow
Definition: doctest.h:726
@ DT_REQUIRE_UNARY
Definition: doctest.h:796
@ DT_CHECK_THROWS_WITH_AS
Definition: doctest.h:763
@ DT_REQUIRE_THROWS_AS
Definition: doctest.h:756
@ DT_CHECK_LT
Definition: doctest.h:783
@ DT_WARN_LE
Definition: doctest.h:790
@ is_gt
Definition: doctest.h:735
@ DT_REQUIRE_UNARY_FALSE
Definition: doctest.h:800
@ DT_CHECK_EQ
Definition: doctest.h:771
@ is_throws_as
Definition: doctest.h:724
@ DT_REQUIRE_NOTHROW
Definition: doctest.h:768
@ is_warn
Definition: doctest.h:718
@ is_normal
Definition: doctest.h:722
@ DT_CHECK_THROWS_AS
Definition: doctest.h:755
@ DT_REQUIRE_NE
Definition: doctest.h:776
@ is_ne
Definition: doctest.h:732
@ is_le
Definition: doctest.h:738
@ DT_CHECK
Definition: doctest.h:743
@ DT_WARN_GE
Definition: doctest.h:786
@ DT_REQUIRE_LE
Definition: doctest.h:792
@ DT_CHECK_GT
Definition: doctest.h:779
@ DT_REQUIRE_GE
Definition: doctest.h:788
@ DT_CHECK_THROWS_WITH
Definition: doctest.h:759
@ DT_CHECK_NOTHROW
Definition: doctest.h:767
@ DT_WARN_NE
Definition: doctest.h:774
@ is_false
Definition: doctest.h:728
@ DT_REQUIRE_GT
Definition: doctest.h:780
@ DT_REQUIRE_LT
Definition: doctest.h:784
@ is_eq
Definition: doctest.h:731
@ DT_WARN_FALSE
Definition: doctest.h:746
@ is_ge
Definition: doctest.h:737
@ DT_REQUIRE_THROWS_WITH
Definition: doctest.h:760
@ DT_REQUIRE
Definition: doctest.h:744
@ DT_REQUIRE_THROWS_WITH_AS
Definition: doctest.h:764
@ DT_WARN_EQ
Definition: doctest.h:770
@ is_throws
Definition: doctest.h:723
@ DT_WARN_THROWS
Definition: doctest.h:750
@ DT_REQUIRE_THROWS
Definition: doctest.h:752
@ DT_WARN_UNARY
Definition: doctest.h:794
@ is_check
Definition: doctest.h:719
@ DT_CHECK_FALSE
Definition: doctest.h:747
@ DT_REQUIRE_EQ
Definition: doctest.h:772
@ DT_WARN_NOTHROW
Definition: doctest.h:766
@ is_throws_with
Definition: doctest.h:725
@ is_lt
Definition: doctest.h:734
@ DT_CHECK_THROWS
Definition: doctest.h:751
@ DT_WARN_THROWS_WITH_AS
Definition: doctest.h:762
@ DT_WARN_UNARY_FALSE
Definition: doctest.h:798
@ DT_CHECK_NE
Definition: doctest.h:775
@ DT_CHECK_LE
Definition: doctest.h:791
@ DT_WARN_THROWS_AS
Definition: doctest.h:754
@ is_unary
Definition: doctest.h:729
@ DT_WARN_THROWS_WITH
Definition: doctest.h:758
@ DT_CHECK_UNARY
Definition: doctest.h:795
@ DT_REQUIRE_FALSE
Definition: doctest.h:748
@ DT_CHECK_UNARY_FALSE
Definition: doctest.h:799
@ DT_WARN_GT
Definition: doctest.h:778
@ DT_WARN_LT
Definition: doctest.h:782
@ DT_WARN
Definition: doctest.h:742
@ DT_CHECK_GE
Definition: doctest.h:787
@ is_require
Definition: doctest.h:720
Enum
Definition: doctest.h:1725
@ dbgbreak
Definition: doctest.h:1727
@ shouldthrow
Definition: doctest.h:1728
@ nothing
Definition: doctest.h:1726
Enum
Definition: doctest.h:1658
constexpr T && forward(typename types::remove_reference< T >::type &&t) noexcept
Definition: doctest.h:989
ContextScope< L > MakeContextScope(const L &lambda)
Definition: doctest.h:1910
void(*)() funcType
Definition: doctest.h:1613
void(*)(const AssertData &) assert_handler
Definition: doctest.h:1961
void registerReporterImpl(const char *name, int prio, reporterCreatorFunc c, bool isReporter)
bool checkIfShouldThrow(assertType::Enum at)
int setTestSuite(const TestSuite &ts)
void throwException()
IReporter * reporterCreator(const ContextOptions &o)
Definition: doctest.h:2105
bool gt(const L &lhs, const R &rhs)
Definition: doctest.h:1478
void failed_out_of_a_testing_context(const AssertData &ad)
static constexpr int consume(const int *, int) noexcept
Definition: doctest.h:447
void registerExceptionTranslatorImpl(const IExceptionTranslator *et)
bool lt(const L &lhs, const R &rhs)
Definition: doctest.h:1477
int regTest(const TestCase &tc)
void filloss(std::ostream *stream, const T(&in)[N])
Definition: doctest.h:1058
String stringifyBinaryExpr(const L &lhs, const char *op, const R &rhs)
Definition: doctest.h:1355
String toStream(const T &in)
Definition: doctest.h:1065
std::ostream * tlssPush()
bool le(const L &lhs, const R &rhs)
Definition: doctest.h:1479
int instantiationHelper(const T &)
Definition: doctest.h:1654
bool ne(const L &lhs, const R &rhs)
Definition: doctest.h:1476
bool isDebuggerActive()
bool decomp_assert(assertType::Enum at, const char *file, int line, const char *expr, const Result &result)
bool ge(const L &lhs, const R &rhs)
Definition: doctest.h:1480
IReporter *(*)(const ContextOptions &) reporterCreatorFunc
Definition: doctest.h:2100
String tlssPop()
bool eq(const L &lhs, const R &rhs)
Definition: doctest.h:1475
Definition: doctest.h:1948
doctest::detail::TestSuite & getCurrentTestSuite()
Definition: doctest.h:446
const char * failureString(assertType::Enum at)
bool operator<(const String &lhs, const String &rhs)
bool operator>(const String &lhs, const String &rhs)
String toString(const Contains &in)
bool is_running_in_test
const char * assertString(assertType::Enum at)
String toString(IsNaN< double long > in)
const char * skipPathFromFilename(const char *file)
String operator+(const String &lhs, const String &rhs)
bool operator==(const String &lhs, const String &rhs)
int registerExceptionTranslator(String(*translateFunction)(T))
Definition: doctest.h:1936
int registerReporter(const char *name, int priority, bool isReporter)
Definition: doctest.h:2111
bool operator>=(const String &lhs, const String &rhs)
const ContextOptions * getContextOptions()
bool operator!=(const String &lhs, const String &rhs)
bool operator<=(const String &lhs, const String &rhs)
Definition: doctest.h:522
basic_istream< char, char_traits< char > > istream
Definition: doctest.h:536
decltype(nullptr) typedef nullptr_t
Definition: doctest.h:523
basic_ostream< char, char_traits< char > > ostream
Definition: doctest.h:530
decltype(sizeof(void *)) typede size_t)
Definition: doctest.h:524
int main(int argc, char **argv)
Definition: neuronviewer.cpp:46
Definition: doctest.h:1211
friend bool operator==(double lhs, const Approx &rhs)
double m_epsilon
Definition: doctest.h:1282
friend bool operator!=(double lhs, const Approx &rhs)
Approx & scale(double newScale)
friend bool operator!=(const Approx &lhs, double rhs)
Approx(double value)
friend bool operator<=(const Approx &lhs, double rhs)
double m_scale
Definition: doctest.h:1283
Approx operator()(double value) const
friend bool operator<=(double lhs, const Approx &rhs)
friend bool operator==(const Approx &lhs, double rhs)
friend bool operator>=(const Approx &lhs, double rhs)
double m_value
Definition: doctest.h:1284
Approx & epsilon(double newEpsilon)
friend bool operator>=(double lhs, const Approx &rhs)
Definition: doctest.h:825
assertType::Enum m_at
Definition: doctest.h:828
int m_line
Definition: doctest.h:830
const char * m_exception_type
Definition: doctest.h:843
String m_decomp
Definition: doctest.h:839
String m_exception
Definition: doctest.h:836
bool m_threw
Definition: doctest.h:835
const TestCaseData * m_test_case
Definition: doctest.h:827
const char * m_file
Definition: doctest.h:829
bool m_failed
Definition: doctest.h:832
bool m_threw_as
Definition: doctest.h:842
AssertData(assertType::Enum at, const char *file, int line, const char *expr, const char *exception_type, const StringContains &exception_string)
const char * m_expr
Definition: doctest.h:831
OCLINT too many fields.
Definition: doctest.h:894
String binary_name
Definition: doctest.h:896
bool case_sensitive
Definition: doctest.h:912
bool version
Definition: doctest.h:935
bool duration
Definition: doctest.h:914
bool no_path_in_filenames
Definition: doctest.h:927
String strip_file_prefixes
Definition: doctest.h:928
bool quiet
Definition: doctest.h:916
bool no_intro
Definition: doctest.h:920
String order_by
Definition: doctest.h:902
bool count
Definition: doctest.h:936
bool no_skipped_summary
Definition: doctest.h:931
bool no_colors
Definition: doctest.h:922
String out
Definition: doctest.h:901
bool no_skip
Definition: doctest.h:925
bool list_test_suites
Definition: doctest.h:938
unsigned last
Definition: doctest.h:906
bool success
Definition: doctest.h:911
bool no_throw
Definition: doctest.h:917
bool no_time_in_output
Definition: doctest.h:932
bool list_test_cases
Definition: doctest.h:937
bool exit
Definition: doctest.h:913
bool no_line_numbers
Definition: doctest.h:929
int abort_after
Definition: doctest.h:908
bool minimal
Definition: doctest.h:915
bool force_colors
Definition: doctest.h:923
int subcase_filter_levels
Definition: doctest.h:909
bool help
Definition: doctest.h:934
unsigned first
Definition: doctest.h:905
bool gnu_file_line
Definition: doctest.h:926
bool no_run
Definition: doctest.h:919
unsigned rand_seed
Definition: doctest.h:903
bool list_reporters
Definition: doctest.h:939
bool no_version
Definition: doctest.h:921
bool no_exitcode
Definition: doctest.h:918
bool no_debug_output
Definition: doctest.h:930
bool no_breaks
Definition: doctest.h:924
Definition: doctest.h:2019
double seconds
Definition: doctest.h:2022
bool testCaseSuccess
Definition: doctest.h:2024
int numAssertsFailedCurrentTest
Definition: doctest.h:2021
int failure_flags
Definition: doctest.h:2023
int numAssertsCurrentTest
Definition: doctest.h:2020
Definition: doctest.h:884
Definition: doctest.h:2051
virtual void subcase_start(const SubcaseSignature &)=0
virtual void subcase_end()=0
virtual void log_message(const MessageData &)=0
virtual void test_case_exception(const TestCaseException &)=0
virtual void test_case_end(const CurrentTestCaseStats &)=0
virtual void test_case_reenter(const TestCaseData &)=0
virtual void log_assert(const AssertData &)=0
virtual void test_run_end(const TestRunStats &)=0
static const IContextScope *const * get_active_contexts()
static int get_num_active_contexts()
virtual void test_run_start()=0
virtual void test_case_skipped(const TestCaseData &)=0
static int get_num_stringified_contexts()
static const String * get_stringified_contexts()
virtual void report_query(const QueryData &)=0
virtual void test_case_start(const TestCaseData &)=0
Definition: doctest.h:1293
bool flipped
Definition: doctest.h:1294
IsNaN(F f, bool flip=false)
Definition: doctest.h:1295
IsNaN< F > operator!() const
Definition: doctest.h:1296
Definition: doctest.h:866
String m_string
Definition: doctest.h:867
assertType::Enum m_severity
Definition: doctest.h:870
int m_line
Definition: doctest.h:869
const char * m_file
Definition: doctest.h:868
Definition: doctest.h:2044
Definition: doctest.h:1083
OCLINT avoid private static members.
Definition: doctest.h:597
char * ptr
Definition: doctest.h:598
size_type capacity
Definition: doctest.h:600
size_type size
Definition: doctest.h:599
Definition: doctest.h:874
bool operator<(const SubcaseSignature &other) const
bool operator==(const SubcaseSignature &other) const
String m_name
Definition: doctest.h:875
int m_line
Definition: doctest.h:877
const char * m_file
Definition: doctest.h:876
Definition: doctest.h:809
bool m_should_fail
Definition: doctest.h:819
bool m_skip
Definition: doctest.h:815
const char * m_name
Definition: doctest.h:812
bool m_no_output
Definition: doctest.h:817
int m_expected_failures
Definition: doctest.h:820
bool m_may_fail
Definition: doctest.h:818
double m_timeout
Definition: doctest.h:821
bool m_no_breaks
Definition: doctest.h:816
unsigned m_line
Definition: doctest.h:811
const char * m_description
Definition: doctest.h:814
String m_file
Definition: doctest.h:810
const char * m_test_suite
Definition: doctest.h:813
Definition: doctest.h:2028
String error_string
Definition: doctest.h:2029
bool is_crash
Definition: doctest.h:2030
Definition: doctest.h:2034
int numAssertsFailed
Definition: doctest.h:2040
unsigned numTestCases
Definition: doctest.h:2035
int numAsserts
Definition: doctest.h:2039
unsigned numTestCasesFailed
Definition: doctest.h:2038
unsigned numTestSuitesPassingFilters
Definition: doctest.h:2037
unsigned numTestCasesPassingFilters
Definition: doctest.h:2036
Definition: doctest.h:1926
Definition: doctest.h:1831
ContextScopeBase(ContextScopeBase &&other) noexcept
ContextScopeBase & operator=(ContextScopeBase &&)=delete
~ContextScopeBase() override=default
ContextScopeBase(const ContextScopeBase &)=delete
ContextScopeBase & operator=(const ContextScopeBase &)=delete
Definition: doctest.h:1572
assertType::Enum m_at
Definition: doctest.h:1573
ExpressionDecomposer(assertType::Enum at)
Definition: doctest.h:1501
assertType::Enum m_at
Definition: doctest.h:1503
Expression_lhs(L &&in, assertType::Enum at)
Definition: doctest.h:1505
L lhs
Definition: doctest.h:1502
Definition: doctest.h:1797
Definition: doctest.h:1871
MessageBuilder & operator=(const MessageBuilder &)=delete
MessageBuilder(MessageBuilder &&)=delete
MessageBuilder & operator=(MessageBuilder &&)=delete
MessageBuilder & operator*(const T &in)
Definition: doctest.h:1903
std::ostream * m_stream
Definition: doctest.h:1872
MessageBuilder(const char *file, int line, assertType::Enum severity)
MessageBuilder & operator<<(const T &in)
Definition: doctest.h:1896
MessageBuilder(const MessageBuilder &)=delete
Definition: doctest.h:1669
bool operator()(const L &, const R &) const
Definition: doctest.h:1669
Definition: doctest.h:1683
ResultBuilder(assertType::Enum at, const char *file, int line, const char *expr, const char *exception_type="", const String &exception_string="")
void setResult(const Result &res)
ResultBuilder(assertType::Enum at, const char *file, int line, const char *expr, const char *exception_type, const Contains &exception_string)
Definition: doctest.h:1397
bool m_passed
Definition: doctest.h:1398
String m_decomp
Definition: doctest.h:1399
Result(bool passed, const String &decomposition=String())
static String convert(const T &in)
Definition: doctest.h:1074
Definition: doctest.h:1039
static String convert(const T &)
Definition: doctest.h:1041
Definition: doctest.h:1337
SubcaseSignature m_signature
Definition: doctest.h:1338
Subcase & operator=(const Subcase &)=delete
Subcase(const String &name, const char *file, int line)
Subcase(const Subcase &)=delete
Subcase(Subcase &&)=delete
Subcase & operator=(Subcase &&)=delete
Definition: doctest.h:1616
TestCase(funcType test, const char *file, unsigned line, const TestSuite &test_suite, const String &type=String(), int template_id=-1)
TestCase(const TestCase &other)
String m_full_name
Definition: doctest.h:1621
TestCase(TestCase &&)=delete
bool operator<(const TestCase &other) const
String m_type
Definition: doctest.h:1619
funcType m_test
Definition: doctest.h:1617
int m_template_id
Definition: doctest.h:1620
Definition: doctest.h:1326
Definition: doctest.h:1593
TestSuite & operator*(const T &in)
Definition: doctest.h:1607
TestSuite & operator*(const char *in)
Definition: doctest.h:994
static void fill(std::ostream *stream, const T(&in)[N])
Definition: doctest.h:1165
static void fill(std::ostream *stream, const char(&in)[N])
Definition: doctest.h:1181
static void fill(std::ostream *stream, const void *in)
Definition: doctest.h:1151
static void fill(std::ostream *stream, const T &in)
Definition: doctest.h:1152
Definition: doctest.h:1024
Definition: doctest.h:948
Definition: doctest.h:954
Definition: doctest.h:973
Definition: doctest.h:967
Definition: doctest.h:970
Definition: doctest.h:963
T type
Definition: doctest.h:963
T type
Definition: doctest.h:956
Definition: doctest.h:953
__underlying_type(T) type
Definition: doctest.h:968
Definition: doctest.h:1933
Definition: doctest.h:1931
Definition: doctest.h:1928
Definition: doctest.h:1929
Definition: doctest.h:1932
Definition: doctest.h:1927
Definition: doctest.h:1925
Definition: doctest.h:1930
Definition: doctest.h:526