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


rosbag_fancy
Author(s):
autogenerated on Tue Feb 20 2024 03:20:59