ChaiScript
catch_amalgamated.hpp
Go to the documentation of this file.
1 
2 // Copyright Catch2 Authors
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE.txt or copy at
5 // https://www.boost.org/LICENSE_1_0.txt)
6 
7 // SPDX-License-Identifier: BSL-1.0
8 
9 // Catch v3.14.0
10 // Generated: 2026-04-05 15:03:01.150393
11 // ----------------------------------------------------------
12 // This file is an amalgamation of multiple different files.
13 // You probably shouldn't edit it directly.
14 // ----------------------------------------------------------
15 
16 #if defined(min) && defined(max)
17 #undef min
18 #undef max
19 #endif
20 
21 #ifndef CATCH_AMALGAMATED_HPP_INCLUDED
22 #define CATCH_AMALGAMATED_HPP_INCLUDED
23 
38 #ifndef CATCH_ALL_HPP_INCLUDED
39 #define CATCH_ALL_HPP_INCLUDED
40 
54 #ifndef CATCH_BENCHMARK_ALL_HPP_INCLUDED
55 #define CATCH_BENCHMARK_ALL_HPP_INCLUDED
56 
57 // Adapted from donated nonius code.
58 
59 #ifndef CATCH_BENCHMARK_HPP_INCLUDED
60 #define CATCH_BENCHMARK_HPP_INCLUDED
61 
62 #ifndef CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
63 #define CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
64 
65 // Detect a number of compiler features - by compiler
66 // The following features are defined:
67 //
68 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
69 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
70 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
71 // ****************
72 // Note to maintainers: if new toggles are added please document them
73 // in configuration.md, too
74 // ****************
75 
76 // In general each macro has a _NO_<feature name> form
77 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
78 // Many features, at point of detection, define an _INTERNAL_ macro, so they
79 // can be combined, en-mass, with the _NO_ forms later.
80 
81 #ifndef CATCH_PLATFORM_HPP_INCLUDED
82 #define CATCH_PLATFORM_HPP_INCLUDED
83 
84 // See e.g.:
85 // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
86 #ifdef __APPLE__
87 #ifndef __has_extension
88 #define __has_extension(x) 0
89 #endif
90 #include <TargetConditionals.h>
91 #if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
92 #define CATCH_PLATFORM_MAC
93 #elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
94 #define CATCH_PLATFORM_IPHONE
95 #endif
96 
97 #elif defined(linux) || defined(__linux) || defined(__linux__)
98 #define CATCH_PLATFORM_LINUX
99 
100 #elif defined(__QNX__)
101 #define CATCH_PLATFORM_QNX
102 
103 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
104 #define CATCH_PLATFORM_WINDOWS
105 
106 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
107 #define CATCH_PLATFORM_WINDOWS_UWP
108 #endif
109 
110 #elif defined(__ORBIS__) || defined(__PROSPERO__)
111 #define CATCH_PLATFORM_PLAYSTATION
112 
113 #endif
114 
115 #endif // CATCH_PLATFORM_HPP_INCLUDED
116 
117 #ifdef __cplusplus
118 
119 #if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
120 #define CATCH_CPP17_OR_GREATER
121 #endif
122 
123 #if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
124 #define CATCH_CPP20_OR_GREATER
125 #endif
126 
127 #endif
128 
129 // Only GCC compiler should be used in this block, so other compilers trying to
130 // mask themselves as GCC should be ignored.
131 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) && !defined(__NVCOMPILER)
132 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic push")
133 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic pop")
134 
135 // This only works on GCC 9+. so we have to also add a global suppression of Wparentheses
136 // for older versions of GCC.
137 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
138  _Pragma("GCC diagnostic ignored \"-Wparentheses\"")
139 
140 #define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
141  _Pragma("GCC diagnostic ignored \"-Wunused-result\"")
142 
143 #define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
144  _Pragma("GCC diagnostic ignored \"-Wunused-variable\"")
145 
146 #define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
147  _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"")
148 
149 #define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
150  _Pragma("GCC diagnostic ignored \"-Wshadow\"")
151 
152 #define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P
153 
154 #endif
155 
156 #if defined(__NVCOMPILER)
157 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("diag push")
158 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("diag pop")
159 #define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma("diag_suppress declared_but_not_referenced")
160 #endif
161 
162 #if defined(__CUDACC__) && !defined(__clang__)
163 #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__
164 // New pragmas introduced in CUDA 11.5+
165 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("nv_diagnostic push")
166 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("nv_diagnostic pop")
167 #define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma("nv_diag_suppress 177")
168 #else
169 #define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma("diag_suppress 177")
170 #endif
171 #endif
172 
173 // clang-cl defines _MSC_VER as well as __clang__, which could cause the
174 // start/stop internal suppression macros to be double defined.
175 #if defined(__clang__) && !defined(_MSC_VER)
176 #define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P
177 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("clang diagnostic push")
178 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("clang diagnostic pop")
179 #endif // __clang__ && !_MSC_VER
180 
181 #if defined(__clang__)
182 
183 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
184  _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \
185  _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"")
186 
187 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
188  _Pragma("clang diagnostic ignored \"-Wparentheses\"")
189 
190 #define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
191  _Pragma("clang diagnostic ignored \"-Wunused-variable\"")
192 
193 #if (__clang_major__ >= 20)
194 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
195  _Pragma("clang diagnostic ignored \"-Wvariadic-macro-arguments-omitted\"")
196 #elif (__clang_major__ == 19)
197 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
198  _Pragma("clang diagnostic ignored \"-Wc++20-extensions\"")
199 #else
200 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
201  _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"")
202 #endif
203 
204 #if (__clang_major__ >= 22)
205 #define CATCH_INTERNAL_SUPPRESS_COUNTER_WARNINGS \
206  _Pragma("clang diagnostic ignored \"-Wc2y-extensions\"")
207 #endif
208 
209 #define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
210  _Pragma("clang diagnostic ignored \"-Wunused-template\"")
211 
212 #define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
213  _Pragma("clang diagnostic ignored \"-Wcomma\"")
214 
215 #define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
216  _Pragma("clang diagnostic ignored \"-Wshadow\"")
217 
218 #endif // __clang__
219 
220 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
221 // which results in calls to destructors being emitted for each temporary,
222 // without a matching initialization. In practice, this can result in something
223 // like `std::string::~string` being called on an uninitialized value.
224 //
225 // For example, this code will likely segfault under IBM XL:
226 // ```
227 // REQUIRE(std::string("12") + "34" == "1234")
228 // ```
229 //
230 // Similarly, NVHPC's implementation of `__builtin_constant_p` has a bug which
231 // results in calls to the immediately evaluated lambda expressions to be
232 // reported as unevaluated lambdas.
233 // https://developer.nvidia.com/nvidia_bug/3321845.
234 //
235 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
236 #if defined(__ibmxl__) || defined(__CUDACC__) || defined(__NVCOMPILER)
237 #define CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P
238 #endif
239 
241 // We know some environments not to support full POSIX signals
242 #if defined(CATCH_PLATFORM_WINDOWS) || defined(CATCH_PLATFORM_PLAYSTATION) || defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) || defined(__OS400__)
243 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
244 #else
245 #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
246 #endif
247 
249 // Assume that some platforms do not support getenv.
250 #if defined(CATCH_PLATFORM_WINDOWS_UWP) || defined(CATCH_PLATFORM_PLAYSTATION) || defined(_GAMING_XBOX)
251 #define CATCH_INTERNAL_CONFIG_NO_GETENV
252 #else
253 #define CATCH_INTERNAL_CONFIG_GETENV
254 #endif
255 
257 // Android somehow still does not support std::to_string
258 #if defined(__ANDROID__)
259 #define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
260 #endif
261 
263 // Not all Windows environments support SEH properly
264 #if defined(__MINGW32__)
265 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
266 #endif
267 
269 // PS4
270 #if defined(__ORBIS__)
271 #define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
272 #endif
273 
275 // Cygwin
276 #ifdef __CYGWIN__
277 
278 // Required for some versions of Cygwin to declare gettimeofday
279 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
280 #define _BSD_SOURCE
281 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
282 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
283 #if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
284  && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
285 
286 #define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
287 
288 #endif
289 #endif // __CYGWIN__
290 
292 // Visual C++
293 #if defined(_MSC_VER) && !defined(__clang__)
294 
295 // We want to defer to nvcc-specific warning suppression if we are compiled
296 // with nvcc masquerading for MSVC.
297 #if !defined(__CUDACC__)
298 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
299  __pragma(warning(push))
300 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
301  __pragma(warning(pop))
302 #endif
303 
304 // Suppress MSVC C++ Core Guidelines checker warning 26426:
305 // "Global initializer calls a non-constexpr function (i.22)"
306 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
307  __pragma(warning(disable : 26426))
308 
309 // Universal Windows platform does not support SEH
310 #if !defined(CATCH_PLATFORM_WINDOWS_UWP)
311 #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
312 #endif
313 
314 // Only some Windows platform families support the console
315 #if defined(WINAPI_FAMILY_PARTITION)
316 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
317 #define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
318 #endif
319 #endif
320 
321 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
322 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
323 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
324 #if !defined(__clang__) // Handle Clang masquerading for msvc
325 #if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
326 #define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
327 #endif // MSVC_TRADITIONAL
328 #endif // __clang__
329 
330 #endif // _MSC_VER
331 
332 #if defined(_REENTRANT) || defined(_MSC_VER)
333 // Enable async processing, as -pthread is specified or no additional linking is required
334 #define CATCH_INTERNAL_CONFIG_USE_ASYNC
335 #endif // _MSC_VER
336 
338 // Check if we are compiled with -fno-exceptions or equivalent
339 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
340 #define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
341 #endif
342 
344 // Embarcadero C++Build
345 #if defined(__BORLANDC__)
346 #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
347 #endif
348 
350 
351 // RTX is a special version of Windows that is real time.
352 // This means that it is detected as Windows, but does not provide
353 // the same set of capabilities as real Windows does.
354 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
355 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
356 #define CATCH_INTERNAL_CONFIG_NO_ASYNC
357 #define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
358 #endif
359 
360 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
361 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
362 #endif
363 
364 // Various stdlib support checks that require __has_include
365 #if defined(__has_include)
366 // Check if string_view is available and usable
367 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
368 #define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
369 #endif
370 
371 // Check if optional is available and usable
372 #if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
373 #define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
374 #endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
375 
376 // Check if byte is available and usable
377 #if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
378 #include <cstddef>
379 #if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
380 #define CATCH_INTERNAL_CONFIG_CPP17_BYTE
381 #endif
382 #endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
383 
384 // Check if variant is available and usable
385 #if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
386 #if defined(__clang__) && (__clang_major__ < 8)
387 // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
388 // fix should be in clang 8, workaround in libstdc++ 8.2
389 #include <ciso646>
390 #if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
391 #define CATCH_CONFIG_NO_CPP17_VARIANT
392 #else
393 #define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
394 #endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
395 #else
396 #define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
397 #endif // defined(__clang__) && (__clang_major__ < 8)
398 #endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
399 #endif // defined(__has_include)
400 
401 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
402 #define CATCH_CONFIG_WINDOWS_SEH
403 #endif
404 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
405 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
406 #define CATCH_CONFIG_POSIX_SIGNALS
407 #endif
408 
409 #if defined(CATCH_INTERNAL_CONFIG_GETENV) && !defined(CATCH_INTERNAL_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_GETENV)
410 #define CATCH_CONFIG_GETENV
411 #endif
412 
413 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
414 #define CATCH_CONFIG_CPP11_TO_STRING
415 #endif
416 
417 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
418 #define CATCH_CONFIG_CPP17_OPTIONAL
419 #endif
420 
421 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
422 #define CATCH_CONFIG_CPP17_STRING_VIEW
423 #endif
424 
425 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
426 #define CATCH_CONFIG_CPP17_VARIANT
427 #endif
428 
429 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
430 #define CATCH_CONFIG_CPP17_BYTE
431 #endif
432 
433 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
434 #define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
435 #endif
436 
437 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
438 #define CATCH_CONFIG_NEW_CAPTURE
439 #endif
440 
441 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_DISABLE_EXCEPTIONS)
442 #define CATCH_CONFIG_DISABLE_EXCEPTIONS
443 #endif
444 
445 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
446 #define CATCH_CONFIG_POLYFILL_ISNAN
447 #endif
448 
449 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
450 #define CATCH_CONFIG_USE_ASYNC
451 #endif
452 
453 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
454 #define CATCH_CONFIG_GLOBAL_NEXTAFTER
455 #endif
456 
457 // The goal of this macro is to avoid evaluation of the arguments, but
458 // still have the compiler warn on problems inside...
459 #if defined(CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P) && !defined(CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P) && !defined(CATCH_CONFIG_USE_BUILTIN_CONSTANT_P)
460 #define CATCH_CONFIG_USE_BUILTIN_CONSTANT_P
461 #endif
462 
463 #if defined(CATCH_CONFIG_USE_BUILTIN_CONSTANT_P) && !defined(CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P)
464 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...) \
465  (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, \
466  hicpp-vararg) */
467 #else
468 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
469 #endif
470 
471 // Even if we do not think the compiler has that warning, we still have
472 // to provide a macro that can be used by the code.
473 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
474 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
475 #endif
476 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
477 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
478 #endif
479 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
480 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
481 #endif
482 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
483 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
484 #endif
485 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT)
486 #define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT
487 #endif
488 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS)
489 #define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
490 #endif
491 #if !defined(CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS)
492 #define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS
493 #endif
494 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
495 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
496 #endif
497 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
498 #define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
499 #endif
500 #if !defined(CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS)
501 #define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS
502 #endif
503 #if !defined(CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS)
504 #define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS
505 #endif
506 #if !defined(CATCH_INTERNAL_SUPPRESS_COUNTER_WARNINGS)
507 #define CATCH_INTERNAL_SUPPRESS_COUNTER_WARNINGS
508 #endif
509 
510 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
511 #undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
512 #elif defined(__clang__) && (__clang_major__ < 5)
513 #undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
514 #endif
515 
516 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
517 #define CATCH_TRY if ((true))
518 #define CATCH_CATCH_ALL if ((false))
519 #define CATCH_CATCH_ANON(type) if ((false))
520 #else
521 #define CATCH_TRY try
522 #define CATCH_CATCH_ALL catch (...)
523 #define CATCH_CATCH_ANON(type) catch (type)
524 #endif
525 
526 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
527 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
528 #endif
529 
530 #if defined(CATCH_PLATFORM_WINDOWS) && !defined(CATCH_CONFIG_COLOUR_WIN32) && !defined(CATCH_CONFIG_NO_COLOUR_WIN32) && !defined(CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32)
531 #define CATCH_CONFIG_COLOUR_WIN32
532 #endif
533 
534 #if defined(CATCH_CONFIG_SHARED_LIBRARY) && defined(_MSC_VER) && !defined(CATCH_CONFIG_STATIC)
535 #ifdef Catch2_EXPORTS
536 #define CATCH_EXPORT //__declspec( dllexport ) // not needed
537 #else
538 #define CATCH_EXPORT __declspec(dllimport)
539 #endif
540 #else
541 #define CATCH_EXPORT
542 #endif
543 
544 #endif // CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
545 
546 #ifndef CATCH_CONTEXT_HPP_INCLUDED
547 #define CATCH_CONTEXT_HPP_INCLUDED
548 
549 namespace Catch {
550 
551  class IResultCapture;
552  class IConfig;
553 
554  class Context {
555  IConfig const *m_config = nullptr;
556  IResultCapture *m_resultCapture = nullptr;
557 
558  CATCH_EXPORT static Context currentContext;
559  friend Context &getCurrentMutableContext();
560  friend Context const &getCurrentContext();
561 
562  public:
563  constexpr IResultCapture *getResultCapture() const {
564  return m_resultCapture;
565  }
566  constexpr IConfig const *getConfig() const { return m_config; }
567  constexpr void setResultCapture(IResultCapture *resultCapture) {
568  m_resultCapture = resultCapture;
569  }
570  constexpr void setConfig(IConfig const *config) { m_config = config; }
571  };
572 
573  Context &getCurrentMutableContext();
574 
575  inline Context const &getCurrentContext() {
576  return Context::currentContext;
577  }
578 
579  class SimplePcg32;
580  SimplePcg32 &sharedRng();
581 } // namespace Catch
582 
583 #endif // CATCH_CONTEXT_HPP_INCLUDED
584 
585 #ifndef CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
586 #define CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
587 
588 #include <type_traits>
589 
591 #define CATCH_MOVE(...) static_cast<std::remove_reference_t<decltype(__VA_ARGS__)> &&>(__VA_ARGS__)
592 
594 #define CATCH_FORWARD(...) static_cast<decltype(__VA_ARGS__) &&>(__VA_ARGS__)
595 
596 #endif // CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
597 
598 #ifndef CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
599 #define CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
600 
601 namespace Catch {
602 
606  struct TestSkipException {};
607 
613  [[noreturn]] void throw_test_failure_exception();
614 
620  [[noreturn]] void throw_test_skip_exception();
621 
622 } // namespace Catch
623 
624 #endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
625 
626 #ifndef CATCH_UNIQUE_NAME_HPP_INCLUDED
627 #define CATCH_UNIQUE_NAME_HPP_INCLUDED
628 
638 #ifndef CATCH_CONFIG_COUNTER_HPP_INCLUDED
639 #define CATCH_CONFIG_COUNTER_HPP_INCLUDED
640 
641 #if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L)
642 #define CATCH_INTERNAL_CONFIG_COUNTER
643 #endif
644 
645 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
646 #define CATCH_CONFIG_COUNTER
647 #endif
648 
649 #endif // CATCH_CONFIG_COUNTER_HPP_INCLUDED
650 
651 // Fixme: Clang 22 has an annoying bug where the localized suppression
652 // below does not actually suppress the extension warning from
653 // using __COUNTER__, so we have to leak the suppression for the
654 // whole TU. Hopefully Clang 23 fixes this before full release.
655 // As AppleClang does its own thing version-wise, we ignore it
656 // completely.
657 #if defined(__clang__) && (__clang_major__ >= 22) && !defined(__APPLE__)
658 CATCH_INTERNAL_SUPPRESS_COUNTER_WARNINGS
659 #endif
660 
661 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line
662 #define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line)
663 
664 #ifdef CATCH_CONFIG_COUNTER
665 #define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__)
666 #else
667 #define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__)
668 #endif
669 
670 #endif // CATCH_UNIQUE_NAME_HPP_INCLUDED
671 
672 #ifndef CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
673 #define CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
674 
675 #include <string>
676 
677 #ifndef CATCH_STRINGREF_HPP_INCLUDED
678 #define CATCH_STRINGREF_HPP_INCLUDED
679 
680 #ifndef CATCH_LIFETIMEBOUND_HPP_INCLUDED
681 #define CATCH_LIFETIMEBOUND_HPP_INCLUDED
682 
683 #if !defined(__has_cpp_attribute)
684 #define CATCH_ATTR_LIFETIMEBOUND
685 #elif __has_cpp_attribute(msvc::lifetimebound)
686 #define CATCH_ATTR_LIFETIMEBOUND [[msvc::lifetimebound]]
687 #elif __has_cpp_attribute(clang::lifetimebound)
688 #define CATCH_ATTR_LIFETIMEBOUND [[clang::lifetimebound]]
689 #elif __has_cpp_attribute(lifetimebound)
690 #define CATCH_ATTR_LIFETIMEBOUND [[lifetimebound]]
691 #else
692 #define CATCH_ATTR_LIFETIMEBOUND
693 #endif
694 
695 #endif // CATCH_LIFETIMEBOUND_HPP_INCLUDED
696 
697 #include <cassert>
698 #include <cstddef>
699 #include <cstring>
700 #include <iosfwd>
701 #include <string>
702 
703 namespace Catch {
704 
708  class StringRef {
709  public:
710  using size_type = std::size_t;
711  using const_iterator = const char *;
712 
713  static constexpr size_type npos{static_cast<size_type>(-1)};
714 
715  private:
716  static constexpr char const *const s_empty = "";
717 
718  char const *m_start = s_empty;
719  size_type m_size = 0;
720 
721  public: // construction
722  constexpr StringRef() noexcept = default;
723 
724  StringRef(char const *rawChars CATCH_ATTR_LIFETIMEBOUND) noexcept;
725 
726  constexpr StringRef(char const *rawChars CATCH_ATTR_LIFETIMEBOUND,
727  size_type size) noexcept
728  : m_start(rawChars), m_size(size) {}
729 
730  StringRef(
731  std::string const &stdString CATCH_ATTR_LIFETIMEBOUND) noexcept
732  : m_start(stdString.c_str()), m_size(stdString.size()) {}
733 
734  explicit operator std::string() const {
735  return std::string(m_start, m_size);
736  }
737 
738  public: // operators
739  auto operator==(StringRef other) const noexcept -> bool {
740  return m_size == other.m_size
741  && (std::memcmp(m_start, other.m_start, m_size) == 0);
742  }
743  auto operator!=(StringRef other) const noexcept -> bool {
744  return !(*this == other);
745  }
746 
747  constexpr auto operator[](size_type index) const noexcept -> char {
748  assert(index < m_size);
749  return m_start[index];
750  }
751 
752  bool operator<(StringRef rhs) const noexcept;
753 
754  public: // named queries
755  constexpr auto empty() const noexcept -> bool {
756  return m_size == 0;
757  }
758  constexpr auto size() const noexcept -> size_type {
759  return m_size;
760  }
761 
762  // Returns a substring of [start, start + length).
763  // If start + length > size(), then the substring is [start, size()).
764  // If start > size(), then the substring is empty.
765  constexpr StringRef substr(size_type start, size_type length) const noexcept {
766  if (start < m_size) {
767  const auto shortened_size = m_size - start;
768  return StringRef(m_start + start, (shortened_size < length) ? shortened_size : length);
769  } else {
770  return StringRef();
771  }
772  }
773 
774  // Returns the current start pointer. May not be null-terminated.
775  constexpr char const *data() const noexcept CATCH_ATTR_LIFETIMEBOUND {
776  return m_start;
777  }
778 
779  constexpr const_iterator begin() const { return m_start; }
780  constexpr const_iterator end() const { return m_start + m_size; }
781 
782  friend std::string &operator+=(std::string &lhs, StringRef rhs);
783  friend std::ostream &operator<<(std::ostream &os, StringRef str);
784  friend std::string operator+(StringRef lhs, StringRef rhs);
785 
792  int compare(StringRef rhs) const;
793  };
794 
795  constexpr auto operator""_sr(char const *rawChars, std::size_t size) noexcept -> StringRef {
796  return StringRef(rawChars, size);
797  }
798 } // namespace Catch
799 
800 constexpr auto operator""_catch_sr(char const *rawChars, std::size_t size) noexcept -> Catch::StringRef {
801  return Catch::StringRef(rawChars, size);
802 }
803 
804 #endif // CATCH_STRINGREF_HPP_INCLUDED
805 
806 #ifndef CATCH_RESULT_TYPE_HPP_INCLUDED
807 #define CATCH_RESULT_TYPE_HPP_INCLUDED
808 
809 namespace Catch {
810 
811  // ResultWas::OfType enum
812  struct ResultWas {
813  enum OfType {
814  Unknown = -1,
815  Ok = 0,
816  Info = 1,
817  Warning = 2,
818  // TODO: Should explicit skip be considered "not OK" (cf. isOk)? I.e., should it have the failure bit?
819  ExplicitSkip = 4,
820 
821  FailureBit = 0x10,
822 
823  ExpressionFailed = FailureBit | 1,
824  ExplicitFailure = FailureBit | 2,
825 
826  Exception = 0x100 | FailureBit,
827 
828  ThrewException = Exception | 1,
829  DidntThrowException = Exception | 2,
830 
831  FatalErrorCondition = 0x200 | FailureBit
832 
833  };
834  };
835 
836  constexpr bool isOk(ResultWas::OfType resultType) {
837  return (resultType & ResultWas::FailureBit) == 0;
838  }
839  constexpr bool isJustInfo(int flags) {
840  return flags == ResultWas::Info;
841  }
842 
843  // ResultDisposition::Flags enum
845  enum Flags {
846  Normal = 0x01,
847 
848  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
849  FalseTest = 0x04, // Prefix expression with !
850  SuppressFail = 0x08 // Failures are reported but do not fail the test
851  };
852  };
853 
854  constexpr ResultDisposition::Flags operator|(ResultDisposition::Flags lhs,
855  ResultDisposition::Flags rhs) {
856  return static_cast<ResultDisposition::Flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
857  }
858 
859  constexpr bool isFalseTest(int flags) {
860  return (flags & ResultDisposition::FalseTest) != 0;
861  }
862  constexpr bool shouldSuppressFailure(int flags) {
863  return (flags & ResultDisposition::SuppressFail) != 0;
864  }
865 
866 } // end namespace Catch
867 
868 #endif // CATCH_RESULT_TYPE_HPP_INCLUDED
869 
870 #ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED
871 #define CATCH_UNIQUE_PTR_HPP_INCLUDED
872 
873 #include <cassert>
874 #include <type_traits>
875 
876 namespace Catch {
877  namespace Detail {
883  template<typename T>
884  class unique_ptr {
885  T *m_ptr;
886 
887  public:
888  constexpr unique_ptr(std::nullptr_t = nullptr)
889  : m_ptr{} {}
890  explicit constexpr unique_ptr(T *ptr)
891  : m_ptr(ptr) {}
892 
893  template<typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
894  unique_ptr(unique_ptr<U> &&from)
895  : m_ptr(from.release()) {}
896 
897  template<typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
898  unique_ptr &operator=(unique_ptr<U> &&from) {
899  reset(from.release());
900 
901  return *this;
902  }
903 
904  unique_ptr(unique_ptr const &) = delete;
905  unique_ptr &operator=(unique_ptr const &) = delete;
906 
907  unique_ptr(unique_ptr &&rhs) noexcept
908  : m_ptr(rhs.m_ptr) {
909  rhs.m_ptr = nullptr;
910  }
911  unique_ptr &operator=(unique_ptr &&rhs) noexcept {
912  reset(rhs.release());
913 
914  return *this;
915  }
916 
917  ~unique_ptr() {
918  delete m_ptr;
919  }
920 
921  T &operator*() {
922  assert(m_ptr);
923  return *m_ptr;
924  }
925  T const &operator*() const {
926  assert(m_ptr);
927  return *m_ptr;
928  }
929  T *operator->() noexcept {
930  assert(m_ptr);
931  return m_ptr;
932  }
933  T const *operator->() const noexcept {
934  assert(m_ptr);
935  return m_ptr;
936  }
937 
938  T *get() { return m_ptr; }
939  T const *get() const { return m_ptr; }
940 
941  void reset(T *ptr = nullptr) {
942  delete m_ptr;
943  m_ptr = ptr;
944  }
945 
946  T *release() {
947  auto temp = m_ptr;
948  m_ptr = nullptr;
949  return temp;
950  }
951 
952  explicit operator bool() const {
953  return m_ptr != nullptr;
954  }
955 
956  friend void swap(unique_ptr &lhs, unique_ptr &rhs) {
957  auto temp = lhs.m_ptr;
958  lhs.m_ptr = rhs.m_ptr;
959  rhs.m_ptr = temp;
960  }
961  };
962 
964  template<typename T>
965  class unique_ptr<T[]>;
966 
967  template<typename T, typename... Args>
968  unique_ptr<T> make_unique(Args &&...args) {
969  return unique_ptr<T>(new T(CATCH_FORWARD(args)...));
970  }
971 
972  } // end namespace Detail
973 } // end namespace Catch
974 
975 #endif // CATCH_UNIQUE_PTR_HPP_INCLUDED
976 
977 #ifndef CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
978 #define CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
979 
980 namespace Catch {
981 
982  namespace Detail {
983  struct DummyTemplateArgPlaceholder;
984  }
985 
986  // We cannot forward declare the type with default template argument
987  // multiple times, so it is split out into a separate header so that
988  // we can prevent multiple declarations in dependencies
989  template<typename Duration = Detail::DummyTemplateArgPlaceholder>
991 
992 } // end namespace Catch
993 
994 #endif // CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
995 
996 namespace Catch {
997 
998  class AssertionResult;
999  struct AssertionInfo;
1000  struct SectionInfo;
1001  struct SectionEndInfo;
1002  struct MessageInfo;
1003  struct MessageBuilder;
1004  struct Counts;
1005  struct AssertionReaction;
1006  struct SourceLineInfo;
1007 
1008  class ITransientExpression;
1009  class IGeneratorTracker;
1010 
1011  struct BenchmarkInfo;
1012 
1013  namespace Generators {
1014  class GeneratorUntypedBase;
1015  using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
1016  } // namespace Generators
1017 
1019  public:
1020  virtual ~IResultCapture();
1021 
1022  virtual void notifyAssertionStarted(AssertionInfo const &info) = 0;
1023  virtual bool sectionStarted(StringRef sectionName,
1024  SourceLineInfo const &sectionLineInfo,
1025  Counts &assertions)
1026  = 0;
1027  virtual void sectionEnded(SectionEndInfo &&endInfo) = 0;
1028  virtual void sectionEndedEarly(SectionEndInfo &&endInfo) = 0;
1029 
1030  virtual IGeneratorTracker *
1031  acquireGeneratorTracker(StringRef generatorName,
1032  SourceLineInfo const &lineInfo)
1033  = 0;
1034  virtual IGeneratorTracker *
1035  createGeneratorTracker(StringRef generatorName,
1036  SourceLineInfo lineInfo,
1037  Generators::GeneratorBasePtr &&generator)
1038  = 0;
1039 
1040  virtual void benchmarkPreparing(StringRef name) = 0;
1041  virtual void benchmarkStarting(BenchmarkInfo const &info) = 0;
1042  virtual void benchmarkEnded(BenchmarkStats<> const &stats) = 0;
1043  virtual void benchmarkFailed(StringRef error) = 0;
1044 
1045  static void pushScopedMessage(MessageInfo &&message);
1046  static void popScopedMessage(unsigned int messageId);
1047  static void addUnscopedMessage(MessageInfo &&message);
1048  static void emplaceUnscopedMessage(MessageBuilder &&builder);
1049 
1050  virtual void handleFatalErrorCondition(StringRef message) = 0;
1051 
1052  virtual void handleExpr(AssertionInfo const &info,
1053  ITransientExpression const &expr,
1054  AssertionReaction &reaction)
1055  = 0;
1056  virtual void handleMessage(AssertionInfo const &info,
1057  ResultWas::OfType resultType,
1058  std::string &&message,
1059  AssertionReaction &reaction)
1060  = 0;
1061  virtual void handleUnexpectedExceptionNotThrown(AssertionInfo const &info,
1062  AssertionReaction &reaction)
1063  = 0;
1064  virtual void handleUnexpectedInflightException(AssertionInfo const &info,
1065  std::string &&message,
1066  AssertionReaction &reaction)
1067  = 0;
1068  virtual void handleIncomplete(AssertionInfo const &info) = 0;
1069  virtual void handleNonExpr(AssertionInfo const &info,
1070  ResultWas::OfType resultType,
1071  AssertionReaction &reaction)
1072  = 0;
1073 
1074  virtual bool lastAssertionPassed() = 0;
1075 
1076  // Deprecated, do not use:
1077  virtual std::string getCurrentTestName() const = 0;
1078  virtual const AssertionResult *getLastResult() const = 0;
1079  virtual void exceptionEarlyReported() = 0;
1080  };
1081 
1082  namespace Detail {
1083  [[noreturn]]
1084  void missingCaptureInstance();
1085  }
1086  inline IResultCapture &getResultCapture() {
1087  if (auto *capture = getCurrentContext().getResultCapture()) {
1088  return *capture;
1089  } else {
1090  Detail::missingCaptureInstance();
1091  }
1092  }
1093 
1094 } // namespace Catch
1095 
1096 #endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
1097 
1098 #ifndef CATCH_INTERFACES_CONFIG_HPP_INCLUDED
1099 #define CATCH_INTERFACES_CONFIG_HPP_INCLUDED
1100 
1101 #ifndef CATCH_NONCOPYABLE_HPP_INCLUDED
1102 #define CATCH_NONCOPYABLE_HPP_INCLUDED
1103 
1104 namespace Catch {
1105  namespace Detail {
1106 
1108  class NonCopyable {
1109  public:
1110  NonCopyable(NonCopyable const &) = delete;
1111  NonCopyable(NonCopyable &&) = delete;
1112  NonCopyable &operator=(NonCopyable const &) = delete;
1113  NonCopyable &operator=(NonCopyable &&) = delete;
1114 
1115  protected:
1116  NonCopyable() noexcept = default;
1117  };
1118 
1119  } // namespace Detail
1120 } // namespace Catch
1121 
1122 #endif // CATCH_NONCOPYABLE_HPP_INCLUDED
1123 
1124 #include <chrono>
1125 #include <string>
1126 #include <vector>
1127 
1128 namespace Catch {
1129 
1130  enum class Verbosity {
1131  Quiet = 0,
1132  Normal,
1133  High
1134  };
1135 
1136  struct WarnAbout {
1137  enum What {
1138  Nothing = 0x00,
1140  NoAssertions = 0x01,
1142  UnmatchedTestSpec = 0x02,
1144  InfiniteGenerator = 0x04,
1145  };
1146  };
1147 
1148  enum class ShowDurations {
1149  DefaultForReporter,
1150  Always,
1151  Never
1152  };
1153  enum class TestRunOrder {
1154  Declared,
1155  LexicographicallySorted,
1156  Randomized
1157  };
1158  enum class ColourMode : std::uint8_t {
1160  PlatformDefault,
1162  ANSI,
1164  Win32,
1166  None
1167  };
1169  enum When {
1170  Never,
1171  BeforeStart = 1,
1172  BeforeExit = 2,
1173  BeforeStartAndExit = BeforeStart | BeforeExit
1174  };
1175  };
1176 
1177  class TestSpec;
1178  class IStream;
1179  struct PathFilter;
1180 
1181  class IConfig : public Detail::NonCopyable {
1182  public:
1183  virtual ~IConfig();
1184 
1185  virtual bool allowThrows() const = 0;
1186  virtual StringRef name() const = 0;
1187  virtual bool includeSuccessfulResults() const = 0;
1188  virtual bool shouldDebugBreak() const = 0;
1189  virtual bool warnAboutMissingAssertions() const = 0;
1190  virtual bool warnAboutUnmatchedTestSpecs() const = 0;
1191  virtual bool warnAboutInfiniteGenerators() const = 0;
1192  virtual bool zeroTestsCountAsSuccess() const = 0;
1193  virtual int abortAfter() const = 0;
1194  virtual bool showInvisibles() const = 0;
1195  virtual ShowDurations showDurations() const = 0;
1196  virtual double minDuration() const = 0;
1197  virtual TestSpec const &testSpec() const = 0;
1198  virtual bool hasTestFilters() const = 0;
1199  virtual std::vector<std::string> const &getTestsOrTags() const = 0;
1200  virtual TestRunOrder runOrder() const = 0;
1201  virtual uint32_t rngSeed() const = 0;
1202  virtual unsigned int shardCount() const = 0;
1203  virtual unsigned int shardIndex() const = 0;
1204  virtual ColourMode defaultColourMode() const = 0;
1205  virtual std::vector<PathFilter> const &getPathFilters() const = 0;
1206  virtual bool useNewFilterBehaviour() const = 0;
1207 
1208  virtual Verbosity verbosity() const = 0;
1209 
1210  virtual bool skipBenchmarks() const = 0;
1211  virtual bool benchmarkNoAnalysis() const = 0;
1212  virtual unsigned int benchmarkSamples() const = 0;
1213  virtual double benchmarkConfidenceInterval() const = 0;
1214  virtual unsigned int benchmarkResamples() const = 0;
1215  virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
1216  };
1217 } // namespace Catch
1218 
1219 #endif // CATCH_INTERFACES_CONFIG_HPP_INCLUDED
1220 
1221 #ifndef CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1222 #define CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1223 
1224 #include <string>
1225 
1226 namespace Catch {
1227 
1228  class TestCaseHandle;
1229  struct TestCaseInfo;
1230  class ITestCaseRegistry;
1232  class IExceptionTranslator;
1233  class ReporterRegistry;
1234  class IReporterFactory;
1235  class ITagAliasRegistry;
1236  class ITestInvoker;
1238  struct SourceLineInfo;
1239 
1240  class StartupExceptionRegistry;
1241  class EventListenerFactory;
1242 
1244 
1246  public:
1247  virtual ~IRegistryHub(); // = default
1248 
1249  virtual ReporterRegistry const &getReporterRegistry() const = 0;
1250  virtual ITestCaseRegistry const &getTestCaseRegistry() const = 0;
1251  virtual ITagAliasRegistry const &getTagAliasRegistry() const = 0;
1252  virtual IExceptionTranslatorRegistry const &getExceptionTranslatorRegistry() const = 0;
1253 
1254  virtual StartupExceptionRegistry const &getStartupExceptionRegistry() const = 0;
1255  };
1256 
1258  public:
1259  virtual ~IMutableRegistryHub(); // = default
1260  virtual void registerReporter(std::string const &name, IReporterFactoryPtr factory) = 0;
1261  virtual void registerListener(Detail::unique_ptr<EventListenerFactory> factory) = 0;
1262  virtual void registerTest(Detail::unique_ptr<TestCaseInfo> &&testInfo, Detail::unique_ptr<ITestInvoker> &&invoker) = 0;
1263  virtual void registerTranslator(Detail::unique_ptr<IExceptionTranslator> &&translator) = 0;
1264  virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) = 0;
1265  virtual void registerStartupException() noexcept = 0;
1266  virtual IMutableEnumValuesRegistry &getMutableEnumValuesRegistry() = 0;
1267  };
1268 
1269  IRegistryHub const &getRegistryHub();
1270  IMutableRegistryHub &getMutableRegistryHub();
1271  void cleanUp();
1272  std::string translateActiveException();
1273 
1274 } // namespace Catch
1275 
1276 #endif // CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1277 
1278 #ifndef CATCH_BENCHMARK_STATS_HPP_INCLUDED
1279 #define CATCH_BENCHMARK_STATS_HPP_INCLUDED
1280 
1281 // Adapted from donated nonius code.
1282 
1283 #ifndef CATCH_CLOCK_HPP_INCLUDED
1284 #define CATCH_CLOCK_HPP_INCLUDED
1285 
1286 #include <chrono>
1287 
1288 namespace Catch {
1289  namespace Benchmark {
1290  using IDuration = std::chrono::nanoseconds;
1291  using FDuration = std::chrono::duration<double, std::nano>;
1292 
1293  template<typename Clock>
1294  using TimePoint = typename Clock::time_point;
1295 
1296  using default_clock = std::chrono::steady_clock;
1297  } // namespace Benchmark
1298 } // namespace Catch
1299 
1300 #endif // CATCH_CLOCK_HPP_INCLUDED
1301 
1302 // Adapted from donated nonius code.
1303 
1304 #ifndef CATCH_ESTIMATE_HPP_INCLUDED
1305 #define CATCH_ESTIMATE_HPP_INCLUDED
1306 
1307 namespace Catch {
1308  namespace Benchmark {
1309  template<typename Type>
1310  struct Estimate {
1311  Type point;
1312  Type lower_bound;
1313  Type upper_bound;
1314  double confidence_interval;
1315  };
1316  } // namespace Benchmark
1317 } // namespace Catch
1318 
1319 #endif // CATCH_ESTIMATE_HPP_INCLUDED
1320 
1321 // Adapted from donated nonius code.
1322 
1323 #ifndef CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED
1324 #define CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED
1325 
1326 namespace Catch {
1327  namespace Benchmark {
1329  int samples_seen = 0;
1330  int low_severe = 0; // more than 3 times IQR below Q1
1331  int low_mild = 0; // 1.5 to 3 times IQR below Q1
1332  int high_mild = 0; // 1.5 to 3 times IQR above Q3
1333  int high_severe = 0; // more than 3 times IQR above Q3
1334 
1335  constexpr int total() const {
1336  return low_severe + low_mild + high_mild + high_severe;
1337  }
1338  };
1339  } // namespace Benchmark
1340 } // namespace Catch
1341 
1342 #endif // CATCH_OUTLIERS_CLASSIFICATION_HPP_INCLUDED
1343 // The fwd decl & default specialization needs to be seen by VS2017 before
1344 // BenchmarkStats itself, or VS2017 will report compilation error.
1345 
1346 #include <string>
1347 #include <vector>
1348 
1349 namespace Catch {
1350 
1351  struct BenchmarkInfo {
1352  std::string name;
1353  double estimatedDuration;
1354  int iterations;
1355  unsigned int samples;
1356  unsigned int resamples;
1357  double clockResolution;
1358  double clockCost;
1359  };
1360 
1361  // We need to keep template parameter for backwards compatibility,
1362  // but we also do not want to use the template paraneter.
1363  template<class Dummy>
1364  struct BenchmarkStats {
1365  BenchmarkInfo info;
1366 
1367  std::vector<Benchmark::FDuration> samples;
1371  double outlierVariance;
1372  };
1373 
1374 } // end namespace Catch
1375 
1376 #endif // CATCH_BENCHMARK_STATS_HPP_INCLUDED
1377 
1378 // Adapted from donated nonius code.
1379 
1380 #ifndef CATCH_ENVIRONMENT_HPP_INCLUDED
1381 #define CATCH_ENVIRONMENT_HPP_INCLUDED
1382 
1383 namespace Catch {
1384  namespace Benchmark {
1386  FDuration mean;
1387  OutlierClassification outliers;
1388  };
1389  struct Environment {
1390  EnvironmentEstimate clock_resolution;
1391  EnvironmentEstimate clock_cost;
1392  };
1393  } // namespace Benchmark
1394 } // namespace Catch
1395 
1396 #endif // CATCH_ENVIRONMENT_HPP_INCLUDED
1397 
1398 // Adapted from donated nonius code.
1399 
1400 #ifndef CATCH_EXECUTION_PLAN_HPP_INCLUDED
1401 #define CATCH_EXECUTION_PLAN_HPP_INCLUDED
1402 
1403 // Adapted from donated nonius code.
1404 
1405 #ifndef CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1406 #define CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1407 
1408 // Adapted from donated nonius code.
1409 
1410 #ifndef CATCH_CHRONOMETER_HPP_INCLUDED
1411 #define CATCH_CHRONOMETER_HPP_INCLUDED
1412 
1413 // Adapted from donated nonius code.
1414 
1415 #ifndef CATCH_OPTIMIZER_HPP_INCLUDED
1416 #define CATCH_OPTIMIZER_HPP_INCLUDED
1417 
1418 #if defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__)
1419 #include <atomic> // atomic_thread_fence
1420 #endif
1421 
1422 #include <type_traits>
1423 
1424 namespace Catch {
1425  namespace Benchmark {
1426 #if defined(__GNUC__) || defined(__clang__)
1427  template<typename T>
1428  inline void keep_memory(T *p) {
1429  asm volatile("" : : "g"(p) : "memory");
1430  }
1431  inline void keep_memory() {
1432  asm volatile("" : : : "memory");
1433  }
1434 
1435  namespace Detail {
1436  inline void optimizer_barrier() {
1437  keep_memory();
1438  }
1439  } // namespace Detail
1440 #elif defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__)
1441 
1442 #if defined(_MSVC_VER)
1443 #pragma optimize("", off)
1444 #elif defined(__IAR_SYSTEMS_ICC__)
1445 // For IAR the pragma only affects the following function
1446 #pragma optimize = disable
1447 #endif
1448  template<typename T>
1449  inline void keep_memory(T *p) {
1450  // thanks @milleniumbug
1451  *reinterpret_cast<char volatile *>(p) = *reinterpret_cast<char const volatile *>(p);
1452  }
1453  // TODO equivalent keep_memory()
1454 #if defined(_MSVC_VER)
1455 #pragma optimize("", on)
1456 #endif
1457 
1458  namespace Detail {
1459  inline void optimizer_barrier() {
1460  std::atomic_thread_fence(std::memory_order_seq_cst);
1461  }
1462  } // namespace Detail
1463 
1464 #endif
1465 
1466  template<typename T>
1467  inline void deoptimize_value(T &&x) {
1468  keep_memory(&x);
1469  }
1470 
1471  template<typename Fn, typename... Args>
1472  inline auto invoke_deoptimized(Fn &&fn, Args &&...args) -> std::enable_if_t<!std::is_same<void, decltype(fn(args...))>::value> {
1473  deoptimize_value(CATCH_FORWARD(fn)(CATCH_FORWARD(args)...));
1474  }
1475 
1476  template<typename Fn, typename... Args>
1477  inline auto invoke_deoptimized(Fn &&fn, Args &&...args) -> std::enable_if_t<std::is_same<void, decltype(fn(args...))>::value> {
1478  CATCH_FORWARD((fn))(CATCH_FORWARD(args)...);
1479  }
1480  } // namespace Benchmark
1481 } // namespace Catch
1482 
1483 #endif // CATCH_OPTIMIZER_HPP_INCLUDED
1484 
1485 #ifndef CATCH_META_HPP_INCLUDED
1486 #define CATCH_META_HPP_INCLUDED
1487 
1488 #include <type_traits>
1489 
1490 namespace Catch {
1491  template<typename>
1492  struct true_given : std::true_type {};
1493 
1495  template<typename Fun, typename... Args>
1496  static true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
1497  template<typename...>
1498  static std::false_type test(...);
1499  };
1500 
1501  template<typename T>
1502  struct is_callable;
1503 
1504  template<typename Fun, typename... Args>
1505  struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
1506 
1507 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
1508  // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
1509  // replaced with std::invoke_result here.
1510  template<typename Func, typename... U>
1511  using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
1512 #else
1513  template<typename Func, typename... U>
1514  using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::result_of_t<Func(U...)>>>;
1515 #endif
1516 
1517 } // namespace Catch
1518 
1519 namespace mpl_ {
1520  struct na;
1521 }
1522 
1523 #endif // CATCH_META_HPP_INCLUDED
1524 
1525 namespace Catch {
1526  namespace Benchmark {
1527  namespace Detail {
1529  virtual void start() = 0;
1530  virtual void finish() = 0;
1531  virtual ~ChronometerConcept(); // = default;
1532 
1533  ChronometerConcept() = default;
1534  ChronometerConcept(ChronometerConcept const &) = default;
1535  ChronometerConcept &operator=(ChronometerConcept const &) = default;
1536  };
1537  template<typename Clock>
1538  struct ChronometerModel final : public ChronometerConcept {
1539  void start() override { started = Clock::now(); }
1540  void finish() override { finished = Clock::now(); }
1541 
1542  IDuration elapsed() const {
1543  return std::chrono::duration_cast<std::chrono::nanoseconds>(
1544  finished - started);
1545  }
1546 
1547  TimePoint<Clock> started;
1548  TimePoint<Clock> finished;
1549  };
1550  } // namespace Detail
1551 
1552  struct Chronometer {
1553  public:
1554  template<typename Fun>
1555  void measure(Fun &&fun) { measure(CATCH_FORWARD(fun), is_callable<Fun(int)>()); }
1556 
1557  int runs() const { return repeats; }
1558 
1559  Chronometer(Detail::ChronometerConcept &meter, int repeats_)
1560  : impl(&meter)
1561  , repeats(repeats_) {}
1562 
1563  private:
1564  template<typename Fun>
1565  void measure(Fun &&fun, std::false_type) {
1566  measure([&fun](int) { return fun(); }, std::true_type());
1567  }
1568 
1569  template<typename Fun>
1570  void measure(Fun &&fun, std::true_type) {
1571  Detail::optimizer_barrier();
1572  impl->start();
1573  for (int i = 0; i < repeats; ++i) invoke_deoptimized(fun, i);
1574  impl->finish();
1575  Detail::optimizer_barrier();
1576  }
1577 
1579  int repeats;
1580  };
1581  } // namespace Benchmark
1582 } // namespace Catch
1583 
1584 #endif // CATCH_CHRONOMETER_HPP_INCLUDED
1585 
1586 #include <type_traits>
1587 
1588 namespace Catch {
1589  namespace Benchmark {
1590  namespace Detail {
1591  template<typename T, typename U>
1592  static constexpr bool is_related_v = std::is_same<std::decay_t<T>, std::decay_t<U>>::value;
1593 
1602  private:
1603  struct callable {
1604  virtual void call(Chronometer meter) const = 0;
1605  virtual ~callable(); // = default;
1606 
1607  callable() = default;
1608  callable(callable &&) = default;
1609  callable &operator=(callable &&) = default;
1610  };
1611  template<typename Fun>
1612  struct model : public callable {
1613  model(Fun &&fun_)
1614  : fun(CATCH_MOVE(fun_)) {}
1615  model(Fun const &fun_)
1616  : fun(fun_) {}
1617 
1618  void call(Chronometer meter) const override {
1619  call(meter, is_callable<Fun(Chronometer)>());
1620  }
1621  void call(Chronometer meter, std::true_type) const {
1622  fun(meter);
1623  }
1624  void call(Chronometer meter, std::false_type) const {
1625  meter.measure(fun);
1626  }
1627 
1628  Fun fun;
1629  };
1630 
1631  public:
1633 
1634  template<typename Fun,
1635  std::enable_if_t<!is_related_v<Fun, BenchmarkFunction>, int> = 0>
1636  BenchmarkFunction(Fun &&fun)
1637  : f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {}
1638 
1639  BenchmarkFunction(BenchmarkFunction &&that) noexcept
1640  : f(CATCH_MOVE(that.f)) {}
1641 
1643  operator=(BenchmarkFunction &&that) noexcept {
1644  f = CATCH_MOVE(that.f);
1645  return *this;
1646  }
1647 
1648  void operator()(Chronometer meter) const { f->call(meter); }
1649 
1650  private:
1652  };
1653  } // namespace Detail
1654  } // namespace Benchmark
1655 } // namespace Catch
1656 
1657 #endif // CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1658 
1659 // Adapted from donated nonius code.
1660 
1661 #ifndef CATCH_REPEAT_HPP_INCLUDED
1662 #define CATCH_REPEAT_HPP_INCLUDED
1663 
1664 #include <type_traits>
1665 
1666 namespace Catch {
1667  namespace Benchmark {
1668  namespace Detail {
1669  template<typename Fun>
1670  struct repeater {
1671  void operator()(int k) const {
1672  for (int i = 0; i < k; ++i) {
1673  fun();
1674  }
1675  }
1676  Fun fun;
1677  };
1678  template<typename Fun>
1679  repeater<std::decay_t<Fun>> repeat(Fun &&fun) {
1680  return {CATCH_FORWARD(fun)};
1681  }
1682  } // namespace Detail
1683  } // namespace Benchmark
1684 } // namespace Catch
1685 
1686 #endif // CATCH_REPEAT_HPP_INCLUDED
1687 
1688 // Adapted from donated nonius code.
1689 
1690 #ifndef CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
1691 #define CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
1692 
1693 // Adapted from donated nonius code.
1694 
1695 #ifndef CATCH_MEASURE_HPP_INCLUDED
1696 #define CATCH_MEASURE_HPP_INCLUDED
1697 
1698 // Adapted from donated nonius code.
1699 
1700 #ifndef CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1701 #define CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1702 
1703 namespace Catch {
1704  namespace Benchmark {
1705  namespace Detail {
1706  template<typename T>
1707  struct CompleteType {
1708  using type = T;
1709  };
1710  template<>
1711  struct CompleteType<void> {
1712  struct type {};
1713  };
1714 
1715  template<typename T>
1716  using CompleteType_t = typename CompleteType<T>::type;
1717 
1718  template<typename Result>
1720  template<typename Fun, typename... Args>
1721  static Result invoke(Fun &&fun, Args &&...args) {
1722  return CATCH_FORWARD(fun)(CATCH_FORWARD(args)...);
1723  }
1724  };
1725  template<>
1726  struct CompleteInvoker<void> {
1727  template<typename Fun, typename... Args>
1728  static CompleteType_t<void> invoke(Fun &&fun, Args &&...args) {
1729  CATCH_FORWARD(fun)(CATCH_FORWARD(args)...);
1730  return {};
1731  }
1732  };
1733 
1734  // invoke and not return void :(
1735  template<typename Fun, typename... Args>
1736  CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun &&fun, Args &&...args) {
1737  return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...);
1738  }
1739 
1740  } // namespace Detail
1741 
1742  template<typename Fun>
1743  Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun &&fun) {
1744  return Detail::complete_invoke(CATCH_FORWARD(fun));
1745  }
1746  } // namespace Benchmark
1747 } // namespace Catch
1748 
1749 #endif // CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1750 
1751 // Adapted from donated nonius code.
1752 
1753 #ifndef CATCH_TIMING_HPP_INCLUDED
1754 #define CATCH_TIMING_HPP_INCLUDED
1755 
1756 namespace Catch {
1757  namespace Benchmark {
1758  template<typename Result>
1759  struct Timing {
1760  IDuration elapsed;
1761  Result result;
1762  int iterations;
1763  };
1764  template<typename Func, typename... Args>
1765  using TimingOf = Timing<Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
1766  } // namespace Benchmark
1767 } // namespace Catch
1768 
1769 #endif // CATCH_TIMING_HPP_INCLUDED
1770 
1771 namespace Catch {
1772  namespace Benchmark {
1773  namespace Detail {
1774  template<typename Clock, typename Fun, typename... Args>
1775  TimingOf<Fun, Args...> measure(Fun &&fun, Args &&...args) {
1776  auto start = Clock::now();
1777  auto &&r = Detail::complete_invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...);
1778  auto end = Clock::now();
1779  auto delta = end - start;
1780  return {delta, CATCH_FORWARD(r), 1};
1781  }
1782  } // namespace Detail
1783  } // namespace Benchmark
1784 } // namespace Catch
1785 
1786 #endif // CATCH_MEASURE_HPP_INCLUDED
1787 
1788 #include <type_traits>
1789 
1790 namespace Catch {
1791  namespace Benchmark {
1792  namespace Detail {
1793  template<typename Clock, typename Fun>
1794  TimingOf<Fun, int> measure_one(Fun &&fun, int iters, std::false_type) {
1795  return Detail::measure<Clock>(fun, iters);
1796  }
1797  template<typename Clock, typename Fun>
1798  TimingOf<Fun, Chronometer> measure_one(Fun &&fun, int iters, std::true_type) {
1800  auto &&result = Detail::complete_invoke(fun, Chronometer(meter, iters));
1801 
1802  return {meter.elapsed(), CATCH_MOVE(result), iters};
1803  }
1804 
1805  template<typename Clock, typename Fun>
1806  using run_for_at_least_argument_t = std::conditional_t<is_callable<Fun(Chronometer)>::value, Chronometer, int>;
1807 
1808  [[noreturn]]
1809  void throw_optimized_away_error();
1810 
1811  template<typename Clock, typename Fun>
1813  run_for_at_least(IDuration how_long,
1814  const int initial_iterations,
1815  Fun &&fun) {
1816  auto iters = initial_iterations;
1817  while (iters < (1 << 30)) {
1818  auto &&Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
1819 
1820  if (Timing.elapsed >= how_long) {
1821  return {Timing.elapsed, CATCH_MOVE(Timing.result), iters};
1822  }
1823  iters *= 2;
1824  }
1825  throw_optimized_away_error();
1826  }
1827  } // namespace Detail
1828  } // namespace Benchmark
1829 } // namespace Catch
1830 
1831 #endif // CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
1832 
1833 #include <vector>
1834 
1835 namespace Catch {
1836  namespace Benchmark {
1837  struct ExecutionPlan {
1838  int iterations_per_sample;
1839  FDuration estimated_duration;
1840  Detail::BenchmarkFunction benchmark;
1841  FDuration warmup_time;
1842  int warmup_iterations;
1843 
1844  template<typename Clock>
1845  std::vector<FDuration> run(const IConfig &cfg, Environment env) const {
1846  // warmup a bit
1847  Detail::run_for_at_least<Clock>(
1848  std::chrono::duration_cast<IDuration>(warmup_time),
1849  warmup_iterations,
1850  Detail::repeat([]() { return Clock::now(); }));
1851 
1852  std::vector<FDuration> times;
1853  const auto num_samples = cfg.benchmarkSamples();
1854  times.reserve(num_samples);
1855  for (size_t i = 0; i < num_samples; ++i) {
1857  this->benchmark(Chronometer(model, iterations_per_sample));
1858  auto sample_time = model.elapsed() - env.clock_cost.mean;
1859  if (sample_time < FDuration::zero()) {
1860  sample_time = FDuration::zero();
1861  }
1862  times.push_back(sample_time / iterations_per_sample);
1863  }
1864  return times;
1865  }
1866  };
1867  } // namespace Benchmark
1868 } // namespace Catch
1869 
1870 #endif // CATCH_EXECUTION_PLAN_HPP_INCLUDED
1871 
1872 // Adapted from donated nonius code.
1873 
1874 #ifndef CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
1875 #define CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
1876 
1877 // Adapted from donated nonius code.
1878 
1879 #ifndef CATCH_STATS_HPP_INCLUDED
1880 #define CATCH_STATS_HPP_INCLUDED
1881 
1882 #include <vector>
1883 
1884 namespace Catch {
1885  namespace Benchmark {
1886  namespace Detail {
1887  using sample = std::vector<double>;
1888 
1889  double weighted_average_quantile(int k,
1890  int q,
1891  double *first,
1892  double *last);
1893 
1895  classify_outliers(double const *first, double const *last);
1896 
1897  double mean(double const *first, double const *last);
1898 
1899  double normal_cdf(double x);
1900 
1901  double erfc_inv(double x);
1902 
1903  double normal_quantile(double p);
1904 
1906  bootstrap(double confidence_level,
1907  double *first,
1908  double *last,
1909  sample const &resample,
1910  double (*estimator)(double const *, double const *));
1911 
1913  Estimate<double> mean;
1914  Estimate<double> standard_deviation;
1915  double outlier_variance;
1916  };
1917 
1918  bootstrap_analysis analyse_samples(double confidence_level,
1919  unsigned int n_resamples,
1920  double *first,
1921  double *last);
1922  } // namespace Detail
1923  } // namespace Benchmark
1924 } // namespace Catch
1925 
1926 #endif // CATCH_STATS_HPP_INCLUDED
1927 
1928 #include <algorithm>
1929 #include <cmath>
1930 #include <vector>
1931 
1932 namespace Catch {
1933  namespace Benchmark {
1934  namespace Detail {
1935  template<typename Clock>
1936  std::vector<double> resolution(int k) {
1937  const size_t points = static_cast<size_t>(k + 1);
1938  // To avoid overhead from the branch inside vector::push_back,
1939  // we allocate them all and then overwrite.
1940  std::vector<TimePoint<Clock>> times(points);
1941  for (auto &time : times) {
1942  time = Clock::now();
1943  }
1944 
1945  std::vector<double> deltas;
1946  deltas.reserve(static_cast<size_t>(k));
1947  for (size_t idx = 1; idx < points; ++idx) {
1948  deltas.push_back(static_cast<double>(
1949  (times[idx] - times[idx - 1]).count()));
1950  }
1951 
1952  return deltas;
1953  }
1954 
1955  constexpr auto warmup_iterations = 10000;
1956  constexpr auto warmup_time = std::chrono::milliseconds(100);
1957  constexpr auto minimum_ticks = 1000;
1958  constexpr auto warmup_seed = 10000;
1959  constexpr auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
1960  constexpr auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
1961  constexpr auto clock_cost_estimation_tick_limit = 100000;
1962  constexpr auto clock_cost_estimation_time = std::chrono::milliseconds(10);
1963  constexpr auto clock_cost_estimation_iterations = 10000;
1964 
1965  template<typename Clock>
1966  int warmup() {
1967  return run_for_at_least<Clock>(warmup_time, warmup_seed, &resolution<Clock>)
1968  .iterations;
1969  }
1970  template<typename Clock>
1971  EnvironmentEstimate estimate_clock_resolution(int iterations) {
1972  auto r = run_for_at_least<Clock>(clock_resolution_estimation_time, iterations, &resolution<Clock>)
1973  .result;
1974  return {
1975  FDuration(mean(r.data(), r.data() + r.size())),
1976  classify_outliers(r.data(), r.data() + r.size()),
1977  };
1978  }
1979  template<typename Clock>
1980  EnvironmentEstimate estimate_clock_cost(FDuration resolution) {
1981  auto time_limit = (std::min)(
1982  resolution * clock_cost_estimation_tick_limit,
1983  FDuration(clock_cost_estimation_time_limit));
1984  auto time_clock = [](int k) {
1985  return Detail::measure<Clock>([k] {
1986  for (int i = 0; i < k; ++i) {
1987  volatile auto ignored = Clock::now();
1988  (void)ignored;
1989  }
1990  })
1991  .elapsed;
1992  };
1993  time_clock(1);
1994  int iters = clock_cost_estimation_iterations;
1995  auto &&r = run_for_at_least<Clock>(clock_cost_estimation_time, iters, time_clock);
1996  std::vector<double> times;
1997  int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
1998  times.reserve(static_cast<size_t>(nsamples));
1999  for (int s = 0; s < nsamples; ++s) {
2000  times.push_back(static_cast<double>(
2001  (time_clock(r.iterations) / r.iterations)
2002  .count()));
2003  }
2004  return {
2005  FDuration(mean(times.data(), times.data() + times.size())),
2006  classify_outliers(times.data(), times.data() + times.size()),
2007  };
2008  }
2009 
2010  template<typename Clock>
2011  Environment measure_environment() {
2012 #if defined(__clang__)
2013 #pragma clang diagnostic push
2014 #pragma clang diagnostic ignored "-Wexit-time-destructors"
2015 #endif
2017 #if defined(__clang__)
2018 #pragma clang diagnostic pop
2019 #endif
2020  if (env) {
2021  return *env;
2022  }
2023 
2024  auto iters = Detail::warmup<Clock>();
2025  auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
2026  auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
2027 
2028  env = Catch::Detail::make_unique<Environment>(Environment{resolution, cost});
2029  return *env;
2030  }
2031  } // namespace Detail
2032  } // namespace Benchmark
2033 } // namespace Catch
2034 
2035 #endif // CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
2036 
2037 // Adapted from donated nonius code.
2038 
2039 #ifndef CATCH_ANALYSE_HPP_INCLUDED
2040 #define CATCH_ANALYSE_HPP_INCLUDED
2041 
2042 // Adapted from donated nonius code.
2043 
2044 #ifndef CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2045 #define CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2046 
2047 #include <vector>
2048 
2049 namespace Catch {
2050  namespace Benchmark {
2052  std::vector<FDuration> samples;
2053  Estimate<FDuration> mean;
2054  Estimate<FDuration> standard_deviation;
2055  OutlierClassification outliers;
2056  double outlier_variance;
2057  };
2058  } // namespace Benchmark
2059 } // namespace Catch
2060 
2061 #endif // CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2062 
2063 namespace Catch {
2064  class IConfig;
2065 
2066  namespace Benchmark {
2067  namespace Detail {
2068  SampleAnalysis analyse(const IConfig &cfg, FDuration *first, FDuration *last);
2069  } // namespace Detail
2070  } // namespace Benchmark
2071 } // namespace Catch
2072 
2073 #endif // CATCH_ANALYSE_HPP_INCLUDED
2074 
2075 #include <algorithm>
2076 #include <chrono>
2077 #include <cmath>
2078 #include <exception>
2079 #include <string>
2080 
2081 namespace Catch {
2082  namespace Benchmark {
2083  struct Benchmark {
2084  Benchmark(std::string &&benchmarkName)
2085  : name(CATCH_MOVE(benchmarkName)) {}
2086 
2087  template<class FUN>
2088  Benchmark(std::string &&benchmarkName, FUN &&func)
2089  : fun(CATCH_MOVE(func)), name(CATCH_MOVE(benchmarkName)) {}
2090 
2091  template<typename Clock>
2092  ExecutionPlan prepare(const IConfig &cfg, Environment env) {
2093  auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
2094  auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
2095  auto &&test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(run_time), 1, fun);
2096  int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
2097  return {new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), CATCH_MOVE(fun), std::chrono::duration_cast<FDuration>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations};
2098  }
2099 
2100  template<typename Clock = default_clock>
2101  void run() {
2102  static_assert(Clock::is_steady,
2103  "Benchmarking clock should be steady");
2104  auto const *cfg = getCurrentContext().getConfig();
2105 
2106  auto env = Detail::measure_environment<Clock>();
2107 
2108  getResultCapture().benchmarkPreparing(name);
2109  CATCH_TRY {
2110  auto plan = user_code([&] {
2111  return prepare<Clock>(*cfg, env);
2112  });
2113 
2114  BenchmarkInfo info{
2115  CATCH_MOVE(name),
2116  plan.estimated_duration.count(),
2117  plan.iterations_per_sample,
2118  cfg->benchmarkSamples(),
2119  cfg->benchmarkResamples(),
2120  env.clock_resolution.mean.count(),
2121  env.clock_cost.mean.count()};
2122 
2123  getResultCapture().benchmarkStarting(info);
2124 
2125  auto samples = user_code([&] {
2126  return plan.template run<Clock>(*cfg, env);
2127  });
2128 
2129  auto analysis = Detail::analyse(*cfg, samples.data(), samples.data() + samples.size());
2130  BenchmarkStats<> stats{CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance};
2131  getResultCapture().benchmarkEnded(stats);
2132  }
2133  CATCH_CATCH_ALL {
2134  getResultCapture().benchmarkFailed(translateActiveException());
2135  // We let the exception go further up so that the
2136  // test case is marked as failed.
2137  std::rethrow_exception(std::current_exception());
2138  }
2139  }
2140 
2141  // sets lambda to be used in fun *and* executes benchmark!
2142  template<typename Fun, std::enable_if_t<!Detail::is_related_v<Fun, Benchmark>, int> = 0>
2143  Benchmark &operator=(Fun func) {
2144  auto const *cfg = getCurrentContext().getConfig();
2145  if (!cfg->skipBenchmarks()) {
2146  fun = Detail::BenchmarkFunction(func);
2147  run();
2148  }
2149  return *this;
2150  }
2151 
2152  explicit operator bool() {
2153  return true;
2154  }
2155 
2156  private:
2158  std::string name;
2159  };
2160  } // namespace Benchmark
2161 } // namespace Catch
2162 
2163 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
2164 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
2165 
2166 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex) \
2167  if (Catch::Benchmark::Benchmark BenchmarkName{name}) \
2168  BenchmarkName = [&](int benchmarkIndex)
2169 
2170 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name) \
2171  if (Catch::Benchmark::Benchmark BenchmarkName{name}) \
2172  BenchmarkName = [&]
2173 
2174 #if defined(CATCH_CONFIG_PREFIX_ALL)
2175 
2176 #define CATCH_BENCHMARK(...) \
2177  INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__, , ), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__, , ))
2178 #define CATCH_BENCHMARK_ADVANCED(name) \
2179  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name)
2180 
2181 #else
2182 
2183 #define BENCHMARK(...) \
2184  INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__, , ), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__, , ))
2185 #define BENCHMARK_ADVANCED(name) \
2186  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name)
2187 
2188 #endif
2189 
2190 #endif // CATCH_BENCHMARK_HPP_INCLUDED
2191 
2192 // Adapted from donated nonius code.
2193 
2194 #ifndef CATCH_CONSTRUCTOR_HPP_INCLUDED
2195 #define CATCH_CONSTRUCTOR_HPP_INCLUDED
2196 
2197 #include <type_traits>
2198 
2199 namespace Catch {
2200  namespace Benchmark {
2201  namespace Detail {
2202  template<typename T, bool Destruct>
2203  struct ObjectStorage {
2204  ObjectStorage() = default;
2205 
2206  ObjectStorage(const ObjectStorage &other) {
2207  new (&data) T(other.stored_object());
2208  }
2209 
2210  ObjectStorage(ObjectStorage &&other) {
2211  new (data) T(CATCH_MOVE(other.stored_object()));
2212  }
2213 
2214  ~ObjectStorage() { destruct_on_exit<T>(); }
2215 
2216  template<typename... Args>
2217  void construct(Args &&...args) {
2218  new (data) T(CATCH_FORWARD(args)...);
2219  }
2220 
2221  template<bool AllowManualDestruction = !Destruct>
2222  std::enable_if_t<AllowManualDestruction> destruct() {
2223  stored_object().~T();
2224  }
2225 
2226  private:
2227  // If this is a constructor benchmark, destruct the underlying object
2228  template<typename U>
2229  void destruct_on_exit(std::enable_if_t<Destruct, U> * = nullptr) { destruct<true>(); }
2230  // Otherwise, don't
2231  template<typename U>
2232  void destruct_on_exit(std::enable_if_t<!Destruct, U> * = nullptr) {}
2233 
2234 #if defined(__GNUC__) && __GNUC__ <= 6
2235 #pragma GCC diagnostic push
2236 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
2237 #endif
2238  T &stored_object() { return *reinterpret_cast<T *>(data); }
2239 
2240  T const &stored_object() const {
2241  return *reinterpret_cast<T const *>(data);
2242  }
2243 #if defined(__GNUC__) && __GNUC__ <= 6
2244 #pragma GCC diagnostic pop
2245 #endif
2246 
2247  alignas(T) unsigned char data[sizeof(T)]{};
2248  };
2249  } // namespace Detail
2250 
2251  template<typename T>
2253 
2254  template<typename T>
2256  } // namespace Benchmark
2257 } // namespace Catch
2258 
2259 #endif // CATCH_CONSTRUCTOR_HPP_INCLUDED
2260 
2261 #endif // CATCH_BENCHMARK_ALL_HPP_INCLUDED
2262 
2263 #ifndef CATCH_APPROX_HPP_INCLUDED
2264 #define CATCH_APPROX_HPP_INCLUDED
2265 
2266 #ifndef CATCH_TOSTRING_HPP_INCLUDED
2267 #define CATCH_TOSTRING_HPP_INCLUDED
2268 
2269 #include <cstddef>
2270 #include <ctime>
2271 #include <string>
2272 #include <type_traits>
2273 #include <vector>
2274 
2283 #ifndef CATCH_CONFIG_WCHAR_HPP_INCLUDED
2284 #define CATCH_CONFIG_WCHAR_HPP_INCLUDED
2285 
2286 // We assume that WCHAR should be enabled by default, and only disabled
2287 // for a shortlist (so far only DJGPP) of compilers.
2288 
2289 #if defined(__DJGPP__)
2290 #define CATCH_INTERNAL_CONFIG_NO_WCHAR
2291 #endif // __DJGPP__
2292 
2293 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
2294 #define CATCH_CONFIG_WCHAR
2295 #endif
2296 
2297 #endif // CATCH_CONFIG_WCHAR_HPP_INCLUDED
2298 
2299 #ifndef CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2300 #define CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2301 
2302 #include <cstddef>
2303 #include <iosfwd>
2304 #include <ostream>
2305 #include <string>
2306 
2307 namespace Catch {
2308 
2310  std::size_t m_index;
2311  std::ostream *m_oss;
2312 
2313  public:
2316 
2318  std::string str() const;
2320  void str(std::string const &str);
2321 
2322 #if defined(__GNUC__) && !defined(__clang__)
2323 #pragma GCC diagnostic push
2324 // Old versions of GCC do not understand -Wnonnull-compare
2325 #pragma GCC diagnostic ignored "-Wpragmas"
2326 // Streaming a function pointer triggers Waddress and Wnonnull-compare
2327 // on GCC, because it implicitly converts it to bool and then decides
2328 // that the check it uses (a? true : false) is tautological and cannot
2329 // be null...
2330 #pragma GCC diagnostic ignored "-Waddress"
2331 #pragma GCC diagnostic ignored "-Wnonnull-compare"
2332 #endif
2333 
2334  template<typename T>
2335  auto operator<<(T const &value) -> ReusableStringStream & {
2336  *m_oss << value;
2337  return *this;
2338  }
2339 
2340 #if defined(__GNUC__) && !defined(__clang__)
2341 #pragma GCC diagnostic pop
2342 #endif
2343  auto get() -> std::ostream & { return *m_oss; }
2344  };
2345 } // namespace Catch
2346 
2347 #endif // CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2348 
2349 #ifndef CATCH_VOID_TYPE_HPP_INCLUDED
2350 #define CATCH_VOID_TYPE_HPP_INCLUDED
2351 
2352 namespace Catch {
2353  namespace Detail {
2354 
2355  template<typename...>
2356  struct make_void {
2357  using type = void;
2358  };
2359 
2360  template<typename... Ts>
2361  using void_t = typename make_void<Ts...>::type;
2362 
2363  } // namespace Detail
2364 } // namespace Catch
2365 
2366 #endif // CATCH_VOID_TYPE_HPP_INCLUDED
2367 
2368 #ifndef CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2369 #define CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2370 
2371 #include <vector>
2372 
2373 namespace Catch {
2374 
2375  namespace Detail {
2376  struct EnumInfo {
2377  StringRef m_name;
2378  std::vector<std::pair<int, StringRef>> m_values;
2379 
2380  ~EnumInfo();
2381 
2382  StringRef lookup(int value) const;
2383  };
2384  } // namespace Detail
2385 
2387  public:
2388  virtual ~IMutableEnumValuesRegistry(); // = default;
2389 
2390  virtual Detail::EnumInfo const &registerEnum(StringRef enumName, StringRef allEnums, std::vector<int> const &values) = 0;
2391 
2392  template<typename E>
2393  Detail::EnumInfo const &registerEnum(StringRef enumName, StringRef allEnums, std::initializer_list<E> values) {
2394  static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
2395  std::vector<int> intValues;
2396  intValues.reserve(values.size());
2397  for (auto enumValue : values)
2398  intValues.push_back(static_cast<int>(enumValue));
2399  return registerEnum(enumName, allEnums, intValues);
2400  }
2401  };
2402 
2403 } // namespace Catch
2404 
2405 #endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2406 
2407 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2408 #include <string_view>
2409 #endif
2410 
2411 #ifdef _MSC_VER
2412 #pragma warning(push)
2413 #pragma warning(disable : 4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
2414 #endif
2415 
2416 // We need a dummy global operator<< so we can bring it into Catch namespace later
2418 std::ostream &operator<<(std::ostream &, Catch_global_namespace_dummy);
2419 
2420 namespace Catch {
2421  // Bring in global namespace operator<< for ADL lookup in
2422  // `IsStreamInsertable` below.
2423  using ::operator<<;
2424 
2425  namespace Detail {
2426 
2427  std::size_t catch_strnlen(const char *str, std::size_t n);
2428 
2429  std::string formatTimeT(std::time_t time);
2430 
2431  constexpr StringRef unprintableString = "{?}"_sr;
2432 
2434  std::string convertIntoString(StringRef string, bool escapeInvisibles);
2435 
2438  std::string convertIntoString(StringRef string);
2439 
2440  std::string rawMemoryToString(const void *object, std::size_t size);
2441 
2442  template<typename T>
2443  std::string rawMemoryToString(const T &object) {
2444  return rawMemoryToString(&object, sizeof(object));
2445  }
2446 
2447  template<typename T, typename = void>
2448  static constexpr bool IsStreamInsertable_v = false;
2449 
2450  template<typename T>
2451  static constexpr bool IsStreamInsertable_v<
2452  T,
2453  decltype(void(std::declval<std::ostream &>() << std::declval<T>()))>
2454  = true;
2455 
2456  template<typename E>
2457  std::string convertUnknownEnumToString(E e);
2458 
2459  template<typename T>
2460  std::enable_if_t<
2461  !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
2462  std::string>
2463  convertUnstreamable(T const &) {
2464  return std::string(Detail::unprintableString);
2465  }
2466  template<typename T>
2467  std::enable_if_t<
2468  !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
2469  std::string>
2470  convertUnstreamable(T const &ex) {
2471  return ex.what();
2472  }
2473 
2474  template<typename T>
2475  std::enable_if_t<
2476  std::is_enum<T>::value,
2477  std::string>
2478  convertUnstreamable(T const &value) {
2479  return convertUnknownEnumToString(value);
2480  }
2481 
2482 #if defined(_MANAGED)
2483  template<typename T>
2485  std::string clrReferenceToString(T ^ ref) {
2486  if (ref == nullptr)
2487  return std::string("null");
2488  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
2489  cli::pin_ptr<System::Byte> p = &bytes[0];
2490  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
2491  }
2492 #endif
2493 
2494  } // namespace Detail
2495 
2496  template<typename T, typename = void>
2497  struct StringMaker {
2498  template<typename Fake = T>
2499  static std::enable_if_t<::Catch::Detail::IsStreamInsertable_v<Fake>, std::string>
2500  convert(const Fake &value) {
2502  // NB: call using the function-like syntax to avoid ambiguity with
2503  // user-defined templated operator<< under clang.
2504  rss.operator<<(value);
2505  return rss.str();
2506  }
2507 
2508  template<typename Fake = T>
2509  static std::enable_if_t<!::Catch::Detail::IsStreamInsertable_v<Fake>, std::string>
2510  convert(const Fake &value) {
2511 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
2512  return Detail::convertUnstreamable(value);
2513 #else
2514  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
2515 #endif
2516  }
2517  };
2518 
2519  namespace Detail {
2520 
2521  std::string makeExceptionHappenedString();
2522 
2523  // This function dispatches all stringification requests inside of Catch.
2524  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
2525  template<typename T>
2526  std::string stringify(const T &e) {
2527  CATCH_TRY {
2528  return ::Catch::StringMaker<
2529  std::remove_cv_t<std::remove_reference_t<T>>>::convert(e);
2530  }
2531  CATCH_CATCH_ALL {
2532  return makeExceptionHappenedString();
2533  }
2534  }
2535 
2536  template<typename E>
2537  std::string convertUnknownEnumToString(E e) {
2538  return ::Catch::Detail::stringify(static_cast<std::underlying_type_t<E>>(e));
2539  }
2540 
2541 #if defined(_MANAGED)
2542  template<typename T>
2543  std::string stringify(T ^ e) {
2544  return ::Catch::StringMaker<T ^>::convert(e);
2545  }
2546 #endif
2547 
2548  } // namespace Detail
2549 
2550  // Some predefined specializations
2551 
2552  template<>
2553  struct StringMaker<std::string> {
2554  static std::string convert(const std::string &str);
2555  };
2556 
2557 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2558  template<>
2559  struct StringMaker<std::string_view> {
2560  static std::string convert(std::string_view str);
2561  };
2562 #endif
2563 
2564  template<>
2565  struct StringMaker<char const *> {
2566  static std::string convert(char const *str);
2567  };
2568  template<>
2569  struct StringMaker<char *> {
2570  static std::string convert(char *str);
2571  };
2572 
2573 #if defined(CATCH_CONFIG_WCHAR)
2574  template<>
2575  struct StringMaker<std::wstring> {
2576  static std::string convert(const std::wstring &wstr);
2577  };
2578 
2579 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2580  template<>
2581  struct StringMaker<std::wstring_view> {
2582  static std::string convert(std::wstring_view str);
2583  };
2584 #endif
2585 
2586  template<>
2587  struct StringMaker<wchar_t const *> {
2588  static std::string convert(wchar_t const *str);
2589  };
2590  template<>
2591  struct StringMaker<wchar_t *> {
2592  static std::string convert(wchar_t *str);
2593  };
2594 #endif // CATCH_CONFIG_WCHAR
2595 
2596  template<size_t SZ>
2597  struct StringMaker<char[SZ]> {
2598  static std::string convert(char const *str) {
2599  return Detail::convertIntoString(
2600  StringRef(str, Detail::catch_strnlen(str, SZ)));
2601  }
2602  };
2603  template<size_t SZ>
2604  struct StringMaker<signed char[SZ]> {
2605  static std::string convert(signed char const *str) {
2606  auto reinterpreted = reinterpret_cast<char const *>(str);
2607  return Detail::convertIntoString(
2608  StringRef(reinterpreted, Detail::catch_strnlen(reinterpreted, SZ)));
2609  }
2610  };
2611  template<size_t SZ>
2612  struct StringMaker<unsigned char[SZ]> {
2613  static std::string convert(unsigned char const *str) {
2614  auto reinterpreted = reinterpret_cast<char const *>(str);
2615  return Detail::convertIntoString(
2616  StringRef(reinterpreted, Detail::catch_strnlen(reinterpreted, SZ)));
2617  }
2618  };
2619 
2620 #if defined(CATCH_CONFIG_CPP17_BYTE)
2621  template<>
2622  struct StringMaker<std::byte> {
2623  static std::string convert(std::byte value);
2624  };
2625 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
2626  template<>
2627  struct StringMaker<int> {
2628  static std::string convert(int value);
2629  };
2630  template<>
2631  struct StringMaker<long> {
2632  static std::string convert(long value);
2633  };
2634  template<>
2635  struct StringMaker<long long> {
2636  static std::string convert(long long value);
2637  };
2638  template<>
2639  struct StringMaker<unsigned int> {
2640  static std::string convert(unsigned int value);
2641  };
2642  template<>
2643  struct StringMaker<unsigned long> {
2644  static std::string convert(unsigned long value);
2645  };
2646  template<>
2647  struct StringMaker<unsigned long long> {
2648  static std::string convert(unsigned long long value);
2649  };
2650 
2651  template<>
2652  struct StringMaker<bool> {
2653  static std::string convert(bool b) {
2654  using namespace std::string_literals;
2655  return b ? "true"s : "false"s;
2656  }
2657  };
2658 
2659  template<>
2660  struct StringMaker<char> {
2661  static std::string convert(char c);
2662  };
2663  template<>
2664  struct StringMaker<signed char> {
2665  static std::string convert(signed char value);
2666  };
2667  template<>
2668  struct StringMaker<unsigned char> {
2669  static std::string convert(unsigned char value);
2670  };
2671 
2672  template<>
2673  struct StringMaker<std::nullptr_t> {
2674  static std::string convert(std::nullptr_t) {
2675  using namespace std::string_literals;
2676  return "nullptr"s;
2677  }
2678  };
2679 
2680  template<>
2681  struct StringMaker<float> {
2682  static std::string convert(float value);
2683  CATCH_EXPORT static int precision;
2684  };
2685 
2686  template<>
2687  struct StringMaker<double> {
2688  static std::string convert(double value);
2689  CATCH_EXPORT static int precision;
2690  };
2691 
2692  template<typename T>
2693  struct StringMaker<T *> {
2694  template<typename U>
2695  static std::string convert(U *p) {
2696  if (p) {
2697  return ::Catch::Detail::rawMemoryToString(p);
2698  } else {
2699  return "nullptr";
2700  }
2701  }
2702  };
2703 
2704  template<typename R, typename C>
2705  struct StringMaker<R C::*> {
2706  static std::string convert(R C::*p) {
2707  if (p) {
2708  return ::Catch::Detail::rawMemoryToString(p);
2709  } else {
2710  return "nullptr";
2711  }
2712  }
2713  };
2714 
2715 #if defined(_MANAGED)
2716  template<typename T>
2717  struct StringMaker<T ^> {
2718  static std::string convert(T ^ ref) {
2719  return ::Catch::Detail::clrReferenceToString(ref);
2720  }
2721  };
2722 #endif
2723 
2724  namespace Detail {
2725  template<typename InputIterator, typename Sentinel = InputIterator>
2726  std::string rangeToString(InputIterator first, Sentinel last) {
2728  rss << "{ ";
2729  if (first != last) {
2730  rss << ::Catch::Detail::stringify(*first);
2731  for (++first; first != last; ++first)
2732  rss << ", " << ::Catch::Detail::stringify(*first);
2733  }
2734  rss << " }";
2735  return rss.str();
2736  }
2737  } // namespace Detail
2738 
2739 } // namespace Catch
2740 
2742 // Separate std-lib types stringification, so it can be selectively enabled
2743 // This means that we do not bring in their headers
2744 
2745 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
2746 #define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2747 #define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2748 #define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2749 #define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2750 #endif
2751 
2752 // Separate std::pair specialization
2753 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
2754 #include <utility>
2755 namespace Catch {
2756  template<typename T1, typename T2>
2757  struct StringMaker<std::pair<T1, T2>> {
2758  static std::string convert(const std::pair<T1, T2> &pair) {
2760  rss << "{ "
2761  << ::Catch::Detail::stringify(pair.first)
2762  << ", "
2763  << ::Catch::Detail::stringify(pair.second)
2764  << " }";
2765  return rss.str();
2766  }
2767  };
2768 } // namespace Catch
2769 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2770 
2771 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
2772 #include <optional>
2773 namespace Catch {
2774  template<typename T>
2775  struct StringMaker<std::optional<T>> {
2776  static std::string convert(const std::optional<T> &optional) {
2777  if (optional.has_value()) {
2778  return ::Catch::Detail::stringify(*optional);
2779  } else {
2780  return "{ }";
2781  }
2782  }
2783  };
2784  template<>
2785  struct StringMaker<std::nullopt_t> {
2786  static std::string convert(const std::nullopt_t &) {
2787  return "{ }";
2788  }
2789  };
2790 } // namespace Catch
2791 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2792 
2793 // Separate std::tuple specialization
2794 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
2795 #include <tuple>
2796 #include <utility>
2797 namespace Catch {
2798  namespace Detail {
2799  template<typename Tuple, std::size_t... Is>
2800  void PrintTuple(const Tuple &tuple,
2801  std::ostream &os,
2802  std::index_sequence<Is...>) {
2803  // 1 + Account for when the tuple is empty
2804  char a[1 + sizeof...(Is)] = {
2805  ((os << (Is ? ", " : " ")
2806  << ::Catch::Detail::stringify(std::get<Is>(tuple))),
2807  '\0')...};
2808  (void)a;
2809  }
2810 
2811  } // namespace Detail
2812 
2813  template<typename... Types>
2814  struct StringMaker<std::tuple<Types...>> {
2815  static std::string convert(const std::tuple<Types...> &tuple) {
2817  rss << '{';
2818  Detail::PrintTuple(
2819  tuple,
2820  rss.get(),
2821  std::make_index_sequence<sizeof...(Types)>{});
2822  rss << " }";
2823  return rss.str();
2824  }
2825  };
2826 } // namespace Catch
2827 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2828 
2829 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
2830 #include <variant>
2831 namespace Catch {
2832  template<>
2833  struct StringMaker<std::monostate> {
2834  static std::string convert(const std::monostate &) {
2835  return "{ }";
2836  }
2837  };
2838 
2839  template<typename... Elements>
2840  struct StringMaker<std::variant<Elements...>> {
2841  static std::string convert(const std::variant<Elements...> &variant) {
2842  if (variant.valueless_by_exception()) {
2843  return "{valueless variant}";
2844  } else {
2845  return std::visit(
2846  [](const auto &value) {
2847  return ::Catch::Detail::stringify(value);
2848  },
2849  variant);
2850  }
2851  }
2852  };
2853 } // namespace Catch
2854 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2855 
2856 namespace Catch {
2857  // Import begin/ end from std here
2858  using std::begin;
2859  using std::end;
2860 
2861  namespace Detail {
2862  template<typename T, typename = void>
2863  struct is_range_impl : std::false_type {};
2864 
2865  template<typename T>
2866  struct is_range_impl<T, void_t<decltype(begin(std::declval<T>()))>> : std::true_type {};
2867  } // namespace Detail
2868 
2869  template<typename T>
2871 
2872 #if defined(_MANAGED) // Managed types are never ranges
2873  template<typename T>
2874  struct is_range<T ^> {
2875  static const bool value = false;
2876  };
2877 #endif
2878 
2879  template<typename Range>
2880  std::string rangeToString(Range const &range) {
2881  return ::Catch::Detail::rangeToString(begin(range), end(range));
2882  }
2883 
2884  // Handle vector<bool> specially
2885  template<typename Allocator>
2886  std::string rangeToString(std::vector<bool, Allocator> const &v) {
2888  rss << "{ ";
2889  bool first = true;
2890  for (bool b : v) {
2891  if (first)
2892  first = false;
2893  else
2894  rss << ", ";
2895  rss << ::Catch::Detail::stringify(b);
2896  }
2897  rss << " }";
2898  return rss.str();
2899  }
2900 
2901  template<typename R>
2902  struct StringMaker<R, std::enable_if_t<is_range<R>::value && !::Catch::Detail::IsStreamInsertable_v<R>>> {
2903  static std::string convert(R const &range) {
2904  return rangeToString(range);
2905  }
2906  };
2907 
2908  template<typename T, size_t SZ>
2909  struct StringMaker<T[SZ]> {
2910  static std::string convert(T const (&arr)[SZ]) {
2911  return rangeToString(arr);
2912  }
2913  };
2914 
2915 } // namespace Catch
2916 
2917 // Separate std::chrono::duration specialization
2918 #include <chrono>
2919 #include <ctime>
2920 #include <ratio>
2921 
2922 namespace Catch {
2923 
2924  template<class Ratio>
2925  struct ratio_string {
2926  static std::string symbol() {
2928  rss << '[' << Ratio::num << '/'
2929  << Ratio::den << ']';
2930  return rss.str();
2931  }
2932  };
2933 
2934  template<>
2935  struct ratio_string<std::atto> {
2936  static char symbol() { return 'a'; }
2937  };
2938  template<>
2939  struct ratio_string<std::femto> {
2940  static char symbol() { return 'f'; }
2941  };
2942  template<>
2943  struct ratio_string<std::pico> {
2944  static char symbol() { return 'p'; }
2945  };
2946  template<>
2947  struct ratio_string<std::nano> {
2948  static char symbol() { return 'n'; }
2949  };
2950  template<>
2951  struct ratio_string<std::micro> {
2952  static char symbol() { return 'u'; }
2953  };
2954  template<>
2955  struct ratio_string<std::milli> {
2956  static char symbol() { return 'm'; }
2957  };
2958 
2960  // std::chrono::duration specializations
2961  template<typename Value, typename Ratio>
2962  struct StringMaker<std::chrono::duration<Value, Ratio>> {
2963  static std::string convert(std::chrono::duration<Value, Ratio> const &duration) {
2965  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2966  return rss.str();
2967  }
2968  };
2969  template<typename Value>
2970  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2971  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const &duration) {
2973  rss << duration.count() << " s";
2974  return rss.str();
2975  }
2976  };
2977  template<typename Value>
2978  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2979  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const &duration) {
2981  rss << duration.count() << " m";
2982  return rss.str();
2983  }
2984  };
2985  template<typename Value>
2986  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2987  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const &duration) {
2989  rss << duration.count() << " h";
2990  return rss.str();
2991  }
2992  };
2993 
2995  // std::chrono::time_point specialization
2996  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2997  template<typename Clock, typename Duration>
2998  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2999  static std::string convert(std::chrono::time_point<Clock, Duration> const &time_point) {
3000  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
3001  }
3002  };
3003  // std::chrono::time_point<system_clock> specialization
3004  template<typename Duration>
3005  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
3006  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const &time_point) {
3007  const auto systemish = std::chrono::time_point_cast<
3008  std::chrono::system_clock::duration>(time_point);
3009  const auto as_time_t = std::chrono::system_clock::to_time_t(systemish);
3010  return ::Catch::Detail::formatTimeT(as_time_t);
3011  }
3012  };
3013 } // namespace Catch
3014 
3015 #define INTERNAL_CATCH_REGISTER_ENUM(enumName, ...) \
3016  namespace Catch { \
3017  template<> \
3018  struct StringMaker<enumName> { \
3019  static std::string convert(enumName value) { \
3020  static const auto &enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum(#enumName, #__VA_ARGS__, {__VA_ARGS__}); \
3021  return static_cast<std::string>(enumInfo.lookup(static_cast<int>(value))); \
3022  } \
3023  }; \
3024  }
3025 
3026 #define CATCH_REGISTER_ENUM(enumName, ...) INTERNAL_CATCH_REGISTER_ENUM(enumName, __VA_ARGS__)
3027 
3028 #ifdef _MSC_VER
3029 #pragma warning(pop)
3030 #endif
3031 
3032 #endif // CATCH_TOSTRING_HPP_INCLUDED
3033 
3034 #include <type_traits>
3035 
3036 namespace Catch {
3037 
3038  class Approx {
3039  private:
3040  bool equalityComparisonImpl(double other) const;
3041  // Sets and validates the new margin (margin >= 0)
3042  void setMargin(double margin);
3043  // Sets and validates the new epsilon (0 < epsilon < 1)
3044  void setEpsilon(double epsilon);
3045 
3046  public:
3047  explicit Approx(double value);
3048 
3049  static Approx custom();
3050 
3051  Approx operator-() const;
3052 
3053  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3054  Approx operator()(T const &value) const {
3055  Approx approx(static_cast<double>(value));
3056  approx.m_epsilon = m_epsilon;
3057  approx.m_margin = m_margin;
3058  approx.m_scale = m_scale;
3059  return approx;
3060  }
3061 
3062  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3063  explicit Approx(T const &value)
3064  : Approx(static_cast<double>(value)) {}
3065 
3066  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3067  friend bool operator==(const T &lhs, Approx const &rhs) {
3068  auto lhs_v = static_cast<double>(lhs);
3069  return rhs.equalityComparisonImpl(lhs_v);
3070  }
3071 
3072  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3073  friend bool operator==(Approx const &lhs, const T &rhs) {
3074  return operator==(rhs, lhs);
3075  }
3076 
3077  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3078  friend bool operator!=(T const &lhs, Approx const &rhs) {
3079  return !operator==(lhs, rhs);
3080  }
3081 
3082  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3083  friend bool operator!=(Approx const &lhs, T const &rhs) {
3084  return !operator==(rhs, lhs);
3085  }
3086 
3087  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3088  friend bool operator<=(T const &lhs, Approx const &rhs) {
3089  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3090  }
3091 
3092  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3093  friend bool operator<=(Approx const &lhs, T const &rhs) {
3094  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3095  }
3096 
3097  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3098  friend bool operator>=(T const &lhs, Approx const &rhs) {
3099  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3100  }
3101 
3102  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3103  friend bool operator>=(Approx const &lhs, T const &rhs) {
3104  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3105  }
3106 
3107  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3108  Approx &epsilon(T const &newEpsilon) {
3109  const auto epsilonAsDouble = static_cast<double>(newEpsilon);
3110  setEpsilon(epsilonAsDouble);
3111  return *this;
3112  }
3113 
3114  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3115  Approx &margin(T const &newMargin) {
3116  const auto marginAsDouble = static_cast<double>(newMargin);
3117  setMargin(marginAsDouble);
3118  return *this;
3119  }
3120 
3121  template<typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3122  Approx &scale(T const &newScale) {
3123  m_scale = static_cast<double>(newScale);
3124  return *this;
3125  }
3126 
3127  std::string toString() const;
3128 
3129  private:
3130  double m_epsilon;
3131  double m_margin;
3132  double m_scale;
3133  double m_value;
3134  };
3135 
3136  namespace literals {
3137  Approx operator""_a(long double val);
3138  Approx operator""_a(unsigned long long val);
3139  } // end namespace literals
3140 
3141  template<>
3143  static std::string convert(Catch::Approx const &value);
3144  };
3145 
3146 } // end namespace Catch
3147 
3148 #endif // CATCH_APPROX_HPP_INCLUDED
3149 
3150 #ifndef CATCH_ASSERTION_INFO_HPP_INCLUDED
3151 #define CATCH_ASSERTION_INFO_HPP_INCLUDED
3152 
3153 #ifndef CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
3154 #define CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
3155 
3156 #include <cstddef>
3157 #include <iosfwd>
3158 
3159 namespace Catch {
3160 
3162  SourceLineInfo() = delete;
3163  constexpr SourceLineInfo(char const *_file, std::size_t _line) noexcept
3164  : file(_file), line(_line) {}
3165 
3166  bool operator==(SourceLineInfo const &other) const noexcept;
3167  bool operator<(SourceLineInfo const &other) const noexcept;
3168 
3169  char const *file;
3170  std::size_t line;
3171 
3172  friend std::ostream &operator<<(std::ostream &os, SourceLineInfo const &info);
3173  };
3174 } // namespace Catch
3175 
3176 #define CATCH_INTERNAL_LINEINFO \
3177  ::Catch::SourceLineInfo(__FILE__, static_cast<std::size_t>(__LINE__))
3178 
3179 #endif // CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
3180 
3181 namespace Catch {
3182 
3183  struct AssertionInfo {
3184  // AssertionInfo() = delete;
3185 
3186  StringRef macroName;
3187  SourceLineInfo lineInfo;
3188  StringRef capturedExpression;
3189  ResultDisposition::Flags resultDisposition;
3190  };
3191 
3192 } // end namespace Catch
3193 
3194 #endif // CATCH_ASSERTION_INFO_HPP_INCLUDED
3195 
3196 #ifndef CATCH_ASSERTION_RESULT_HPP_INCLUDED
3197 #define CATCH_ASSERTION_RESULT_HPP_INCLUDED
3198 
3199 #ifndef CATCH_LAZY_EXPR_HPP_INCLUDED
3200 #define CATCH_LAZY_EXPR_HPP_INCLUDED
3201 
3202 #include <iosfwd>
3203 
3204 namespace Catch {
3205 
3206  class ITransientExpression;
3207 
3209  friend class AssertionHandler;
3210  friend struct AssertionStats;
3211  friend class RunContext;
3212 
3213  ITransientExpression const *m_transientExpression = nullptr;
3214  bool m_isNegated;
3215 
3216  public:
3217  constexpr LazyExpression(bool isNegated)
3218  : m_isNegated(isNegated) {}
3219  constexpr LazyExpression(LazyExpression const &other) = default;
3220  LazyExpression &operator=(LazyExpression const &) = delete;
3221 
3222  constexpr explicit operator bool() const {
3223  return m_transientExpression != nullptr;
3224  }
3225 
3226  friend auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream &;
3227  };
3228 
3229 } // namespace Catch
3230 
3231 #endif // CATCH_LAZY_EXPR_HPP_INCLUDED
3232 
3233 #include <string>
3234 
3235 namespace Catch {
3236 
3238  AssertionResultData() = delete;
3239 
3240  AssertionResultData(ResultWas::OfType _resultType, LazyExpression const &_lazyExpression);
3241 
3242  std::string message;
3243  mutable std::string reconstructedExpression;
3244  LazyExpression lazyExpression;
3245  ResultWas::OfType resultType;
3246 
3247  std::string reconstructExpression() const;
3248  };
3249 
3251  public:
3252  AssertionResult() = delete;
3253  AssertionResult(AssertionInfo const &info, AssertionResultData &&data);
3254 
3255  bool isOk() const;
3256  bool succeeded() const;
3257  ResultWas::OfType getResultType() const;
3258  bool hasExpression() const;
3259  bool hasMessage() const;
3260  std::string getExpression() const;
3261  std::string getExpressionInMacro() const;
3262  bool hasExpandedExpression() const;
3263  std::string getExpandedExpression() const;
3264  StringRef getMessage() const;
3265  SourceLineInfo getSourceInfo() const;
3266  StringRef getTestMacroName() const;
3267 
3268  // protected:
3269  AssertionInfo m_info;
3270  AssertionResultData m_resultData;
3271  };
3272 
3273 } // end namespace Catch
3274 
3275 #endif // CATCH_ASSERTION_RESULT_HPP_INCLUDED
3276 
3277 #ifndef CATCH_CASE_SENSITIVE_HPP_INCLUDED
3278 #define CATCH_CASE_SENSITIVE_HPP_INCLUDED
3279 
3280 namespace Catch {
3281 
3282  enum class CaseSensitive { Yes,
3283  No };
3284 
3285 } // namespace Catch
3286 
3287 #endif // CATCH_CASE_SENSITIVE_HPP_INCLUDED
3288 
3289 #ifndef CATCH_CONFIG_HPP_INCLUDED
3290 #define CATCH_CONFIG_HPP_INCLUDED
3291 
3292 #ifndef CATCH_TEST_SPEC_HPP_INCLUDED
3293 #define CATCH_TEST_SPEC_HPP_INCLUDED
3294 
3295 #ifdef __clang__
3296 #pragma clang diagnostic push
3297 #pragma clang diagnostic ignored "-Wpadded"
3298 #endif
3299 
3300 #ifndef CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3301 #define CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3302 
3303 #include <string>
3304 
3305 namespace Catch {
3307  enum WildcardPosition {
3308  NoWildcard = 0,
3309  WildcardAtStart = 1,
3310  WildcardAtEnd = 2,
3311  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3312  };
3313 
3314  public:
3315  WildcardPattern(std::string const &pattern, CaseSensitive caseSensitivity);
3316  bool matches(std::string const &str) const;
3317 
3318  private:
3319  std::string normaliseString(std::string const &str) const;
3320  CaseSensitive m_caseSensitivity;
3321  WildcardPosition m_wildcard = NoWildcard;
3322  std::string m_pattern;
3323  };
3324 } // namespace Catch
3325 
3326 #endif // CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3327 
3328 #include <iosfwd>
3329 #include <string>
3330 #include <vector>
3331 
3332 namespace Catch {
3333 
3334  class IConfig;
3335  struct TestCaseInfo;
3336  class TestCaseHandle;
3337 
3338  class TestSpec {
3339  class Pattern {
3340  public:
3341  explicit Pattern(std::string const &name);
3342  virtual ~Pattern();
3343  virtual bool matches(TestCaseInfo const &testCase) const = 0;
3344  std::string const &name() const;
3345 
3346  private:
3347  virtual void serializeTo(std::ostream &out) const = 0;
3348  // Writes string that would be reparsed into the pattern
3349  friend std::ostream &operator<<(std::ostream &out,
3350  Pattern const &pattern) {
3351  pattern.serializeTo(out);
3352  return out;
3353  }
3354 
3355  std::string const m_name;
3356  };
3357 
3358  class NamePattern : public Pattern {
3359  public:
3360  explicit NamePattern(std::string const &name, std::string const &filterString);
3361  bool matches(TestCaseInfo const &testCase) const override;
3362 
3363  private:
3364  void serializeTo(std::ostream &out) const override;
3365 
3366  WildcardPattern m_wildcardPattern;
3367  };
3368 
3369  class TagPattern : public Pattern {
3370  public:
3371  explicit TagPattern(std::string const &tag, std::string const &filterString);
3372  bool matches(TestCaseInfo const &testCase) const override;
3373 
3374  private:
3375  void serializeTo(std::ostream &out) const override;
3376 
3377  std::string m_tag;
3378  };
3379 
3380  struct Filter {
3381  std::vector<Detail::unique_ptr<Pattern>> m_required;
3382  std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
3383 
3386  void serializeTo(std::ostream &out) const;
3387  friend std::ostream &operator<<(std::ostream &out, Filter const &f) {
3388  f.serializeTo(out);
3389  return out;
3390  }
3391 
3392  bool matches(TestCaseInfo const &testCase) const;
3393  };
3394 
3395  static std::string extractFilterName(Filter const &filter);
3396 
3397  public:
3398  struct FilterMatch {
3399  std::string name;
3400  std::vector<TestCaseHandle const *> tests;
3401  };
3402  using Matches = std::vector<FilterMatch>;
3403  using vectorStrings = std::vector<std::string>;
3404 
3405  bool hasFilters() const;
3406  bool matches(TestCaseInfo const &testCase) const;
3407  Matches matchesByFilter(std::vector<TestCaseHandle> const &testCases, IConfig const &config) const;
3408  const vectorStrings &getInvalidSpecs() const;
3409 
3410  private:
3411  std::vector<Filter> m_filters;
3412  std::vector<std::string> m_invalidSpecs;
3413 
3414  friend class TestSpecParser;
3417  void serializeTo(std::ostream &out) const;
3418  friend std::ostream &operator<<(std::ostream &out,
3419  TestSpec const &spec) {
3420  spec.serializeTo(out);
3421  return out;
3422  }
3423  };
3424 } // namespace Catch
3425 
3426 #ifdef __clang__
3427 #pragma clang diagnostic pop
3428 #endif
3429 
3430 #endif // CATCH_TEST_SPEC_HPP_INCLUDED
3431 
3432 #ifndef CATCH_OPTIONAL_HPP_INCLUDED
3433 #define CATCH_OPTIONAL_HPP_INCLUDED
3434 
3435 #include <cassert>
3436 
3437 namespace Catch {
3438 
3439  // An optional type
3440  template<typename T>
3441  class Optional {
3442  public:
3443  Optional()
3444  : nullableValue(nullptr) {}
3445  ~Optional() { reset(); }
3446 
3447  Optional(T const &_value)
3448  : nullableValue(new (storage) T(_value)) {}
3449  Optional(T &&_value)
3450  : nullableValue(new (storage) T(CATCH_MOVE(_value))) {}
3451 
3452  Optional &operator=(T const &_value) {
3453  reset();
3454  nullableValue = new (storage) T(_value);
3455  return *this;
3456  }
3457  Optional &operator=(T &&_value) {
3458  reset();
3459  nullableValue = new (storage) T(CATCH_MOVE(_value));
3460  return *this;
3461  }
3462 
3463  Optional(Optional const &_other)
3464  : nullableValue(_other ? new (storage) T(*_other) : nullptr) {}
3465  Optional(Optional &&_other)
3466  : nullableValue(_other ? new (storage) T(CATCH_MOVE(*_other))
3467  : nullptr) {}
3468 
3469  Optional &operator=(Optional const &_other) {
3470  if (&_other != this) {
3471  reset();
3472  if (_other) { nullableValue = new (storage) T(*_other); }
3473  }
3474  return *this;
3475  }
3476  Optional &operator=(Optional &&_other) {
3477  if (&_other != this) {
3478  reset();
3479  if (_other) {
3480  nullableValue = new (storage) T(CATCH_MOVE(*_other));
3481  }
3482  }
3483  return *this;
3484  }
3485 
3486  void reset() {
3487  if (nullableValue) { nullableValue->~T(); }
3488  nullableValue = nullptr;
3489  }
3490 
3491  T &operator*() {
3492  assert(nullableValue);
3493  return *nullableValue;
3494  }
3495  T const &operator*() const {
3496  assert(nullableValue);
3497  return *nullableValue;
3498  }
3499  T *operator->() {
3500  assert(nullableValue);
3501  return nullableValue;
3502  }
3503  const T *operator->() const {
3504  assert(nullableValue);
3505  return nullableValue;
3506  }
3507 
3508  T valueOr(T const &defaultValue) const {
3509  return nullableValue ? *nullableValue : defaultValue;
3510  }
3511 
3512  bool some() const { return nullableValue != nullptr; }
3513  bool none() const { return nullableValue == nullptr; }
3514 
3515  bool operator!() const { return nullableValue == nullptr; }
3516  explicit operator bool() const {
3517  return some();
3518  }
3519 
3520  friend bool operator==(Optional const &a, Optional const &b) {
3521  if (a.none() && b.none()) {
3522  return true;
3523  } else if (a.some() && b.some()) {
3524  return *a == *b;
3525  } else {
3526  return false;
3527  }
3528  }
3529  friend bool operator!=(Optional const &a, Optional const &b) {
3530  return !(a == b);
3531  }
3532 
3533  private:
3534  T *nullableValue;
3535  alignas(alignof(T)) char storage[sizeof(T)];
3536  };
3537 
3538 } // end namespace Catch
3539 
3540 #endif // CATCH_OPTIONAL_HPP_INCLUDED
3541 
3542 #ifndef CATCH_PATH_FILTER_HPP_INCLUDED
3543 #define CATCH_PATH_FILTER_HPP_INCLUDED
3544 
3545 #include <string>
3546 
3547 namespace Catch {
3548 
3549  struct PathFilter {
3550  enum class For {
3551  Section,
3552  Generator,
3553  };
3554  PathFilter(For type_, std::string filter_)
3555  : type(type_), filter(CATCH_MOVE(filter_)) {}
3556 
3557  For type;
3558  std::string filter;
3559 
3560  friend bool operator==(PathFilter const &lhs, PathFilter const &rhs);
3561  };
3562 
3563 } // end namespace Catch
3564 
3565 #endif // CATCH_PATH_FILTER_HPP_INCLUDED
3566 
3567 #ifndef CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3568 #define CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3569 
3570 #include <cstdint>
3571 
3572 namespace Catch {
3573 
3574  enum class GenerateFrom {
3575  Time,
3576  RandomDevice,
3578  Default
3579  };
3580 
3581  std::uint32_t generateRandomSeed(GenerateFrom from);
3582 
3583 } // end namespace Catch
3584 
3585 #endif // CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3586 
3587 #ifndef CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3588 #define CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3589 
3590 #include <map>
3591 #include <string>
3592 #include <vector>
3593 
3594 namespace Catch {
3595 
3596  enum class ColourMode : std::uint8_t;
3597 
3598  namespace Detail {
3600  std::vector<std::string> splitReporterSpec(StringRef reporterSpec);
3601 
3602  Optional<ColourMode> stringToColourMode(StringRef colourMode);
3603  } // namespace Detail
3604 
3614  std::string m_name;
3615  Optional<std::string> m_outputFileName;
3616  Optional<ColourMode> m_colourMode;
3617  std::map<std::string, std::string> m_customOptions;
3618 
3619  friend bool operator==(ReporterSpec const &lhs,
3620  ReporterSpec const &rhs);
3621  friend bool operator!=(ReporterSpec const &lhs,
3622  ReporterSpec const &rhs) {
3623  return !(lhs == rhs);
3624  }
3625 
3626  public:
3627  ReporterSpec(
3628  std::string name,
3629  Optional<std::string> outputFileName,
3630  Optional<ColourMode> colourMode,
3631  std::map<std::string, std::string> customOptions);
3632 
3633  std::string const &name() const { return m_name; }
3634 
3635  Optional<std::string> const &outputFile() const {
3636  return m_outputFileName;
3637  }
3638 
3639  Optional<ColourMode> const &colourMode() const { return m_colourMode; }
3640 
3641  std::map<std::string, std::string> const &customOptions() const {
3642  return m_customOptions;
3643  }
3644  };
3645 
3657 
3658 } // namespace Catch
3659 
3660 #endif // CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3661 
3662 #include <chrono>
3663 #include <map>
3664 #include <string>
3665 #include <vector>
3666 
3667 namespace Catch {
3668 
3669  class IStream;
3670 
3677  std::string name;
3678  std::string outputFilename;
3679  ColourMode colourMode;
3680  std::map<std::string, std::string> customOptions;
3681  friend bool operator==(ProcessedReporterSpec const &lhs,
3682  ProcessedReporterSpec const &rhs);
3683  friend bool operator!=(ProcessedReporterSpec const &lhs,
3684  ProcessedReporterSpec const &rhs) {
3685  return !(lhs == rhs);
3686  }
3687  };
3688 
3689  struct ConfigData {
3690  bool listTests = false;
3691  bool listTags = false;
3692  bool listReporters = false;
3693  bool listListeners = false;
3694 
3695  bool showSuccessfulTests = false;
3696  bool shouldDebugBreak = false;
3697  bool noThrow = false;
3698  bool showHelp = false;
3699  bool showInvisibles = false;
3700  bool filenamesAsTags = false;
3701  bool libIdentify = false;
3702  bool allowZeroTests = false;
3703 
3704  int abortAfter = -1;
3705  uint32_t rngSeed = generateRandomSeed(GenerateFrom::Default);
3706 
3707  unsigned int shardCount = 1;
3708  unsigned int shardIndex = 0;
3709 
3710  bool skipBenchmarks = false;
3711  bool benchmarkNoAnalysis = false;
3712  unsigned int benchmarkSamples = 100;
3713  double benchmarkConfidenceInterval = 0.95;
3714  unsigned int benchmarkResamples = 100'000;
3715  std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
3716 
3717  Verbosity verbosity = Verbosity::Normal;
3718  WarnAbout::What warnings = WarnAbout::Nothing;
3719  ShowDurations showDurations = ShowDurations::DefaultForReporter;
3720  double minDuration = -1;
3721  TestRunOrder runOrder = TestRunOrder::Randomized;
3722  ColourMode defaultColourMode = ColourMode::PlatformDefault;
3723  WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
3724 
3725  std::string defaultOutputFilename;
3726  std::string name;
3727  std::string processName;
3728  std::vector<ReporterSpec> reporterSpecifications;
3729 
3730  std::vector<std::string> testsOrTags;
3731  std::vector<PathFilter> pathFilters;
3732  bool useNewPathFilteringBehaviour = false;
3733 
3734  std::string prematureExitGuardFilePath;
3735  };
3736 
3737  class Config : public IConfig {
3738  public:
3739  Config() = default;
3740  Config(ConfigData const &data);
3741  ~Config() override; // = default in the cpp file
3742 
3743  bool listTests() const;
3744  bool listTags() const;
3745  bool listReporters() const;
3746  bool listListeners() const;
3747 
3748  std::vector<ReporterSpec> const &getReporterSpecs() const;
3749  std::vector<ProcessedReporterSpec> const &
3750  getProcessedReporterSpecs() const;
3751 
3752  std::vector<std::string> const &getTestsOrTags() const override;
3753  std::vector<PathFilter> const &getPathFilters() const override;
3754  bool useNewFilterBehaviour() const override;
3755 
3756  TestSpec const &testSpec() const override;
3757  bool hasTestFilters() const override;
3758 
3759  bool showHelp() const;
3760 
3761  std::string const &getExitGuardFilePath() const;
3762 
3763  // IConfig interface
3764  bool allowThrows() const override;
3765  StringRef name() const override;
3766  bool includeSuccessfulResults() const override;
3767  bool warnAboutMissingAssertions() const override;
3768  bool warnAboutUnmatchedTestSpecs() const override;
3769  bool warnAboutInfiniteGenerators() const override;
3770  bool zeroTestsCountAsSuccess() const override;
3771  ShowDurations showDurations() const override;
3772  double minDuration() const override;
3773  TestRunOrder runOrder() const override;
3774  uint32_t rngSeed() const override;
3775  unsigned int shardCount() const override;
3776  unsigned int shardIndex() const override;
3777  ColourMode defaultColourMode() const override;
3778  bool shouldDebugBreak() const override;
3779  int abortAfter() const override;
3780  bool showInvisibles() const override;
3781  Verbosity verbosity() const override;
3782  bool skipBenchmarks() const override;
3783  bool benchmarkNoAnalysis() const override;
3784  unsigned int benchmarkSamples() const override;
3785  double benchmarkConfidenceInterval() const override;
3786  unsigned int benchmarkResamples() const override;
3787  std::chrono::milliseconds benchmarkWarmupTime() const override;
3788 
3789  private:
3790  // Reads Bazel env vars and applies them to the config
3791  void readBazelEnvVars();
3792 
3793  ConfigData m_data;
3794  std::vector<ProcessedReporterSpec> m_processedReporterSpecs;
3795  TestSpec m_testSpec;
3796  bool m_hasTestFilters = false;
3797  };
3798 } // end namespace Catch
3799 
3800 #endif // CATCH_CONFIG_HPP_INCLUDED
3801 
3802 #ifndef CATCH_GET_RANDOM_SEED_HPP_INCLUDED
3803 #define CATCH_GET_RANDOM_SEED_HPP_INCLUDED
3804 
3805 #include <cstdint>
3806 
3807 namespace Catch {
3809  std::uint32_t getSeed();
3810 } // namespace Catch
3811 
3812 #endif // CATCH_GET_RANDOM_SEED_HPP_INCLUDED
3813 
3814 #ifndef CATCH_MESSAGE_HPP_INCLUDED
3815 #define CATCH_MESSAGE_HPP_INCLUDED
3816 
3828 #ifndef CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED
3829 #define CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED
3830 
3831 #if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_PREFIX_MESSAGES)
3832 #define CATCH_CONFIG_PREFIX_MESSAGES
3833 #endif
3834 
3835 #endif // CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED
3836 
3837 #ifndef CATCH_STREAM_END_STOP_HPP_INCLUDED
3838 #define CATCH_STREAM_END_STOP_HPP_INCLUDED
3839 
3840 namespace Catch {
3841 
3842  // Use this in variadic streaming macros to allow
3843  // << +StreamEndStop
3844  // as well as
3845  // << stuff +StreamEndStop
3846  struct StreamEndStop {
3847  constexpr StringRef operator+() const { return StringRef(); }
3848 
3849  template<typename T>
3850  constexpr friend T const &operator+(T const &value, StreamEndStop) {
3851  return value;
3852  }
3853  };
3854 
3855 } // namespace Catch
3856 
3857 #endif // CATCH_STREAM_END_STOP_HPP_INCLUDED
3858 
3859 #ifndef CATCH_MESSAGE_INFO_HPP_INCLUDED
3860 #define CATCH_MESSAGE_INFO_HPP_INCLUDED
3861 
3862 #ifndef CATCH_DEPRECATION_MACRO_HPP_INCLUDED
3863 #define CATCH_DEPRECATION_MACRO_HPP_INCLUDED
3864 
3865 #if !defined(CATCH_CONFIG_NO_DEPRECATION_ANNOTATIONS)
3866 #define CATCH_DEPRECATED(msg) [[deprecated(msg)]]
3867 #else
3868 #define CATCH_DEPRECATED(msg)
3869 #endif
3870 
3871 #endif // CATCH_DEPRECATION_MACRO_HPP_INCLUDED
3872 
3873 #include <string>
3874 
3875 namespace Catch {
3876 
3877  struct MessageInfo {
3878  MessageInfo(StringRef _macroName,
3879  SourceLineInfo const &_lineInfo,
3880  ResultWas::OfType _type);
3881 
3882  StringRef macroName;
3883  std::string message;
3884  SourceLineInfo lineInfo;
3885  ResultWas::OfType type;
3886  // The "ID" of the message, used to know when to remove it from reporter context.
3887  unsigned int sequence;
3888 
3889  CATCH_DEPRECATED("Explicitly use the 'sequence' member instead")
3890  bool operator==(MessageInfo const &other) const {
3891  return sequence == other.sequence;
3892  }
3893  CATCH_DEPRECATED("Explicitly use the 'sequence' member instead")
3894  bool operator<(MessageInfo const &other) const {
3895  return sequence < other.sequence;
3896  }
3897  };
3898 
3899 } // end namespace Catch
3900 
3901 #endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
3902 
3903 #include <string>
3904 #include <vector>
3905 
3906 namespace Catch {
3907 
3908  struct SourceLineInfo;
3909  class IResultCapture;
3910 
3911  struct MessageStream {
3912  template<typename T>
3913  MessageStream &operator<<(T const &value) {
3914  m_stream << value;
3915  return *this;
3916  }
3917 
3918  ReusableStringStream m_stream;
3919  };
3920 
3921  struct MessageBuilder : MessageStream {
3922  MessageBuilder(StringRef macroName,
3923  SourceLineInfo const &lineInfo,
3924  ResultWas::OfType type)
3925  : m_info(macroName, lineInfo, type) {}
3926 
3927  template<typename T>
3928  MessageBuilder &&operator<<(T const &value) && {
3929  m_stream << value;
3930  return CATCH_MOVE(*this);
3931  }
3932 
3933  MessageInfo m_info;
3934  };
3935 
3936  class ScopedMessage {
3937  public:
3938  explicit ScopedMessage(MessageBuilder &&builder);
3939  ScopedMessage(ScopedMessage &duplicate) = delete;
3940  ScopedMessage(ScopedMessage &&old) noexcept;
3941  ~ScopedMessage();
3942 
3943  unsigned int m_messageId;
3944  bool m_moved = false;
3945  };
3946 
3947  class Capturer {
3948  std::vector<MessageInfo> m_messages;
3949  size_t m_captured = 0;
3950  bool m_isScoped = false;
3951 
3952  public:
3953  Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names, bool isScoped);
3954 
3955  Capturer(Capturer const &) = delete;
3956  Capturer &operator=(Capturer const &) = delete;
3957 
3958  ~Capturer();
3959 
3960  void captureValue(size_t index, std::string const &value);
3961 
3962  template<typename T>
3963  void captureValues(size_t index, T const &value) {
3964  captureValue(index, Catch::Detail::stringify(value));
3965  }
3966 
3967  template<typename T, typename... Ts>
3968  void captureValues(size_t index, T const &value, Ts const &...values) {
3969  captureValue(index, Catch::Detail::stringify(value));
3970  captureValues(index + 1, values...);
3971  }
3972  };
3973 
3974 } // end namespace Catch
3975 
3977 #define INTERNAL_CATCH_MSG(macroName, messageType, resultDisposition, ...) \
3978  do { \
3979  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition); \
3980  catchAssertionHandler.handleMessage(messageType, (Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop()).m_stream.str()); \
3981  catchAssertionHandler.complete(); \
3982  } while (false)
3983 
3985 #define INTERNAL_CATCH_CAPTURE(varName, macroName, scopedCapture, ...) \
3986  Catch::Capturer varName(macroName##_catch_sr, \
3987  CATCH_INTERNAL_LINEINFO, \
3988  Catch::ResultWas::Info, \
3989  #__VA_ARGS__##_catch_sr, \
3990  scopedCapture); \
3991  varName.captureValues(0, __VA_ARGS__)
3992 
3994 #define INTERNAL_CATCH_INFO(macroName, log) \
3995  const Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME(scopedMessage)(Catch::MessageBuilder(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log)
3996 
3998 #define INTERNAL_CATCH_UNSCOPED_INFO(macroName, log) \
3999  Catch::IResultCapture::emplaceUnscopedMessage(Catch::MessageBuilder(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log)
4000 
4001 #if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
4002 
4003 #define CATCH_INFO(msg) INTERNAL_CATCH_INFO("CATCH_INFO", msg)
4004 #define CATCH_UNSCOPED_INFO(msg) INTERNAL_CATCH_UNSCOPED_INFO("CATCH_UNSCOPED_INFO", msg)
4005 #define CATCH_WARN(msg) INTERNAL_CATCH_MSG("CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg)
4006 #define CATCH_CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", true, __VA_ARGS__)
4007 #define CATCH_UNSCOPED_CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_UNSCOPED_CAPTURE", false, __VA_ARGS__)
4008 
4009 #elif defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
4010 
4011 #define CATCH_INFO(msg) (void)(0)
4012 #define CATCH_UNSCOPED_INFO(msg) (void)(0)
4013 #define CATCH_WARN(msg) (void)(0)
4014 #define CATCH_CAPTURE(...) (void)(0)
4015 #define CATCH_UNSCOPED_CAPTURE(...) (void)(0)
4016 
4017 #elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
4018 
4019 #define INFO(msg) INTERNAL_CATCH_INFO("INFO", msg)
4020 #define UNSCOPED_INFO(msg) INTERNAL_CATCH_UNSCOPED_INFO("UNSCOPED_INFO", msg)
4021 #define WARN(msg) INTERNAL_CATCH_MSG("WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg)
4022 #define CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", true, __VA_ARGS__)
4023 #define UNSCOPED_CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "UNSCOPED_CAPTURE", false, __VA_ARGS__)
4024 
4025 #elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
4026 
4027 #define INFO(msg) (void)(0)
4028 #define UNSCOPED_INFO(msg) (void)(0)
4029 #define WARN(msg) (void)(0)
4030 #define CAPTURE(...) (void)(0)
4031 #define UNSCOPED_CAPTURE(...) (void)(0)
4032 
4033 #endif // end of user facing macro declarations
4034 
4035 #endif // CATCH_MESSAGE_HPP_INCLUDED
4036 
4037 #ifndef CATCH_SECTION_INFO_HPP_INCLUDED
4038 #define CATCH_SECTION_INFO_HPP_INCLUDED
4039 
4040 #ifndef CATCH_TOTALS_HPP_INCLUDED
4041 #define CATCH_TOTALS_HPP_INCLUDED
4042 
4043 #include <cstdint>
4044 
4045 namespace Catch {
4046 
4047  struct Counts {
4048  Counts operator-(Counts const &other) const;
4049  Counts &operator+=(Counts const &other);
4050 
4051  std::uint64_t total() const;
4052  bool allPassed() const;
4053  bool allOk() const;
4054 
4055  std::uint64_t passed = 0;
4056  std::uint64_t failed = 0;
4057  std::uint64_t failedButOk = 0;
4058  std::uint64_t skipped = 0;
4059  };
4060 
4061  struct Totals {
4062  Totals operator-(Totals const &other) const;
4063  Totals &operator+=(Totals const &other);
4064 
4065  Totals delta(Totals const &prevTotals) const;
4066 
4067  Counts assertions;
4068  Counts testCases;
4069  };
4070 } // namespace Catch
4071 
4072 #endif // CATCH_TOTALS_HPP_INCLUDED
4073 
4074 #include <string>
4075 
4076 namespace Catch {
4077 
4078  struct SectionInfo {
4079  // The last argument is ignored, so that people can write
4080  // SECTION("ShortName", "Proper description that is long") and
4081  // still use the `-c` flag comfortably.
4082  SectionInfo(SourceLineInfo const &_lineInfo, std::string _name,
4083  const char *const = nullptr)
4084  : name(CATCH_MOVE(_name)), lineInfo(_lineInfo) {}
4085 
4086  std::string name;
4087  SourceLineInfo lineInfo;
4088  };
4089 
4090  struct SectionEndInfo {
4091  SectionInfo sectionInfo;
4092  Counts prevAssertions;
4093  double durationInSeconds;
4094  };
4095 
4096 } // end namespace Catch
4097 
4098 #endif // CATCH_SECTION_INFO_HPP_INCLUDED
4099 
4100 #ifndef CATCH_SESSION_HPP_INCLUDED
4101 #define CATCH_SESSION_HPP_INCLUDED
4102 
4103 #ifndef CATCH_COMMANDLINE_HPP_INCLUDED
4104 #define CATCH_COMMANDLINE_HPP_INCLUDED
4105 
4106 #ifndef CATCH_CLARA_HPP_INCLUDED
4107 #define CATCH_CLARA_HPP_INCLUDED
4108 
4109 #if defined(__clang__)
4110 #pragma clang diagnostic push
4111 #pragma clang diagnostic ignored "-Wweak-vtables"
4112 #pragma clang diagnostic ignored "-Wshadow"
4113 #pragma clang diagnostic ignored "-Wdeprecated"
4114 #endif
4115 
4116 #if defined(__GNUC__)
4117 #pragma GCC diagnostic push
4118 #pragma GCC diagnostic ignored "-Wsign-conversion"
4119 #endif
4120 
4121 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
4122 #ifdef __has_include
4123 #if __has_include(<optional>) && __cplusplus >= 201703L
4124 #include <optional>
4125 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
4126 #endif
4127 #endif
4128 #endif
4129 
4130 #include <cassert>
4131 #include <memory>
4132 #include <ostream>
4133 #include <sstream>
4134 #include <string>
4135 #include <type_traits>
4136 #include <vector>
4137 
4138 namespace Catch {
4139  namespace Clara {
4140 
4141  class Args;
4142  class Parser;
4143 
4144  // enum of result types from a parse
4145  enum class ParseResultType {
4146  Matched,
4147  NoMatch,
4148  ShortCircuitAll,
4149  ShortCircuitSame
4150  };
4151 
4152  struct accept_many_t {};
4153  constexpr accept_many_t accept_many{};
4154 
4155  namespace Detail {
4156  struct fake_arg {
4157  template<typename T>
4158  operator T();
4159  };
4160 
4161  template<typename F, typename = void>
4162  static constexpr bool is_unary_function_v = false;
4163 
4164  template<typename F>
4165  static constexpr bool is_unary_function_v<
4166  F,
4167  Catch::Detail::void_t<decltype(std::declval<F>()(
4168  fake_arg()))>>
4169  = true;
4170 
4171  // Traits for extracting arg and return type of lambdas (for single
4172  // argument lambdas)
4173  template<typename L>
4174  struct UnaryLambdaTraits
4175  : UnaryLambdaTraits<decltype(&L::operator())> {};
4176 
4177  template<typename ClassT, typename ReturnT, typename... Args>
4178  struct UnaryLambdaTraits<ReturnT (ClassT::*)(Args...) const> {
4179  static const bool isValid = false;
4180  };
4181 
4182  template<typename ClassT, typename ReturnT, typename ArgT>
4183  struct UnaryLambdaTraits<ReturnT (ClassT::*)(ArgT) const> {
4184  static const bool isValid = true;
4185  using ArgType = std::remove_const_t<std::remove_reference_t<ArgT>>;
4186  using ReturnType = ReturnT;
4187  };
4188 
4189  class TokenStream;
4190 
4191  // Wraps a token coming from a token stream. These may not directly
4192  // correspond to strings as a single string may encode an option +
4193  // its argument if the : or = form is used
4194  enum class TokenType { Option,
4195  Argument };
4196  struct Token {
4197  TokenType type;
4198  StringRef token;
4199  };
4200 
4201  // Abstracts iterators into args as a stream of tokens, with option
4202  // arguments uniformly handled
4203  class TokenStream {
4204  using Iterator = std::vector<StringRef>::const_iterator;
4205  Iterator it;
4206  Iterator itEnd;
4207  std::vector<Token> m_tokenBuffer;
4208  void loadBuffer();
4209 
4210  public:
4211  explicit TokenStream(Args const &args);
4212  TokenStream(Iterator it, Iterator itEnd);
4213 
4214  explicit operator bool() const {
4215  return !m_tokenBuffer.empty() || it != itEnd;
4216  }
4217 
4218  size_t count() const {
4219  return m_tokenBuffer.size() + (itEnd - it);
4220  }
4221 
4222  Token operator*() const {
4223  assert(!m_tokenBuffer.empty());
4224  return m_tokenBuffer.front();
4225  }
4226 
4227  Token const *operator->() const {
4228  assert(!m_tokenBuffer.empty());
4229  return &m_tokenBuffer.front();
4230  }
4231 
4232  TokenStream &operator++();
4233  };
4234 
4236  enum class ResultType {
4237  Ok, ///< No errors
4238  LogicError, ///< Error in user-specified arguments for
4240  RuntimeError ///< Error in parsing inputs
4241  };
4242 
4243  class ResultBase {
4244  protected:
4245  ResultBase(ResultType type)
4246  : m_type(type) {}
4247  virtual ~ResultBase(); // = default;
4248 
4249  ResultBase(ResultBase const &) = default;
4250  ResultBase &operator=(ResultBase const &) = default;
4251  ResultBase(ResultBase &&) = default;
4252  ResultBase &operator=(ResultBase &&) = default;
4253 
4254  virtual void enforceOk() const = 0;
4255 
4256  ResultType m_type;
4257  };
4258 
4259  template<typename T>
4260  class ResultValueBase : public ResultBase {
4261  public:
4262  T const &value() const & {
4263  enforceOk();
4264  return m_value;
4265  }
4266  T &&value() && {
4267  enforceOk();
4268  return CATCH_MOVE(m_value);
4269  }
4270 
4271  protected:
4272  ResultValueBase(ResultType type)
4273  : ResultBase(type) {}
4274 
4275  ResultValueBase(ResultValueBase const &other)
4276  : ResultBase(other) {
4277  if (m_type == ResultType::Ok)
4278  new (&m_value) T(other.m_value);
4279  }
4280  ResultValueBase(ResultValueBase &&other)
4281  : ResultBase(other) {
4282  if (m_type == ResultType::Ok)
4283  new (&m_value) T(CATCH_MOVE(other.m_value));
4284  }
4285 
4286  ResultValueBase(ResultType, T const &value)
4287  : ResultBase(ResultType::Ok) {
4288  new (&m_value) T(value);
4289  }
4290  ResultValueBase(ResultType, T &&value)
4291  : ResultBase(ResultType::Ok) {
4292  new (&m_value) T(CATCH_MOVE(value));
4293  }
4294 
4295  ResultValueBase &operator=(ResultValueBase const &other) {
4296  if (m_type == ResultType::Ok)
4297  m_value.~T();
4298  ResultBase::operator=(other);
4299  if (m_type == ResultType::Ok)
4300  new (&m_value) T(other.m_value);
4301  return *this;
4302  }
4303  ResultValueBase &operator=(ResultValueBase &&other) {
4304  if (m_type == ResultType::Ok) m_value.~T();
4305  ResultBase::operator=(other);
4306  if (m_type == ResultType::Ok)
4307  new (&m_value) T(CATCH_MOVE(other.m_value));
4308  return *this;
4309  }
4310 
4311  ~ResultValueBase() override {
4312  if (m_type == ResultType::Ok)
4313  m_value.~T();
4314  }
4315 
4316  union {
4317  T m_value;
4318  };
4319  };
4320 
4321  template<>
4322  class ResultValueBase<void> : public ResultBase {
4323  protected:
4324  using ResultBase::ResultBase;
4325  };
4326 
4327  template<typename T = void>
4328  class BasicResult : public ResultValueBase<T> {
4329  public:
4330  template<typename U>
4331  explicit BasicResult(BasicResult<U> const &other)
4332  : ResultValueBase<T>(other.type()), m_errorMessage(other.errorMessage()) {
4333  assert(type() != ResultType::Ok);
4334  }
4335 
4336  template<typename U>
4337  static auto ok(U &&value) -> BasicResult {
4338  return {ResultType::Ok, CATCH_FORWARD(value)};
4339  }
4340  static auto ok() -> BasicResult { return {ResultType::Ok}; }
4341  static auto logicError(std::string &&message)
4342  -> BasicResult {
4343  return {ResultType::LogicError, CATCH_MOVE(message)};
4344  }
4345  static auto runtimeError(std::string &&message)
4346  -> BasicResult {
4347  return {ResultType::RuntimeError, CATCH_MOVE(message)};
4348  }
4349 
4350  explicit operator bool() const {
4351  return m_type == ResultType::Ok;
4352  }
4353  auto type() const -> ResultType { return m_type; }
4354  auto errorMessage() const -> std::string const & {
4355  return m_errorMessage;
4356  }
4357 
4358  protected:
4359  void enforceOk() const override {
4360  // Errors shouldn't reach this point, but if they do
4361  // the actual error message will be in m_errorMessage
4362  assert(m_type != ResultType::LogicError);
4363  assert(m_type != ResultType::RuntimeError);
4364  if (m_type != ResultType::Ok)
4365  std::abort();
4366  }
4367 
4368  std::string
4369  m_errorMessage; // Only populated if resultType is an error
4370 
4371  BasicResult(ResultType type,
4372  std::string &&message)
4373  : ResultValueBase<T>(type), m_errorMessage(CATCH_MOVE(message)) {
4374  assert(m_type != ResultType::Ok);
4375  }
4376 
4378  using ResultBase::m_type;
4379  };
4380 
4381  class ParseState {
4382  public:
4383  ParseState(ParseResultType type,
4384  TokenStream remainingTokens);
4385 
4386  ParseResultType type() const { return m_type; }
4387  TokenStream const &remainingTokens() const & {
4388  return m_remainingTokens;
4389  }
4390  TokenStream &&remainingTokens() && {
4391  return CATCH_MOVE(m_remainingTokens);
4392  }
4393 
4394  private:
4395  ParseResultType m_type;
4396  TokenStream m_remainingTokens;
4397  };
4398 
4399  using Result = BasicResult<void>;
4402 
4403  struct HelpColumns {
4404  std::string left;
4405  StringRef descriptions;
4406  };
4407 
4408  template<typename T>
4409  ParserResult convertInto(std::string const &source, T &target) {
4410  std::stringstream ss(source);
4411  ss >> target;
4412  if (ss.fail()) {
4413  return ParserResult::runtimeError(
4414  "Unable to convert '" + source + "' to destination type");
4415  } else {
4416  return ParserResult::ok(ParseResultType::Matched);
4417  }
4418  }
4419  ParserResult convertInto(std::string const &source,
4420  std::string &target);
4421  ParserResult convertInto(std::string const &source, bool &target);
4422 
4423 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
4424  template<typename T>
4425  auto convertInto(std::string const &source,
4426  CLARA_CONFIG_OPTIONAL_TYPE<T> &target)
4427  -> ParserResult {
4428  T temp;
4429  auto result = convertInto(source, temp);
4430  if (result)
4431  target = CATCH_MOVE(temp);
4432  return result;
4433  }
4434 #endif // CLARA_CONFIG_OPTIONAL_TYPE
4435 
4437  virtual ~BoundRef() = default;
4438  virtual bool isContainer() const;
4439  virtual bool isFlag() const;
4440  };
4442  virtual auto setValue(std::string const &arg)
4443  -> ParserResult
4444  = 0;
4445  };
4447  virtual auto setFlag(bool flag) -> ParserResult = 0;
4448  bool isFlag() const override;
4449  };
4450 
4451  template<typename T>
4453  T &m_ref;
4454 
4455  explicit BoundValueRef(T &ref)
4456  : m_ref(ref) {}
4457 
4458  ParserResult setValue(std::string const &arg) override {
4459  return convertInto(arg, m_ref);
4460  }
4461  };
4462 
4463  template<typename T>
4464  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
4465  std::vector<T> &m_ref;
4466 
4467  explicit BoundValueRef(std::vector<T> &ref)
4468  : m_ref(ref) {}
4469 
4470  auto isContainer() const -> bool override { return true; }
4471 
4472  auto setValue(std::string const &arg)
4473  -> ParserResult override {
4474  T temp;
4475  auto result = convertInto(arg, temp);
4476  if (result)
4477  m_ref.push_back(temp);
4478  return result;
4479  }
4480  };
4481 
4483  bool &m_ref;
4484 
4485  explicit BoundFlagRef(bool &ref)
4486  : m_ref(ref) {}
4487 
4488  ParserResult setFlag(bool flag) override;
4489  };
4490 
4491  template<typename ReturnType>
4492  struct LambdaInvoker {
4493  static_assert(
4494  std::is_same<ReturnType, ParserResult>::value,
4495  "Lambda must return void or clara::ParserResult");
4496 
4497  template<typename L, typename ArgType>
4498  static auto invoke(L const &lambda, ArgType const &arg)
4499  -> ParserResult {
4500  return lambda(arg);
4501  }
4502  };
4503 
4504  template<>
4505  struct LambdaInvoker<void> {
4506  template<typename L, typename ArgType>
4507  static auto invoke(L const &lambda, ArgType const &arg)
4508  -> ParserResult {
4509  lambda(arg);
4510  return ParserResult::ok(ParseResultType::Matched);
4511  }
4512  };
4513 
4514  template<typename ArgType, typename L>
4515  auto invokeLambda(L const &lambda, std::string const &arg)
4516  -> ParserResult {
4517  ArgType temp{};
4518  auto result = convertInto(arg, temp);
4519  return !result ? result
4520  : LambdaInvoker<typename UnaryLambdaTraits<
4521  L>::ReturnType>::invoke(lambda, temp);
4522  }
4523 
4524  template<typename L>
4526  L m_lambda;
4527 
4528  static_assert(
4530  "Supplied lambda must take exactly one argument");
4531  explicit BoundLambda(L const &lambda)
4532  : m_lambda(lambda) {}
4533 
4534  auto setValue(std::string const &arg)
4535  -> ParserResult override {
4536  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(
4537  m_lambda, arg);
4538  }
4539  };
4540 
4541  template<typename L>
4543  explicit BoundManyLambda(L const &lambda)
4544  : BoundLambda<L>(lambda) {}
4545  bool isContainer() const override { return true; }
4546  };
4547 
4548  template<typename L>
4550  L m_lambda;
4551 
4552  static_assert(
4554  "Supplied lambda must take exactly one argument");
4555  static_assert(
4556  std::is_same<typename UnaryLambdaTraits<L>::ArgType,
4557  bool>::value,
4558  "flags must be boolean");
4559 
4560  explicit BoundFlagLambda(L const &lambda)
4561  : m_lambda(lambda) {}
4562 
4563  auto setFlag(bool flag) -> ParserResult override {
4564  return LambdaInvoker<typename UnaryLambdaTraits<
4565  L>::ReturnType>::invoke(m_lambda, flag);
4566  }
4567  };
4568 
4569  enum class Optionality { Optional,
4570  Required };
4571 
4572  class ParserBase {
4573  public:
4574  virtual ~ParserBase() = default;
4575  virtual auto validate() const -> Result { return Result::ok(); }
4576  virtual auto parse(std::string const &exeName,
4577  TokenStream tokens) const
4579  = 0;
4580  virtual size_t cardinality() const;
4581 
4582  InternalParseResult parse(Args const &args) const;
4583  };
4584 
4585  template<typename DerivedT>
4587  public:
4588  template<typename T>
4589  auto operator|(T const &other) const -> Parser;
4590  };
4591 
4592  // Common code and state for Args and Opts
4593  template<typename DerivedT>
4594  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
4595  protected:
4596  Optionality m_optionality = Optionality::Optional;
4597  std::shared_ptr<BoundRef> m_ref;
4598  StringRef m_hint;
4599  StringRef m_description;
4600 
4601  explicit ParserRefImpl(std::shared_ptr<BoundRef> const &ref)
4602  : m_ref(ref) {}
4603 
4604  public:
4605  template<typename LambdaT>
4607  LambdaT const &ref,
4608  StringRef hint)
4609  : m_ref(std::make_shared<BoundManyLambda<LambdaT>>(ref)), m_hint(hint) {}
4610 
4611  template<typename T,
4612  typename = typename std::enable_if_t<
4613  !Detail::is_unary_function_v<T>>>
4614  ParserRefImpl(T &ref, StringRef hint)
4615  : m_ref(std::make_shared<BoundValueRef<T>>(ref)), m_hint(hint) {}
4616 
4617  template<typename LambdaT,
4618  typename = typename std::enable_if_t<
4619  Detail::is_unary_function_v<LambdaT>>>
4620  ParserRefImpl(LambdaT const &ref, StringRef hint)
4621  : m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)), m_hint(hint) {}
4622 
4623  DerivedT &operator()(StringRef description) & {
4624  m_description = description;
4625  return static_cast<DerivedT &>(*this);
4626  }
4627  DerivedT &&operator()(StringRef description) && {
4628  m_description = description;
4629  return static_cast<DerivedT &&>(*this);
4630  }
4631 
4632  auto optional() -> DerivedT & {
4633  m_optionality = Optionality::Optional;
4634  return static_cast<DerivedT &>(*this);
4635  }
4636 
4637  auto required() -> DerivedT & {
4638  m_optionality = Optionality::Required;
4639  return static_cast<DerivedT &>(*this);
4640  }
4641 
4642  auto isOptional() const -> bool {
4643  return m_optionality == Optionality::Optional;
4644  }
4645 
4646  auto cardinality() const -> size_t override {
4647  if (m_ref->isContainer())
4648  return 0;
4649  else
4650  return 1;
4651  }
4652 
4653  StringRef hint() const { return m_hint; }
4654  };
4655 
4656  } // namespace Detail
4657 
4658  // A parser for arguments
4659  class Arg : public Detail::ParserRefImpl<Arg> {
4660  public:
4661  using ParserBase::parse;
4662  using ParserRefImpl::ParserRefImpl;
4663 
4665  parse(std::string const &,
4666  Detail::TokenStream tokens) const override;
4667  };
4668 
4669  // A parser for options
4670  class Opt : public Detail::ParserRefImpl<Opt> {
4671  protected:
4672  std::vector<StringRef> m_optNames;
4673 
4674  public:
4675  template<typename LambdaT>
4676  explicit Opt(LambdaT const &ref)
4677  : ParserRefImpl(
4678  std::make_shared<Detail::BoundFlagLambda<LambdaT>>(ref)) {}
4679 
4680  explicit Opt(bool &ref);
4681 
4682  template<typename LambdaT,
4683  typename = typename std::enable_if_t<
4684  Detail::is_unary_function_v<LambdaT>>>
4685  Opt(LambdaT const &ref, StringRef hint)
4686  : ParserRefImpl(ref, hint) {}
4687 
4688  template<typename LambdaT>
4689  Opt(accept_many_t, LambdaT const &ref, StringRef hint)
4690  : ParserRefImpl(accept_many, ref, hint) {}
4691 
4692  template<typename T,
4693  typename = typename std::enable_if_t<
4694  !Detail::is_unary_function_v<T>>>
4695  Opt(T &ref, StringRef hint)
4696  : ParserRefImpl(ref, hint) {}
4697 
4698  Opt &operator[](StringRef optName) & {
4699  m_optNames.push_back(optName);
4700  return *this;
4701  }
4702  Opt &&operator[](StringRef optName) && {
4703  m_optNames.push_back(optName);
4704  return CATCH_MOVE(*this);
4705  }
4706 
4707  Detail::HelpColumns getHelpColumns() const;
4708 
4709  bool isMatch(StringRef optToken) const;
4710 
4711  using ParserBase::parse;
4712 
4714  parse(std::string const &,
4715  Detail::TokenStream tokens) const override;
4716 
4717  Detail::Result validate() const override;
4718  };
4719 
4720  // Specifies the name of the executable
4721  class ExeName : public Detail::ComposableParserImpl<ExeName> {
4722  std::shared_ptr<std::string> m_name;
4723  std::shared_ptr<Detail::BoundValueRefBase> m_ref;
4724 
4725  public:
4726  ExeName();
4727  explicit ExeName(std::string &ref);
4728 
4729  template<typename LambdaT>
4730  explicit ExeName(LambdaT const &lambda)
4731  : ExeName() {
4732  m_ref = std::make_shared<Detail::BoundLambda<LambdaT>>(lambda);
4733  }
4734 
4735  // The exe name is not parsed out of the normal tokens, but is
4736  // handled specially
4738  parse(std::string const &,
4739  Detail::TokenStream tokens) const override;
4740 
4741  std::string const &name() const { return *m_name; }
4742  Detail::ParserResult set(std::string const &newName);
4743  };
4744 
4745  // A Combined parser
4747  mutable ExeName m_exeName;
4748  std::vector<Opt> m_options;
4749  std::vector<Arg> m_args;
4750 
4751  public:
4752  auto operator|=(ExeName const &exeName) -> Parser & {
4753  m_exeName = exeName;
4754  return *this;
4755  }
4756 
4757  auto operator|=(Arg const &arg) -> Parser & {
4758  m_args.push_back(arg);
4759  return *this;
4760  }
4761 
4762  friend Parser &operator|=(Parser &p, Opt const &opt) {
4763  p.m_options.push_back(opt);
4764  return p;
4765  }
4766  friend Parser &operator|=(Parser &p, Opt &&opt) {
4767  p.m_options.push_back(CATCH_MOVE(opt));
4768  return p;
4769  }
4770 
4771  Parser &operator|=(Parser const &other);
4772 
4773  template<typename T>
4774  friend Parser operator|(Parser const &p, T &&rhs) {
4775  Parser temp(p);
4776  temp |= rhs;
4777  return temp;
4778  }
4779 
4780  template<typename T>
4781  friend Parser operator|(Parser &&p, T &&rhs) {
4782  p |= CATCH_FORWARD(rhs);
4783  return CATCH_MOVE(p);
4784  }
4785 
4786  std::vector<Detail::HelpColumns> getHelpColumns() const;
4787 
4788  void writeToStream(std::ostream &os) const;
4789 
4790  friend auto operator<<(std::ostream &os, Parser const &parser)
4791  -> std::ostream & {
4792  parser.writeToStream(os);
4793  return os;
4794  }
4795 
4796  Detail::Result validate() const override;
4797 
4798  using ParserBase::parse;
4800  parse(std::string const &exeName,
4801  Detail::TokenStream tokens) const override;
4802  };
4803 
4807  class Args {
4808  friend Detail::TokenStream;
4809  StringRef m_exeName;
4810  std::vector<StringRef> m_args;
4811 
4812  public:
4813  Args(int argc, char const *const *argv);
4814  // Helper constructor for testing
4815  Args(std::initializer_list<StringRef> args);
4816 
4817  StringRef exeName() const { return m_exeName; }
4818  };
4819 
4820  // Convenience wrapper for option parser that specifies the help option
4821  struct Help : Opt {
4822  Help(bool &showHelpFlag);
4823  };
4824 
4825  // Result type for parser operation
4826  using Detail::ParserResult;
4827 
4828  namespace Detail {
4829  template<typename DerivedT>
4830  template<typename T>
4831  Parser
4832  ComposableParserImpl<DerivedT>::operator|(T const &other) const {
4833  return Parser() | static_cast<DerivedT const &>(*this) | other;
4834  }
4835  } // namespace Detail
4836 
4837  } // namespace Clara
4838 } // namespace Catch
4839 
4840 #if defined(__clang__)
4841 #pragma clang diagnostic pop
4842 #endif
4843 
4844 #if defined(__GNUC__)
4845 #pragma GCC diagnostic pop
4846 #endif
4847 
4848 #endif // CATCH_CLARA_HPP_INCLUDED
4849 
4850 namespace Catch {
4851 
4852  struct ConfigData;
4853 
4854  Clara::Parser makeCommandLineParser(ConfigData &config);
4855 
4856 } // end namespace Catch
4857 
4858 #endif // CATCH_COMMANDLINE_HPP_INCLUDED
4859 
4860 namespace Catch {
4861 
4862  // TODO: Use C++17 `inline` variables
4863  constexpr int UnspecifiedErrorExitCode = 1;
4864  constexpr int NoTestsRunExitCode = 2;
4865  constexpr int UnmatchedTestSpecExitCode = 3;
4866  constexpr int AllTestsSkippedExitCode = 4;
4867  constexpr int InvalidTestSpecExitCode = 5;
4868  constexpr int TestFailureExitCode = 42;
4869 
4871  public:
4872  Session();
4873  ~Session();
4874 
4875  void showHelp() const;
4876  void libIdentify();
4877 
4878  int applyCommandLine(int argc, char const *const *argv);
4879 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
4880  int applyCommandLine(int argc, wchar_t const *const *argv);
4881 #endif
4882 
4883  void useConfigData(ConfigData const &configData);
4884 
4885  template<typename CharT>
4886  int run(int argc, CharT const *const argv[]) {
4887  if (m_startupExceptions)
4888  return 1;
4889  int returnCode = applyCommandLine(argc, argv);
4890  if (returnCode == 0)
4891  returnCode = run();
4892  return returnCode;
4893  }
4894 
4895  int run();
4896 
4897  Clara::Parser const &cli() const;
4898  void cli(Clara::Parser const &newParser);
4899  ConfigData &configData();
4900  Config &config();
4901 
4902  private:
4903  int runInternal();
4904 
4905  Clara::Parser m_cli;
4906  ConfigData m_configData;
4907  Detail::unique_ptr<Config> m_config;
4908  bool m_startupExceptions = false;
4909  };
4910 
4911 } // end namespace Catch
4912 
4913 #endif // CATCH_SESSION_HPP_INCLUDED
4914 
4915 #ifndef CATCH_TAG_ALIAS_HPP_INCLUDED
4916 #define CATCH_TAG_ALIAS_HPP_INCLUDED
4917 
4918 #include <string>
4919 
4920 namespace Catch {
4921 
4922  struct TagAlias {
4923  TagAlias(std::string const &_tag, SourceLineInfo _lineInfo)
4924  : tag(_tag), lineInfo(_lineInfo) {}
4925 
4926  std::string tag;
4927  SourceLineInfo lineInfo;
4928  };
4929 
4930 } // end namespace Catch
4931 
4932 #endif // CATCH_TAG_ALIAS_HPP_INCLUDED
4933 
4934 #ifndef CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
4935 #define CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
4936 
4937 namespace Catch {
4938 
4940  RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo);
4941  };
4942 
4943 } // end namespace Catch
4944 
4945 #define CATCH_REGISTER_TAG_ALIAS(alias, spec) \
4946  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
4947  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4948  namespace { \
4949  const Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME(AutoRegisterTagAlias)(alias, spec, CATCH_INTERNAL_LINEINFO); \
4950  } \
4951  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
4952 
4953 #endif // CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
4954 
4955 #ifndef CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
4956 #define CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
4957 
4958 // We need this suppression to leak, because it took until GCC 10
4959 // for the front end to handle local suppression via _Pragma properly
4960 // inside templates (so `TEMPLATE_TEST_CASE` and co).
4961 // **THIS IS DIFFERENT FOR STANDARD TESTS, WHERE GCC 9 IS SUFFICIENT**
4962 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 10
4963 #pragma GCC diagnostic ignored "-Wparentheses"
4964 #endif
4965 
4966 #ifndef CATCH_TEST_MACROS_HPP_INCLUDED
4967 #define CATCH_TEST_MACROS_HPP_INCLUDED
4968 
4969 #ifndef CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
4970 #define CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
4971 
4972 #ifndef CATCH_ASSERTION_HANDLER_HPP_INCLUDED
4973 #define CATCH_ASSERTION_HANDLER_HPP_INCLUDED
4974 
4975 #ifndef CATCH_DECOMPOSER_HPP_INCLUDED
4976 #define CATCH_DECOMPOSER_HPP_INCLUDED
4977 
4978 #ifndef CATCH_COMPARE_TRAITS_HPP_INCLUDED
4979 #define CATCH_COMPARE_TRAITS_HPP_INCLUDED
4980 
4981 #include <type_traits>
4982 
4983 namespace Catch {
4984  namespace Detail {
4985 
4986 #if defined(__GNUC__) && !defined(__clang__)
4987 #pragma GCC diagnostic push
4988  // GCC likes to complain about comparing bool with 0, in the decltype()
4989  // that defines the comparable traits below.
4990 #pragma GCC diagnostic ignored "-Wbool-compare"
4991  // "ordered comparison of pointer with integer zero" same as above,
4992  // but it does not have a separate warning flag to suppress
4993 #pragma GCC diagnostic ignored "-Wextra"
4994  // Did you know that comparing floats with `0` directly
4995  // is super-duper dangerous in unevaluated context?
4996 #pragma GCC diagnostic ignored "-Wfloat-equal"
4997 #endif
4998 
4999 #if defined(__clang__)
5000 #pragma clang diagnostic push
5001  // Did you know that comparing floats with `0` directly
5002  // is super-duper dangerous in unevaluated context?
5003 #pragma clang diagnostic ignored "-Wfloat-equal"
5004 #endif
5005 
5006 #define CATCH_DEFINE_COMPARABLE_TRAIT(id, op) \
5007  template<typename, typename, typename = void> \
5008  struct is_##id##_comparable : std::false_type {}; \
5009  template<typename T, typename U> \
5010  struct is_##id##_comparable< \
5011  T, \
5012  U, \
5013  void_t<decltype(std::declval<T>() op std::declval<U>())>> \
5014  : std::true_type {}; \
5015  template<typename, typename = void> \
5016  struct is_##id##_0_comparable : std::false_type {}; \
5017  template<typename T> \
5018  struct is_##id##_0_comparable<T, \
5019  void_t<decltype(std::declval<T>() op 0)>> \
5020  : std::true_type {};
5021 
5022  // We need all 6 pre-spaceship comparison ops: <, <=, >, >=, ==, !=
5023  CATCH_DEFINE_COMPARABLE_TRAIT(lt, <)
5024  CATCH_DEFINE_COMPARABLE_TRAIT(le, <=)
5025  CATCH_DEFINE_COMPARABLE_TRAIT(gt, >)
5026  CATCH_DEFINE_COMPARABLE_TRAIT(ge, >=)
5027  CATCH_DEFINE_COMPARABLE_TRAIT(eq, ==)
5028  CATCH_DEFINE_COMPARABLE_TRAIT(ne, !=)
5029 
5030 #undef CATCH_DEFINE_COMPARABLE_TRAIT
5031 
5032 #if defined(__GNUC__) && !defined(__clang__)
5033 #pragma GCC diagnostic pop
5034 #endif
5035 #if defined(__clang__)
5036 #pragma clang diagnostic pop
5037 #endif
5038 
5039  } // namespace Detail
5040 } // namespace Catch
5041 
5042 #endif // CATCH_COMPARE_TRAITS_HPP_INCLUDED
5043 
5044 #ifndef CATCH_LOGICAL_TRAITS_HPP_INCLUDED
5045 #define CATCH_LOGICAL_TRAITS_HPP_INCLUDED
5046 
5047 #include <type_traits>
5048 
5049 namespace Catch {
5050  namespace Detail {
5051 
5052 #if defined(__cpp_lib_logical_traits) && __cpp_lib_logical_traits >= 201510
5053 
5054  using std::conjunction;
5055  using std::disjunction;
5056  using std::negation;
5057 
5058 #else
5059 
5060  template<class...>
5061  struct conjunction : std::true_type {};
5062  template<class B1>
5063  struct conjunction<B1> : B1 {};
5064  template<class B1, class... Bn>
5065  struct conjunction<B1, Bn...>
5066  : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
5067 
5068  template<class...>
5069  struct disjunction : std::false_type {};
5070  template<class B1>
5071  struct disjunction<B1> : B1 {};
5072  template<class B1, class... Bn>
5073  struct disjunction<B1, Bn...>
5074  : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>> {};
5075 
5076  template<class B>
5077  struct negation : std::integral_constant<bool, !bool(B::value)> {};
5078 
5079 #endif
5080 
5081  } // namespace Detail
5082 } // namespace Catch
5083 
5084 #endif // CATCH_LOGICAL_TRAITS_HPP_INCLUDED
5085 
5086 #include <iosfwd>
5087 #include <type_traits>
5088 
5170 #ifdef _MSC_VER
5171 #pragma warning(push)
5172 #pragma warning(disable : 4389) // '==' : signed/unsigned mismatch
5173 #pragma warning(disable : 4018) // more "signed/unsigned mismatch"
5174 #pragma warning(disable : 4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
5175 #pragma warning(disable : 4180) // qualifier applied to function type has no meaning
5176 #pragma warning(disable : 4800) // Forcing result to true or false
5177 #endif
5178 
5179 #ifdef __clang__
5180 #pragma clang diagnostic push
5181 #pragma clang diagnostic ignored "-Wsign-compare"
5182 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
5183 #elif defined __GNUC__
5184 #pragma GCC diagnostic push
5185 #pragma GCC diagnostic ignored "-Wsign-compare"
5186 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
5187 #endif
5188 
5189 #if defined(CATCH_CPP20_OR_GREATER) && __has_include(<compare>)
5190 #include <compare>
5191 #if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
5192 #define CATCH_CONFIG_CPP20_COMPARE_OVERLOADS
5193 #endif
5194 #endif
5195 
5196 namespace Catch {
5197 
5198  namespace Detail {
5199  // This was added in C++20, but we require only C++14 for now.
5200  template<typename T>
5201  using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>;
5202  } // namespace Detail
5203 
5204  // Note: This is about as much as we can currently reasonably support.
5205  // In an ideal world, we could capture by value small trivially
5206  // copyable types, but the actual `std::is_trivially_copyable`
5207  // trait is a huge mess with standard-violating results on
5208  // GCC and Clang, which are unlikely to be fixed soon due to ABI
5209  // concerns.
5210  // `std::is_scalar` also causes issues due to the `is_pointer`
5211  // component, which causes ambiguity issues with (references-to)
5212  // function pointer. If those are resolved, we still need to
5213  // disambiguate the overload set for arrays, through explicit
5214  // overload for references to sized arrays.
5215  template<typename T>
5217  : std::integral_constant<bool,
5218  std::is_arithmetic<T>::value || std::is_enum<T>::value> {};
5219 
5220 #if defined(CATCH_CONFIG_CPP20_COMPARE_OVERLOADS)
5221  template<>
5222  struct capture_by_value<std::strong_ordering> : std::true_type {};
5223  template<>
5224  struct capture_by_value<std::weak_ordering> : std::true_type {};
5225  template<>
5226  struct capture_by_value<std::partial_ordering> : std::true_type {};
5227 #endif
5228 
5229  template<typename T>
5230  struct always_false : std::false_type {};
5231 
5233  bool m_isBinaryExpression;
5234  bool m_result;
5235 
5236  protected:
5237  ~ITransientExpression() = default;
5238 
5239  public:
5240  constexpr auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
5241  constexpr auto getResult() const -> bool { return m_result; }
5243  virtual void streamReconstructedExpression(std::ostream &os) const;
5244 
5245  constexpr ITransientExpression(bool isBinaryExpression, bool result)
5246  : m_isBinaryExpression(isBinaryExpression), m_result(result) {}
5247 
5248  constexpr ITransientExpression(ITransientExpression const &) = default;
5249  constexpr ITransientExpression &operator=(ITransientExpression const &) = default;
5250 
5251  friend std::ostream &operator<<(std::ostream &out, ITransientExpression const &expr) {
5253  return out;
5254  }
5255  };
5256 
5257  void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs);
5258 
5259  template<typename LhsT, typename RhsT>
5261  LhsT m_lhs;
5262  StringRef m_op;
5263  RhsT m_rhs;
5264 
5265  void streamReconstructedExpression(std::ostream &os) const override {
5266  formatReconstructedExpression(os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
5267  }
5268 
5269  public:
5270  constexpr BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
5271  : ITransientExpression{true, comparisonResult}, m_lhs(lhs), m_op(op), m_rhs(rhs) {}
5272 
5273  template<typename T>
5274  auto operator&&(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5275  static_assert(always_false<T>::value,
5276  "chained comparisons are not supported inside assertions, "
5277  "wrap the expression inside parentheses, or decompose it");
5278  }
5279 
5280  template<typename T>
5281  auto operator||(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5282  static_assert(always_false<T>::value,
5283  "chained comparisons are not supported inside assertions, "
5284  "wrap the expression inside parentheses, or decompose it");
5285  }
5286 
5287  template<typename T>
5288  auto operator==(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5289  static_assert(always_false<T>::value,
5290  "chained comparisons are not supported inside assertions, "
5291  "wrap the expression inside parentheses, or decompose it");
5292  }
5293 
5294  template<typename T>
5295  auto operator!=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5296  static_assert(always_false<T>::value,
5297  "chained comparisons are not supported inside assertions, "
5298  "wrap the expression inside parentheses, or decompose it");
5299  }
5300 
5301  template<typename T>
5302  auto operator>(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5303  static_assert(always_false<T>::value,
5304  "chained comparisons are not supported inside assertions, "
5305  "wrap the expression inside parentheses, or decompose it");
5306  }
5307 
5308  template<typename T>
5309  auto operator<(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5310  static_assert(always_false<T>::value,
5311  "chained comparisons are not supported inside assertions, "
5312  "wrap the expression inside parentheses, or decompose it");
5313  }
5314 
5315  template<typename T>
5316  auto operator>=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5317  static_assert(always_false<T>::value,
5318  "chained comparisons are not supported inside assertions, "
5319  "wrap the expression inside parentheses, or decompose it");
5320  }
5321 
5322  template<typename T>
5323  auto operator<=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
5324  static_assert(always_false<T>::value,
5325  "chained comparisons are not supported inside assertions, "
5326  "wrap the expression inside parentheses, or decompose it");
5327  }
5328  };
5329 
5330  template<typename LhsT>
5332  LhsT m_lhs;
5333 
5334  void streamReconstructedExpression(std::ostream &os) const override {
5335  os << Catch::Detail::stringify(m_lhs);
5336  }
5337 
5338  public:
5339  explicit constexpr UnaryExpr(LhsT lhs)
5340  : ITransientExpression{false, static_cast<bool>(lhs)}, m_lhs(lhs) {}
5341  };
5342 
5343  template<typename LhsT>
5344  class ExprLhs {
5345  LhsT m_lhs;
5346 
5347  public:
5348  explicit constexpr ExprLhs(LhsT lhs)
5349  : m_lhs(lhs) {}
5350 
5351 #define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR(id, op) \
5352  template<typename RhsT> \
5353  constexpr friend auto operator op(ExprLhs &&lhs, RhsT &&rhs) \
5354  ->std::enable_if_t< \
5355  Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5356  Detail::negation<capture_by_value< \
5357  Detail::RemoveCVRef_t<RhsT>>>>::value, \
5358  BinaryExpr<LhsT, RhsT const &>> { \
5359  return { \
5360  static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5361  } \
5362  template<typename RhsT> \
5363  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5364  ->std::enable_if_t< \
5365  Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5366  capture_by_value<RhsT>>::value, \
5367  BinaryExpr<LhsT, RhsT>> { \
5368  return { \
5369  static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5370  } \
5371  template<typename RhsT> \
5372  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5373  ->std::enable_if_t< \
5374  Detail::conjunction< \
5375  Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5376  Detail::is_eq_0_comparable<LhsT>, /* We allow long because we want `ptr op NULL` to be accepted */ \
5377  Detail::disjunction<std::is_same<RhsT, int>, \
5378  std::is_same<RhsT, long>>>::value, \
5379  BinaryExpr<LhsT, RhsT>> { \
5380  if (rhs != 0) { throw_test_failure_exception(); } \
5381  return { \
5382  static_cast<bool>(lhs.m_lhs op 0), lhs.m_lhs, #op##_sr, rhs}; \
5383  } \
5384  template<typename RhsT> \
5385  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5386  ->std::enable_if_t< \
5387  Detail::conjunction< \
5388  Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5389  Detail::is_eq_0_comparable<RhsT>, /* We allow long because we want `ptr op NULL` to be accepted */ \
5390  Detail::disjunction<std::is_same<LhsT, int>, \
5391  std::is_same<LhsT, long>>>::value, \
5392  BinaryExpr<LhsT, RhsT>> { \
5393  if (lhs.m_lhs != 0) { throw_test_failure_exception(); } \
5394  return {static_cast<bool>(0 op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5395  }
5396 
5397  CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR(eq, ==)
5398  CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR(ne, !=)
5399 
5400 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
5401 
5402 #define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR(id, op) \
5403  template<typename RhsT> \
5404  constexpr friend auto operator op(ExprLhs &&lhs, RhsT &&rhs) \
5405  ->std::enable_if_t< \
5406  Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5407  Detail::negation<capture_by_value< \
5408  Detail::RemoveCVRef_t<RhsT>>>>::value, \
5409  BinaryExpr<LhsT, RhsT const &>> { \
5410  return { \
5411  static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5412  } \
5413  template<typename RhsT> \
5414  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5415  ->std::enable_if_t< \
5416  Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5417  capture_by_value<RhsT>>::value, \
5418  BinaryExpr<LhsT, RhsT>> { \
5419  return { \
5420  static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5421  } \
5422  template<typename RhsT> \
5423  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5424  ->std::enable_if_t< \
5425  Detail::conjunction< \
5426  Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5427  Detail::is_##id##_0_comparable<LhsT>, \
5428  std::is_same<RhsT, int>>::value, \
5429  BinaryExpr<LhsT, RhsT>> { \
5430  if (rhs != 0) { throw_test_failure_exception(); } \
5431  return { \
5432  static_cast<bool>(lhs.m_lhs op 0), lhs.m_lhs, #op##_sr, rhs}; \
5433  } \
5434  template<typename RhsT> \
5435  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5436  ->std::enable_if_t< \
5437  Detail::conjunction< \
5438  Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5439  Detail::is_##id##_0_comparable<RhsT>, \
5440  std::is_same<LhsT, int>>::value, \
5441  BinaryExpr<LhsT, RhsT>> { \
5442  if (lhs.m_lhs != 0) { throw_test_failure_exception(); } \
5443  return {static_cast<bool>(0 op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5444  }
5445 
5446  CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR(lt, <)
5447  CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR(le, <=)
5448  CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR(gt, >)
5449  CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR(ge, >=)
5450 
5451 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR
5452 
5453 #define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(op) \
5454  template<typename RhsT> \
5455  constexpr friend auto operator op(ExprLhs &&lhs, RhsT &&rhs) \
5456  ->std::enable_if_t< \
5457  !capture_by_value<Detail::RemoveCVRef_t<RhsT>>::value, \
5458  BinaryExpr<LhsT, RhsT const &>> { \
5459  return { \
5460  static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5461  } \
5462  template<typename RhsT> \
5463  constexpr friend auto operator op(ExprLhs &&lhs, RhsT rhs) \
5464  ->std::enable_if_t<capture_by_value<RhsT>::value, \
5465  BinaryExpr<LhsT, RhsT>> { \
5466  return { \
5467  static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs}; \
5468  }
5469 
5470  CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(|)
5471  CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(&)
5472  CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(^)
5473 
5474 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR
5475 
5476  template<typename RhsT>
5477  friend auto operator&&(ExprLhs &&, RhsT &&) -> BinaryExpr<LhsT, RhsT const &> {
5478  static_assert(always_false<RhsT>::value,
5479  "operator&& is not supported inside assertions, "
5480  "wrap the expression inside parentheses, or decompose it");
5481  }
5482 
5483  template<typename RhsT>
5484  friend auto operator||(ExprLhs &&, RhsT &&) -> BinaryExpr<LhsT, RhsT const &> {
5485  static_assert(always_false<RhsT>::value,
5486  "operator|| is not supported inside assertions, "
5487  "wrap the expression inside parentheses, or decompose it");
5488  }
5489 
5490  constexpr auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
5491  return UnaryExpr<LhsT>{m_lhs};
5492  }
5493  };
5494 
5495  struct Decomposer {
5496  template<typename T,
5497  std::enable_if_t<!capture_by_value<Detail::RemoveCVRef_t<T>>::value,
5498  int>
5499  = 0>
5500  constexpr friend auto operator<=(Decomposer &&, T &&lhs) -> ExprLhs<T const &> {
5501  return ExprLhs<const T &>{lhs};
5502  }
5503 
5504  template<typename T,
5505  std::enable_if_t<capture_by_value<T>::value, int> = 0>
5506  constexpr friend auto operator<=(Decomposer &&, T value) -> ExprLhs<T> {
5507  return ExprLhs<T>{value};
5508  }
5509  };
5510 
5511 } // end namespace Catch
5512 
5513 #ifdef _MSC_VER
5514 #pragma warning(pop)
5515 #endif
5516 #ifdef __clang__
5517 #pragma clang diagnostic pop
5518 #elif defined __GNUC__
5519 #pragma GCC diagnostic pop
5520 #endif
5521 
5522 #endif // CATCH_DECOMPOSER_HPP_INCLUDED
5523 
5524 #include <string>
5525 
5526 namespace Catch {
5527 
5529  bool shouldDebugBreak = false;
5530  bool shouldThrow = false;
5531  bool shouldSkip = false;
5532  };
5533 
5535  AssertionInfo m_assertionInfo;
5536  AssertionReaction m_reaction;
5537  bool m_completed = false;
5538  IResultCapture &m_resultCapture;
5539 
5540  public:
5541  AssertionHandler(StringRef macroName,
5542  SourceLineInfo const &lineInfo,
5543  StringRef capturedExpression,
5544  ResultDisposition::Flags resultDisposition);
5545  ~AssertionHandler() {
5546  if (!m_completed) {
5547  m_resultCapture.handleIncomplete(m_assertionInfo);
5548  }
5549  }
5550 
5551  template<typename T>
5552  constexpr void handleExpr(ExprLhs<T> const &expr) {
5553  handleExpr(expr.makeUnaryExpr());
5554  }
5555  void handleExpr(ITransientExpression const &expr);
5556 
5557  void handleMessage(ResultWas::OfType resultType, std::string &&message);
5558 
5559  void handleExceptionThrownAsExpected();
5560  void handleUnexpectedExceptionNotThrown();
5561  void handleExceptionNotThrownAsExpected();
5562  void handleThrowingCallSkipped();
5563  void handleUnexpectedInflightException();
5564 
5565  void complete();
5566 
5567  // query
5568  auto allowThrows() const -> bool;
5569  };
5570 
5571  void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str);
5572 
5573 } // namespace Catch
5574 
5575 #endif // CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5576 
5577 #ifndef CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
5578 #define CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
5579 
5580 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
5581 #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__##_catch_sr
5582 #else
5583 #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"_catch_sr
5584 #endif
5585 
5586 #endif // CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
5587 
5588 // We need this suppression to leak, because it took until GCC 10
5589 // for the front end to handle local suppression via _Pragma properly
5590 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ <= 9
5591 #pragma GCC diagnostic ignored "-Wparentheses"
5592 #endif
5593 
5594 #if !defined(CATCH_CONFIG_DISABLE)
5595 
5596 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
5597 
5599 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
5600 // macros.
5601 #define INTERNAL_CATCH_TRY
5602 #define INTERNAL_CATCH_CATCH(capturer)
5603 
5604 #else // CATCH_CONFIG_FAST_COMPILE
5605 
5606 #define INTERNAL_CATCH_TRY try
5607 #define INTERNAL_CATCH_CATCH(handler) \
5608  catch (...) { \
5609  (handler).handleUnexpectedInflightException(); \
5610  }
5611 
5612 #endif
5613 
5615 #define INTERNAL_CATCH_TEST(macroName, resultDisposition, ...) \
5616  do { /* NOLINT(bugprone-infinite-loop) */ \
5617  /* The expression should not be evaluated, but warnings should hopefully be checked */ \
5618  CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
5619  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
5620  INTERNAL_CATCH_TRY { \
5621  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5622  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
5623  catchAssertionHandler.handleExpr(Catch::Decomposer() <= __VA_ARGS__); /* NOLINT(bugprone-chained-comparison) */ \
5624  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5625  } \
5626  INTERNAL_CATCH_CATCH(catchAssertionHandler) \
5627  catchAssertionHandler.complete(); \
5628  } while ((void)0, (false) && static_cast<const bool &>(!!(__VA_ARGS__))) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
5629  // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
5630 
5632 #define INTERNAL_CATCH_IF(macroName, resultDisposition, ...) \
5633  INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__); \
5634  if (Catch::getResultCapture().lastAssertionPassed())
5635 
5637 #define INTERNAL_CATCH_ELSE(macroName, resultDisposition, ...) \
5638  INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__); \
5639  if (!Catch::getResultCapture().lastAssertionPassed())
5640 
5642 #define INTERNAL_CATCH_NO_THROW(macroName, resultDisposition, ...) \
5643  do { \
5644  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
5645  try { \
5646  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5647  CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5648  static_cast<void>(__VA_ARGS__); \
5649  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5650  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
5651  } catch (...) { \
5652  catchAssertionHandler.handleUnexpectedInflightException(); \
5653  } \
5654  catchAssertionHandler.complete(); \
5655  } while (false)
5656 
5658 #define INTERNAL_CATCH_THROWS(macroName, resultDisposition, ...) \
5659  do { \
5660  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
5661  if (catchAssertionHandler.allowThrows()) \
5662  try { \
5663  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5664  CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
5665  CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5666  static_cast<void>(__VA_ARGS__); \
5667  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5668  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5669  } catch (...) { \
5670  catchAssertionHandler.handleExceptionThrownAsExpected(); \
5671  } \
5672  else \
5673  catchAssertionHandler.handleThrowingCallSkipped(); \
5674  catchAssertionHandler.complete(); \
5675  } while (false)
5676 
5678 #define INTERNAL_CATCH_THROWS_AS(macroName, exceptionType, resultDisposition, expr) \
5679  do { \
5680  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition); \
5681  if (catchAssertionHandler.allowThrows()) \
5682  try { \
5683  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5684  CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
5685  CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5686  static_cast<void>(expr); \
5687  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5688  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5689  } catch (exceptionType const &) { \
5690  catchAssertionHandler.handleExceptionThrownAsExpected(); \
5691  } catch (...) { \
5692  catchAssertionHandler.handleUnexpectedInflightException(); \
5693  } \
5694  else \
5695  catchAssertionHandler.handleThrowingCallSkipped(); \
5696  catchAssertionHandler.complete(); \
5697  } while (false)
5698 
5700 // Although this is matcher-based, it can be used with just a string
5701 #define INTERNAL_CATCH_THROWS_STR_MATCHES(macroName, resultDisposition, matcher, ...) \
5702  do { \
5703  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition); \
5704  if (catchAssertionHandler.allowThrows()) \
5705  try { \
5706  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5707  CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
5708  CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5709  static_cast<void>(__VA_ARGS__); \
5710  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5711  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5712  } catch (...) { \
5713  Catch::handleExceptionMatchExpr(catchAssertionHandler, matcher); \
5714  } \
5715  else \
5716  catchAssertionHandler.handleThrowingCallSkipped(); \
5717  catchAssertionHandler.complete(); \
5718  } while (false)
5719 
5720 #endif // CATCH_CONFIG_DISABLE
5721 
5722 #endif // CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5723 
5724 #ifndef CATCH_SECTION_HPP_INCLUDED
5725 #define CATCH_SECTION_HPP_INCLUDED
5726 
5736 #ifndef CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
5737 #define CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
5738 
5739 #if defined(__clang_analyzer__) || defined(__COVERITY__)
5740 #define CATCH_INTERNAL_CONFIG_STATIC_ANALYSIS_SUPPORT
5741 #endif
5742 
5743 #if defined(CATCH_INTERNAL_CONFIG_STATIC_ANALYSIS_SUPPORT) && !defined(CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT) && !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
5744 #define CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
5745 #endif
5746 
5747 #endif // CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
5748 
5749 #ifndef CATCH_TIMER_HPP_INCLUDED
5750 #define CATCH_TIMER_HPP_INCLUDED
5751 
5752 #include <cstdint>
5753 
5754 namespace Catch {
5755 
5756  class Timer {
5757  uint64_t m_nanoseconds = 0;
5758 
5759  public:
5760  void start();
5761  auto getElapsedNanoseconds() const -> uint64_t;
5762  auto getElapsedMicroseconds() const -> uint64_t;
5763  auto getElapsedMilliseconds() const -> unsigned int;
5764  auto getElapsedSeconds() const -> double;
5765  };
5766 
5767 } // namespace Catch
5768 
5769 #endif // CATCH_TIMER_HPP_INCLUDED
5770 
5771 namespace Catch {
5772 
5774  public:
5775  Section(SectionInfo &&info);
5776  Section(SourceLineInfo const &_lineInfo,
5777  StringRef _name,
5778  const char *const = nullptr);
5779  ~Section();
5780 
5781  // This indicates whether the section should be executed or not
5782  explicit operator bool() const;
5783 
5784  private:
5785  SectionInfo m_info;
5786 
5787  Counts m_assertions;
5788  bool m_sectionIncluded;
5789  Timer m_timer;
5790  };
5791 
5792 } // end namespace Catch
5793 
5794 #if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
5795 #define INTERNAL_CATCH_SECTION(...) \
5796  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5797  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5798  if (Catch::Section const &INTERNAL_CATCH_UNIQUE_NAME( \
5799  catch_internal_Section) \
5800  = Catch::Section(CATCH_INTERNAL_LINEINFO, __VA_ARGS__)) \
5801  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5802 
5803 #define INTERNAL_CATCH_DYNAMIC_SECTION(...) \
5804  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5805  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5806  if (Catch::Section const &INTERNAL_CATCH_UNIQUE_NAME( \
5807  catch_internal_Section) \
5808  = Catch::SectionInfo( \
5809  CATCH_INTERNAL_LINEINFO, \
5810  (Catch::ReusableStringStream() << __VA_ARGS__) \
5811  .str())) \
5812  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5813 
5814 #else
5815 
5816 // These section definitions imply that at most one section at one level
5817 // will be entered (because only one section's __LINE__ can be equal to
5818 // the dummy `catchInternalSectionHint` variable from `TEST_CASE`).
5819 
5820 namespace Catch {
5821  namespace Detail {
5822  // Intentionally without linkage, as it should only be used as a dummy
5823  // symbol for static analysis.
5824  // The arguments are used as a dummy for checking warnings in the passed
5825  // expressions.
5826  int GetNewSectionHint(StringRef, const char *const = nullptr);
5827  } // namespace Detail
5828 } // namespace Catch
5829 
5830 #define INTERNAL_CATCH_SECTION(...) \
5831  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5832  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5833  CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
5834  if ([[maybe_unused]] const int catchInternalPreviousSectionHint = catchInternalSectionHint, \
5835  catchInternalSectionHint = Catch::Detail::GetNewSectionHint(__VA_ARGS__); \
5836  catchInternalPreviousSectionHint == __LINE__) \
5837  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5838 
5839 #define INTERNAL_CATCH_DYNAMIC_SECTION(...) \
5840  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5841  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5842  CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
5843  if ([[maybe_unused]] const int catchInternalPreviousSectionHint = catchInternalSectionHint, \
5844  catchInternalSectionHint = Catch::Detail::GetNewSectionHint( \
5845  (Catch::ReusableStringStream() << __VA_ARGS__).str()); \
5846  catchInternalPreviousSectionHint == __LINE__) \
5847  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5848 
5849 #endif
5850 
5851 #endif // CATCH_SECTION_HPP_INCLUDED
5852 
5853 #ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
5854 #define CATCH_TEST_REGISTRY_HPP_INCLUDED
5855 
5856 #ifndef CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED
5857 #define CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED
5858 
5859 namespace Catch {
5860 
5862  public:
5863  virtual void prepareTestCase();
5864  virtual void tearDownTestCase();
5865  virtual void invoke() const = 0;
5866  virtual ~ITestInvoker(); // = default
5867  };
5868 
5869 } // namespace Catch
5870 
5871 #endif // CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED
5872 
5873 #ifndef CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5874 #define CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5875 
5876 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
5877 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__
5878 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
5879 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
5880 
5881 #define INTERNAL_CATCH_REMOVE_PARENS(...) \
5882  INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
5883 
5884 #endif // CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5885 
5886 // GCC 5 and older do not properly handle disabling unused-variable warning
5887 // with a _Pragma. This means that we have to leak the suppression to the
5888 // user code as well :-(
5889 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
5890 #pragma GCC diagnostic ignored "-Wunused-variable"
5891 #endif
5892 
5893 namespace Catch {
5894 
5895  template<typename C>
5897  void (C::*m_testAsMethod)();
5898 
5899  public:
5900  constexpr TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept
5901  : m_testAsMethod(testAsMethod) {}
5902 
5903  void invoke() const override {
5904  C obj;
5905  (obj.*m_testAsMethod)();
5906  }
5907  };
5908 
5909  Detail::unique_ptr<ITestInvoker> makeTestInvoker(void (*testAsFunction)());
5910 
5911  template<typename C>
5912  Detail::unique_ptr<ITestInvoker> makeTestInvoker(void (C::*testAsMethod)()) {
5913  return Detail::make_unique<TestInvokerAsMethod<C>>(testAsMethod);
5914  }
5915 
5916  template<typename C>
5918  void (C::*m_testAsMethod)() const;
5919  Detail::unique_ptr<C> m_fixture = nullptr;
5920 
5921  public:
5922  constexpr TestInvokerFixture(void (C::*testAsMethod)() const) noexcept
5923  : m_testAsMethod(testAsMethod) {}
5924 
5925  void prepareTestCase() override {
5926  m_fixture = Detail::make_unique<C>();
5927  }
5928 
5929  void tearDownTestCase() override {
5930  m_fixture.reset();
5931  }
5932 
5933  void invoke() const override {
5934  auto *f = m_fixture.get();
5935  (f->*m_testAsMethod)();
5936  }
5937  };
5938 
5939  template<typename C>
5940  Detail::unique_ptr<ITestInvoker> makeTestInvokerFixture(void (C::*testAsMethod)() const) {
5941  return Detail::make_unique<TestInvokerFixture<C>>(testAsMethod);
5942  }
5943 
5944  struct NameAndTags {
5945  constexpr NameAndTags(StringRef name_ = StringRef(),
5946  StringRef tags_ = StringRef()) noexcept
5947  : name(name_), tags(tags_) {}
5948  StringRef name;
5949  StringRef tags;
5950  };
5951 
5953  AutoReg(Detail::unique_ptr<ITestInvoker> invoker, SourceLineInfo const &lineInfo, StringRef classOrMethod, NameAndTags const &nameAndTags) noexcept;
5954  };
5955 
5956 } // end namespace Catch
5957 
5958 #if defined(CATCH_CONFIG_DISABLE)
5959 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(TestName, ...) \
5960  static inline void TestName()
5961 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(TestName, ClassName, ...) \
5962  namespace { \
5963  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
5964  void test(); \
5965  }; \
5966  } \
5967  void TestName::test()
5968 #endif
5969 
5970 #if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
5971 
5973 #define INTERNAL_CATCH_TESTCASE2(TestName, ...) \
5974  static void TestName(); \
5975  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5976  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5977  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5978  namespace { \
5979  const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{__VA_ARGS__}); \
5980  } /* NOLINT */ \
5981  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5982  static void TestName()
5983 #define INTERNAL_CATCH_TESTCASE(...) \
5984  INTERNAL_CATCH_TESTCASE2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), __VA_ARGS__)
5985 
5986 #else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
5987 
5988 // Dummy registrator for the dumy test case macros
5989 namespace Catch {
5990  namespace Detail {
5991  struct DummyUse {
5992  DummyUse(void (*)(int), Catch::NameAndTags const &);
5993  };
5994  } // namespace Detail
5995 } // namespace Catch
5996 
5997 // Note that both the presence of the argument and its exact name are
5998 // necessary for the section support.
5999 
6000 // We provide a shadowed variable so that a `SECTION` inside non-`TEST_CASE`
6001 // tests can compile. The redefined `TEST_CASE` shadows this with param.
6002 static int catchInternalSectionHint = 0;
6003 
6004 #define INTERNAL_CATCH_TESTCASE2(fname, ...) \
6005  static void fname(int); \
6006  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6007  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6008  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6009  static const Catch::Detail::DummyUse INTERNAL_CATCH_UNIQUE_NAME( \
6010  dummyUser)(&(fname), Catch::NameAndTags{__VA_ARGS__}); \
6011  CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
6012  static void fname([[maybe_unused]] int catchInternalSectionHint) \
6013  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6014 #define INTERNAL_CATCH_TESTCASE(...) \
6015  INTERNAL_CATCH_TESTCASE2(INTERNAL_CATCH_UNIQUE_NAME(dummyFunction), __VA_ARGS__)
6016 
6017 #endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
6018 
6020 #define INTERNAL_CATCH_TEST_CASE_METHOD2(TestName, ClassName, ...) \
6021  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6022  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6023  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6024  namespace { \
6025  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
6026  void test(); \
6027  }; \
6028  const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)( \
6029  Catch::makeTestInvoker(&TestName::test), \
6030  CATCH_INTERNAL_LINEINFO, \
6031  #ClassName##_catch_sr, \
6032  Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \
6033  } \
6034  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6035  void TestName::test()
6036 #define INTERNAL_CATCH_TEST_CASE_METHOD(ClassName, ...) \
6037  INTERNAL_CATCH_TEST_CASE_METHOD2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), ClassName, __VA_ARGS__)
6038 
6040 #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2(TestName, ClassName, ...) \
6041  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6042  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6043  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6044  namespace { \
6045  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
6046  void test() const; \
6047  }; \
6048  const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)( \
6049  Catch::makeTestInvokerFixture(&TestName::test), \
6050  CATCH_INTERNAL_LINEINFO, \
6051  #ClassName##_catch_sr, \
6052  Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \
6053  } \
6054  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6055  void TestName::test() const
6056 #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE(ClassName, ...) \
6057  INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), ClassName, __VA_ARGS__)
6058 
6060 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE(QualifiedMethod, ...) \
6061  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6062  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6063  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6064  namespace { \
6065  const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)( \
6066  Catch::makeTestInvoker(&QualifiedMethod), \
6067  CATCH_INTERNAL_LINEINFO, \
6068  "&" #QualifiedMethod##_catch_sr, \
6069  Catch::NameAndTags{__VA_ARGS__}); \
6070  } /* NOLINT */ \
6071  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6072 
6074 #define INTERNAL_CATCH_REGISTER_TESTCASE(Function, ...) \
6075  do { \
6076  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6077  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6078  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6079  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(Function), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \
6080  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6081  } while (false)
6082 
6083 #endif // CATCH_TEST_REGISTRY_HPP_INCLUDED
6084 
6085 #ifndef CATCH_UNREACHABLE_HPP_INCLUDED
6086 #define CATCH_UNREACHABLE_HPP_INCLUDED
6087 
6097 #include <exception>
6098 
6099 #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable > 202202L
6100 #include <utility>
6101 namespace Catch {
6102  namespace Detail {
6103  using Unreachable = std::unreachable;
6104  }
6105 } // namespace Catch
6106 
6107 #else // vv If we do not have std::unreachable, we implement something similar
6108 
6109 namespace Catch {
6110  namespace Detail {
6111 
6112  [[noreturn]]
6113  inline void Unreachable() noexcept {
6114 #if defined(NDEBUG)
6115 #if defined(_MSC_VER) && !defined(__clang__)
6116  __assume(false);
6117 #elif defined(__GNUC__)
6118  __builtin_unreachable();
6119 #else // vv platform without known optimization hint
6120  std::terminate();
6121 #endif
6122 #else // ^^ NDEBUG
6123  // For non-release builds, we prefer termination on bug over UB
6124  std::terminate();
6125 #endif //
6126  }
6127 
6128  } // namespace Detail
6129 } // end namespace Catch
6130 
6131 #endif
6132 
6133 #endif // CATCH_UNREACHABLE_HPP_INCLUDED
6134 
6135 // All of our user-facing macros support configuration toggle, that
6136 // forces them to be defined prefixed with CATCH_. We also like to
6137 // support another toggle that can minimize (disable) their implementation.
6138 // Given this, we have 4 different configuration options below
6139 
6140 #if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
6141 
6142 #define CATCH_REQUIRE(...) INTERNAL_CATCH_TEST("CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__)
6143 #define CATCH_REQUIRE_FALSE(...) INTERNAL_CATCH_TEST("CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
6144 
6145 #define CATCH_REQUIRE_THROWS(...) INTERNAL_CATCH_THROWS("CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__)
6146 #define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) INTERNAL_CATCH_THROWS_AS("CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr)
6147 #define CATCH_REQUIRE_NOTHROW(...) INTERNAL_CATCH_NO_THROW("CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__)
6148 
6149 #define CATCH_CHECK(...) INTERNAL_CATCH_TEST("CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6150 #define CATCH_CHECK_FALSE(...) INTERNAL_CATCH_TEST("CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
6151 #define CATCH_CHECKED_IF(...) INTERNAL_CATCH_IF("CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
6152 #define CATCH_CHECKED_ELSE(...) INTERNAL_CATCH_ELSE("CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
6153 #define CATCH_CHECK_NOFAIL(...) INTERNAL_CATCH_TEST("CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
6154 
6155 #define CATCH_CHECK_THROWS(...) INTERNAL_CATCH_THROWS("CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6156 #define CATCH_CHECK_THROWS_AS(expr, exceptionType) INTERNAL_CATCH_THROWS_AS("CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr)
6157 #define CATCH_CHECK_NOTHROW(...) INTERNAL_CATCH_NO_THROW("CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6158 
6159 #define CATCH_TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__)
6160 #define CATCH_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__)
6161 #define CATCH_METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__)
6162 #define CATCH_TEST_CASE_PERSISTENT_FIXTURE(className, ...) INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE(className, __VA_ARGS__)
6163 #define CATCH_REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__)
6164 #define CATCH_SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__)
6165 #define CATCH_DYNAMIC_SECTION(...) INTERNAL_CATCH_DYNAMIC_SECTION(__VA_ARGS__)
6166 #define CATCH_FAIL(...) \
6167  do { \
6168  INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__); \
6169  Catch::Detail::Unreachable(); \
6170  } while (false)
6171 #define CATCH_FAIL_CHECK(...) INTERNAL_CATCH_MSG("CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6172 #define CATCH_SUCCEED(...) INTERNAL_CATCH_MSG("CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6173 #define CATCH_SKIP(...) \
6174  do { \
6175  INTERNAL_CATCH_MSG("CATCH_SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__); \
6176  Catch::Detail::Unreachable(); \
6177  } while (false)
6178 
6179 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
6180 #define CATCH_STATIC_REQUIRE(...) \
6181  static_assert(__VA_ARGS__, #__VA_ARGS__); \
6182  CATCH_SUCCEED(#__VA_ARGS__)
6183 #define CATCH_STATIC_REQUIRE_FALSE(...) \
6184  static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")"); \
6185  CATCH_SUCCEED(#__VA_ARGS__)
6186 #define CATCH_STATIC_CHECK(...) \
6187  static_assert(__VA_ARGS__, #__VA_ARGS__); \
6188  CATCH_SUCCEED(#__VA_ARGS__)
6189 #define CATCH_STATIC_CHECK_FALSE(...) \
6190  static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")"); \
6191  CATCH_SUCCEED(#__VA_ARGS__)
6192 #else
6193 #define CATCH_STATIC_REQUIRE(...) CATCH_REQUIRE(__VA_ARGS__)
6194 #define CATCH_STATIC_REQUIRE_FALSE(...) CATCH_REQUIRE_FALSE(__VA_ARGS__)
6195 #define CATCH_STATIC_CHECK(...) CATCH_CHECK(__VA_ARGS__)
6196 #define CATCH_STATIC_CHECK_FALSE(...) CATCH_CHECK_FALSE(__VA_ARGS__)
6197 #endif
6198 
6199 // "BDD-style" convenience wrappers
6200 #define CATCH_SCENARIO(...) CATCH_TEST_CASE("Scenario: " __VA_ARGS__)
6201 #define CATCH_SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
6202 #define CATCH_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Given: " << desc)
6203 #define CATCH_AND_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("And given: " << desc)
6204 #define CATCH_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" When: " << desc)
6205 #define CATCH_AND_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And when: " << desc)
6206 #define CATCH_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Then: " << desc)
6207 #define CATCH_AND_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And: " << desc)
6208 
6209 #elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) // ^^ prefixed, implemented | vv prefixed, disabled
6210 
6211 #define CATCH_REQUIRE(...) (void)(0)
6212 #define CATCH_REQUIRE_FALSE(...) (void)(0)
6213 
6214 #define CATCH_REQUIRE_THROWS(...) (void)(0)
6215 #define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) (void)(0)
6216 #define CATCH_REQUIRE_NOTHROW(...) (void)(0)
6217 
6218 #define CATCH_CHECK(...) (void)(0)
6219 #define CATCH_CHECK_FALSE(...) (void)(0)
6220 #define CATCH_CHECKED_IF(...) if (__VA_ARGS__)
6221 #define CATCH_CHECKED_ELSE(...) if (!(__VA_ARGS__))
6222 #define CATCH_CHECK_NOFAIL(...) (void)(0)
6223 
6224 #define CATCH_CHECK_THROWS(...) (void)(0)
6225 #define CATCH_CHECK_THROWS_AS(expr, exceptionType) (void)(0)
6226 #define CATCH_CHECK_NOTHROW(...) (void)(0)
6227 
6228 #define CATCH_TEST_CASE(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_))
6229 #define CATCH_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_))
6230 #define CATCH_METHOD_AS_TEST_CASE(method, ...)
6231 #define CATCH_TEST_CASE_PERSISTENT_FIXTURE(className, ...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_))
6232 #define CATCH_REGISTER_TEST_CASE(Function, ...) (void)(0)
6233 #define CATCH_SECTION(...)
6234 #define CATCH_DYNAMIC_SECTION(...)
6235 #define CATCH_FAIL(...) (void)(0)
6236 #define CATCH_FAIL_CHECK(...) (void)(0)
6237 #define CATCH_SUCCEED(...) (void)(0)
6238 #define CATCH_SKIP(...) (void)(0)
6239 
6240 #define CATCH_STATIC_REQUIRE(...) (void)(0)
6241 #define CATCH_STATIC_REQUIRE_FALSE(...) (void)(0)
6242 #define CATCH_STATIC_CHECK(...) (void)(0)
6243 #define CATCH_STATIC_CHECK_FALSE(...) (void)(0)
6244 
6245 // "BDD-style" convenience wrappers
6246 #define CATCH_SCENARIO(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_))
6247 #define CATCH_SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), className)
6248 #define CATCH_GIVEN(desc)
6249 #define CATCH_AND_GIVEN(desc)
6250 #define CATCH_WHEN(desc)
6251 #define CATCH_AND_WHEN(desc)
6252 #define CATCH_THEN(desc)
6253 #define CATCH_AND_THEN(desc)
6254 
6255 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE) // ^^ prefixed, disabled | vv unprefixed, implemented
6256 
6257 #define REQUIRE(...) INTERNAL_CATCH_TEST("REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__)
6258 #define REQUIRE_FALSE(...) INTERNAL_CATCH_TEST("REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
6259 
6260 #define REQUIRE_THROWS(...) INTERNAL_CATCH_THROWS("REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__)
6261 #define REQUIRE_THROWS_AS(expr, exceptionType) INTERNAL_CATCH_THROWS_AS("REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr)
6262 #define REQUIRE_NOTHROW(...) INTERNAL_CATCH_NO_THROW("REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__)
6263 
6264 #define CHECK(...) INTERNAL_CATCH_TEST("CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6265 #define CHECK_FALSE(...) INTERNAL_CATCH_TEST("CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
6266 #define CHECKED_IF(...) INTERNAL_CATCH_IF("CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
6267 #define CHECKED_ELSE(...) INTERNAL_CATCH_ELSE("CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
6268 #define CHECK_NOFAIL(...) INTERNAL_CATCH_TEST("CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
6269 
6270 #define CHECK_THROWS(...) INTERNAL_CATCH_THROWS("CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6271 #define CHECK_THROWS_AS(expr, exceptionType) INTERNAL_CATCH_THROWS_AS("CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr)
6272 #define CHECK_NOTHROW(...) INTERNAL_CATCH_NO_THROW("CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6273 
6274 #define TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__)
6275 #define TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__)
6276 #define METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__)
6277 #define TEST_CASE_PERSISTENT_FIXTURE(className, ...) INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE(className, __VA_ARGS__)
6278 #define REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__)
6279 #define SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__)
6280 #define DYNAMIC_SECTION(...) INTERNAL_CATCH_DYNAMIC_SECTION(__VA_ARGS__)
6281 #define FAIL(...) \
6282  do { \
6283  INTERNAL_CATCH_MSG("FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__); \
6284  Catch::Detail::Unreachable(); \
6285  } while (false)
6286 #define FAIL_CHECK(...) INTERNAL_CATCH_MSG("FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6287 #define SUCCEED(...) INTERNAL_CATCH_MSG("SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
6288 #define SKIP(...) \
6289  do { \
6290  INTERNAL_CATCH_MSG("SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__); \
6291  Catch::Detail::Unreachable(); \
6292  } while (false)
6293 
6294 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
6295 #define STATIC_REQUIRE(...) \
6296  static_assert(__VA_ARGS__, #__VA_ARGS__); \
6297  SUCCEED(#__VA_ARGS__)
6298 #define STATIC_REQUIRE_FALSE(...) \
6299  static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")"); \
6300  SUCCEED("!(" #__VA_ARGS__ ")")
6301 #define STATIC_CHECK(...) \
6302  static_assert(__VA_ARGS__, #__VA_ARGS__); \
6303  SUCCEED(#__VA_ARGS__)
6304 #define STATIC_CHECK_FALSE(...) \
6305  static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")"); \
6306  SUCCEED("!(" #__VA_ARGS__ ")")
6307 #else
6308 #define STATIC_REQUIRE(...) REQUIRE(__VA_ARGS__)
6309 #define STATIC_REQUIRE_FALSE(...) REQUIRE_FALSE(__VA_ARGS__)
6310 #define STATIC_CHECK(...) CHECK(__VA_ARGS__)
6311 #define STATIC_CHECK_FALSE(...) CHECK_FALSE(__VA_ARGS__)
6312 #endif
6313 
6314 // "BDD-style" convenience wrappers
6315 #define SCENARIO(...) TEST_CASE("Scenario: " __VA_ARGS__)
6316 #define SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
6317 #define GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Given: " << desc)
6318 #define AND_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("And given: " << desc)
6319 #define WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" When: " << desc)
6320 #define AND_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And when: " << desc)
6321 #define THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Then: " << desc)
6322 #define AND_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And: " << desc)
6323 
6324 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) // ^^ unprefixed, implemented | vv unprefixed, disabled
6325 
6326 #define REQUIRE(...) (void)(0)
6327 #define REQUIRE_FALSE(...) (void)(0)
6328 
6329 #define REQUIRE_THROWS(...) (void)(0)
6330 #define REQUIRE_THROWS_AS(expr, exceptionType) (void)(0)
6331 #define REQUIRE_NOTHROW(...) (void)(0)
6332 
6333 #define CHECK(...) (void)(0)
6334 #define CHECK_FALSE(...) (void)(0)
6335 #define CHECKED_IF(...) if (__VA_ARGS__)
6336 #define CHECKED_ELSE(...) if (!(__VA_ARGS__))
6337 #define CHECK_NOFAIL(...) (void)(0)
6338 
6339 #define CHECK_THROWS(...) (void)(0)
6340 #define CHECK_THROWS_AS(expr, exceptionType) (void)(0)
6341 #define CHECK_NOTHROW(...) (void)(0)
6342 
6343 #define TEST_CASE(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), __VA_ARGS__)
6344 #define TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_))
6345 #define METHOD_AS_TEST_CASE(method, ...)
6346 #define TEST_CASE_PERSISTENT_FIXTURE(className, ...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), __VA_ARGS__)
6347 #define REGISTER_TEST_CASE(Function, ...) (void)(0)
6348 #define SECTION(...)
6349 #define DYNAMIC_SECTION(...)
6350 #define FAIL(...) (void)(0)
6351 #define FAIL_CHECK(...) (void)(0)
6352 #define SUCCEED(...) (void)(0)
6353 #define SKIP(...) (void)(0)
6354 
6355 #define STATIC_REQUIRE(...) (void)(0)
6356 #define STATIC_REQUIRE_FALSE(...) (void)(0)
6357 #define STATIC_CHECK(...) (void)(0)
6358 #define STATIC_CHECK_FALSE(...) (void)(0)
6359 
6360 // "BDD-style" convenience wrappers
6361 #define SCENARIO(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_))
6362 #define SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEST_), className)
6363 
6364 #define GIVEN(desc)
6365 #define AND_GIVEN(desc)
6366 #define WHEN(desc)
6367 #define AND_WHEN(desc)
6368 #define THEN(desc)
6369 #define AND_THEN(desc)
6370 
6371 #endif // ^^ unprefixed, disabled
6372 
6373 // end of user facing macros
6374 
6375 #endif // CATCH_TEST_MACROS_HPP_INCLUDED
6376 
6377 #ifndef CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6378 #define CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6379 
6380 #ifndef CATCH_PREPROCESSOR_HPP_INCLUDED
6381 #define CATCH_PREPROCESSOR_HPP_INCLUDED
6382 
6383 #if defined(__GNUC__)
6384 // We need to silence "empty __VA_ARGS__ warning", and using just _Pragma does not work
6385 #pragma GCC system_header
6386 #endif
6387 
6388 namespace Catch {
6389  namespace Detail {
6390  template<int N>
6391  struct priority_tag : priority_tag<N - 1> {};
6392  template<>
6393  struct priority_tag<0> {};
6394  } // namespace Detail
6395 } // namespace Catch
6396 
6397 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
6398 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
6399 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
6400 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
6401 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
6402 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
6403 
6404 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6405 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
6406 // MSVC needs more evaluations
6407 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
6408 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
6409 #else
6410 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
6411 #endif
6412 
6413 #define CATCH_REC_END(...)
6414 #define CATCH_REC_OUT
6415 
6416 #define CATCH_EMPTY()
6417 #define CATCH_DEFER(id) id CATCH_EMPTY()
6418 
6419 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
6420 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
6421 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
6422 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
6423 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER(CATCH_REC_NEXT0)(test, next, 0)
6424 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
6425 
6426 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
6427 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0))(f, peek, __VA_ARGS__)
6428 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
6429 
6430 #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__)
6431 #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD))(f, userdata, peek, __VA_ARGS__)
6432 #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__)
6433 
6434 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
6435 // and passes userdata as the first parameter to each invocation,
6436 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
6437 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
6438 
6439 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
6440 
6441 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
6442 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6443 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
6444 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
6445 #else
6446 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
6447 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
6448 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
6449 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
6450 #endif
6451 
6452 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
6453 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
6454 
6455 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6456 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>(Catch::Detail::priority_tag<1>{}))
6457 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
6458 #else
6459 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>(Catch::Detail::priority_tag<1>{})))
6460 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
6461 #endif
6462 
6463 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...) \
6464  CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST, __VA_ARGS__)
6465 
6466 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
6467 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
6468 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
6469 #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
6470 #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
6471 #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
6472 #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
6473 #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
6474 #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
6475 #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
6476 #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
6477 
6478 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
6479 
6480 #define INTERNAL_CATCH_TYPE_GEN \
6481  template<typename...> \
6482  struct TypeList {}; \
6483  template<typename... Ts> \
6484  constexpr auto get_wrapper(Catch::Detail::priority_tag<1>) noexcept -> TypeList<Ts...> { \
6485  return {}; \
6486  } \
6487  template<template<typename...> class...> \
6488  struct TemplateTypeList {}; \
6489  template<template<typename...> class... Cs> \
6490  constexpr auto get_wrapper(Catch::Detail::priority_tag<1>) noexcept -> TemplateTypeList<Cs...> { \
6491  return {}; \
6492  } \
6493  template<typename...> \
6494  struct append; \
6495  template<typename...> \
6496  struct rewrap; \
6497  template<template<typename...> class, typename...> \
6498  struct create; \
6499  template<template<typename...> class, typename> \
6500  struct convert; \
6501  \
6502  template<typename T> \
6503  struct append<T> { \
6504  using type = T; \
6505  }; \
6506  template<template<typename...> class L1, typename... E1, template<typename...> class L2, typename... E2, typename... Rest> \
6507  struct append<L1<E1...>, L2<E2...>, Rest...> { \
6508  using type = typename append<L1<E1..., E2...>, Rest...>::type; \
6509  }; \
6510  template<template<typename...> class L1, typename... E1, typename... Rest> \
6511  struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { \
6512  using type = L1<E1...>; \
6513  }; \
6514  \
6515  template<template<typename...> class Container, template<typename...> class List, typename... elems> \
6516  struct rewrap<TemplateTypeList<Container>, List<elems...>> { \
6517  using type = TypeList<Container<elems...>>; \
6518  }; \
6519  template<template<typename...> class Container, template<typename...> class List, class... Elems, typename... Elements> \
6520  struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { \
6521  using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; \
6522  }; \
6523  \
6524  template<template<typename...> class Final, template<typename...> class... Containers, typename... Types> \
6525  struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { \
6526  using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; \
6527  }; \
6528  template<template<typename...> class Final, template<typename...> class List, typename... Ts> \
6529  struct convert<Final, List<Ts...>> { \
6530  using type = typename append<Final<>, TypeList<Ts>...>::type; \
6531  };
6532 
6533 #define INTERNAL_CATCH_NTTP_1(signature, ...) \
6534  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6535  struct Nttp {}; \
6536  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6537  constexpr auto get_wrapper(Catch::Detail::priority_tag<0>) noexcept -> Nttp<__VA_ARGS__> { \
6538  return {}; \
6539  } \
6540  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> \
6541  struct NttpTemplateTypeList {}; \
6542  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Cs> \
6543  constexpr auto get_wrapper(Catch::Detail::priority_tag<0>) noexcept -> NttpTemplateTypeList<Cs...> { \
6544  return {}; \
6545  } \
6546  \
6547  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6548  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { \
6549  using type = TypeList<Container<__VA_ARGS__>>; \
6550  }; \
6551  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename... Elements> \
6552  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { \
6553  using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; \
6554  }; \
6555  template<template<typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Containers, typename... Types> \
6556  struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { \
6557  using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; \
6558  };
6559 
6560 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
6561 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature) \
6562  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6563  static void TestName()
6564 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...) \
6565  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6566  static void TestName()
6567 
6568 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
6569 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature) \
6570  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6571  static void TestName()
6572 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature, ...) \
6573  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6574  static void TestName()
6575 
6576 #define INTERNAL_CATCH_TYPES_REGISTER(TestFunc) \
6577  template<typename... Ts> \
6578  void reg_test(TypeList<Ts...>, Catch::NameAndTags nameAndTags) { \
6579  Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Ts...>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags); \
6580  }
6581 
6582 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature, ...)
6583 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...) \
6584  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6585  void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags) { \
6586  Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags); \
6587  }
6588 
6589 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...) \
6590  template<typename Type> \
6591  void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags) { \
6592  Catch::AutoReg(Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags); \
6593  }
6594 
6595 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...) \
6596  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6597  void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags) { \
6598  Catch::AutoReg(Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags); \
6599  }
6600 
6601 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
6602 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature) \
6603  template<typename TestType> \
6604  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
6605  void test(); \
6606  }
6607 
6608 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...) \
6609  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6610  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
6611  void test(); \
6612  }
6613 
6614 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
6615 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature) \
6616  template<typename TestType> \
6617  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
6618 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...) \
6619  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6620  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
6621 
6622 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6623 #define INTERNAL_CATCH_NTTP_0
6624 #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_0)
6625 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
6626 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
6627 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
6628 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_TYPES_REGISTER(TestFunc) INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
6629 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
6630 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
6631 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG, INTERNAL_CATCH_REMOVE_PARENS_10_ARG, INTERNAL_CATCH_REMOVE_PARENS_9_ARG, INTERNAL_CATCH_REMOVE_PARENS_8_ARG, INTERNAL_CATCH_REMOVE_PARENS_7_ARG, INTERNAL_CATCH_REMOVE_PARENS_6_ARG, INTERNAL_CATCH_REMOVE_PARENS_5_ARG, INTERNAL_CATCH_REMOVE_PARENS_4_ARG, INTERNAL_CATCH_REMOVE_PARENS_3_ARG, INTERNAL_CATCH_REMOVE_PARENS_2_ARG, INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
6632 #else
6633 #define INTERNAL_CATCH_NTTP_0(signature)
6634 #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)(__VA_ARGS__))
6635 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
6636 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
6637 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
6638 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_TYPES_REGISTER(TestFunc) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
6639 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
6640 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
6641 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG, INTERNAL_CATCH_REMOVE_PARENS_10_ARG, INTERNAL_CATCH_REMOVE_PARENS_9_ARG, INTERNAL_CATCH_REMOVE_PARENS_8_ARG, INTERNAL_CATCH_REMOVE_PARENS_7_ARG, INTERNAL_CATCH_REMOVE_PARENS_6_ARG, INTERNAL_CATCH_REMOVE_PARENS_5_ARG, INTERNAL_CATCH_REMOVE_PARENS_4_ARG, INTERNAL_CATCH_REMOVE_PARENS_3_ARG, INTERNAL_CATCH_REMOVE_PARENS_2_ARG, INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
6642 #endif
6643 
6644 #endif // CATCH_PREPROCESSOR_HPP_INCLUDED
6645 
6646 // GCC 5 and older do not properly handle disabling unused-variable warning
6647 // with a _Pragma. This means that we have to leak the suppression to the
6648 // user code as well :-(
6649 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
6650 #pragma GCC diagnostic ignored "-Wunused-variable"
6651 #endif
6652 
6653 #if defined(CATCH_CONFIG_DISABLE)
6654 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(TestName, TestFunc, Name, Tags, Signature, ...) \
6655  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6656 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, ...) \
6657  namespace { \
6658  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6659  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
6660  } \
6661  } \
6662  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6663 
6664 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6665 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
6666  INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, typename TestType, __VA_ARGS__)
6667 #else
6668 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
6669  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, typename TestType, __VA_ARGS__))
6670 #endif
6671 
6672 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6673 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
6674  INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, Signature, __VA_ARGS__)
6675 #else
6676 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
6677  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, Signature, __VA_ARGS__))
6678 #endif
6679 
6680 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6681 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...) \
6682  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, typename T, __VA_ARGS__)
6683 #else
6684 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...) \
6685  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, typename T, __VA_ARGS__))
6686 #endif
6687 
6688 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6689 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(ClassName, Name, Tags, Signature, ...) \
6690  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, Signature, __VA_ARGS__)
6691 #else
6692 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(ClassName, Name, Tags, Signature, ...) \
6693  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, Signature, __VA_ARGS__))
6694 #endif
6695 #endif
6696 
6698 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ...) \
6699  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6700  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6701  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6702  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6703  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6704  CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6705  INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
6706  namespace { \
6707  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6708  INTERNAL_CATCH_TYPE_GEN \
6709  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6710  INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6711  template<typename... Types> \
6712  struct TestName { \
6713  TestName() { \
6714  size_t index = 0; \
6715  constexpr char const *tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */ \
6716  using expander = size_t[]; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */ \
6717  (void)expander{(reg_test(Types{}, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), Tags}), index++)...}; /* NOLINT */ \
6718  } \
6719  }; \
6720  static const int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
6721  TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>(); \
6722  return 0; \
6723  }(); \
6724  } \
6725  } \
6726  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6727  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6728 
6729 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6730 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
6731  INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, typename TestType, __VA_ARGS__)
6732 #else
6733 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
6734  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, typename TestType, __VA_ARGS__))
6735 #endif
6736 
6737 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6738 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6739  INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, Signature, __VA_ARGS__)
6740 #else
6741 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6742  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, Signature, __VA_ARGS__))
6743 #endif
6744 
6745 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
6746  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6747  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6748  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6749  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6750  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6751  CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6752  template<typename TestType> \
6753  static void TestFuncName(); \
6754  namespace { \
6755  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6756  INTERNAL_CATCH_TYPE_GEN \
6757  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6758  template<typename... Types> \
6759  struct TestName { \
6760  void reg_tests() { \
6761  size_t index = 0; \
6762  using expander = size_t[]; \
6763  constexpr char const *tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))}; \
6764  constexpr char const *types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))}; \
6765  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]); \
6766  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestFuncName<Types>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{Name " - " + std::string(tmpl_types[index / num_types]) + '<' + types_list[index % num_types] + '>', Tags}), index++)...}; /* NOLINT */ \
6767  } \
6768  }; \
6769  static const int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
6770  using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(Catch::Detail::priority_tag<1>{})), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
6771  TestInit t; \
6772  t.reg_tests(); \
6773  return 0; \
6774  }(); \
6775  } \
6776  } \
6777  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6778  template<typename TestType> \
6779  static void TestFuncName()
6780 
6781 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6782 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...) \
6783  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, typename T, __VA_ARGS__)
6784 #else
6785 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...) \
6786  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, typename T, __VA_ARGS__))
6787 #endif
6788 
6789 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6790 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6791  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, Signature, __VA_ARGS__)
6792 #else
6793 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6794  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, Signature, __VA_ARGS__))
6795 #endif
6796 
6797 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList) \
6798  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6799  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6800  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6801  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6802  CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6803  template<typename TestType> \
6804  static void TestFunc(); \
6805  namespace { \
6806  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6807  INTERNAL_CATCH_TYPE_GEN \
6808  template<typename... Types> \
6809  struct TestName { \
6810  void reg_tests() { \
6811  size_t index = 0; \
6812  using expander = size_t[]; \
6813  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Types>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags}), index++)...}; /* NOLINT */ \
6814  } \
6815  }; \
6816  static const int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
6817  using TestInit = typename convert<TestName, TmplList>::type; \
6818  TestInit t; \
6819  t.reg_tests(); \
6820  return 0; \
6821  }(); \
6822  } \
6823  } \
6824  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6825  template<typename TestType> \
6826  static void TestFunc()
6827 
6828 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
6829  INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), Name, Tags, TmplList)
6830 
6831 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, ...) \
6832  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6833  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6834  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6835  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6836  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6837  namespace { \
6838  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6839  INTERNAL_CATCH_TYPE_GEN \
6840  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6841  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
6842  INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6843  template<typename... Types> \
6844  struct TestNameClass { \
6845  TestNameClass() { \
6846  size_t index = 0; \
6847  constexpr char const *tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; \
6848  using expander = size_t[]; \
6849  (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), Tags}), index++)...}; /* NOLINT */ \
6850  } \
6851  }; \
6852  static const int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
6853  TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>(); \
6854  return 0; \
6855  }(); \
6856  } \
6857  } \
6858  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6859  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6860 
6861 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6862 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
6863  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, typename T, __VA_ARGS__)
6864 #else
6865 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
6866  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, typename T, __VA_ARGS__))
6867 #endif
6868 
6869 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6870 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
6871  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, Signature, __VA_ARGS__)
6872 #else
6873 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
6874  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, Signature, __VA_ARGS__))
6875 #endif
6876 
6877 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList) \
6878  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6879  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6880  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6881  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6882  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6883  template<typename TestType> \
6884  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) { \
6885  void test(); \
6886  }; \
6887  namespace { \
6888  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) { \
6889  INTERNAL_CATCH_TYPE_GEN \
6890  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6891  template<typename... Types> \
6892  struct TestNameClass { \
6893  void reg_tests() { \
6894  std::size_t index = 0; \
6895  using expander = std::size_t[]; \
6896  constexpr char const *tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))}; \
6897  constexpr char const *types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))}; \
6898  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]); \
6899  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index / num_types]) + '<' + types_list[index % num_types] + '>', Tags}), index++)...}; /* NOLINT */ \
6900  } \
6901  }; \
6902  static const int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
6903  using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(Catch::Detail::priority_tag<1>{})), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
6904  TestInit t; \
6905  t.reg_tests(); \
6906  return 0; \
6907  }(); \
6908  } \
6909  } \
6910  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6911  template<typename TestType> \
6912  void TestName<TestType>::test()
6913 
6914 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6915 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
6916  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, typename T, __VA_ARGS__)
6917 #else
6918 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
6919  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, typename T, __VA_ARGS__))
6920 #endif
6921 
6922 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6923 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
6924  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, Signature, __VA_ARGS__)
6925 #else
6926 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
6927  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, Signature, __VA_ARGS__))
6928 #endif
6929 
6930 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
6931  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6932  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6933  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6934  CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6935  CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6936  template<typename TestType> \
6937  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) { \
6938  void test(); \
6939  }; \
6940  namespace { \
6941  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6942  INTERNAL_CATCH_TYPE_GEN \
6943  template<typename... Types> \
6944  struct TestNameClass { \
6945  void reg_tests() { \
6946  size_t index = 0; \
6947  using expander = size_t[]; \
6948  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags}), index++)...}; /* NOLINT */ \
6949  } \
6950  }; \
6951  static const int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
6952  using TestInit = typename convert<TestNameClass, TmplList>::type; \
6953  TestInit t; \
6954  t.reg_tests(); \
6955  return 0; \
6956  }(); \
6957  } \
6958  } \
6959  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6960  template<typename TestType> \
6961  void TestName<TestType>::test()
6962 
6963 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
6964  INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_TEMPLATE_TEST_), ClassName, Name, Tags, TmplList)
6965 
6966 #endif // CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6967 
6968 #if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
6969 
6970 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6971 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
6972 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
6973 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
6974 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
6975 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
6976 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
6977 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__)
6978 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
6979 #define CATCH_TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
6980 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__)
6981 #else
6982 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__))
6983 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__))
6984 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__))
6985 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
6986 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__))
6987 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__))
6988 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__))
6989 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
6990 #define CATCH_TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__))
6991 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__))
6992 #endif
6993 
6994 #elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
6995 
6996 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6997 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
6998 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
6999 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
7000 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__)
7001 #else
7002 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__))
7003 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__))
7004 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__))
7005 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__))
7006 #endif
7007 
7008 // When disabled, these can be shared between proper preprocessor and MSVC preprocessor
7009 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
7010 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
7011 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7012 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7013 #define CATCH_TEMPLATE_LIST_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
7014 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7015 
7016 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
7017 
7018 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
7019 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
7020 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
7021 #define TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7022 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
7023 #define TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
7024 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
7025 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__)
7026 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
7027 #define TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
7028 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__)
7029 #else
7030 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__))
7031 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__))
7032 #define TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__))
7033 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
7034 #define TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__))
7035 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__))
7036 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__))
7037 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
7038 #define TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__))
7039 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__))
7040 #endif
7041 
7042 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
7043 
7044 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
7045 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
7046 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
7047 #define TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
7048 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__)
7049 #else
7050 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__))
7051 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__))
7052 #define TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__))
7053 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__))
7054 #endif
7055 
7056 // When disabled, these can be shared between proper preprocessor and MSVC preprocessor
7057 #define TEMPLATE_PRODUCT_TEST_CASE(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
7058 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
7059 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7060 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7061 #define TEMPLATE_LIST_TEST_CASE(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
7062 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
7063 
7064 #endif // end of user facing macro declarations
7065 
7066 #endif // CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
7067 
7068 #ifndef CATCH_TEST_CASE_INFO_HPP_INCLUDED
7069 #define CATCH_TEST_CASE_INFO_HPP_INCLUDED
7070 
7071 #include <cstdint>
7072 #include <string>
7073 #include <vector>
7074 
7075 #ifdef __clang__
7076 #pragma clang diagnostic push
7077 #pragma clang diagnostic ignored "-Wpadded"
7078 #endif
7079 
7080 namespace Catch {
7081 
7089  struct Tag {
7090  constexpr Tag(StringRef original_)
7091  : original(original_) {}
7092  StringRef original;
7093 
7094  friend bool operator<(Tag const &lhs, Tag const &rhs);
7095  friend bool operator==(Tag const &lhs, Tag const &rhs);
7096  };
7097 
7098  class ITestInvoker;
7099  struct NameAndTags;
7100 
7101  enum class TestCaseProperties : uint8_t {
7102  None = 0,
7103  IsHidden = 1 << 1,
7104  ShouldFail = 1 << 2,
7105  MayFail = 1 << 3,
7106  Throws = 1 << 4,
7107  NonPortable = 1 << 5,
7108  Benchmark = 1 << 6
7109  };
7110 
7121  TestCaseInfo(StringRef _className,
7122  NameAndTags const &_nameAndTags,
7123  SourceLineInfo const &_lineInfo);
7124 
7125  bool isHidden() const;
7126  bool throws() const;
7127  bool okToFail() const;
7128  bool expectedToFail() const;
7129 
7130  // Adds the tag(s) with test's filename (for the -# flag)
7131  void addFilenameTag();
7132 
7134  friend bool operator<(TestCaseInfo const &lhs,
7135  TestCaseInfo const &rhs);
7136 
7137  std::string tagsAsString() const;
7138 
7139  std::string name;
7140  StringRef className;
7141 
7142  private:
7143  std::string backingTags;
7144  // Internally we copy tags to the backing storage and then add
7145  // refs to this storage to the tags vector.
7146  void internalAppendTag(StringRef tagString);
7147 
7148  public:
7149  std::vector<Tag> tags;
7150  SourceLineInfo lineInfo;
7151  TestCaseProperties properties = TestCaseProperties::None;
7152  };
7153 
7161  TestCaseInfo *m_info;
7162  ITestInvoker *m_invoker;
7163 
7164  public:
7165  constexpr TestCaseHandle(TestCaseInfo *info, ITestInvoker *invoker)
7166  : m_info(info), m_invoker(invoker) {}
7167 
7168  void prepareTestCase() const {
7169  m_invoker->prepareTestCase();
7170  }
7171 
7172  void tearDownTestCase() const {
7173  m_invoker->tearDownTestCase();
7174  }
7175 
7176  void invoke() const {
7177  m_invoker->invoke();
7178  }
7179 
7180  constexpr TestCaseInfo const &getTestCaseInfo() const {
7181  return *m_info;
7182  }
7183  };
7184 
7186  makeTestCaseInfo(StringRef className,
7187  NameAndTags const &nameAndTags,
7188  SourceLineInfo const &lineInfo);
7189 } // namespace Catch
7190 
7191 #ifdef __clang__
7192 #pragma clang diagnostic pop
7193 #endif
7194 
7195 #endif // CATCH_TEST_CASE_INFO_HPP_INCLUDED
7196 
7197 #ifndef CATCH_TEST_RUN_INFO_HPP_INCLUDED
7198 #define CATCH_TEST_RUN_INFO_HPP_INCLUDED
7199 
7200 namespace Catch {
7201 
7202  struct TestRunInfo {
7203  constexpr TestRunInfo(StringRef _name)
7204  : name(_name) {}
7205  StringRef name;
7206  };
7207 
7208 } // end namespace Catch
7209 
7210 #endif // CATCH_TEST_RUN_INFO_HPP_INCLUDED
7211 
7212 #ifndef CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7213 #define CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7214 
7215 #ifndef CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
7216 #define CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
7217 
7218 #include <string>
7219 #include <vector>
7220 
7221 namespace Catch {
7222  using exceptionTranslateFunction = std::string (*)();
7223 
7224  class IExceptionTranslator;
7225  using ExceptionTranslators = std::vector<Detail::unique_ptr<IExceptionTranslator const>>;
7226 
7228  public:
7229  virtual ~IExceptionTranslator(); // = default
7230  virtual std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const = 0;
7231  };
7232 
7234  public:
7235  virtual ~IExceptionTranslatorRegistry(); // = default
7236  virtual std::string translateActiveException() const = 0;
7237  };
7238 
7239 } // namespace Catch
7240 
7241 #endif // CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
7242 
7243 #include <exception>
7244 
7245 namespace Catch {
7246  namespace Detail {
7247  void registerTranslatorImpl(
7249  }
7250 
7252  template<typename T>
7253  class ExceptionTranslator : public IExceptionTranslator {
7254  public:
7255  constexpr ExceptionTranslator(std::string (*translateFunction)(T const &))
7256  : m_translateFunction(translateFunction) {}
7257 
7258  std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override {
7259 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
7260  try {
7261  if (it == itEnd)
7262  std::rethrow_exception(std::current_exception());
7263  else
7264  return (*it)->translate(it + 1, itEnd);
7265  } catch (T const &ex) {
7266  return m_translateFunction(ex);
7267  }
7268 #else
7269  return "You should never get here!";
7270 #endif
7271  }
7272 
7273  protected:
7274  std::string (*m_translateFunction)(T const &);
7275  };
7276 
7277  public:
7278  template<typename T>
7279  ExceptionTranslatorRegistrar(std::string (*translateFunction)(T const &)) {
7280  Detail::registerTranslatorImpl(
7281  Detail::make_unique<ExceptionTranslator<T>>(
7282  translateFunction));
7283  }
7284  };
7285 
7286 } // namespace Catch
7287 
7289 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2(translatorName, signature) \
7290  static std::string translatorName(signature); \
7291  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
7292  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
7293  namespace { \
7294  const Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionRegistrar)(&translatorName); \
7295  } \
7296  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
7297  static std::string translatorName(signature)
7298 
7299 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature) INTERNAL_CATCH_TRANSLATE_EXCEPTION2(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature)
7300 
7301 #if defined(CATCH_CONFIG_DISABLE)
7302 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(translatorName, signature) \
7303  static std::string translatorName(signature)
7304 #endif
7305 
7306 // This macro is always prefixed
7307 #if !defined(CATCH_CONFIG_DISABLE)
7308 #define CATCH_TRANSLATE_EXCEPTION(signature) INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature)
7309 #else
7310 #define CATCH_TRANSLATE_EXCEPTION(signature) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature)
7311 #endif
7312 
7313 #endif // CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7314 
7315 #ifndef CATCH_VERSION_HPP_INCLUDED
7316 #define CATCH_VERSION_HPP_INCLUDED
7317 
7318 #include <iosfwd>
7319 
7320 namespace Catch {
7321 
7322  // Versioning information
7323  struct Version {
7324  Version(Version const &) = delete;
7325  Version &operator=(Version const &) = delete;
7326  Version(unsigned int _majorVersion,
7327  unsigned int _minorVersion,
7328  unsigned int _patchNumber,
7329  char const *const _branchName,
7330  unsigned int _buildNumber);
7331 
7332  unsigned int const majorVersion;
7333  unsigned int const minorVersion;
7334  unsigned int const patchNumber;
7335 
7336  // buildNumber is only used if branchName is not null
7337  char const *const branchName;
7338  unsigned int const buildNumber;
7339 
7340  friend std::ostream &operator<<(std::ostream &os, Version const &version);
7341  };
7342 
7343  Version const &libraryVersion();
7344 } // namespace Catch
7345 
7346 #endif // CATCH_VERSION_HPP_INCLUDED
7347 
7348 #ifndef CATCH_VERSION_MACROS_HPP_INCLUDED
7349 #define CATCH_VERSION_MACROS_HPP_INCLUDED
7350 
7351 #define CATCH_VERSION_MAJOR 3
7352 #define CATCH_VERSION_MINOR 14
7353 #define CATCH_VERSION_PATCH 0
7354 
7355 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED
7356 
7370 #ifndef CATCH_GENERATORS_ALL_HPP_INCLUDED
7371 #define CATCH_GENERATORS_ALL_HPP_INCLUDED
7372 
7373 #ifndef CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7374 #define CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7375 
7376 #include <exception>
7377 
7378 namespace Catch {
7379 
7380  // Exception type to be thrown when a Generator runs into an error,
7381  // e.g. it cannot initialize the first return value based on
7382  // runtime information
7383  class GeneratorException : public std::exception {
7384  const char *const m_msg = "";
7385 
7386  public:
7387  GeneratorException(const char *msg)
7388  : m_msg(msg) {}
7389 
7390  const char *what() const noexcept final;
7391  };
7392 
7393 } // end namespace Catch
7394 
7395 #endif // CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7396 
7397 #ifndef CATCH_GENERATORS_HPP_INCLUDED
7398 #define CATCH_GENERATORS_HPP_INCLUDED
7399 
7400 #ifndef CATCH_GENERATORS_THROW_HPP_INCLUDED
7401 #define CATCH_GENERATORS_THROW_HPP_INCLUDED
7402 
7403 namespace Catch {
7404  namespace Generators {
7405  namespace Detail {
7406 
7408  [[noreturn]]
7409  void throw_generator_exception(char const *msg);
7410 
7411  } // namespace Detail
7412  } // namespace Generators
7413 } // namespace Catch
7414 
7415 #endif // CATCH_GENERATORS_THROW_HPP_INCLUDED
7416 
7417 #ifndef CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7418 #define CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7419 
7420 #include <string>
7421 
7422 namespace Catch {
7423 
7424  namespace Generators {
7426  // Caches result from `toStringImpl`, assume that when it is an
7427  // empty string, the cache is invalidated.
7428  mutable std::string m_stringReprCache;
7429 
7430  // Counts based on `next` returning true
7431  std::size_t m_currentElementIndex = 0;
7432 
7439  virtual bool next() = 0;
7440 
7442  virtual std::string stringifyImpl() const = 0;
7443 
7451  virtual void skipToNthElementImpl(std::size_t n);
7452 
7453  public:
7454  GeneratorUntypedBase() = default;
7455  // Generation of copy ops is deprecated (and Clang will complain)
7456  // if there is a user destructor defined
7457  GeneratorUntypedBase(GeneratorUntypedBase const &) = default;
7458  GeneratorUntypedBase &operator=(GeneratorUntypedBase const &) = default;
7459 
7460  virtual ~GeneratorUntypedBase(); // = default;
7461 
7472  bool countedNext();
7473 
7474  std::size_t currentElementIndex() const { return m_currentElementIndex; }
7475 
7481  void skipToNthElement(std::size_t n);
7482 
7496  StringRef currentElementAsString() const;
7497 
7505  virtual bool isFinite() const;
7506  };
7508 
7509  } // namespace Generators
7510 
7512  public:
7513  virtual ~IGeneratorTracker(); // = default;
7514  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const & = 0;
7515  };
7516 
7517 } // namespace Catch
7518 
7519 #endif // CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7520 
7521 #include <tuple>
7522 #include <vector>
7523 
7524 namespace Catch {
7525 
7526  namespace Generators {
7527 
7528  template<typename T>
7530  std::string stringifyImpl() const override {
7531  return ::Catch::Detail::stringify(get());
7532  }
7533 
7534  public:
7535  // Returns the current element of the generator
7536  //
7537  // \Precondition The generator is either freshly constructed,
7538  // or the last call to `next()` returned true
7539  virtual T const &get() const = 0;
7540  using type = T;
7541  };
7542 
7543  template<typename T>
7545 
7546  template<typename T>
7547  class GeneratorWrapper final {
7548  GeneratorPtr<T> m_generator;
7549 
7550  public:
7553  : m_generator(generator) {}
7555  : m_generator(CATCH_MOVE(generator)) {}
7556 
7557  T const &get() const {
7558  return m_generator->get();
7559  }
7560  bool next() {
7561  return m_generator->countedNext();
7562  }
7563 
7564  bool isFinite() const { return m_generator->isFinite(); }
7565  void skipToNthElement(size_t n) { m_generator->skipToNthElement(n); }
7566  };
7567 
7568  template<typename T>
7569  class SingleValueGenerator final : public IGenerator<T> {
7570  T m_value;
7571 
7572  public:
7573  SingleValueGenerator(T const &value)
7574  : m_value(value) {}
7575  SingleValueGenerator(T &&value)
7576  : m_value(CATCH_MOVE(value)) {}
7577 
7578  T const &get() const override {
7579  return m_value;
7580  }
7581  bool next() override {
7582  return false;
7583  }
7584 
7585  bool isFinite() const override { return true; }
7586  };
7587 
7588  template<typename T>
7589  class FixedValuesGenerator final : public IGenerator<T> {
7590  static_assert(!std::is_same<T, bool>::value,
7591  "FixedValuesGenerator does not support bools because of std::vector<bool>"
7592  "specialization, use SingleValue Generator instead.");
7593  std::vector<T> m_values;
7594  size_t m_idx = 0;
7595 
7596  void skipToNthElementImpl(std::size_t n) override {
7597  if (n >= m_values.size()) {
7598  Detail::throw_generator_exception(
7599  "Coud not jump to Nth element: not enough elements");
7600  }
7601  m_idx = n;
7602  }
7603 
7604  public:
7605  FixedValuesGenerator(std::initializer_list<T> values)
7606  : m_values(values) {}
7607 
7608  T const &get() const override {
7609  return m_values[m_idx];
7610  }
7611  bool next() override {
7612  ++m_idx;
7613  return m_idx < m_values.size();
7614  }
7615 
7616  bool isFinite() const override { return true; }
7617  };
7618 
7619  template<typename T, typename DecayedT = std::decay_t<T>>
7620  GeneratorWrapper<DecayedT> value(T &&value) {
7622  Catch::Detail::make_unique<SingleValueGenerator<DecayedT>>(
7623  CATCH_FORWARD(value)));
7624  }
7625  template<typename T>
7626  GeneratorWrapper<T> values(std::initializer_list<T> values) {
7627  return GeneratorWrapper<T>(Catch::Detail::make_unique<FixedValuesGenerator<T>>(values));
7628  }
7629 
7630  template<typename T>
7631  class Generators : public IGenerator<T> {
7632  std::vector<GeneratorWrapper<T>> m_generators;
7633  size_t m_current = 0;
7634 
7635  void add_generator(GeneratorWrapper<T> &&generator) {
7636  m_generators.emplace_back(CATCH_MOVE(generator));
7637  }
7638  void add_generator(T const &val) {
7639  m_generators.emplace_back(value(val));
7640  }
7641  void add_generator(T &&val) {
7642  m_generators.emplace_back(value(CATCH_MOVE(val)));
7643  }
7644  template<typename U>
7645  std::enable_if_t<!std::is_same<std::decay_t<U>, T>::value>
7646  add_generator(U &&val) {
7647  add_generator(T(CATCH_FORWARD(val)));
7648  }
7649 
7650  template<typename U>
7651  void add_generators(U &&valueOrGenerator) {
7652  add_generator(CATCH_FORWARD(valueOrGenerator));
7653  }
7654 
7655  template<typename U, typename... Gs>
7656  void add_generators(U &&valueOrGenerator, Gs &&...moreGenerators) {
7657  add_generator(CATCH_FORWARD(valueOrGenerator));
7658  add_generators(CATCH_FORWARD(moreGenerators)...);
7659  }
7660 
7661  public:
7662  template<typename... Gs>
7663  Generators(Gs &&...moreGenerators) {
7664  m_generators.reserve(sizeof...(Gs));
7665  add_generators(CATCH_FORWARD(moreGenerators)...);
7666  }
7667 
7668  T const &get() const override {
7669  return m_generators[m_current].get();
7670  }
7671 
7672  bool next() override {
7673  if (m_current >= m_generators.size()) {
7674  return false;
7675  }
7676  const bool current_status = m_generators[m_current].next();
7677  if (!current_status) {
7678  ++m_current;
7679  }
7680  return m_current < m_generators.size();
7681  }
7682 
7683  bool isFinite() const override {
7684  for (auto const &gen : m_generators) {
7685  if (!gen.isFinite()) {
7686  return false;
7687  }
7688  }
7689  return true;
7690  }
7691  };
7692 
7693  template<typename... Ts>
7695  table(std::initializer_list<std::tuple<std::decay_t<Ts>...>> tuples) {
7696  return values<std::tuple<Ts...>>(tuples);
7697  }
7698 
7699  // Tag type to signal that a generator sequence should convert arguments to a specific type
7700  template<typename T>
7701  struct as {};
7702 
7703  template<typename T, typename... Gs>
7704  auto makeGenerators(GeneratorWrapper<T> &&generator, Gs &&...moreGenerators) -> Generators<T> {
7705  return Generators<T>(CATCH_MOVE(generator), CATCH_FORWARD(moreGenerators)...);
7706  }
7707  template<typename T>
7708  auto makeGenerators(GeneratorWrapper<T> &&generator) -> Generators<T> {
7709  return Generators<T>(CATCH_MOVE(generator));
7710  }
7711  template<typename T, typename... Gs>
7712  auto makeGenerators(T &&val, Gs &&...moreGenerators) -> Generators<std::decay_t<T>> {
7713  return makeGenerators(value(CATCH_FORWARD(val)), CATCH_FORWARD(moreGenerators)...);
7714  }
7715  template<typename T, typename U, typename... Gs>
7716  auto makeGenerators(as<T>, U &&val, Gs &&...moreGenerators) -> Generators<T> {
7717  return makeGenerators(value(T(CATCH_FORWARD(val))), CATCH_FORWARD(moreGenerators)...);
7718  }
7719 
7720  IGeneratorTracker *acquireGeneratorTracker(StringRef generatorName,
7721  SourceLineInfo const &lineInfo);
7722  IGeneratorTracker *createGeneratorTracker(StringRef generatorName,
7723  SourceLineInfo lineInfo,
7724  GeneratorBasePtr &&generator);
7725 
7726  template<typename L>
7727  auto generate(StringRef generatorName, SourceLineInfo const &lineInfo, L const &generatorExpression) -> typename decltype(generatorExpression())::type {
7728  using UnderlyingType = typename decltype(generatorExpression())::type;
7729 
7730  IGeneratorTracker *tracker = acquireGeneratorTracker(generatorName, lineInfo);
7731  // Creation of tracker is delayed after generator creation, so
7732  // that constructing generator can fail without breaking everything.
7733  if (!tracker) {
7734  tracker = createGeneratorTracker(
7735  generatorName,
7736  lineInfo,
7737  Catch::Detail::make_unique<Generators<UnderlyingType>>(
7738  generatorExpression()));
7739  }
7740 
7741  auto const &generator = static_cast<IGenerator<UnderlyingType> const &>(*tracker->getGenerator());
7742  return generator.get();
7743  }
7744 
7745  } // namespace Generators
7746 } // namespace Catch
7747 
7748 #define CATCH_INTERNAL_GENERATOR_STRINGIZE_IMPL(...) #__VA_ARGS__##_catch_sr
7749 #define CATCH_INTERNAL_GENERATOR_STRINGIZE(...) CATCH_INTERNAL_GENERATOR_STRINGIZE_IMPL(__VA_ARGS__)
7750 
7751 #define GENERATE(...) \
7752  Catch::Generators::generate(CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7753  CATCH_INTERNAL_LINEINFO, \
7754  [] { using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); }) // NOLINT(google-build-using-namespace)
7755 #define GENERATE_COPY(...) \
7756  Catch::Generators::generate(CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7757  CATCH_INTERNAL_LINEINFO, \
7758  [=] { using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); }) // NOLINT(google-build-using-namespace)
7759 #define GENERATE_REF(...) \
7760  Catch::Generators::generate(CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7761  CATCH_INTERNAL_LINEINFO, \
7762  [&] { using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); }) // NOLINT(google-build-using-namespace)
7763 
7764 #endif // CATCH_GENERATORS_HPP_INCLUDED
7765 
7766 #ifndef CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7767 #define CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7768 
7769 #include <cassert>
7770 
7771 namespace Catch {
7772  namespace Generators {
7773 
7774  template<typename T>
7775  class TakeGenerator final : public IGenerator<T> {
7776  GeneratorWrapper<T> m_generator;
7777  size_t m_returned = 0;
7778  size_t m_target;
7779 
7780  void skipToNthElementImpl(std::size_t n) override {
7781  if (n >= m_target) {
7782  Detail::throw_generator_exception(
7783  "Coud not jump to Nth element: not enough elements");
7784  }
7785 
7786  m_generator.skipToNthElement(n);
7787  m_returned = n;
7788  }
7789 
7790  public:
7791  TakeGenerator(size_t target, GeneratorWrapper<T> &&generator)
7792  : m_generator(CATCH_MOVE(generator)), m_target(target) {
7793  assert(target != 0 && "Empty generators are not allowed");
7794  }
7795  T const &get() const override {
7796  return m_generator.get();
7797  }
7798  bool next() override {
7799  ++m_returned;
7800  if (m_returned >= m_target) {
7801  return false;
7802  }
7803 
7804  const auto success = m_generator.next();
7805  // If the underlying generator does not contain enough values
7806  // then we cut short as well
7807  if (!success) {
7808  m_returned = m_target;
7809  }
7810  return success;
7811  }
7812 
7813  bool isFinite() const override { return true; }
7814  };
7815 
7816  template<typename T>
7817  GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T> &&generator) {
7818  return GeneratorWrapper<T>(Catch::Detail::make_unique<TakeGenerator<T>>(target, CATCH_MOVE(generator)));
7819  }
7820 
7821  template<typename T, typename Predicate>
7822  class FilterGenerator final : public IGenerator<T> {
7823  GeneratorWrapper<T> m_generator;
7824  Predicate m_predicate;
7825  static_assert(!std::is_reference<Predicate>::value, "This would most likely result in a dangling reference");
7826 
7827  public:
7828  template<typename P>
7829  FilterGenerator(P &&pred, GeneratorWrapper<T> &&generator)
7830  : m_generator(CATCH_MOVE(generator)), m_predicate(CATCH_FORWARD(pred)) {
7831  if (!m_predicate(m_generator.get())) {
7832  // It might happen that there are no values that pass the
7833  // filter. In that case we throw an exception.
7834  auto has_initial_value = next();
7835  if (!has_initial_value) {
7836  Detail::throw_generator_exception("No valid value found in filtered generator");
7837  }
7838  }
7839  }
7840 
7841  T const &get() const override {
7842  return m_generator.get();
7843  }
7844 
7845  bool next() override {
7846  bool success = m_generator.next();
7847  if (!success) {
7848  return false;
7849  }
7850  while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
7851  return success;
7852  }
7853 
7854  bool isFinite() const override { return m_generator.isFinite(); }
7855  };
7856 
7857  template<typename T, typename Predicate>
7858  GeneratorWrapper<T> filter(Predicate &&pred, GeneratorWrapper<T> &&generator) {
7859  return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, typename std::remove_reference<Predicate>::type>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
7860  }
7861 
7862  template<typename T>
7863  class RepeatGenerator final : public IGenerator<T> {
7864  static_assert(!std::is_same<T, bool>::value,
7865  "RepeatGenerator currently does not support bools"
7866  "because of std::vector<bool> specialization");
7867  GeneratorWrapper<T> m_generator;
7868  mutable std::vector<T> m_returned;
7869  size_t m_target_repeats;
7870  size_t m_current_repeat = 0;
7871  size_t m_repeat_index = 0;
7872 
7873  public:
7874  RepeatGenerator(size_t repeats, GeneratorWrapper<T> &&generator)
7875  : m_generator(CATCH_MOVE(generator)), m_target_repeats(repeats) {
7876  assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
7877  if (!m_generator.isFinite()) {
7878  Detail::throw_generator_exception("Cannot repeat infinite generator");
7879  }
7880  }
7881 
7882  T const &get() const override {
7883  if (m_current_repeat == 0) {
7884  m_returned.push_back(m_generator.get());
7885  return m_returned.back();
7886  }
7887  return m_returned[m_repeat_index];
7888  }
7889 
7890  bool next() override {
7891  // There are 2 basic cases:
7892  // 1) We are still reading the generator
7893  // 2) We are reading our own cache
7894 
7895  // In the first case, we need to poke the underlying generator.
7896  // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
7897  if (m_current_repeat == 0) {
7898  const auto success = m_generator.next();
7899  if (!success) {
7900  ++m_current_repeat;
7901  }
7902  return m_current_repeat < m_target_repeats;
7903  }
7904 
7905  // In the second case, we need to move indices forward and check that we haven't run up against the end
7906  ++m_repeat_index;
7907  if (m_repeat_index == m_returned.size()) {
7908  m_repeat_index = 0;
7909  ++m_current_repeat;
7910  }
7911  return m_current_repeat < m_target_repeats;
7912  }
7913 
7914  bool isFinite() const override { return m_generator.isFinite(); }
7915  };
7916 
7917  template<typename T>
7918  GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T> &&generator) {
7919  return GeneratorWrapper<T>(Catch::Detail::make_unique<RepeatGenerator<T>>(repeats, CATCH_MOVE(generator)));
7920  }
7921 
7922  template<typename T, typename U, typename Func>
7923  class MapGenerator final : public IGenerator<T> {
7924  // TBD: provide static assert for mapping function, for friendly error message
7925  GeneratorWrapper<U> m_generator;
7926  Func m_function;
7927  // To avoid returning dangling reference, we have to save the values
7928  mutable Optional<T> m_cache;
7929 
7930  void skipToNthElementImpl(std::size_t n) override {
7931  m_generator.skipToNthElement(n);
7932  m_cache.reset();
7933  }
7934 
7935  public:
7936  template<typename F2 = Func>
7937  MapGenerator(F2 &&function, GeneratorWrapper<U> &&generator)
7938  : m_generator(CATCH_MOVE(generator)), m_function(CATCH_FORWARD(function)) {}
7939 
7940  T const &get() const override {
7941  if (!m_cache) { m_cache = m_function(m_generator.get()); }
7942  return *m_cache;
7943  }
7944  bool next() override {
7945  m_cache.reset();
7946  return m_generator.next();
7947  }
7948 
7949  bool isFinite() const override { return m_generator.isFinite(); }
7950  };
7951 
7952  template<typename Func, typename U, typename T = FunctionReturnType<Func, U>>
7953  GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator) {
7954  return GeneratorWrapper<T>(
7955  Catch::Detail::make_unique<MapGenerator<T, U, Func>>(CATCH_FORWARD(function), CATCH_MOVE(generator)));
7956  }
7957 
7958  template<typename T, typename U, typename Func>
7959  GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator) {
7960  return GeneratorWrapper<T>(
7961  Catch::Detail::make_unique<MapGenerator<T, U, Func>>(CATCH_FORWARD(function), CATCH_MOVE(generator)));
7962  }
7963 
7964  template<typename T>
7965  class ChunkGenerator final : public IGenerator<std::vector<T>> {
7966  std::vector<T> m_chunk;
7967  size_t m_chunk_size;
7968  GeneratorWrapper<T> m_generator;
7969 
7970  public:
7971  ChunkGenerator(size_t size, GeneratorWrapper<T> generator)
7972  : m_chunk_size(size), m_generator(CATCH_MOVE(generator)) {
7973  m_chunk.reserve(m_chunk_size);
7974  if (m_chunk_size != 0) {
7975  m_chunk.push_back(m_generator.get());
7976  for (size_t i = 1; i < m_chunk_size; ++i) {
7977  if (!m_generator.next()) {
7978  Detail::throw_generator_exception("Not enough values to initialize the first chunk");
7979  }
7980  m_chunk.push_back(m_generator.get());
7981  }
7982  }
7983  }
7984  std::vector<T> const &get() const override {
7985  return m_chunk;
7986  }
7987  bool next() override {
7988  m_chunk.clear();
7989  for (size_t idx = 0; idx < m_chunk_size; ++idx) {
7990  if (!m_generator.next()) {
7991  return false;
7992  }
7993  m_chunk.push_back(m_generator.get());
7994  }
7995  return true;
7996  }
7997 
7998  bool isFinite() const override { return m_generator.isFinite(); }
7999  };
8000 
8001  template<typename T>
8002  GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T> &&generator) {
8004  Catch::Detail::make_unique<ChunkGenerator<T>>(size, CATCH_MOVE(generator)));
8005  }
8006 
8007  template<typename T>
8008  class ConcatGenerator final : public IGenerator<T> {
8009  std::vector<GeneratorWrapper<T>> m_generators;
8010  size_t m_current_generator = 0;
8011 
8012  void InsertGenerators(GeneratorWrapper<T> &&gen) {
8013  m_generators.push_back(CATCH_MOVE(gen));
8014  }
8015 
8016  template<typename... Generators>
8017  void InsertGenerators(GeneratorWrapper<T> &&gen, Generators &&...gens) {
8018  m_generators.push_back(CATCH_MOVE(gen));
8019  InsertGenerators(CATCH_MOVE(gens)...);
8020  }
8021 
8022  public:
8023  template<typename... Generators>
8024  ConcatGenerator(Generators &&...generators) {
8025  InsertGenerators(CATCH_MOVE(generators)...);
8026  }
8027 
8028  T const &get() const override {
8029  return m_generators[m_current_generator].get();
8030  }
8031  bool next() override {
8032  const bool success = m_generators[m_current_generator].next();
8033  if (success) { return true; }
8034 
8035  // If current generator is used up, we have to move to the next one
8036  ++m_current_generator;
8037  return m_current_generator < m_generators.size();
8038  }
8039 
8040  bool isFinite() const override {
8041  for (auto const &gen : m_generators) {
8042  if (!gen.isFinite()) { return false; }
8043  }
8044  return true;
8045  }
8046  };
8047 
8048  template<typename T, typename... Generators>
8049  GeneratorWrapper<T> cat(GeneratorWrapper<T> &&generator,
8050  Generators &&...generators) {
8051  return GeneratorWrapper<T>(
8052  Catch::Detail::make_unique<ConcatGenerator<T>>(
8053  CATCH_MOVE(generator), CATCH_MOVE(generators)...));
8054  }
8055 
8056  } // namespace Generators
8057 } // namespace Catch
8058 
8059 #endif // CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
8060 
8061 #ifndef CATCH_GENERATORS_RANDOM_HPP_INCLUDED
8062 #define CATCH_GENERATORS_RANDOM_HPP_INCLUDED
8063 
8064 #ifndef CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
8065 #define CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
8066 
8067 #include <cstdint>
8068 
8069 namespace Catch {
8070 
8071  // This is a simple implementation of C++11 Uniform Random Number
8072  // Generator. It does not provide all operators, because Catch2
8073  // does not use it, but it should behave as expected inside stdlib's
8074  // distributions.
8075  // The implementation is based on the PCG family (http://pcg-random.org)
8076  class SimplePcg32 {
8077  using state_type = std::uint64_t;
8078 
8079  public:
8080  using result_type = std::uint32_t;
8081  static constexpr result_type(min)() {
8082  return 0;
8083  }
8084  static constexpr result_type(max)() {
8085  return static_cast<result_type>(-1);
8086  }
8087 
8088  // Provide some default initial state for the default constructor
8089  SimplePcg32()
8090  : SimplePcg32(0xed743cc4U) {}
8091 
8092  explicit SimplePcg32(result_type seed_);
8093 
8094  void seed(result_type seed_);
8095  void discard(uint64_t skip);
8096 
8097  result_type operator()();
8098 
8099  private:
8100  friend bool operator==(SimplePcg32 const &lhs, SimplePcg32 const &rhs);
8101  friend bool operator!=(SimplePcg32 const &lhs, SimplePcg32 const &rhs);
8102 
8103  // In theory we also need operator<< and operator>>
8104  // In practice we do not use them, so we will skip them for now
8105 
8106  std::uint64_t m_state;
8107  // This part of the state determines which "stream" of the numbers
8108  // is chosen -- we take it as a constant for Catch2, so we only
8109  // need to deal with seeding the main state.
8110  // Picked by reading 8 bytes from `/dev/random` :-)
8111  static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
8112  };
8113 
8114 } // end namespace Catch
8115 
8116 #endif // CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
8117 
8118 #ifndef CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
8119 #define CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
8120 
8121 #ifndef CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED
8122 #define CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED
8123 
8124 #include <climits>
8125 #include <cstddef>
8126 #include <cstdint>
8127 #include <type_traits>
8128 
8129 // Note: We use the usual enable-disable-autodetect dance here even though
8130 // we do not support these in CMake configuration options (yet?).
8131 // It is highly unlikely that we will need to make these actually
8132 // user-configurable, but this will make it simpler if weend up needing
8133 // it, and it provides an escape hatch to the users who need it.
8134 #if defined(__SIZEOF_INT128__)
8135 #define CATCH_CONFIG_INTERNAL_UINT128
8136 // Unlike GCC, MSVC does not polyfill umul as mulh + mul pair on ARM machines.
8137 // Currently we do not bother doing this ourselves, but we could if it became
8138 // important for perf.
8139 #elif defined(_MSC_VER) && defined(_M_X64)
8140 #define CATCH_CONFIG_INTERNAL_MSVC_UMUL128
8141 #endif
8142 
8143 #if defined(CATCH_CONFIG_INTERNAL_UINT128) && !defined(CATCH_CONFIG_NO_UINT128) && !defined(CATCH_CONFIG_UINT128)
8144 #define CATCH_CONFIG_UINT128
8145 #endif
8146 
8147 #if defined(CATCH_CONFIG_INTERNAL_MSVC_UMUL128) && !defined(CATCH_CONFIG_NO_MSVC_UMUL128) && !defined(CATCH_CONFIG_MSVC_UMUL128)
8148 #define CATCH_CONFIG_MSVC_UMUL128
8149 #include <intrin.h>
8150 #endif
8151 
8152 namespace Catch {
8153  namespace Detail {
8154 
8155  template<std::size_t>
8156  struct SizedUnsignedType;
8157 #define SizedUnsignedTypeHelper(TYPE) \
8158  template<> \
8159  struct SizedUnsignedType<sizeof(TYPE)> { \
8160  using type = TYPE; \
8161  }
8162 
8163  SizedUnsignedTypeHelper(std::uint8_t);
8164  SizedUnsignedTypeHelper(std::uint16_t);
8165  SizedUnsignedTypeHelper(std::uint32_t);
8166  SizedUnsignedTypeHelper(std::uint64_t);
8167 #undef SizedUnsignedTypeHelper
8168 
8169  template<std::size_t sz>
8170  using SizedUnsignedType_t = typename SizedUnsignedType<sz>::type;
8171 
8172  template<typename T>
8173  using DoubleWidthUnsignedType_t = SizedUnsignedType_t<2 * sizeof(T)>;
8174 
8175  template<typename T>
8176  struct ExtendedMultResult {
8177  T upper;
8178  T lower;
8179  constexpr bool operator==(ExtendedMultResult const &rhs) const {
8180  return upper == rhs.upper && lower == rhs.lower;
8181  }
8182  };
8183 
8190  constexpr ExtendedMultResult<std::uint64_t>
8191  extendedMultPortable(std::uint64_t lhs, std::uint64_t rhs) {
8192 #define CarryBits(x) (x >> 32)
8193 #define Digits(x) (x & 0xFF'FF'FF'FF)
8194  std::uint64_t lhs_low = Digits(lhs);
8195  std::uint64_t rhs_low = Digits(rhs);
8196  std::uint64_t low_low = (lhs_low * rhs_low);
8197  std::uint64_t high_high = CarryBits(lhs) * CarryBits(rhs);
8198 
8199  // We add in carry bits from low-low already
8200  std::uint64_t high_low = (CarryBits(lhs) * rhs_low) + CarryBits(low_low);
8201  // Note that we can add only low bits from high_low, to avoid
8202  // overflow with large inputs
8203  std::uint64_t low_high = (lhs_low * CarryBits(rhs)) + Digits(high_low);
8204 
8205  return {high_high + CarryBits(high_low) + CarryBits(low_high),
8206  (low_high << 32) | Digits(low_low)};
8207 #undef CarryBits
8208 #undef Digits
8209  }
8210 
8212  inline ExtendedMultResult<std::uint64_t>
8213  extendedMult(std::uint64_t lhs, std::uint64_t rhs) {
8214 #if defined(CATCH_CONFIG_UINT128)
8215  auto result = __uint128_t(lhs) * __uint128_t(rhs);
8216  return {static_cast<std::uint64_t>(result >> 64),
8217  static_cast<std::uint64_t>(result)};
8218 #elif defined(CATCH_CONFIG_MSVC_UMUL128)
8219  std::uint64_t high;
8220  std::uint64_t low = _umul128(lhs, rhs, &high);
8221  return {high, low};
8222 #else
8223  return extendedMultPortable(lhs, rhs);
8224 #endif
8225  }
8226 
8227  template<typename UInt>
8228  constexpr ExtendedMultResult<UInt> extendedMult(UInt lhs, UInt rhs) {
8229  static_assert(std::is_unsigned<UInt>::value,
8230  "extendedMult can only handle unsigned integers");
8231  static_assert(sizeof(UInt) < sizeof(std::uint64_t),
8232  "Generic extendedMult can only handle types smaller "
8233  "than uint64_t");
8234  using WideType = DoubleWidthUnsignedType_t<UInt>;
8235 
8236  auto result = WideType(lhs) * WideType(rhs);
8237  return {
8238  static_cast<UInt>(result >> (CHAR_BIT * sizeof(UInt))),
8239  static_cast<UInt>(result & UInt(-1))};
8240  }
8241 
8242  template<typename TargetType,
8243  typename Generator>
8244  std::enable_if_t<sizeof(typename Generator::result_type) >= sizeof(TargetType),
8245  TargetType>
8246  fillBitsFrom(Generator &gen) {
8247  using gresult_type = typename Generator::result_type;
8248  static_assert(std::is_unsigned<TargetType>::value, "Only unsigned integers are supported");
8249  static_assert(Generator::min() == 0 && Generator::max() == static_cast<gresult_type>(-1),
8250  "Generator must be able to output all numbers in its result type (effectively it must be a random bit generator)");
8251 
8252  // We want to return the top bits from a generator, as they are
8253  // usually considered higher quality.
8254  constexpr auto generated_bits = sizeof(gresult_type) * CHAR_BIT;
8255  constexpr auto return_bits = sizeof(TargetType) * CHAR_BIT;
8256 
8257  return static_cast<TargetType>(gen() >> (generated_bits - return_bits));
8258  }
8259 
8260  template<typename TargetType,
8261  typename Generator>
8262  std::enable_if_t<sizeof(typename Generator::result_type) < sizeof(TargetType),
8263  TargetType>
8264  fillBitsFrom(Generator &gen) {
8265  using gresult_type = typename Generator::result_type;
8266  static_assert(std::is_unsigned<TargetType>::value,
8267  "Only unsigned integers are supported");
8268  static_assert(Generator::min() == 0 && Generator::max() == static_cast<gresult_type>(-1),
8269  "Generator must be able to output all numbers in its result type (effectively it must be a random bit generator)");
8270 
8271  constexpr auto generated_bits = sizeof(gresult_type) * CHAR_BIT;
8272  constexpr auto return_bits = sizeof(TargetType) * CHAR_BIT;
8273  std::size_t filled_bits = 0;
8274  TargetType ret = 0;
8275  do {
8276  ret <<= generated_bits;
8277  ret |= gen();
8278  filled_bits += generated_bits;
8279  } while (filled_bits < return_bits);
8280 
8281  return ret;
8282  }
8283 
8284  /*
8285  * Transposes numbers into unsigned type while keeping their ordering
8286  *
8287  * This means that signed types are changed so that the ordering is
8288  * [INT_MIN, ..., -1, 0, ..., INT_MAX], rather than order we would
8289  * get by simple casting ([0, ..., INT_MAX, INT_MIN, ..., -1])
8290  */
8291  template<typename OriginalType, typename UnsignedType>
8292  constexpr std::enable_if_t<std::is_signed<OriginalType>::value, UnsignedType>
8293  transposeToNaturalOrder(UnsignedType in) {
8294  static_assert(
8295  sizeof(OriginalType) == sizeof(UnsignedType),
8296  "reordering requires the same sized types on both sides");
8297  static_assert(std::is_unsigned<UnsignedType>::value,
8298  "Input type must be unsigned");
8299  // Assuming 2s complement (standardized in current C++), the
8300  // positive and negative numbers are already internally ordered,
8301  // and their difference is in the top bit. Swapping it orders
8302  // them the desired way.
8303  constexpr auto highest_bit = UnsignedType(1) << (sizeof(UnsignedType) * CHAR_BIT - 1);
8304  return static_cast<UnsignedType>(in ^ highest_bit);
8305  }
8306 
8307  template<typename OriginalType,
8308  typename UnsignedType>
8309  constexpr std::enable_if_t<std::is_unsigned<OriginalType>::value, UnsignedType>
8310  transposeToNaturalOrder(UnsignedType in) {
8311  static_assert(
8312  sizeof(OriginalType) == sizeof(UnsignedType),
8313  "reordering requires the same sized types on both sides");
8314  static_assert(std::is_unsigned<UnsignedType>::value, "Input type must be unsigned");
8315  // No reordering is needed for unsigned -> unsigned
8316  return in;
8317  }
8318  } // namespace Detail
8319 } // namespace Catch
8320 
8321 #endif // CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED
8322 
8323 namespace Catch {
8324 
8336  template<typename IntegerType>
8337  class uniform_integer_distribution {
8338  static_assert(std::is_integral<IntegerType>::value, "...");
8339 
8340  using UnsignedIntegerType = Detail::SizedUnsignedType_t<sizeof(IntegerType)>;
8341 
8342  // Only the left bound is stored, and we store it converted to its
8343  // unsigned image. This avoids having to do the conversions inside
8344  // the operator(), at the cost of having to do the conversion in
8345  // the a() getter. The right bound is only needed in the b() getter,
8346  // so we recompute it there from other stored data.
8347  UnsignedIntegerType m_a;
8348 
8349  // How many different values are there in [a, b]. a == b => 1, can be 0 for distribution over all values in the type.
8350  UnsignedIntegerType m_ab_distance;
8351 
8352  // We hoisted this out of the main generation function. Technically,
8353  // this means that using this distribution will be slower than Lemire's
8354  // algorithm if this distribution instance will be used only few times,
8355  // but it will be faster if it is used many times. Since Catch2 uses
8356  // distributions only to implement random generators, we assume that each
8357  // distribution will be reused many times and this is an optimization.
8358  UnsignedIntegerType m_rejection_threshold = 0;
8359 
8360  static constexpr UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) {
8361  // This overflows and returns 0 if a == 0 and b == TYPE_MAX.
8362  // We handle that later when generating the number.
8363  return transposeTo(b) - transposeTo(a) + 1;
8364  }
8365 
8366  static constexpr UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) {
8367  // distance == 0 means that we will return all possible values from
8368  // the type's range, and that we shouldn't reject anything.
8369  if (ab_distance == 0) { return 0; }
8370  return (~ab_distance + 1) % ab_distance;
8371  }
8372 
8373  static constexpr UnsignedIntegerType transposeTo(IntegerType in) {
8374  return Detail::transposeToNaturalOrder<IntegerType>(
8375  static_cast<UnsignedIntegerType>(in));
8376  }
8377  static constexpr IntegerType transposeBack(UnsignedIntegerType in) {
8378  return static_cast<IntegerType>(
8379  Detail::transposeToNaturalOrder<IntegerType>(in));
8380  }
8381 
8382  public:
8383  using result_type = IntegerType;
8384 
8385  constexpr uniform_integer_distribution(IntegerType a, IntegerType b)
8386  : m_a(transposeTo(a)), m_ab_distance(computeDistance(a, b)), m_rejection_threshold(computeRejectionThreshold(m_ab_distance)) {
8387  assert(a <= b);
8388  }
8389 
8390  template<typename Generator>
8391  constexpr result_type operator()(Generator &g) {
8392  // All possible values of result_type are valid.
8393  if (m_ab_distance == 0) {
8394  return transposeBack(Detail::fillBitsFrom<UnsignedIntegerType>(g));
8395  }
8396 
8397  auto random_number = Detail::fillBitsFrom<UnsignedIntegerType>(g);
8398  auto emul = Detail::extendedMult(random_number, m_ab_distance);
8399  // Unlike Lemire's algorithm we skip the ab_distance check, since
8400  // we precomputed the rejection threshold, which is always tighter.
8401  while (emul.lower < m_rejection_threshold) {
8402  random_number = Detail::fillBitsFrom<UnsignedIntegerType>(g);
8403  emul = Detail::extendedMult(random_number, m_ab_distance);
8404  }
8405 
8406  return transposeBack(m_a + emul.upper);
8407  }
8408 
8409  constexpr result_type a() const { return transposeBack(m_a); }
8410  constexpr result_type b() const { return transposeBack(m_ab_distance + m_a - 1); }
8411  };
8412 
8413 } // end namespace Catch
8414 
8415 #endif // CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
8416 
8417 #ifndef CATCH_UNIFORM_FLOATING_POINT_DISTRIBUTION_HPP_INCLUDED
8418 #define CATCH_UNIFORM_FLOATING_POINT_DISTRIBUTION_HPP_INCLUDED
8419 
8420 #ifndef CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
8421 #define CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
8422 
8423 #ifndef CATCH_POLYFILLS_HPP_INCLUDED
8424 #define CATCH_POLYFILLS_HPP_INCLUDED
8425 
8426 namespace Catch {
8427 
8428  bool isnan(float f);
8429  bool isnan(double d);
8430 
8431  float nextafter(float x, float y);
8432  double nextafter(double x, double y);
8433 
8434 } // namespace Catch
8435 
8436 #endif // CATCH_POLYFILLS_HPP_INCLUDED
8437 
8438 #include <cassert>
8439 #include <cmath>
8440 #include <cstdint>
8441 #include <limits>
8442 #include <type_traits>
8443 
8444 namespace Catch {
8445 
8446  namespace Detail {
8452  template<typename FloatType>
8453  FloatType gamma(FloatType a, FloatType b) {
8454  static_assert(std::is_floating_point<FloatType>::value,
8455  "gamma returns the largest ULP magnitude within "
8456  "floating point range [a, b]. This only makes sense "
8457  "for floating point types");
8458  assert(a <= b);
8459 
8460  const auto gamma_up = Catch::nextafter(a, std::numeric_limits<FloatType>::infinity()) - a;
8461  const auto gamma_down = b - Catch::nextafter(b, -std::numeric_limits<FloatType>::infinity());
8462 
8463  return gamma_up < gamma_down ? gamma_down : gamma_up;
8464  }
8465 
8466  template<typename FloatingPoint>
8467  struct DistanceTypePicker;
8468  template<>
8469  struct DistanceTypePicker<float> {
8470  using type = std::uint32_t;
8471  };
8472  template<>
8473  struct DistanceTypePicker<double> {
8474  using type = std::uint64_t;
8475  };
8476 
8477  template<typename T>
8478  using DistanceType = typename DistanceTypePicker<T>::type;
8479 
8480 #if defined(__GNUC__) || defined(__clang__)
8481 #pragma GCC diagnostic push
8482 #pragma GCC diagnostic ignored "-Wfloat-equal"
8483 #endif
8484 
8493  template<typename FloatType>
8494  DistanceType<FloatType>
8495  count_equidistant_floats(FloatType a, FloatType b, FloatType distance) {
8496  assert(a <= b);
8497  // We get distance as gamma for our uniform float distribution,
8498  // so this will round perfectly.
8499  const auto ag = a / distance;
8500  const auto bg = b / distance;
8501 
8502  const auto s = bg - ag;
8503  const auto err = (std::fabs(a) <= std::fabs(b))
8504  ? -ag - (s - bg)
8505  : bg - (s + ag);
8506  const auto ceil_s = static_cast<DistanceType<FloatType>>(std::ceil(s));
8507 
8508  return (ceil_s != s) ? ceil_s : ceil_s + (err > 0);
8509  }
8510 #if defined(__GNUC__) || defined(__clang__)
8511 #pragma GCC diagnostic pop
8512 #endif
8513 
8514  } // namespace Detail
8515 
8516 } // end namespace Catch
8517 
8518 #endif // CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
8519 
8520 #include <cmath>
8521 #include <type_traits>
8522 
8523 namespace Catch {
8524 
8525  namespace Detail {
8526 #if defined(__GNUC__) || defined(__clang__)
8527 #pragma GCC diagnostic push
8528 #pragma GCC diagnostic ignored "-Wfloat-equal"
8529 #endif
8530  // The issue with overflow only happens with maximal ULP and HUGE
8531  // distance, e.g. when generating numbers in [-inf, inf] for given
8532  // type. So we only check for the largest possible ULP in the
8533  // type, and return something that does not overflow to inf in 1 mult.
8534  constexpr std::uint64_t calculate_max_steps_in_one_go(double gamma) {
8535  if (gamma == 1.99584030953472e+292) { return 9007199254740991; }
8536  return static_cast<std::uint64_t>(-1);
8537  }
8538  constexpr std::uint32_t calculate_max_steps_in_one_go(float gamma) {
8539  if (gamma == 2.028241e+31f) { return 16777215; }
8540  return static_cast<std::uint32_t>(-1);
8541  }
8542 #if defined(__GNUC__) || defined(__clang__)
8543 #pragma GCC diagnostic pop
8544 #endif
8545  } // namespace Detail
8546 
8573  template<typename FloatType>
8574  class uniform_floating_point_distribution {
8575  static_assert(std::is_floating_point<FloatType>::value, "...");
8576  static_assert(!std::is_same<FloatType, long double>::value,
8577  "We do not support long double due to inconsistent behaviour between platforms");
8578 
8579  using WidthType = Detail::DistanceType<FloatType>;
8580 
8581  FloatType m_a, m_b;
8582  FloatType m_ulp_magnitude;
8583  WidthType m_floats_in_range;
8584  uniform_integer_distribution<WidthType> m_int_dist;
8585 
8586  // In specific cases, we can overflow into `inf` when computing the
8587  // `steps * g` offset. To avoid this, we don't offset by more than this
8588  // in one multiply + addition.
8589  WidthType m_max_steps_in_one_go;
8590  // We don't want to do the magnitude check every call to `operator()`
8591  bool m_a_has_leq_magnitude;
8592 
8593  public:
8594  using result_type = FloatType;
8595 
8596  uniform_floating_point_distribution(FloatType a, FloatType b)
8597  : m_a(a), m_b(b), m_ulp_magnitude(Detail::gamma(m_a, m_b)), m_floats_in_range(Detail::count_equidistant_floats(m_a, m_b, m_ulp_magnitude)), m_int_dist(0, m_floats_in_range), m_max_steps_in_one_go(Detail::calculate_max_steps_in_one_go(m_ulp_magnitude)), m_a_has_leq_magnitude(std::fabs(m_a) <= std::fabs(m_b)) {
8598  assert(a <= b);
8599  }
8600 
8601  template<typename Generator>
8602  result_type operator()(Generator &g) {
8603  WidthType steps = m_int_dist(g);
8604  if (m_a_has_leq_magnitude) {
8605  if (steps == m_floats_in_range) { return m_a; }
8606  auto b = m_b;
8607  while (steps > m_max_steps_in_one_go) {
8608  b -= m_max_steps_in_one_go * m_ulp_magnitude;
8609  steps -= m_max_steps_in_one_go;
8610  }
8611  return b - steps * m_ulp_magnitude;
8612  } else {
8613  if (steps == m_floats_in_range) { return m_b; }
8614  auto a = m_a;
8615  while (steps > m_max_steps_in_one_go) {
8616  a += m_max_steps_in_one_go * m_ulp_magnitude;
8617  steps -= m_max_steps_in_one_go;
8618  }
8619  return a + steps * m_ulp_magnitude;
8620  }
8621  }
8622 
8623  result_type a() const { return m_a; }
8624  result_type b() const { return m_b; }
8625  };
8626 
8627 } // end namespace Catch
8628 
8629 #endif // CATCH_UNIFORM_FLOATING_POINT_DISTRIBUTION_HPP_INCLUDED
8630 
8631 namespace Catch {
8632  namespace Generators {
8633  namespace Detail {
8634  // Returns a suitable seed for a random floating generator based off
8635  // the primary internal rng. It does so by taking current value from
8636  // the rng and returning it as the seed.
8637  std::uint32_t getSeed();
8638  } // namespace Detail
8639 
8640  template<typename Float>
8641  class RandomFloatingGenerator final : public IGenerator<Float> {
8642  Catch::SimplePcg32 m_rng;
8643  Catch::uniform_floating_point_distribution<Float> m_dist;
8644  Float m_current_number;
8645 
8646  public:
8647  RandomFloatingGenerator(Float a, Float b, std::uint32_t seed)
8648  : m_rng(seed), m_dist(a, b) {
8649  static_cast<void>(next());
8650  }
8651 
8652  Float const &get() const override {
8653  return m_current_number;
8654  }
8655  bool next() override {
8656  m_current_number = m_dist(m_rng);
8657  return true;
8658  }
8659  bool isFinite() const override { return false; }
8660  };
8661 
8662  template<>
8663  class RandomFloatingGenerator<long double> final : public IGenerator<long double> {
8664  // We still rely on <random> for this specialization, but we don't
8665  // want to drag it into the header.
8666  struct PImpl;
8668  long double m_current_number;
8669 
8670  public:
8671  RandomFloatingGenerator(long double a, long double b, std::uint32_t seed);
8672 
8673  long double const &get() const override { return m_current_number; }
8674  bool next() override;
8675 
8676  ~RandomFloatingGenerator() override; // = default
8677  bool isFinite() const override;
8678  };
8679 
8680  template<typename Integer>
8681  class RandomIntegerGenerator final : public IGenerator<Integer> {
8682  Catch::SimplePcg32 m_rng;
8683  Catch::uniform_integer_distribution<Integer> m_dist;
8684  Integer m_current_number;
8685 
8686  public:
8687  RandomIntegerGenerator(Integer a, Integer b, std::uint32_t seed)
8688  : m_rng(seed), m_dist(a, b) {
8689  static_cast<void>(next());
8690  }
8691 
8692  Integer const &get() const override {
8693  return m_current_number;
8694  }
8695  bool next() override {
8696  m_current_number = m_dist(m_rng);
8697  return true;
8698  }
8699  bool isFinite() const override { return false; }
8700  };
8701 
8702  template<typename T>
8703  std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
8704  random(T a, T b) {
8705  return GeneratorWrapper<T>(
8706  Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed()));
8707  }
8708 
8709  template<typename T>
8710  std::enable_if_t<std::is_floating_point<T>::value,
8711  GeneratorWrapper<T>>
8712  random(T a, T b) {
8713  return GeneratorWrapper<T>(
8714  Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed()));
8715  }
8716 
8717  } // namespace Generators
8718 } // namespace Catch
8719 
8720 #endif // CATCH_GENERATORS_RANDOM_HPP_INCLUDED
8721 
8722 #ifndef CATCH_GENERATORS_RANGE_HPP_INCLUDED
8723 #define CATCH_GENERATORS_RANGE_HPP_INCLUDED
8724 
8725 #include <iterator>
8726 #include <type_traits>
8727 
8728 namespace Catch {
8729  namespace Generators {
8730 
8731  template<typename T>
8732  class RangeGenerator final : public IGenerator<T> {
8733  T m_current;
8734  T m_end;
8735  T m_step;
8736  bool m_positive;
8737 
8738  public:
8739  RangeGenerator(T const &start, T const &end, T const &step)
8740  : m_current(start), m_end(end), m_step(step), m_positive(m_step > T(0)) {
8741  assert(m_current != m_end && "Range start and end cannot be equal");
8742  assert(m_step != T(0) && "Step size cannot be zero");
8743  assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
8744  }
8745 
8746  RangeGenerator(T const &start, T const &end)
8747  : RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) {}
8748 
8749  T const &get() const override {
8750  return m_current;
8751  }
8752 
8753  bool next() override {
8754  m_current += m_step;
8755  return (m_positive) ? (m_current < m_end) : (m_current > m_end);
8756  }
8757 
8758  bool isFinite() const override { return true; }
8759  };
8760 
8761  template<typename T>
8762  GeneratorWrapper<T> range(T const &start, T const &end, T const &step) {
8763  static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
8764  return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end, step));
8765  }
8766 
8767  template<typename T>
8768  GeneratorWrapper<T> range(T const &start, T const &end) {
8769  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
8770  return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end));
8771  }
8772 
8773  template<typename T>
8774  class IteratorGenerator final : public IGenerator<T> {
8775  static_assert(!std::is_same<T, bool>::value,
8776  "IteratorGenerator currently does not support bools"
8777  "because of std::vector<bool> specialization");
8778 
8779  std::vector<T> m_elems;
8780  size_t m_current = 0;
8781 
8782  public:
8783  template<typename InputIterator, typename InputSentinel>
8784  IteratorGenerator(InputIterator first, InputSentinel last)
8785  : m_elems(first, last) {
8786  if (m_elems.empty()) {
8787  Detail::throw_generator_exception("IteratorGenerator received no valid values");
8788  }
8789  }
8790 
8791  T const &get() const override {
8792  return m_elems[m_current];
8793  }
8794 
8795  bool next() override {
8796  ++m_current;
8797  return m_current != m_elems.size();
8798  }
8799 
8800  bool isFinite() const override { return true; }
8801  };
8802 
8803  template<typename InputIterator,
8804  typename InputSentinel,
8805  typename ResultType = std::remove_const_t<typename std::iterator_traits<InputIterator>::value_type>>
8806  GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
8807  return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(from, to));
8808  }
8809 
8810  template<typename Container>
8811  auto from_range(Container const &cnt) {
8812  using std::begin;
8813  using std::end;
8814  return from_range(begin(cnt), end(cnt));
8815  }
8816 
8817  } // namespace Generators
8818 } // namespace Catch
8819 
8820 #endif // CATCH_GENERATORS_RANGE_HPP_INCLUDED
8821 
8822 #endif // CATCH_GENERATORS_ALL_HPP_INCLUDED
8823 
8837 #ifndef CATCH_INTERFACES_ALL_HPP_INCLUDED
8838 #define CATCH_INTERFACES_ALL_HPP_INCLUDED
8839 
8840 #ifndef CATCH_INTERFACES_REPORTER_HPP_INCLUDED
8841 #define CATCH_INTERFACES_REPORTER_HPP_INCLUDED
8842 
8843 #include <map>
8844 #include <string>
8845 #include <vector>
8846 
8847 namespace Catch {
8848 
8849  struct ReporterDescription;
8850  struct ListenerDescription;
8851  struct TagInfo;
8852  struct TestCaseInfo;
8853  class TestCaseHandle;
8854  class IConfig;
8855  class IStream;
8856  enum class ColourMode : std::uint8_t;
8857 
8858  struct ReporterConfig {
8859  ReporterConfig(IConfig const *_fullConfig,
8861  ColourMode colourMode,
8862  std::map<std::string, std::string> customOptions);
8863 
8864  ReporterConfig(ReporterConfig &&) = default;
8865  ReporterConfig &operator=(ReporterConfig &&) = default;
8866  ~ReporterConfig(); // = default
8867 
8868  Detail::unique_ptr<IStream> takeStream() &&;
8869  IConfig const *fullConfig() const;
8870  ColourMode colourMode() const;
8871  std::map<std::string, std::string> const &customOptions() const;
8872 
8873  private:
8874  Detail::unique_ptr<IStream> m_stream;
8875  IConfig const *m_fullConfig;
8876  ColourMode m_colourMode;
8877  std::map<std::string, std::string> m_customOptions;
8878  };
8879 
8880  struct AssertionStats {
8881  AssertionStats(AssertionResult const &_assertionResult,
8882  std::vector<MessageInfo> const &_infoMessages,
8883  Totals const &_totals);
8884 
8885  AssertionStats(AssertionStats const &) = default;
8886  AssertionStats(AssertionStats &&) = default;
8887  AssertionStats &operator=(AssertionStats const &) = delete;
8888  AssertionStats &operator=(AssertionStats &&) = delete;
8889 
8890  AssertionResult assertionResult;
8891  std::vector<MessageInfo> infoMessages;
8892  Totals totals;
8893  };
8894 
8895  struct SectionStats {
8896  SectionStats(SectionInfo &&_sectionInfo,
8897  Counts const &_assertions,
8898  double _durationInSeconds,
8899  bool _missingAssertions);
8900 
8901  SectionInfo sectionInfo;
8902  Counts assertions;
8903  double durationInSeconds;
8904  bool missingAssertions;
8905  };
8906 
8907  struct TestCaseStats {
8908  TestCaseStats(TestCaseInfo const &_testInfo,
8909  Totals const &_totals,
8910  std::string &&_stdOut,
8911  std::string &&_stdErr,
8912  bool _aborting);
8913 
8914  TestCaseInfo const *testInfo;
8915  Totals totals;
8916  std::string stdOut;
8917  std::string stdErr;
8918  bool aborting;
8919  };
8920 
8921  struct TestRunStats {
8922  TestRunStats(TestRunInfo const &_runInfo,
8923  Totals const &_totals,
8924  bool _aborting);
8925 
8926  TestRunInfo runInfo;
8927  Totals totals;
8928  bool aborting;
8929  };
8930 
8934  struct ReporterPreferences {
8937  bool shouldRedirectStdOut = false;
8940  bool shouldReportAllAssertions = false;
8942  // Defaults to true for backwards compatibility, but none of our current
8943  // reporters actually want this, and it enables a fast path in assertion
8944  // handling.
8945  bool shouldReportAllAssertionStarts = true;
8946  };
8947 
8960  class IEventListener {
8961  protected:
8963  ReporterPreferences m_preferences;
8965  IConfig const *m_config;
8966 
8967  public:
8968  IEventListener(IConfig const *config)
8969  : m_config(config) {}
8970 
8971  virtual ~IEventListener(); // = default;
8972 
8973  // Implementing class must also provide the following static methods:
8974  // static std::string getDescription();
8975 
8976  ReporterPreferences const &getPreferences() const {
8977  return m_preferences;
8978  }
8979 
8981  virtual void noMatchingTestCases(StringRef unmatchedSpec) = 0;
8983  virtual void reportInvalidTestSpec(StringRef invalidArgument) = 0;
8984 
8990  virtual void testRunStarting(TestRunInfo const &testRunInfo) = 0;
8991 
8993  virtual void testCaseStarting(TestCaseInfo const &testInfo) = 0;
8995  virtual void testCasePartialStarting(TestCaseInfo const &testInfo, uint64_t partNumber) = 0;
8997  virtual void sectionStarting(SectionInfo const &sectionInfo) = 0;
8998 
9000  virtual void benchmarkPreparing(StringRef benchmarkName) = 0;
9002  virtual void benchmarkStarting(BenchmarkInfo const &benchmarkInfo) = 0;
9004  virtual void benchmarkEnded(BenchmarkStats<> const &benchmarkStats) = 0;
9006  virtual void benchmarkFailed(StringRef benchmarkName) = 0;
9007 
9009  virtual void assertionStarting(AssertionInfo const &assertionInfo) = 0;
9010 
9012  virtual void assertionEnded(AssertionStats const &assertionStats) = 0;
9013 
9015  virtual void sectionEnded(SectionStats const &sectionStats) = 0;
9017  virtual void testCasePartialEnded(TestCaseStats const &testCaseStats, uint64_t partNumber) = 0;
9019  virtual void testCaseEnded(TestCaseStats const &testCaseStats) = 0;
9025  virtual void testRunEnded(TestRunStats const &testRunStats) = 0;
9026 
9033  virtual void skipTest(TestCaseInfo const &testInfo) = 0;
9034 
9036  virtual void fatalErrorEncountered(StringRef error) = 0;
9037 
9039  virtual void listReporters(std::vector<ReporterDescription> const &descriptions) = 0;
9041  virtual void listListeners(std::vector<ListenerDescription> const &descriptions) = 0;
9043  virtual void listTests(std::vector<TestCaseHandle> const &tests) = 0;
9045  virtual void listTags(std::vector<TagInfo> const &tags) = 0;
9046  };
9047  using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
9048 
9049 } // end namespace Catch
9050 
9051 #endif // CATCH_INTERFACES_REPORTER_HPP_INCLUDED
9052 
9053 #ifndef CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
9054 #define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
9055 
9056 #include <string>
9057 
9058 namespace Catch {
9059 
9060  struct ReporterConfig;
9061  class IConfig;
9062  class IEventListener;
9063  using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
9064 
9065  class IReporterFactory {
9066  public:
9067  virtual ~IReporterFactory(); // = default
9068 
9069  virtual IEventListenerPtr
9070  create(ReporterConfig &&config) const
9071  = 0;
9072  virtual std::string getDescription() const = 0;
9073  };
9075 
9076  class EventListenerFactory {
9077  public:
9078  virtual ~EventListenerFactory(); // = default
9079  virtual IEventListenerPtr create(IConfig const *config) const = 0;
9081  virtual StringRef getName() const = 0;
9083  virtual std::string getDescription() const = 0;
9084  };
9085 } // namespace Catch
9086 
9087 #endif // CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
9088 
9089 #ifndef CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9090 #define CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9091 
9092 #include <string>
9093 
9094 namespace Catch {
9095 
9096  struct TagAlias;
9097 
9098  class ITagAliasRegistry {
9099  public:
9100  virtual ~ITagAliasRegistry(); // = default
9101  // Nullptr if not present
9102  virtual TagAlias const *find(std::string const &alias) const = 0;
9103  virtual std::string expandAliases(std::string const &unexpandedTestSpec) const = 0;
9104 
9105  static ITagAliasRegistry const &get();
9106  };
9107 
9108 } // end namespace Catch
9109 
9110 #endif // CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9111 
9112 #ifndef CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
9113 #define CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
9114 
9115 #include <vector>
9116 
9117 namespace Catch {
9118 
9119  struct TestCaseInfo;
9120  class TestCaseHandle;
9121  class IConfig;
9122 
9123  class ITestCaseRegistry {
9124  public:
9125  virtual ~ITestCaseRegistry(); // = default
9126  // TODO: this exists only for adding filenames to test cases -- let's expose this in a saner way later
9127  virtual std::vector<TestCaseInfo *> const &getAllInfos() const = 0;
9128  virtual std::vector<TestCaseHandle> const &getAllTests() const = 0;
9129  virtual std::vector<TestCaseHandle> const &getAllTestsSorted(IConfig const &config) const = 0;
9130  };
9131 
9132 } // namespace Catch
9133 
9134 #endif // CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
9135 
9136 #endif // CATCH_INTERFACES_ALL_HPP_INCLUDED
9137 
9138 #ifndef CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
9139 #define CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
9140 
9141 namespace Catch {
9142  namespace Detail {
9144  struct CaseInsensitiveLess {
9145  bool operator()(StringRef lhs,
9146  StringRef rhs) const;
9147  };
9148 
9150  struct CaseInsensitiveEqualTo {
9151  bool operator()(StringRef lhs,
9152  StringRef rhs) const;
9153  };
9154 
9155  } // namespace Detail
9156 } // namespace Catch
9157 
9158 #endif // CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
9159 
9168 #ifndef CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
9169 #define CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
9170 
9171 #if defined(__ANDROID__)
9172 #define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
9173 #endif
9174 
9175 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
9176 #define CATCH_CONFIG_ANDROID_LOGWRITE
9177 #endif
9178 
9179 #endif // CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
9180 
9189 #ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9190 #define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9191 
9192 #if defined(_MSC_VER)
9193 #if _MSC_VER >= 1900 // Visual Studio 2015 or newer
9194 #define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
9195 #endif
9196 #endif
9197 
9198 #include <exception>
9199 
9200 #if defined(__cpp_lib_uncaught_exceptions) \
9201  && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
9202 
9203 #define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
9204 #endif // __cpp_lib_uncaught_exceptions
9205 
9206 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
9207  && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
9208  && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
9209 
9210 #define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
9211 #endif
9212 
9213 #endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9214 
9215 #ifndef CATCH_CONSOLE_COLOUR_HPP_INCLUDED
9216 #define CATCH_CONSOLE_COLOUR_HPP_INCLUDED
9217 
9218 #include <cstdint>
9219 #include <iosfwd>
9220 
9221 namespace Catch {
9222 
9223  enum class ColourMode : std::uint8_t;
9224  class IStream;
9225 
9226  struct Colour {
9227  enum Code {
9228  None = 0,
9229 
9230  White,
9231  Red,
9232  Green,
9233  Blue,
9234  Cyan,
9235  Yellow,
9236  Grey,
9237 
9238  Bright = 0x10,
9239 
9240  BrightRed = Bright | Red,
9241  BrightGreen = Bright | Green,
9242  LightGrey = Bright | Grey,
9243  BrightWhite = Bright | White,
9244  BrightYellow = Bright | Yellow,
9245 
9246  // By intention
9247  FileName = LightGrey,
9248  Warning = BrightYellow,
9249  ResultError = BrightRed,
9250  ResultSuccess = BrightGreen,
9251  ResultExpectedFailure = Warning,
9252 
9253  Error = BrightRed,
9254  Success = Green,
9255  Skip = LightGrey,
9256 
9257  OriginalExpression = Cyan,
9258  ReconstructedExpression = BrightYellow,
9259 
9260  SecondaryText = LightGrey,
9261  Headers = White
9262  };
9263  };
9264 
9265  class ColourImpl {
9266  protected:
9268  IStream *m_stream;
9269 
9270  public:
9271  ColourImpl(IStream *stream)
9272  : m_stream(stream) {}
9273 
9276  class ColourGuard {
9277  ColourImpl const *m_colourImpl;
9278  Colour::Code m_code;
9279  bool m_engaged = false;
9280 
9281  public:
9283  ColourGuard(Colour::Code code,
9284  ColourImpl const *colour);
9285 
9286  ColourGuard(ColourGuard const &rhs) = delete;
9287  ColourGuard &operator=(ColourGuard const &rhs) = delete;
9288 
9289  ColourGuard(ColourGuard &&rhs) noexcept;
9290  ColourGuard &operator=(ColourGuard &&rhs) noexcept;
9291 
9293  ~ColourGuard();
9294 
9300  ColourGuard &engage(std::ostream &stream) &;
9306  ColourGuard &&engage(std::ostream &stream) &&;
9307 
9308  private:
9310  friend std::ostream &operator<<(std::ostream &lhs,
9311  ColourGuard &guard) {
9312  guard.engageImpl(lhs);
9313  return lhs;
9314  }
9316  friend std::ostream &operator<<(std::ostream &lhs,
9317  ColourGuard &&guard) {
9318  guard.engageImpl(lhs);
9319  return lhs;
9320  }
9321 
9322  void engageImpl(std::ostream &stream);
9323  };
9324 
9325  virtual ~ColourImpl(); // = default
9332  ColourGuard guardColour(Colour::Code colourCode);
9333 
9334  private:
9335  virtual void use(Colour::Code colourCode) const = 0;
9336  };
9337 
9339  Detail::unique_ptr<ColourImpl> makeColourImpl(ColourMode colourSelection,
9340  IStream *stream);
9341 
9343  bool isColourImplAvailable(ColourMode colourSelection);
9344 
9345 } // end namespace Catch
9346 
9347 #endif // CATCH_CONSOLE_COLOUR_HPP_INCLUDED
9348 
9349 #ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
9350 #define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
9351 
9352 // This include must be kept so that user's configured value for CONSOLE_WIDTH
9353 // is used before we attempt to provide a default value
9354 
9355 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
9356 #define CATCH_CONFIG_CONSOLE_WIDTH 80
9357 #endif
9358 
9359 #endif // CATCH_CONSOLE_WIDTH_HPP_INCLUDED
9360 
9361 #ifndef CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
9362 #define CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
9363 
9364 #include <cstddef>
9365 #include <initializer_list>
9366 
9367 // We want a simple polyfill over `std::empty`, `std::size` and so on
9368 // for C++14 or C++ libraries with incomplete support.
9369 // We also have to handle that MSVC std lib will happily provide these
9370 // under older standards.
9371 #if defined(CATCH_CPP17_OR_GREATER) || defined(_MSC_VER)
9372 
9373 // We are already using this header either way, so there shouldn't
9374 // be much additional overhead in including it to get the feature
9375 // test macros
9376 #include <string>
9377 
9378 #if !defined(__cpp_lib_nonmember_container_access)
9379 #define CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
9380 #endif
9381 
9382 #else
9383 #define CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
9384 #endif
9385 
9386 namespace Catch {
9387  namespace Detail {
9388 
9389 #if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
9390  template<typename Container>
9391  constexpr auto empty(Container const &cont) -> decltype(cont.empty()) {
9392  return cont.empty();
9393  }
9394  template<typename T, std::size_t N>
9395  constexpr bool empty(const T (&)[N]) noexcept {
9396  // GCC < 7 does not support the const T(&)[] parameter syntax
9397  // so we have to ignore the length explicitly
9398  (void)N;
9399  return false;
9400  }
9401  template<typename T>
9402  constexpr bool empty(std::initializer_list<T> list) noexcept {
9403  return list.size() > 0;
9404  }
9405 
9406  template<typename Container>
9407  constexpr auto size(Container const &cont) -> decltype(cont.size()) {
9408  return cont.size();
9409  }
9410  template<typename T, std::size_t N>
9411  constexpr std::size_t size(const T (&)[N]) noexcept {
9412  return N;
9413  }
9414 #endif // CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
9415 
9416  } // end namespace Detail
9417 } // end namespace Catch
9418 
9419 #endif // CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
9420 
9421 #ifndef CATCH_DEBUG_CONSOLE_HPP_INCLUDED
9422 #define CATCH_DEBUG_CONSOLE_HPP_INCLUDED
9423 
9424 #include <string>
9425 
9426 namespace Catch {
9427  void writeToDebugConsole(std::string const &text);
9428 }
9429 
9430 #endif // CATCH_DEBUG_CONSOLE_HPP_INCLUDED
9431 
9432 #ifndef CATCH_DEBUGGER_HPP_INCLUDED
9433 #define CATCH_DEBUGGER_HPP_INCLUDED
9434 
9435 namespace Catch {
9436  bool isDebuggerActive();
9437 }
9438 
9439 #if !defined(CATCH_TRAP) && defined(__clang__) && defined(__has_builtin)
9440 #if __has_builtin(__builtin_debugtrap)
9441 #define CATCH_TRAP() __builtin_debugtrap()
9442 #endif
9443 #endif
9444 
9445 #if !defined(CATCH_TRAP) && defined(_MSC_VER)
9446 #define CATCH_TRAP() __debugbreak()
9447 #endif
9448 
9449 #if !defined(CATCH_TRAP) // If we couldn't use compiler-specific impl from above, we get into platform-specific options
9450 #ifdef CATCH_PLATFORM_MAC
9451 
9452 #if defined(__i386__) || defined(__x86_64__)
9453 #define CATCH_TRAP() __asm__("int $3\n" : :) /* NOLINT */
9454 #elif defined(__aarch64__)
9455 #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
9456 #elif defined(__POWERPC__)
9457 #define CATCH_TRAP() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
9458  : : : "memory", "r0", "r3", "r4") /* NOLINT */
9459 #endif
9460 
9461 #elif defined(CATCH_PLATFORM_IPHONE)
9462 
9463 // use inline assembler
9464 #if defined(__i386__) || defined(__x86_64__)
9465 #define CATCH_TRAP() __asm__("int $3")
9466 #elif defined(__aarch64__)
9467 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
9468 #elif defined(__arm__) && !defined(__thumb__)
9469 #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
9470 #elif defined(__arm__) && defined(__thumb__)
9471 #define CATCH_TRAP() __asm__(".inst 0xde01")
9472 #endif
9473 
9474 #elif defined(CATCH_PLATFORM_LINUX) || defined(CATCH_PLATFORM_QNX)
9475 // If we can use inline assembler, do it because this allows us to break
9476 // directly at the location of the failing check instead of breaking inside
9477 // raise() called from it, i.e. one stack frame below.
9478 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
9479 #define CATCH_TRAP() asm volatile("int $3") /* NOLINT */
9480 #else // Fall back to the generic way.
9481 #include <signal.h>
9482 
9483 #define CATCH_TRAP() raise(SIGTRAP)
9484 #endif
9485 #elif defined(__MINGW32__)
9486 extern "C" __declspec(dllimport) void __stdcall DebugBreak();
9487 #define CATCH_TRAP() DebugBreak()
9488 #endif
9489 #endif // ^^ CATCH_TRAP is not defined yet, so we define it
9490 
9491 #if !defined(CATCH_BREAK_INTO_DEBUGGER)
9492 #if defined(CATCH_TRAP)
9493 #define CATCH_BREAK_INTO_DEBUGGER() [] { if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
9494 #else
9495 #define CATCH_BREAK_INTO_DEBUGGER() [] {}()
9496 #endif
9497 #endif
9498 
9499 #endif // CATCH_DEBUGGER_HPP_INCLUDED
9500 
9501 #ifndef CATCH_ENFORCE_HPP_INCLUDED
9502 #define CATCH_ENFORCE_HPP_INCLUDED
9503 
9504 #include <exception> // for `std::exception` in no-exception configuration
9505 
9506 namespace Catch {
9507 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
9508  template<typename Ex>
9509  [[noreturn]]
9510  void throw_exception(Ex const &e) {
9511  throw e;
9512  }
9513 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
9514  [[noreturn]]
9515  void throw_exception(std::exception const &e);
9516 #endif
9517 
9518  [[noreturn]]
9519  void throw_logic_error(std::string const &msg);
9520  [[noreturn]]
9521  void throw_domain_error(std::string const &msg);
9522  [[noreturn]]
9523  void throw_runtime_error(std::string const &msg);
9524 
9525 } // namespace Catch
9526 
9527 #define CATCH_MAKE_MSG(...) \
9528  (Catch::ReusableStringStream() << __VA_ARGS__).str()
9529 
9530 #define CATCH_INTERNAL_ERROR(...) \
9531  Catch::throw_logic_error(CATCH_MAKE_MSG(CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
9532 
9533 #define CATCH_ERROR(...) \
9534  Catch::throw_domain_error(CATCH_MAKE_MSG(__VA_ARGS__))
9535 
9536 #define CATCH_RUNTIME_ERROR(...) \
9537  Catch::throw_runtime_error(CATCH_MAKE_MSG(__VA_ARGS__))
9538 
9539 #define CATCH_ENFORCE(condition, ...) \
9540  do { \
9541  if (!(condition)) CATCH_ERROR(__VA_ARGS__); \
9542  } while (false)
9543 
9544 #endif // CATCH_ENFORCE_HPP_INCLUDED
9545 
9546 #ifndef CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
9547 #define CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
9548 
9549 #include <vector>
9550 
9551 namespace Catch {
9552 
9553  namespace Detail {
9554 
9555  Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo(StringRef enumName, StringRef allValueNames, std::vector<int> const &values);
9556 
9557  class EnumValuesRegistry : public IMutableEnumValuesRegistry {
9558  std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
9559 
9560  EnumInfo const &registerEnum(StringRef enumName, StringRef allValueNames, std::vector<int> const &values) override;
9561  };
9562 
9563  std::vector<StringRef> parseEnums(StringRef enums);
9564 
9565  } // namespace Detail
9566 
9567 } // namespace Catch
9568 
9569 #endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
9570 
9571 #ifndef CATCH_ERRNO_GUARD_HPP_INCLUDED
9572 #define CATCH_ERRNO_GUARD_HPP_INCLUDED
9573 
9574 namespace Catch {
9575 
9578  class ErrnoGuard {
9579  public:
9580  // Keep these outlined to avoid dragging in macros from <cerrno>
9581 
9582  ErrnoGuard();
9583  ~ErrnoGuard();
9584 
9585  private:
9586  int m_oldErrno;
9587  };
9588 
9589 } // namespace Catch
9590 
9591 #endif // CATCH_ERRNO_GUARD_HPP_INCLUDED
9592 
9593 #ifndef CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
9594 #define CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
9595 
9596 #include <string>
9597 
9598 namespace Catch {
9599 
9600  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
9601  public:
9602  ~ExceptionTranslatorRegistry() override;
9603  void registerTranslator(Detail::unique_ptr<IExceptionTranslator> &&translator);
9604  std::string translateActiveException() const override;
9605 
9606  private:
9607  ExceptionTranslators m_translators;
9608  };
9609 } // namespace Catch
9610 
9611 #endif // CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
9612 
9613 #ifndef CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
9614 #define CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
9615 
9616 #include <cassert>
9617 
9618 namespace Catch {
9619 
9630  class FatalConditionHandler {
9631  bool m_started = false;
9632 
9633  // Install/disengage implementation for specific platform.
9634  // Should be if-defed to work on current platform, can assume
9635  // engage-disengage 1:1 pairing.
9636  void engage_platform();
9637  void disengage_platform() noexcept;
9638 
9639  public:
9640  // Should also have platform-specific implementations as needed
9641  FatalConditionHandler();
9642  ~FatalConditionHandler();
9643 
9644  void engage() {
9645  assert(!m_started && "Handler cannot be installed twice.");
9646  m_started = true;
9647  engage_platform();
9648  }
9649 
9650  void disengage() noexcept {
9651  assert(m_started && "Handler cannot be uninstalled without being installed first");
9652  m_started = false;
9653  disengage_platform();
9654  }
9655  };
9656 
9658  class FatalConditionHandlerGuard {
9659  FatalConditionHandler *m_handler;
9660 
9661  public:
9662  FatalConditionHandlerGuard(FatalConditionHandler *handler)
9663  : m_handler(handler) {
9664  m_handler->engage();
9665  }
9666  ~FatalConditionHandlerGuard() {
9667  m_handler->disengage();
9668  }
9669  };
9670 
9671 } // end namespace Catch
9672 
9673 #endif // CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
9674 
9675 #ifndef CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
9676 #define CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
9677 
9678 #include <cassert>
9679 #include <cmath>
9680 #include <cstdint>
9681 #include <limits>
9682 #include <utility>
9683 
9684 namespace Catch {
9685  namespace Detail {
9686 
9687  uint32_t convertToBits(float f);
9688  uint64_t convertToBits(double d);
9689 
9690  // Used when we know we want == comparison of two doubles
9691  // to centralize warning suppression
9692  bool directCompare(float lhs, float rhs);
9693  bool directCompare(double lhs, double rhs);
9694 
9695  } // end namespace Detail
9696 
9697 #if defined(__GNUC__) || defined(__clang__)
9698 #pragma GCC diagnostic push
9699  // We do a bunch of direct compensations of floating point numbers,
9700  // because we know what we are doing and actually do want the direct
9701  // comparison behaviour.
9702 #pragma GCC diagnostic ignored "-Wfloat-equal"
9703 #endif
9704 
9722  template<typename FP>
9723  uint64_t ulpDistance(FP lhs, FP rhs) {
9724  assert(std::numeric_limits<FP>::is_iec559 && "ulpDistance assumes IEEE-754 format for floating point types");
9725  assert(!Catch::isnan(lhs) && "Distance between NaN and number is not meaningful");
9726  assert(!Catch::isnan(rhs) && "Distance between NaN and number is not meaningful");
9727 
9728  // We want X == Y to imply 0 ULP distance even if X and Y aren't
9729  // bit-equal (-0 and 0), or X - Y != 0 (same sign infinities).
9730  if (lhs == rhs) { return 0; }
9731 
9732  // We need a properly typed positive zero for type inference.
9733  static constexpr FP positive_zero{};
9734 
9735  // We want to ensure that +/- 0 is always represented as positive zero
9736  if (lhs == positive_zero) { lhs = positive_zero; }
9737  if (rhs == positive_zero) { rhs = positive_zero; }
9738 
9739  // If arguments have different signs, we can handle them by summing
9740  // how far are they from 0 each.
9741  if (std::signbit(lhs) != std::signbit(rhs)) {
9742  return ulpDistance(std::abs(lhs), positive_zero) + ulpDistance(std::abs(rhs), positive_zero);
9743  }
9744 
9745  // When both lhs and rhs are of the same sign, we can just
9746  // read the numbers bitwise as integers, and then subtract them
9747  // (assuming IEEE).
9748  uint64_t lc = Detail::convertToBits(lhs);
9749  uint64_t rc = Detail::convertToBits(rhs);
9750 
9751  // The ulp distance between two numbers is symmetric, so to avoid
9752  // dealing with overflows we want the bigger converted number on the lhs
9753  if (lc < rc) {
9754  std::swap(lc, rc);
9755  }
9756 
9757  return lc - rc;
9758  }
9759 
9760 #if defined(__GNUC__) || defined(__clang__)
9761 #pragma GCC diagnostic pop
9762 #endif
9763 
9764 } // end namespace Catch
9765 
9766 #endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
9767 
9768 #ifndef CATCH_GETENV_HPP_INCLUDED
9769 #define CATCH_GETENV_HPP_INCLUDED
9770 
9771 namespace Catch {
9772  namespace Detail {
9773 
9775  char const *getEnv(char const *varName);
9776 
9777  } // namespace Detail
9778 } // namespace Catch
9779 
9780 #endif // CATCH_GETENV_HPP_INCLUDED
9781 
9782 #ifndef CATCH_IS_PERMUTATION_HPP_INCLUDED
9783 #define CATCH_IS_PERMUTATION_HPP_INCLUDED
9784 
9785 #include <iterator>
9786 #include <type_traits>
9787 
9788 namespace Catch {
9789  namespace Detail {
9790 
9791  template<typename ForwardIter,
9792  typename Sentinel,
9793  typename T,
9794  typename Comparator>
9795  constexpr ForwardIter find_sentinel(ForwardIter start,
9796  Sentinel sentinel,
9797  T const &value,
9798  Comparator cmp) {
9799  while (start != sentinel) {
9800  if (cmp(*start, value)) { break; }
9801  ++start;
9802  }
9803  return start;
9804  }
9805 
9806  template<typename ForwardIter,
9807  typename Sentinel,
9808  typename T,
9809  typename Comparator>
9810  constexpr std::ptrdiff_t count_sentinel(ForwardIter start,
9811  Sentinel sentinel,
9812  T const &value,
9813  Comparator cmp) {
9814  std::ptrdiff_t count = 0;
9815  while (start != sentinel) {
9816  if (cmp(*start, value)) { ++count; }
9817  ++start;
9818  }
9819  return count;
9820  }
9821 
9822  template<typename ForwardIter, typename Sentinel>
9823  constexpr std::enable_if_t<!std::is_same<ForwardIter, Sentinel>::value,
9824  std::ptrdiff_t>
9825  sentinel_distance(ForwardIter iter, const Sentinel sentinel) {
9826  std::ptrdiff_t dist = 0;
9827  while (iter != sentinel) {
9828  ++iter;
9829  ++dist;
9830  }
9831  return dist;
9832  }
9833 
9834  template<typename ForwardIter>
9835  constexpr std::ptrdiff_t sentinel_distance(ForwardIter first,
9836  ForwardIter last) {
9837  return std::distance(first, last);
9838  }
9839 
9840  template<typename ForwardIter1,
9841  typename Sentinel1,
9842  typename ForwardIter2,
9843  typename Sentinel2,
9844  typename Comparator>
9845  constexpr bool check_element_counts(ForwardIter1 first_1,
9846  const Sentinel1 end_1,
9847  ForwardIter2 first_2,
9848  const Sentinel2 end_2,
9849  Comparator cmp) {
9850  auto cursor = first_1;
9851  while (cursor != end_1) {
9852  if (find_sentinel(first_1, cursor, *cursor, cmp) == cursor) {
9853  // we haven't checked this element yet
9854  const auto count_in_range_2 = count_sentinel(first_2, end_2, *cursor, cmp);
9855  // Not a single instance in 2nd range, so it cannot be a
9856  // permutation of 1st range
9857  if (count_in_range_2 == 0) { return false; }
9858 
9859  const auto count_in_range_1 = count_sentinel(cursor, end_1, *cursor, cmp);
9860  if (count_in_range_1 != count_in_range_2) {
9861  return false;
9862  }
9863  }
9864 
9865  ++cursor;
9866  }
9867 
9868  return true;
9869  }
9870 
9871  template<typename ForwardIter1,
9872  typename Sentinel1,
9873  typename ForwardIter2,
9874  typename Sentinel2,
9875  typename Comparator>
9876  constexpr bool is_permutation(ForwardIter1 first_1,
9877  const Sentinel1 end_1,
9878  ForwardIter2 first_2,
9879  const Sentinel2 end_2,
9880  Comparator cmp) {
9881  // TODO: no optimization for stronger iterators, because we would also have to constrain on sentinel vs not sentinel types
9882  // TODO: Comparator has to be "both sides", e.g. a == b => b == a
9883  // This skips shared prefix of the two ranges
9884  while (first_1 != end_1 && first_2 != end_2 && cmp(*first_1, *first_2)) {
9885  ++first_1;
9886  ++first_2;
9887  }
9888 
9889  // We need to handle case where at least one of the ranges has no more elements
9890  if (first_1 == end_1 || first_2 == end_2) {
9891  return first_1 == end_1 && first_2 == end_2;
9892  }
9893 
9894  // pair counting is n**2, so we pay linear walk to compare the sizes first
9895  auto dist_1 = sentinel_distance(first_1, end_1);
9896  auto dist_2 = sentinel_distance(first_2, end_2);
9897 
9898  if (dist_1 != dist_2) { return false; }
9899 
9900  // Since we do not try to handle stronger iterators pair (e.g.
9901  // bidir) optimally, the only thing left to do is to check counts in
9902  // the remaining ranges.
9903  return check_element_counts(first_1, end_1, first_2, end_2, cmp);
9904  }
9905 
9906  } // namespace Detail
9907 } // namespace Catch
9908 
9909 #endif // CATCH_IS_PERMUTATION_HPP_INCLUDED
9910 
9911 #ifndef CATCH_ISTREAM_HPP_INCLUDED
9912 #define CATCH_ISTREAM_HPP_INCLUDED
9913 
9914 #include <iosfwd>
9915 #include <string>
9916 
9917 namespace Catch {
9918 
9919  class IStream {
9920  public:
9921  virtual ~IStream(); // = default
9922  virtual std::ostream &stream() = 0;
9934  virtual bool isConsole() const { return false; }
9935  };
9936 
9948  auto makeStream(std::string const &filename) -> Detail::unique_ptr<IStream>;
9949 
9950 } // namespace Catch
9951 
9952 #endif // CATCH_STREAM_HPP_INCLUDED
9953 
9954 #ifndef CATCH_JSONWRITER_HPP_INCLUDED
9955 #define CATCH_JSONWRITER_HPP_INCLUDED
9956 
9957 #include <cstdint>
9958 #include <sstream>
9959 
9960 namespace Catch {
9961  class JsonObjectWriter;
9962  class JsonArrayWriter;
9963 
9964  struct JsonUtils {
9965  static void indent(std::ostream &os, std::uint64_t level);
9966  static void appendCommaNewline(std::ostream &os,
9967  bool &should_comma,
9968  std::uint64_t level);
9969  };
9970 
9971  class JsonValueWriter {
9972  public:
9973  JsonValueWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND);
9974  JsonValueWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND, std::uint64_t indent_level);
9975 
9976  JsonObjectWriter writeObject() &&;
9977  JsonArrayWriter writeArray() &&;
9978 
9979  template<typename T>
9980  void write(T const &value) && {
9981  writeImpl(value, !std::is_arithmetic<T>::value);
9982  }
9983  void write(StringRef value) &&;
9984  void write(bool value) &&;
9985 
9986  private:
9987  void writeImpl(StringRef value, bool quote);
9988 
9989  // Without this SFINAE, this overload is a better match
9990  // for `std::string`, `char const*`, `char const[N]` args.
9991  // While it would still work, it would cause code bloat
9992  // and multiple iteration over the strings
9993  template<typename T,
9994  typename = typename std::enable_if_t<
9995  !std::is_convertible<T, StringRef>::value>>
9996  void writeImpl(T const &value, bool quote_value) {
9997  m_sstream << value;
9998  writeImpl(m_sstream.str(), quote_value);
9999  }
10000 
10001  std::ostream &m_os;
10002  std::stringstream m_sstream;
10003  std::uint64_t m_indent_level;
10004  };
10005 
10006  class JsonObjectWriter {
10007  public:
10008  JsonObjectWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND);
10009  JsonObjectWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND, std::uint64_t indent_level);
10010 
10011  JsonObjectWriter(JsonObjectWriter &&source) noexcept;
10012  JsonObjectWriter &operator=(JsonObjectWriter &&source) = delete;
10013 
10014  ~JsonObjectWriter();
10015 
10016  JsonValueWriter write(StringRef key);
10017 
10018  private:
10019  std::ostream &m_os;
10020  std::uint64_t m_indent_level;
10021  bool m_should_comma = false;
10022  bool m_active = true;
10023  };
10024 
10025  class JsonArrayWriter {
10026  public:
10027  JsonArrayWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND);
10028  JsonArrayWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND, std::uint64_t indent_level);
10029 
10030  JsonArrayWriter(JsonArrayWriter &&source) noexcept;
10031  JsonArrayWriter &operator=(JsonArrayWriter &&source) = delete;
10032 
10033  ~JsonArrayWriter();
10034 
10035  JsonObjectWriter writeObject();
10036  JsonArrayWriter writeArray();
10037 
10038  template<typename T>
10039  JsonArrayWriter &write(T const &value) {
10040  return writeImpl(value);
10041  }
10042 
10043  JsonArrayWriter &write(bool value);
10044 
10045  private:
10046  template<typename T>
10047  JsonArrayWriter &writeImpl(T const &value) {
10048  JsonUtils::appendCommaNewline(
10049  m_os, m_should_comma, m_indent_level + 1);
10050  JsonValueWriter{m_os}.write(value);
10051 
10052  return *this;
10053  }
10054 
10055  std::ostream &m_os;
10056  std::uint64_t m_indent_level;
10057  bool m_should_comma = false;
10058  bool m_active = true;
10059  };
10060 
10061 } // namespace Catch
10062 
10063 #endif // CATCH_JSONWRITER_HPP_INCLUDED
10064 
10065 #ifndef CATCH_LEAK_DETECTOR_HPP_INCLUDED
10066 #define CATCH_LEAK_DETECTOR_HPP_INCLUDED
10067 
10068 namespace Catch {
10069 
10070  struct LeakDetector {
10071  LeakDetector();
10072  ~LeakDetector();
10073  };
10074 
10075 } // namespace Catch
10076 #endif // CATCH_LEAK_DETECTOR_HPP_INCLUDED
10077 
10078 #ifndef CATCH_LIST_HPP_INCLUDED
10079 #define CATCH_LIST_HPP_INCLUDED
10080 
10081 #include <set>
10082 #include <string>
10083 
10084 namespace Catch {
10085 
10086  class IEventListener;
10087  class Config;
10088 
10089  struct ReporterDescription {
10090  std::string name, description;
10091  };
10092  struct ListenerDescription {
10093  StringRef name;
10094  std::string description;
10095  };
10096 
10097  struct TagInfo {
10098  void add(StringRef spelling);
10099  std::string all() const;
10100 
10101  std::set<StringRef> spellings;
10102  std::size_t count = 0;
10103  };
10104 
10105  bool list(IEventListener &reporter, Config const &config);
10106 
10107 } // end namespace Catch
10108 
10109 #endif // CATCH_LIST_HPP_INCLUDED
10110 
10111 #ifndef CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
10112 #define CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
10113 
10114 #include <cassert>
10115 #include <string>
10116 
10117 namespace Catch {
10118 
10119  class OutputRedirect {
10120  bool m_redirectActive = false;
10121  virtual void activateImpl() = 0;
10122  virtual void deactivateImpl() = 0;
10123 
10124  public:
10125  enum Kind {
10127  None,
10129  Streams,
10131  FileDescriptors,
10132  };
10133 
10134  virtual ~OutputRedirect(); // = default;
10135 
10136  // TODO: Do we want to check that redirect is not active before retrieving the output?
10137  virtual std::string getStdout() = 0;
10138  virtual std::string getStderr() = 0;
10139  virtual void clearBuffers() = 0;
10140  bool isActive() const { return m_redirectActive; }
10141  void activate() {
10142  assert(!m_redirectActive && "redirect is already active");
10143  activateImpl();
10144  m_redirectActive = true;
10145  }
10146  void deactivate() {
10147  assert(m_redirectActive && "redirect is not active");
10148  deactivateImpl();
10149  m_redirectActive = false;
10150  }
10151  };
10152 
10153  bool isRedirectAvailable(OutputRedirect::Kind kind);
10154  Detail::unique_ptr<OutputRedirect> makeOutputRedirect(bool actual);
10155 
10156  class RedirectGuard {
10157  OutputRedirect *m_redirect;
10158  bool m_activate;
10159  bool m_previouslyActive;
10160  bool m_moved = false;
10161 
10162  public:
10163  RedirectGuard(bool activate, OutputRedirect &redirectImpl);
10164  ~RedirectGuard() noexcept(false);
10165 
10166  RedirectGuard(RedirectGuard const &) = delete;
10167  RedirectGuard &operator=(RedirectGuard const &) = delete;
10168 
10169  // C++14 needs move-able guards to return them from functions
10170  RedirectGuard(RedirectGuard &&rhs) noexcept;
10171  RedirectGuard &operator=(RedirectGuard &&rhs) noexcept;
10172  };
10173 
10174  RedirectGuard scopedActivate(OutputRedirect &redirectImpl);
10175  RedirectGuard scopedDeactivate(OutputRedirect &redirectImpl);
10176 
10177 } // end namespace Catch
10178 
10179 #endif // CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
10180 
10181 #ifndef CATCH_PARSE_NUMBERS_HPP_INCLUDED
10182 #define CATCH_PARSE_NUMBERS_HPP_INCLUDED
10183 
10184 #include <string>
10185 
10186 namespace Catch {
10187 
10194  Optional<unsigned int> parseUInt(std::string const &input, int base = 10);
10195 } // namespace Catch
10196 
10197 #endif // CATCH_PARSE_NUMBERS_HPP_INCLUDED
10198 
10199 #ifndef CATCH_REPORTER_REGISTRY_HPP_INCLUDED
10200 #define CATCH_REPORTER_REGISTRY_HPP_INCLUDED
10201 
10202 #include <map>
10203 #include <string>
10204 #include <vector>
10205 
10206 namespace Catch {
10207 
10208  class IEventListener;
10209  using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
10210  class IReporterFactory;
10212  struct ReporterConfig;
10213  class EventListenerFactory;
10214 
10215  class ReporterRegistry {
10216  struct ReporterRegistryImpl;
10218 
10219  public:
10220  ReporterRegistry();
10221  ~ReporterRegistry(); // = default;
10222 
10223  IEventListenerPtr create(std::string const &name,
10224  ReporterConfig &&config) const;
10225 
10226  void registerReporter(std::string const &name,
10227  IReporterFactoryPtr factory);
10228 
10229  void
10230  registerListener(Detail::unique_ptr<EventListenerFactory> factory);
10231 
10232  std::map<std::string,
10234  Detail::CaseInsensitiveLess> const &
10235  getFactories() const;
10236 
10237  std::vector<Detail::unique_ptr<EventListenerFactory>> const &
10238  getListeners() const;
10239  };
10240 
10241 } // end namespace Catch
10242 
10243 #endif // CATCH_REPORTER_REGISTRY_HPP_INCLUDED
10244 
10245 #ifndef CATCH_RUN_CONTEXT_HPP_INCLUDED
10246 #define CATCH_RUN_CONTEXT_HPP_INCLUDED
10247 
10248 #ifndef CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
10249 #define CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
10250 
10251 #include <string>
10252 #include <vector>
10253 
10254 namespace Catch {
10255 
10256  struct PathFilter;
10257 
10258  namespace TestCaseTracking {
10259 
10260  struct NameAndLocation {
10261  std::string name;
10262  SourceLineInfo location;
10263 
10264  NameAndLocation(std::string &&_name, SourceLineInfo const &_location);
10265  friend bool operator==(NameAndLocation const &lhs, NameAndLocation const &rhs) {
10266  // This is a very cheap check that should have a very high hit rate.
10267  // If we get to SourceLineInfo::operator==, we will redo it, but the
10268  // cost of repeating is trivial at that point (we will be paying
10269  // multiple strcmp/memcmps at that point).
10270  if (lhs.location.line != rhs.location.line) { return false; }
10271  return lhs.name == rhs.name && lhs.location == rhs.location;
10272  }
10273  friend bool operator!=(NameAndLocation const &lhs,
10274  NameAndLocation const &rhs) {
10275  return !(lhs == rhs);
10276  }
10277  };
10278 
10286  struct NameAndLocationRef {
10287  StringRef name;
10288  SourceLineInfo location;
10289 
10290  constexpr NameAndLocationRef(StringRef name_ CATCH_ATTR_LIFETIMEBOUND,
10291  SourceLineInfo location_)
10292  : name(name_), location(location_) {}
10293 
10294  friend bool operator==(NameAndLocation const &lhs,
10295  NameAndLocationRef const &rhs) {
10296  // This is a very cheap check that should have a very high hit rate.
10297  // If we get to SourceLineInfo::operator==, we will redo it, but the
10298  // cost of repeating is trivial at that point (we will be paying
10299  // multiple strcmp/memcmps at that point).
10300  if (lhs.location.line != rhs.location.line) { return false; }
10301  return StringRef(lhs.name) == rhs.name && lhs.location == rhs.location;
10302  }
10303  friend bool operator==(NameAndLocationRef const &lhs,
10304  NameAndLocation const &rhs) {
10305  return rhs == lhs;
10306  }
10307  };
10308 
10309  class ITracker;
10310 
10311  using ITrackerPtr = Catch::Detail::unique_ptr<ITracker>;
10312 
10313  class ITracker {
10314  NameAndLocation m_nameAndLocation;
10315 
10316  using Children = std::vector<ITrackerPtr>;
10317 
10318  protected:
10319  enum CycleState {
10320  NotStarted,
10321  Executing,
10322  ExecutingChildren,
10323  NeedsAnotherRun,
10324  CompletedSuccessfully,
10325  Failed
10326  };
10327 
10328  ITracker *m_parent = nullptr;
10329  Children m_children;
10330  CycleState m_runState = NotStarted;
10331 
10332  // Members for path filtering
10333  std::vector<PathFilter> const *m_filterRef = nullptr;
10334 
10335  // Note: There are 2 dummy section trackers (root, test-case) before
10336  // the first "real" section tracker can be encountered. We start
10337  // the default tracker at -2, so that the first "real" section
10338  // tracker overflows to index 0.
10339  // Nesting depth of this tracker, used to decide which new-style filter applies.
10340  size_t m_allTrackerDepth = static_cast<size_t>(-2);
10341  // Nesting depth of sections (inc. this tracker), used for old-style filters.
10342  // Must be updated by the section tracker on its own.
10343  size_t m_sectionOnlyDepth = static_cast<size_t>(-2);
10344  // Transitory: Remove once we remove backwards compatibility with old-style (v3.x) filters
10345  bool m_newStyleFilters = false;
10346 
10347  public:
10348  ITracker(NameAndLocation &&nameAndLoc, ITracker *parent);
10349 
10350  // static queries
10351  NameAndLocation const &nameAndLocation() const {
10352  return m_nameAndLocation;
10353  }
10354  ITracker *parent() const {
10355  return m_parent;
10356  }
10357 
10358  virtual ~ITracker(); // = default
10359 
10360  // dynamic queries
10361 
10363  virtual bool isComplete() const = 0;
10365  bool isSuccessfullyCompleted() const {
10366  return m_runState == CompletedSuccessfully;
10367  }
10369  bool isOpen() const;
10371  bool hasStarted() const;
10372 
10373  void setFilters(std::vector<PathFilter> const *filters, bool newStyleFilters) {
10374  m_filterRef = filters;
10375  m_newStyleFilters = newStyleFilters;
10376  }
10377 
10378  // actions
10379  virtual void close() = 0; // Successfully complete
10380  virtual void fail() = 0;
10381  void markAsNeedingAnotherRun();
10382 
10384  void addChild(ITrackerPtr &&child);
10390  ITracker *findChild(NameAndLocationRef const &nameAndLocation);
10392  bool hasChildren() const {
10393  return !m_children.empty();
10394  }
10395 
10397  void openChild();
10398 
10405  virtual bool isSectionTracker() const;
10412  virtual bool isGeneratorTracker() const;
10413  };
10414 
10415  class TrackerContext {
10416  enum RunState {
10417  NotStarted,
10418  Executing,
10419  CompletedCycle
10420  };
10421 
10422  ITrackerPtr m_rootTracker;
10423  ITracker *m_currentTracker = nullptr;
10424  RunState m_runState = NotStarted;
10425 
10426  public:
10427  ITracker &startRun();
10428 
10429  void startCycle() {
10430  m_currentTracker = m_rootTracker.get();
10431  m_runState = Executing;
10432  }
10433  void completeCycle();
10434 
10435  bool completedCycle() const;
10436  ITracker &currentTracker() { return *m_currentTracker; }
10437  void setCurrentTracker(ITracker *tracker);
10438  };
10439 
10440  class TrackerBase : public ITracker {
10441  protected:
10442  TrackerContext &m_ctx;
10443 
10444  public:
10445  TrackerBase(NameAndLocation &&nameAndLocation, TrackerContext &ctx, ITracker *parent);
10446 
10447  bool isComplete() const override;
10448 
10449  void open();
10450 
10451  void close() override;
10452  void fail() override;
10453 
10454  private:
10455  void moveToParent();
10456  void moveToThis();
10457  };
10458 
10459  class SectionTracker final : public TrackerBase {
10460  // Note that lifetime-wise we piggy back off the name stored in the `ITracker` parent`.
10461  // Currently it allocates owns the name, so this is safe. If it is later refactored
10462  // to not own the name, the name still has to outlive the `ITracker` parent, so
10463  // this should still be safe.
10464  StringRef m_trimmed_name;
10465 
10466  public:
10467  SectionTracker(NameAndLocation &&nameAndLocation, TrackerContext &ctx, ITracker *parent);
10468 
10469  bool isSectionTracker() const override;
10470 
10471  bool isComplete() const override;
10472 
10473  static SectionTracker &acquire(TrackerContext &ctx, NameAndLocationRef const &nameAndLocation);
10474 
10475  void tryOpen();
10476 
10478  StringRef trimmedName() const;
10479  };
10480 
10481  } // namespace TestCaseTracking
10482 
10483  using TestCaseTracking::ITracker;
10484  using TestCaseTracking::SectionTracker;
10485  using TestCaseTracking::TrackerContext;
10486 
10487 } // namespace Catch
10488 
10489 #endif // CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
10490 
10491 #ifndef CATCH_THREAD_SUPPORT_HPP_INCLUDED
10492 #define CATCH_THREAD_SUPPORT_HPP_INCLUDED
10493 
10494 #if defined(CATCH_CONFIG_THREAD_SAFE_ASSERTIONS)
10495 #include <atomic>
10496 #include <mutex>
10497 #endif
10498 
10499 namespace Catch {
10500  namespace Detail {
10501 #if defined(CATCH_CONFIG_THREAD_SAFE_ASSERTIONS)
10502  using Mutex = std::mutex;
10503  using LockGuard = std::lock_guard<std::mutex>;
10504  struct AtomicCounts {
10505  std::atomic<std::uint64_t> passed{0};
10506  std::atomic<std::uint64_t> failed{0};
10507  std::atomic<std::uint64_t> failedButOk{0};
10508  std::atomic<std::uint64_t> skipped{0};
10509  };
10510 #else // ^^ Use actual mutex, lock and atomics
10511  // vv Dummy implementations for single-thread performance
10512 
10513  struct Mutex {
10514  void lock() {}
10515  void unlock() {}
10516  };
10517 
10518  struct LockGuard {
10519  LockGuard(Mutex) {}
10520  };
10521 
10522  using AtomicCounts = Counts;
10523 #endif
10524 
10525  } // namespace Detail
10526 } // namespace Catch
10527 
10528 #endif // CATCH_THREAD_SUPPORT_HPP_INCLUDED
10529 
10530 #include <string>
10531 
10532 namespace Catch {
10533 
10534  class IGeneratorTracker;
10535  class IConfig;
10536  class IEventListener;
10537  using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
10538  class OutputRedirect;
10539 
10541 
10542  class RunContext final : public IResultCapture {
10543  public:
10544  RunContext(RunContext const &) = delete;
10545  RunContext &operator=(RunContext const &) = delete;
10546 
10547  explicit RunContext(IConfig const *_config, IEventListenerPtr &&reporter);
10548 
10549  ~RunContext() override;
10550 
10551  Totals runTest(TestCaseHandle const &testCase);
10552 
10553  public: // IResultCapture
10554  // Assertion handlers
10555  void handleExpr(AssertionInfo const &info,
10556  ITransientExpression const &expr,
10557  AssertionReaction &reaction) override;
10558  void handleMessage(AssertionInfo const &info,
10559  ResultWas::OfType resultType,
10560  std::string &&message,
10561  AssertionReaction &reaction) override;
10562  void handleUnexpectedExceptionNotThrown(AssertionInfo const &info,
10563  AssertionReaction &reaction) override;
10564  void handleUnexpectedInflightException(AssertionInfo const &info,
10565  std::string &&message,
10566  AssertionReaction &reaction) override;
10567  void handleIncomplete(AssertionInfo const &info) override;
10568  void handleNonExpr(AssertionInfo const &info,
10569  ResultWas::OfType resultType,
10570  AssertionReaction &reaction) override;
10571 
10572  void notifyAssertionStarted(AssertionInfo const &info) override;
10573  bool sectionStarted(StringRef sectionName,
10574  SourceLineInfo const &sectionLineInfo,
10575  Counts &assertions) override;
10576 
10577  void sectionEnded(SectionEndInfo &&endInfo) override;
10578  void sectionEndedEarly(SectionEndInfo &&endInfo) override;
10579 
10581  acquireGeneratorTracker(StringRef generatorName,
10582  SourceLineInfo const &lineInfo) override;
10583  IGeneratorTracker *createGeneratorTracker(
10584  StringRef generatorName,
10585  SourceLineInfo lineInfo,
10586  Generators::GeneratorBasePtr &&generator) override;
10587 
10588  void benchmarkPreparing(StringRef name) override;
10589  void benchmarkStarting(BenchmarkInfo const &info) override;
10590  void benchmarkEnded(BenchmarkStats<> const &stats) override;
10591  void benchmarkFailed(StringRef error) override;
10592 
10593  std::string getCurrentTestName() const override;
10594 
10595  const AssertionResult *getLastResult() const override;
10596 
10597  void exceptionEarlyReported() override;
10598 
10599  void handleFatalErrorCondition(StringRef message) override;
10600 
10601  bool lastAssertionPassed() override;
10602 
10603  public:
10604  // !TBD We need to do this another way!
10605  bool aborting() const;
10606 
10607  private:
10608  void assertionPassedFastPath(SourceLineInfo lineInfo);
10609  // Update the non-thread-safe m_totals from the atomic assertion counts.
10610  void updateTotalsFromAtomics();
10611 
10612  void runCurrentTest();
10613  void invokeActiveTestCase();
10614 
10615  bool testForMissingAssertions(Counts &assertions);
10616 
10617  void assertionEnded(AssertionResult &&result);
10618  void reportExpr(AssertionInfo const &info,
10619  ResultWas::OfType resultType,
10620  ITransientExpression const *expr,
10621  bool negated);
10622 
10623  void populateReaction(AssertionReaction &reaction, bool has_normal_disposition);
10624 
10625  // Creates dummy info for unexpected exceptions/fatal errors,
10626  // where we do not have the access to one, but we still need
10627  // to send one to the reporters.
10628  AssertionInfo makeDummyAssertionInfo();
10629 
10630  private:
10631  void handleUnfinishedSections();
10632  mutable Detail::Mutex m_assertionMutex;
10633  TestRunInfo m_runInfo;
10634  TestCaseHandle const *m_activeTestCase = nullptr;
10635  ITracker *m_testCaseTracker = nullptr;
10636  Optional<AssertionResult> m_lastResult;
10637  IConfig const *m_config;
10638  Totals m_totals;
10639  Detail::AtomicCounts m_atomicAssertionCount;
10640  IEventListenerPtr m_reporter;
10641  std::vector<SectionEndInfo> m_unfinishedSections;
10642  std::vector<ITracker *> m_activeSections;
10643  TrackerContext m_trackerContext;
10644  Detail::unique_ptr<OutputRedirect> m_outputRedirect;
10645  FatalConditionHandler m_fatalConditionhandler;
10646  // Caches m_config->abortAfter() to avoid vptr calls/allow inlining
10647  size_t m_abortAfterXFailedAssertions;
10648  bool m_shouldReportUnexpected = true;
10649  // Caches whether `assertionStarting` events should be sent to the reporter.
10650  bool m_reportAssertionStarting;
10651  // Caches whether `assertionEnded` events for successful assertions should be sent to the reporter
10652  bool m_includeSuccessfulResults;
10653  // Caches m_config->shouldDebugBreak() to avoid vptr calls/allow inlining
10654  bool m_shouldDebugBreak;
10655  };
10656 
10657  void seedRng(IConfig const &config);
10658  unsigned int rngSeed();
10659 } // end namespace Catch
10660 
10661 #endif // CATCH_RUN_CONTEXT_HPP_INCLUDED
10662 
10663 #ifndef CATCH_SHARDING_HPP_INCLUDED
10664 #define CATCH_SHARDING_HPP_INCLUDED
10665 
10666 #include <algorithm>
10667 #include <cassert>
10668 
10669 namespace Catch {
10670 
10671  template<typename Container>
10672  Container createShard(Container const &container, std::size_t const shardCount, std::size_t const shardIndex) {
10673  assert(shardCount > shardIndex);
10674 
10675  if (shardCount == 1) {
10676  return container;
10677  }
10678 
10679  const std::size_t totalTestCount = container.size();
10680 
10681  const std::size_t shardSize = totalTestCount / shardCount;
10682  const std::size_t leftoverTests = totalTestCount % shardCount;
10683 
10684  const std::size_t startIndex = shardIndex * shardSize + (std::min)(shardIndex, leftoverTests);
10685  const std::size_t endIndex = (shardIndex + 1) * shardSize + (std::min)(shardIndex + 1, leftoverTests);
10686 
10687  auto startIterator = std::next(container.begin(), static_cast<std::ptrdiff_t>(startIndex));
10688  auto endIterator = std::next(container.begin(), static_cast<std::ptrdiff_t>(endIndex));
10689 
10690  return Container(startIterator, endIterator);
10691  }
10692 
10693 } // namespace Catch
10694 
10695 #endif // CATCH_SHARDING_HPP_INCLUDED
10696 
10697 #ifndef CATCH_SINGLETONS_HPP_INCLUDED
10698 #define CATCH_SINGLETONS_HPP_INCLUDED
10699 
10700 namespace Catch {
10701 
10702  struct ISingleton {
10703  virtual ~ISingleton(); // = default
10704  };
10705 
10706  void addSingleton(ISingleton *singleton);
10707  void cleanupSingletons();
10708 
10709  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
10710  class Singleton : SingletonImplT, public ISingleton {
10711  static auto getInternal() -> Singleton * {
10712  static Singleton *s_instance = nullptr;
10713  if (!s_instance) {
10714  s_instance = new Singleton;
10715  addSingleton(s_instance);
10716  }
10717  return s_instance;
10718  }
10719 
10720  public:
10721  static auto get() -> InterfaceT const & {
10722  return *getInternal();
10723  }
10724  static auto getMutable() -> MutableInterfaceT & {
10725  return *getInternal();
10726  }
10727  };
10728 
10729 } // namespace Catch
10730 
10731 #endif // CATCH_SINGLETONS_HPP_INCLUDED
10732 
10733 #ifndef CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
10734 #define CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
10735 
10736 #include <exception>
10737 #include <vector>
10738 
10739 namespace Catch {
10740 
10741  class StartupExceptionRegistry {
10742 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10743  public:
10744  void add(std::exception_ptr const &exception) noexcept;
10745  std::vector<std::exception_ptr> const &getExceptions() const noexcept;
10746 
10747  private:
10748  std::vector<std::exception_ptr> m_exceptions;
10749 #endif
10750  };
10751 
10752 } // end namespace Catch
10753 
10754 #endif // CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
10755 
10756 #ifndef CATCH_STDSTREAMS_HPP_INCLUDED
10757 #define CATCH_STDSTREAMS_HPP_INCLUDED
10758 
10759 #include <iosfwd>
10760 
10761 namespace Catch {
10762 
10763  std::ostream &cout();
10764  std::ostream &cerr();
10765  std::ostream &clog();
10766 
10767 } // namespace Catch
10768 
10769 #endif
10770 
10771 #ifndef CATCH_STRING_MANIP_HPP_INCLUDED
10772 #define CATCH_STRING_MANIP_HPP_INCLUDED
10773 
10774 #include <cstdint>
10775 #include <iosfwd>
10776 #include <string>
10777 #include <vector>
10778 
10779 namespace Catch {
10780 
10781  bool startsWith(std::string const &s, std::string const &prefix);
10782  bool startsWith(StringRef s, char prefix);
10783  bool endsWith(std::string const &s, std::string const &suffix);
10784  bool endsWith(std::string const &s, char suffix);
10785  bool contains(std::string const &s, std::string const &infix);
10786  void toLowerInPlace(std::string &s);
10787  std::string toLower(std::string const &s);
10788  char toLower(char c);
10790  std::string trim(std::string const &str);
10792  StringRef trim(StringRef ref CATCH_ATTR_LIFETIMEBOUND);
10793 
10794  // !!! Be aware, returns refs into original string - make sure original string outlives them
10795  std::vector<StringRef> splitStringRef(StringRef str CATCH_ATTR_LIFETIMEBOUND, char delimiter);
10796  bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis);
10797 
10808  class pluralise {
10809  std::uint64_t m_count;
10810  StringRef m_label;
10811 
10812  public:
10813  constexpr pluralise(std::uint64_t count, StringRef label CATCH_ATTR_LIFETIMEBOUND)
10814  : m_count(count), m_label(label) {}
10815 
10816  friend std::ostream &operator<<(std::ostream &os, pluralise const &pluraliser);
10817  };
10818 } // namespace Catch
10819 
10820 #endif // CATCH_STRING_MANIP_HPP_INCLUDED
10821 
10822 #ifndef CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
10823 #define CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
10824 
10825 #include <map>
10826 #include <string>
10827 
10828 namespace Catch {
10829  struct SourceLineInfo;
10830 
10831  class TagAliasRegistry : public ITagAliasRegistry {
10832  public:
10833  ~TagAliasRegistry() override;
10834  TagAlias const *find(std::string const &alias) const override;
10835  std::string expandAliases(std::string const &unexpandedTestSpec) const override;
10836  void add(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo);
10837 
10838  private:
10839  std::map<std::string, TagAlias> m_registry;
10840  };
10841 
10842 } // end namespace Catch
10843 
10844 #endif // CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
10845 
10846 #ifndef CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED
10847 #define CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED
10848 
10849 #include <cstdint>
10850 
10851 namespace Catch {
10852 
10853  struct TestCaseInfo;
10854 
10855  class TestCaseInfoHasher {
10856  public:
10857  using hash_t = std::uint64_t;
10858  TestCaseInfoHasher(hash_t seed);
10859  uint32_t operator()(TestCaseInfo const &t) const;
10860 
10861  private:
10862  hash_t m_seed;
10863  };
10864 
10865 } // namespace Catch
10866 
10867 #endif /* CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED */
10868 
10869 #ifndef CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
10870 #define CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
10871 
10872 #include <vector>
10873 
10874 namespace Catch {
10875 
10876  class IConfig;
10877  class ITestInvoker;
10878  class TestCaseHandle;
10879  class TestSpec;
10880 
10881  std::vector<TestCaseHandle> sortTests(IConfig const &config, std::vector<TestCaseHandle> const &unsortedTestCases);
10882 
10883  bool isThrowSafe(TestCaseHandle const &testCase, IConfig const &config);
10884 
10885  std::vector<TestCaseHandle> filterTests(std::vector<TestCaseHandle> const &testCases, TestSpec const &testSpec, IConfig const &config);
10886  std::vector<TestCaseHandle> const &getAllTestCasesSorted(IConfig const &config);
10887 
10888  class TestRegistry : public ITestCaseRegistry {
10889  public:
10890  void registerTest(Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker);
10891 
10892  std::vector<TestCaseInfo *> const &getAllInfos() const override;
10893  std::vector<TestCaseHandle> const &getAllTests() const override;
10894  std::vector<TestCaseHandle> const &getAllTestsSorted(IConfig const &config) const override;
10895 
10896  ~TestRegistry() override; // = default
10897 
10898  private:
10899  std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
10900  // Keeps a materialized vector for `getAllInfos`.
10901  // We should get rid of that eventually (see interface note)
10902  std::vector<TestCaseInfo *> m_viewed_test_infos;
10903 
10904  std::vector<Detail::unique_ptr<ITestInvoker>> m_invokers;
10905  std::vector<TestCaseHandle> m_handles;
10906  mutable TestRunOrder m_currentSortOrder = TestRunOrder::Declared;
10907  mutable std::vector<TestCaseHandle> m_sortedFunctions;
10908  };
10909 
10911 
10912 } // end namespace Catch
10913 
10914 #endif // CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
10915 
10916 #ifndef CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
10917 #define CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
10918 
10919 #ifdef __clang__
10920 #pragma clang diagnostic push
10921 #pragma clang diagnostic ignored "-Wpadded"
10922 #endif
10923 
10924 #include <string>
10925 #include <vector>
10926 
10927 namespace Catch {
10928 
10929  class ITagAliasRegistry;
10930 
10931  class TestSpecParser {
10932  enum Mode { None,
10933  Name,
10934  QuotedName,
10935  Tag,
10936  EscapedName };
10937  Mode m_mode = None;
10938  Mode lastMode = None;
10939  bool m_exclusion = false;
10940  std::size_t m_pos = 0;
10941  std::size_t m_realPatternPos = 0;
10942  std::string m_arg;
10943  std::string m_substring;
10944  std::string m_patternName;
10945  std::vector<std::size_t> m_escapeChars;
10946  TestSpec::Filter m_currentFilter;
10947  TestSpec m_testSpec;
10948  ITagAliasRegistry const *m_tagAliases = nullptr;
10949 
10950  public:
10951  TestSpecParser(ITagAliasRegistry const &tagAliases);
10952 
10953  TestSpecParser &parse(std::string const &arg);
10954  TestSpec testSpec();
10955 
10956  private:
10957  bool visitChar(char c);
10958  void startNewMode(Mode mode);
10959  bool processNoneChar(char c);
10960  void processNameChar(char c);
10961  bool processOtherChar(char c);
10962  void endMode();
10963  void escape();
10964  bool isControlChar(char c) const;
10965  void saveLastMode();
10966  void revertBackToLastMode();
10967  void addFilter();
10968  bool separate();
10969 
10970  // Handles common preprocessing of the pattern for name/tag patterns
10971  std::string preprocessPattern();
10972  // Adds the current pattern as a test name
10973  void addNamePattern();
10974  // Adds the current pattern as a tag
10975  void addTagPattern();
10976 
10977  inline void addCharToPattern(char c) {
10978  m_substring += c;
10979  m_patternName += c;
10980  m_realPatternPos++;
10981  }
10982  };
10983 
10984 } // namespace Catch
10985 
10986 #ifdef __clang__
10987 #pragma clang diagnostic pop
10988 #endif
10989 
10990 #endif // CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
10991 
10992 #ifndef CATCH_TEXTFLOW_HPP_INCLUDED
10993 #define CATCH_TEXTFLOW_HPP_INCLUDED
10994 
10995 #include <cassert>
10996 #include <string>
10997 #include <vector>
10998 
10999 namespace Catch {
11000  namespace TextFlow {
11001 
11002  class Columns;
11003 
11016  class AnsiSkippingString {
11017  std::string m_string;
11018  std::size_t m_size = 0;
11019 
11020  // perform 0xff replacement and calculate m_size
11021  void preprocessString();
11022 
11023  public:
11024  class const_iterator;
11025  using iterator = const_iterator;
11026  // note: must be u-suffixed or this will cause a "truncation of
11027  // constant value" warning on MSVC
11028  static constexpr char sentinel = static_cast<char>(0xffu);
11029 
11030  explicit AnsiSkippingString(std::string const &text);
11031  explicit AnsiSkippingString(std::string &&text);
11032 
11033  const_iterator begin() const;
11034  const_iterator end() const;
11035 
11036  size_t size() const { return m_size; }
11037 
11038  std::string substring(const_iterator begin,
11039  const_iterator end) const;
11040  };
11041 
11042  class AnsiSkippingString::const_iterator {
11043  friend AnsiSkippingString;
11044  struct EndTag {};
11045 
11046  const std::string *m_string;
11047  std::string::const_iterator m_it;
11048 
11049  explicit const_iterator(const std::string &string, EndTag)
11050  : m_string(&string), m_it(string.end()) {}
11051 
11052  void tryParseAnsiEscapes();
11053  void advance();
11054  void unadvance();
11055 
11056  public:
11057  using difference_type = std::ptrdiff_t;
11058  using value_type = char;
11059  using pointer = value_type *;
11060  using reference = value_type &;
11061  using iterator_category = std::bidirectional_iterator_tag;
11062 
11063  explicit const_iterator(const std::string &string)
11064  : m_string(&string), m_it(string.begin()) {
11065  tryParseAnsiEscapes();
11066  }
11067 
11068  char operator*() const { return *m_it; }
11069 
11070  const_iterator &operator++() {
11071  advance();
11072  return *this;
11073  }
11074  const_iterator operator++(int) {
11075  iterator prev(*this);
11076  operator++();
11077  return prev;
11078  }
11079  const_iterator &operator--() {
11080  unadvance();
11081  return *this;
11082  }
11083  const_iterator operator--(int) {
11084  iterator prev(*this);
11085  operator--();
11086  return prev;
11087  }
11088 
11089  bool operator==(const_iterator const &other) const {
11090  return m_it == other.m_it;
11091  }
11092  bool operator!=(const_iterator const &other) const {
11093  return !operator==(other);
11094  }
11095  bool operator<=(const_iterator const &other) const {
11096  return m_it <= other.m_it;
11097  }
11098 
11099  const_iterator oneBefore() const {
11100  auto it = *this;
11101  return --it;
11102  }
11103  };
11104 
11112  class Column {
11113  // String to be written out
11114  AnsiSkippingString m_string;
11115  // Width of the column for linebreaking
11116  size_t m_width = CATCH_CONFIG_CONSOLE_WIDTH - 1;
11117  // Indentation of other lines (including first if initial indent is
11118  // unset)
11119  size_t m_indent = 0;
11120  // Indentation of the first line
11121  size_t m_initialIndent = std::string::npos;
11122 
11123  public:
11127  class const_iterator {
11128  friend Column;
11129  struct EndTag {};
11130 
11131  Column const &m_column;
11132  // Where does the current line start?
11133  AnsiSkippingString::const_iterator m_lineStart;
11134  // How long should the current line be?
11135  AnsiSkippingString::const_iterator m_lineEnd;
11136  // How far have we checked the string to iterate?
11137  AnsiSkippingString::const_iterator m_parsedTo;
11138  // Should a '-' be appended to the line?
11139  bool m_addHyphen = false;
11140 
11141  const_iterator(Column const &column, EndTag)
11142  : m_column(column), m_lineStart(m_column.m_string.end()), m_lineEnd(column.m_string.end()), m_parsedTo(column.m_string.end()) {}
11143 
11144  // Calculates the length of the current line
11145  void calcLength();
11146 
11147  // Returns current indentation width
11148  size_t indentSize() const;
11149 
11150  // Creates an indented and (optionally) suffixed string from
11151  // current iterator position, indentation and length.
11152  std::string addIndentAndSuffix(
11153  AnsiSkippingString::const_iterator start,
11154  AnsiSkippingString::const_iterator end) const;
11155 
11156  public:
11157  using difference_type = std::ptrdiff_t;
11158  using value_type = std::string;
11159  using pointer = value_type *;
11160  using reference = value_type &;
11161  using iterator_category = std::forward_iterator_tag;
11162 
11163  explicit const_iterator(Column const &column);
11164 
11165  std::string operator*() const;
11166 
11167  const_iterator &operator++();
11168  const_iterator operator++(int);
11169 
11170  bool operator==(const_iterator const &other) const {
11171  return m_lineStart == other.m_lineStart && &m_column == &other.m_column;
11172  }
11173  bool operator!=(const_iterator const &other) const {
11174  return !operator==(other);
11175  }
11176  };
11177  using iterator = const_iterator;
11178 
11179  explicit Column(std::string const &text)
11180  : m_string(text) {}
11181  explicit Column(std::string &&text)
11182  : m_string(CATCH_MOVE(text)) {}
11183 
11184  Column &width(size_t newWidth) & {
11185  assert(newWidth > 0);
11186  m_width = newWidth;
11187  return *this;
11188  }
11189  Column &&width(size_t newWidth) && {
11190  assert(newWidth > 0);
11191  m_width = newWidth;
11192  return CATCH_MOVE(*this);
11193  }
11194  Column &indent(size_t newIndent) & {
11195  m_indent = newIndent;
11196  return *this;
11197  }
11198  Column &&indent(size_t newIndent) && {
11199  m_indent = newIndent;
11200  return CATCH_MOVE(*this);
11201  }
11202  Column &initialIndent(size_t newIndent) & {
11203  m_initialIndent = newIndent;
11204  return *this;
11205  }
11206  Column &&initialIndent(size_t newIndent) && {
11207  m_initialIndent = newIndent;
11208  return CATCH_MOVE(*this);
11209  }
11210 
11211  size_t width() const { return m_width; }
11212  const_iterator begin() const { return const_iterator(*this); }
11213  const_iterator end() const {
11214  return {*this, const_iterator::EndTag{}};
11215  }
11216 
11217  friend std::ostream &operator<<(std::ostream &os,
11218  Column const &col);
11219 
11220  friend Columns operator+(Column const &lhs, Column const &rhs);
11221  friend Columns operator+(Column &&lhs, Column &&rhs);
11222  };
11223 
11225  Column Spacer(size_t spaceWidth);
11226 
11227  class Columns {
11228  std::vector<Column> m_columns;
11229 
11230  public:
11231  class iterator {
11232  friend Columns;
11233  struct EndTag {};
11234 
11235  std::vector<Column> const &m_columns;
11236  std::vector<Column::const_iterator> m_iterators;
11237  size_t m_activeIterators;
11238 
11239  iterator(Columns const &columns, EndTag);
11240 
11241  public:
11242  using difference_type = std::ptrdiff_t;
11243  using value_type = std::string;
11244  using pointer = value_type *;
11245  using reference = value_type &;
11246  using iterator_category = std::forward_iterator_tag;
11247 
11248  explicit iterator(Columns const &columns);
11249 
11250  auto operator==(iterator const &other) const -> bool {
11251  return m_iterators == other.m_iterators;
11252  }
11253  auto operator!=(iterator const &other) const -> bool {
11254  return m_iterators != other.m_iterators;
11255  }
11256  std::string operator*() const;
11257  iterator &operator++();
11258  iterator operator++(int);
11259  };
11260  using const_iterator = iterator;
11261 
11262  iterator begin() const { return iterator(*this); }
11263  iterator end() const { return {*this, iterator::EndTag()}; }
11264 
11265  friend Columns &operator+=(Columns &lhs, Column const &rhs);
11266  friend Columns &operator+=(Columns &lhs, Column &&rhs);
11267  friend Columns operator+(Columns const &lhs, Column const &rhs);
11268  friend Columns operator+(Columns &&lhs, Column &&rhs);
11269 
11270  friend std::ostream &operator<<(std::ostream &os,
11271  Columns const &cols);
11272  };
11273 
11274  } // namespace TextFlow
11275 } // namespace Catch
11276 #endif // CATCH_TEXTFLOW_HPP_INCLUDED
11277 
11278 #ifndef CATCH_THREAD_LOCAL_HPP_INCLUDED
11279 #define CATCH_THREAD_LOCAL_HPP_INCLUDED
11280 
11281 #if defined(CATCH_CONFIG_THREAD_SAFE_ASSERTIONS)
11282 #define CATCH_INTERNAL_THREAD_LOCAL thread_local
11283 #else
11284 #define CATCH_INTERNAL_THREAD_LOCAL
11285 #endif
11286 
11287 #endif // CATCH_THREAD_LOCAL_HPP_INCLUDED
11288 
11289 #ifndef CATCH_TO_STRING_HPP_INCLUDED
11290 #define CATCH_TO_STRING_HPP_INCLUDED
11291 
11292 #include <string>
11293 
11294 namespace Catch {
11295  template<typename T>
11296  std::string to_string(T const &t) {
11297 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11298  return std::to_string(t);
11299 #else
11301  rss << t;
11302  return rss.str();
11303 #endif
11304  }
11305 } // end namespace Catch
11306 
11307 #endif // CATCH_TO_STRING_HPP_INCLUDED
11308 
11309 #ifndef CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
11310 #define CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
11311 
11312 namespace Catch {
11313  bool uncaught_exceptions();
11314 } // end namespace Catch
11315 
11316 #endif // CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
11317 
11318 #ifndef CATCH_XMLWRITER_HPP_INCLUDED
11319 #define CATCH_XMLWRITER_HPP_INCLUDED
11320 
11321 #include <cstdint>
11322 #include <iosfwd>
11323 #include <vector>
11324 
11325 namespace Catch {
11326  enum class XmlFormatting : std::uint8_t {
11327  None = 0x00,
11328  Indent = 0x01,
11329  Newline = 0x02,
11330  };
11331 
11332  constexpr XmlFormatting operator|(XmlFormatting lhs, XmlFormatting rhs) {
11333  return static_cast<XmlFormatting>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
11334  }
11335 
11336  constexpr XmlFormatting operator&(XmlFormatting lhs, XmlFormatting rhs) {
11337  return static_cast<XmlFormatting>(static_cast<std::uint8_t>(lhs) & static_cast<std::uint8_t>(rhs));
11338  }
11339 
11346  class XmlEncode {
11347  public:
11348  enum ForWhat { ForTextNodes,
11349  ForAttributes };
11350 
11351  constexpr XmlEncode(StringRef str CATCH_ATTR_LIFETIMEBOUND, ForWhat forWhat = ForTextNodes)
11352  : m_str(str), m_forWhat(forWhat) {}
11353 
11354  void encodeTo(std::ostream &os) const;
11355 
11356  friend std::ostream &operator<<(std::ostream &os, XmlEncode const &xmlEncode);
11357 
11358  private:
11359  StringRef m_str;
11360  ForWhat m_forWhat;
11361  };
11362 
11363  class XmlWriter {
11364  public:
11365  class ScopedElement {
11366  public:
11367  ScopedElement(XmlWriter *writer CATCH_ATTR_LIFETIMEBOUND, XmlFormatting fmt);
11368 
11369  ScopedElement(ScopedElement &&other) noexcept;
11370  ScopedElement &operator=(ScopedElement &&other) noexcept;
11371 
11372  ~ScopedElement();
11373 
11374  ScopedElement &
11375  writeText(StringRef text,
11376  XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11377 
11378  ScopedElement &writeAttribute(StringRef name,
11379  StringRef attribute);
11380  template<typename T,
11381  // Without this SFINAE, this overload is a better match
11382  // for `std::string`, `char const*`, `char const[N]` args.
11383  // While it would still work, it would cause code bloat
11384  // and multiple iteration over the strings
11385  typename = typename std::enable_if_t<
11386  !std::is_convertible<T, StringRef>::value>>
11387  ScopedElement &writeAttribute(StringRef name,
11388  T const &attribute) {
11389  m_writer->writeAttribute(name, attribute);
11390  return *this;
11391  }
11392 
11393  private:
11394  XmlWriter *m_writer = nullptr;
11395  XmlFormatting m_fmt;
11396  };
11397 
11398  XmlWriter(std::ostream &os CATCH_ATTR_LIFETIMEBOUND);
11399  ~XmlWriter();
11400 
11401  XmlWriter(XmlWriter const &) = delete;
11402  XmlWriter &operator=(XmlWriter const &) = delete;
11403 
11404  XmlWriter &startElement(std::string const &name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11405 
11406  ScopedElement scopedElement(std::string const &name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11407 
11408  XmlWriter &endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11409 
11411  XmlWriter &writeAttribute(StringRef name, StringRef attribute);
11412 
11414  XmlWriter &writeAttribute(StringRef name, bool attribute);
11415 
11417  XmlWriter &writeAttribute(StringRef name, char const *attribute);
11418 
11421  template<typename T,
11422  // Without this SFINAE, this overload is a better match
11423  // for `std::string`, `char const*`, `char const[N]` args.
11424  // While it would still work, it would cause code bloat
11425  // and multiple iteration over the strings
11426  typename = typename std::enable_if_t<
11427  !std::is_convertible<T, StringRef>::value>>
11428  XmlWriter &writeAttribute(StringRef name, T const &attribute) {
11430  rss << attribute;
11431  return writeAttribute(name, rss.str());
11432  }
11433 
11435  XmlWriter &writeText(StringRef text,
11436  XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11437 
11439  XmlWriter &writeComment(StringRef text,
11440  XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11441 
11442  void writeStylesheetRef(StringRef url);
11443 
11444  void ensureTagClosed();
11445 
11446  private:
11447  void applyFormatting(XmlFormatting fmt);
11448 
11449  void writeDeclaration();
11450 
11451  void newlineIfNecessary();
11452 
11453  bool m_tagIsOpen = false;
11454  bool m_needsNewline = false;
11455  std::vector<std::string> m_tags;
11456  std::string m_indent;
11457  std::ostream &m_os;
11458  };
11459 
11460 } // namespace Catch
11461 
11462 #endif // CATCH_XMLWRITER_HPP_INCLUDED
11463 
11476 #ifndef CATCH_MATCHERS_ALL_HPP_INCLUDED
11477 #define CATCH_MATCHERS_ALL_HPP_INCLUDED
11478 
11479 #ifndef CATCH_MATCHERS_HPP_INCLUDED
11480 #define CATCH_MATCHERS_HPP_INCLUDED
11481 
11482 #ifndef CATCH_MATCHERS_IMPL_HPP_INCLUDED
11483 #define CATCH_MATCHERS_IMPL_HPP_INCLUDED
11484 
11485 #include <string>
11486 
11487 namespace Catch {
11488 
11489 #ifdef __clang__
11490 #pragma clang diagnostic push
11491 #pragma clang diagnostic ignored "-Wsign-compare"
11492 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
11493 #elif defined __GNUC__
11494 #pragma GCC diagnostic push
11495 #pragma GCC diagnostic ignored "-Wsign-compare"
11496 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
11497 #endif
11498 
11499  template<typename ArgT, typename MatcherT>
11500  class MatchExpr : public ITransientExpression {
11501  ArgT &&m_arg;
11502  MatcherT const &m_matcher;
11503 
11504  public:
11505  constexpr MatchExpr(ArgT &&arg, MatcherT const &matcher)
11506  : ITransientExpression{true, matcher.match(arg)}, // not forwarding arg here on purpose
11507  m_arg(CATCH_FORWARD(arg))
11508  , m_matcher(matcher) {}
11509 
11510  void streamReconstructedExpression(std::ostream &os) const override {
11511  os << Catch::Detail::stringify(m_arg)
11512  << ' '
11513  << m_matcher.toString();
11514  }
11515  };
11516 
11517 #ifdef __clang__
11518 #pragma clang diagnostic pop
11519 #elif defined __GNUC__
11520 #pragma GCC diagnostic pop
11521 #endif
11522 
11523  namespace Matchers {
11524  template<typename ArgT>
11525  class MatcherBase;
11526  }
11527 
11528  using StringMatcher = Matchers::MatcherBase<std::string>;
11529 
11530  void handleExceptionMatchExpr(AssertionHandler &handler, StringMatcher const &matcher);
11531 
11532  template<typename ArgT, typename MatcherT>
11533  constexpr MatchExpr<ArgT, MatcherT>
11534  makeMatchExpr(ArgT &&arg, MatcherT const &matcher) {
11535  return MatchExpr<ArgT, MatcherT>(CATCH_FORWARD(arg), matcher);
11536  }
11537 
11538 } // namespace Catch
11539 
11541 #define INTERNAL_CHECK_THAT(macroName, matcher, resultDisposition, arg) \
11542  do { \
11543  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition); \
11544  INTERNAL_CATCH_TRY { \
11545  catchAssertionHandler.handleExpr(Catch::makeMatchExpr(arg, matcher)); \
11546  } \
11547  INTERNAL_CATCH_CATCH(catchAssertionHandler) \
11548  catchAssertionHandler.complete(); \
11549  } while (false)
11550 
11552 #define INTERNAL_CATCH_THROWS_MATCHES(macroName, exceptionType, resultDisposition, matcher, ...) \
11553  do { \
11554  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition); \
11555  if (catchAssertionHandler.allowThrows()) \
11556  try { \
11557  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
11558  CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
11559  static_cast<void>(__VA_ARGS__); \
11560  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
11561  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
11562  } catch (exceptionType const &ex) { \
11563  catchAssertionHandler.handleExpr(Catch::makeMatchExpr(ex, matcher)); \
11564  } catch (...) { \
11565  catchAssertionHandler.handleUnexpectedInflightException(); \
11566  } \
11567  else \
11568  catchAssertionHandler.handleThrowingCallSkipped(); \
11569  catchAssertionHandler.complete(); \
11570  } while (false)
11571 
11572 #endif // CATCH_MATCHERS_IMPL_HPP_INCLUDED
11573 
11574 #include <string>
11575 #include <vector>
11576 
11577 namespace Catch {
11578  namespace Matchers {
11579 
11580  class MatcherUntypedBase {
11581  public:
11582  MatcherUntypedBase() = default;
11583 
11584  MatcherUntypedBase(MatcherUntypedBase const &) = default;
11585  MatcherUntypedBase(MatcherUntypedBase &&) = default;
11586 
11587  MatcherUntypedBase &operator=(MatcherUntypedBase const &) = delete;
11588  MatcherUntypedBase &operator=(MatcherUntypedBase &&) = delete;
11589 
11590  std::string toString() const;
11591 
11592  protected:
11593  virtual ~MatcherUntypedBase(); // = default;
11594  virtual std::string describe() const = 0;
11595  mutable std::string m_cachedToString;
11596  };
11597 
11598  template<typename T>
11599  class MatcherBase : public MatcherUntypedBase {
11600  public:
11601  virtual bool match(T const &arg) const = 0;
11602  };
11603 
11604  namespace Detail {
11605 
11606  template<typename ArgT>
11607  class MatchAllOf final : public MatcherBase<ArgT> {
11608  std::vector<MatcherBase<ArgT> const *> m_matchers;
11609 
11610  public:
11611  MatchAllOf() = default;
11612  MatchAllOf(MatchAllOf const &) = delete;
11613  MatchAllOf &operator=(MatchAllOf const &) = delete;
11614  MatchAllOf(MatchAllOf &&) = default;
11615  MatchAllOf &operator=(MatchAllOf &&) = default;
11616 
11617  bool match(ArgT const &arg) const override {
11618  for (auto matcher : m_matchers) {
11619  if (!matcher->match(arg))
11620  return false;
11621  }
11622  return true;
11623  }
11624  std::string describe() const override {
11625  std::string description;
11626  description.reserve(4 + m_matchers.size() * 32);
11627  description += "( ";
11628  bool first = true;
11629  for (auto matcher : m_matchers) {
11630  if (first)
11631  first = false;
11632  else
11633  description += " and ";
11634  description += matcher->toString();
11635  }
11636  description += " )";
11637  return description;
11638  }
11639 
11640  friend MatchAllOf operator&&(MatchAllOf &&lhs,
11641  MatcherBase<ArgT> const &rhs
11642  CATCH_ATTR_LIFETIMEBOUND) {
11643  lhs.m_matchers.push_back(&rhs);
11644  return CATCH_MOVE(lhs);
11645  }
11646  friend MatchAllOf
11647  operator&&(MatcherBase<ArgT> const &lhs CATCH_ATTR_LIFETIMEBOUND,
11648  MatchAllOf &&rhs) {
11649  rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
11650  return CATCH_MOVE(rhs);
11651  }
11652  };
11653 
11656  template<typename ArgT>
11657  MatchAllOf<ArgT> operator&&(MatchAllOf<ArgT> const &lhs, MatcherBase<ArgT> const &rhs) = delete;
11660  template<typename ArgT>
11661  MatchAllOf<ArgT> operator&&(MatcherBase<ArgT> const &lhs, MatchAllOf<ArgT> const &rhs) = delete;
11662 
11663  template<typename ArgT>
11664  class MatchAnyOf final : public MatcherBase<ArgT> {
11665  std::vector<MatcherBase<ArgT> const *> m_matchers;
11666 
11667  public:
11668  MatchAnyOf() = default;
11669  MatchAnyOf(MatchAnyOf const &) = delete;
11670  MatchAnyOf &operator=(MatchAnyOf const &) = delete;
11671  MatchAnyOf(MatchAnyOf &&) = default;
11672  MatchAnyOf &operator=(MatchAnyOf &&) = default;
11673 
11674  bool match(ArgT const &arg) const override {
11675  for (auto matcher : m_matchers) {
11676  if (matcher->match(arg))
11677  return true;
11678  }
11679  return false;
11680  }
11681  std::string describe() const override {
11682  std::string description;
11683  description.reserve(4 + m_matchers.size() * 32);
11684  description += "( ";
11685  bool first = true;
11686  for (auto matcher : m_matchers) {
11687  if (first)
11688  first = false;
11689  else
11690  description += " or ";
11691  description += matcher->toString();
11692  }
11693  description += " )";
11694  return description;
11695  }
11696 
11697  friend MatchAnyOf operator||(MatchAnyOf &&lhs,
11698  MatcherBase<ArgT> const &rhs
11699  CATCH_ATTR_LIFETIMEBOUND) {
11700  lhs.m_matchers.push_back(&rhs);
11701  return CATCH_MOVE(lhs);
11702  }
11703  friend MatchAnyOf
11704  operator||(MatcherBase<ArgT> const &lhs CATCH_ATTR_LIFETIMEBOUND,
11705  MatchAnyOf &&rhs) {
11706  rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
11707  return CATCH_MOVE(rhs);
11708  }
11709  };
11710 
11713  template<typename ArgT>
11714  MatchAnyOf<ArgT> operator||(MatchAnyOf<ArgT> const &lhs, MatcherBase<ArgT> const &rhs) = delete;
11717  template<typename ArgT>
11718  MatchAnyOf<ArgT> operator||(MatcherBase<ArgT> const &lhs, MatchAnyOf<ArgT> const &rhs) = delete;
11719 
11720  template<typename ArgT>
11721  class MatchNotOf final : public MatcherBase<ArgT> {
11722  MatcherBase<ArgT> const &m_underlyingMatcher;
11723 
11724  public:
11725  explicit MatchNotOf(MatcherBase<ArgT> const &underlyingMatcher
11726  CATCH_ATTR_LIFETIMEBOUND)
11727  : m_underlyingMatcher(underlyingMatcher) {}
11728 
11729  bool match(ArgT const &arg) const override {
11730  return !m_underlyingMatcher.match(arg);
11731  }
11732 
11733  std::string describe() const override {
11734  return "not " + m_underlyingMatcher.toString();
11735  }
11736  };
11737 
11738  } // namespace Detail
11739 
11740  template<typename T>
11741  Detail::MatchAllOf<T>
11742  operator&&(MatcherBase<T> const &lhs CATCH_ATTR_LIFETIMEBOUND,
11743  MatcherBase<T> const &rhs CATCH_ATTR_LIFETIMEBOUND) {
11744  return Detail::MatchAllOf<T>{} && lhs && rhs;
11745  }
11746 
11747  template<typename T>
11748  Detail::MatchAnyOf<T>
11749  operator||(MatcherBase<T> const &lhs CATCH_ATTR_LIFETIMEBOUND,
11750  MatcherBase<T> const &rhs CATCH_ATTR_LIFETIMEBOUND) {
11751  return Detail::MatchAnyOf<T>{} || lhs || rhs;
11752  }
11753 
11754  template<typename T>
11755  Detail::MatchNotOf<T>
11756  operator!(MatcherBase<T> const &matcher CATCH_ATTR_LIFETIMEBOUND) {
11757  return Detail::MatchNotOf<T>{matcher};
11758  }
11759 
11760  } // namespace Matchers
11761 } // namespace Catch
11762 
11763 #if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
11764 #define CATCH_REQUIRE_THROWS_WITH(expr, matcher) INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr)
11765 #define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) INTERNAL_CATCH_THROWS_MATCHES("CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr)
11766 
11767 #define CATCH_CHECK_THROWS_WITH(expr, matcher) INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
11768 #define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) INTERNAL_CATCH_THROWS_MATCHES("CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
11769 
11770 #define CATCH_CHECK_THAT(arg, matcher) INTERNAL_CHECK_THAT("CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg)
11771 #define CATCH_REQUIRE_THAT(arg, matcher) INTERNAL_CHECK_THAT("CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg)
11772 
11773 #elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
11774 
11775 #define CATCH_REQUIRE_THROWS_WITH(expr, matcher) (void)(0)
11776 #define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
11777 
11778 #define CATCH_CHECK_THROWS_WITH(expr, matcher) (void)(0)
11779 #define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
11780 
11781 #define CATCH_CHECK_THAT(arg, matcher) (void)(0)
11782 #define CATCH_REQUIRE_THAT(arg, matcher) (void)(0)
11783 
11784 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
11785 
11786 #define REQUIRE_THROWS_WITH(expr, matcher) INTERNAL_CATCH_THROWS_STR_MATCHES("REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr)
11787 #define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) INTERNAL_CATCH_THROWS_MATCHES("REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr)
11788 
11789 #define CHECK_THROWS_WITH(expr, matcher) INTERNAL_CATCH_THROWS_STR_MATCHES("CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
11790 #define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) INTERNAL_CATCH_THROWS_MATCHES("CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
11791 
11792 #define CHECK_THAT(arg, matcher) INTERNAL_CHECK_THAT("CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg)
11793 #define REQUIRE_THAT(arg, matcher) INTERNAL_CHECK_THAT("REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg)
11794 
11795 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
11796 
11797 #define REQUIRE_THROWS_WITH(expr, matcher) (void)(0)
11798 #define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
11799 
11800 #define CHECK_THROWS_WITH(expr, matcher) (void)(0)
11801 #define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
11802 
11803 #define CHECK_THAT(arg, matcher) (void)(0)
11804 #define REQUIRE_THAT(arg, matcher) (void)(0)
11805 
11806 #endif // end of user facing macro declarations
11807 
11808 #endif // CATCH_MATCHERS_HPP_INCLUDED
11809 
11810 #ifndef CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
11811 #define CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
11812 
11813 #ifndef CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
11814 #define CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
11815 
11816 #include <algorithm>
11817 #include <array>
11818 #include <string>
11819 #include <type_traits>
11820 
11821 namespace Catch {
11822  namespace Matchers {
11823  class MatcherGenericBase : public MatcherUntypedBase {
11824  public:
11825  MatcherGenericBase() = default;
11826  ~MatcherGenericBase() override; // = default;
11827 
11828  MatcherGenericBase(MatcherGenericBase const &) = default;
11829  MatcherGenericBase(MatcherGenericBase &&) = default;
11830 
11831  MatcherGenericBase &operator=(MatcherGenericBase const &) = delete;
11832  MatcherGenericBase &operator=(MatcherGenericBase &&) = delete;
11833  };
11834 
11835  namespace Detail {
11836  template<std::size_t N, std::size_t M>
11837  std::array<void const *, N + M> array_cat(std::array<void const *, N> &&lhs, std::array<void const *, M> &&rhs) {
11838  std::array<void const *, N + M> arr{};
11839  std::copy_n(lhs.begin(), N, arr.begin());
11840  std::copy_n(rhs.begin(), M, arr.begin() + N);
11841  return arr;
11842  }
11843 
11844  template<std::size_t N>
11845  std::array<void const *, N + 1> array_cat(std::array<void const *, N> &&lhs, void const *rhs) {
11846  std::array<void const *, N + 1> arr{};
11847  std::copy_n(lhs.begin(), N, arr.begin());
11848  arr[N] = rhs;
11849  return arr;
11850  }
11851 
11852  template<std::size_t N>
11853  std::array<void const *, N + 1> array_cat(void const *lhs, std::array<void const *, N> &&rhs) {
11854  std::array<void const *, N + 1> arr{{lhs}};
11855  std::copy_n(rhs.begin(), N, arr.begin() + 1);
11856  return arr;
11857  }
11858 
11859  template<typename T>
11860  static constexpr bool is_generic_matcher_v = std::is_base_of<
11861  Catch::Matchers::MatcherGenericBase,
11862  std::remove_cv_t<std::remove_reference_t<T>>>::value;
11863 
11864  template<typename... Ts>
11865  static constexpr bool are_generic_matchers_v = Catch::Detail::conjunction<std::integral_constant<bool, is_generic_matcher_v<Ts>>...>::value;
11866 
11867  template<typename T>
11868  static constexpr bool is_matcher_v = std::is_base_of<
11869  Catch::Matchers::MatcherUntypedBase,
11870  std::remove_cv_t<std::remove_reference_t<T>>>::value;
11871 
11872  template<std::size_t N, typename Arg>
11873  bool match_all_of(Arg &&, std::array<void const *, N> const &, std::index_sequence<>) {
11874  return true;
11875  }
11876 
11877  template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
11878  bool match_all_of(Arg &&arg, std::array<void const *, N> const &matchers, std::index_sequence<Idx, Indices...>) {
11879  return static_cast<T const *>(matchers[Idx])->match(arg) && match_all_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
11880  }
11881 
11882  template<std::size_t N, typename Arg>
11883  bool match_any_of(Arg &&, std::array<void const *, N> const &, std::index_sequence<>) {
11884  return false;
11885  }
11886 
11887  template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
11888  bool match_any_of(Arg &&arg, std::array<void const *, N> const &matchers, std::index_sequence<Idx, Indices...>) {
11889  return static_cast<T const *>(matchers[Idx])->match(arg) || match_any_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
11890  }
11891 
11892  std::string describe_multi_matcher(StringRef combine, std::string const *descriptions_begin, std::string const *descriptions_end);
11893 
11894  template<typename... MatcherTs, std::size_t... Idx>
11895  std::string describe_multi_matcher(StringRef combine, std::array<void const *, sizeof...(MatcherTs)> const &matchers, std::index_sequence<Idx...>) {
11896  std::array<std::string, sizeof...(MatcherTs)> descriptions{{static_cast<MatcherTs const *>(matchers[Idx])->toString()...}};
11897 
11898  return describe_multi_matcher(combine, descriptions.data(), descriptions.data() + descriptions.size());
11899  }
11900 
11901  template<typename... MatcherTs>
11902  class MatchAllOfGeneric final : public MatcherGenericBase {
11903  public:
11904  MatchAllOfGeneric(MatchAllOfGeneric const &) = delete;
11905  MatchAllOfGeneric &operator=(MatchAllOfGeneric const &) = delete;
11906  MatchAllOfGeneric(MatchAllOfGeneric &&) = default;
11907  MatchAllOfGeneric &operator=(MatchAllOfGeneric &&) = default;
11908 
11909  MatchAllOfGeneric(MatcherTs const &...matchers CATCH_ATTR_LIFETIMEBOUND)
11910  : m_matchers{{std::addressof(matchers)...}} {}
11911  explicit MatchAllOfGeneric(std::array<void const *, sizeof...(MatcherTs)> matchers)
11912  : m_matchers{matchers} {}
11913 
11914  template<typename Arg>
11915  bool match(Arg &&arg) const {
11916  return match_all_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
11917  }
11918 
11919  std::string describe() const override {
11920  return describe_multi_matcher<MatcherTs...>(" and "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
11921  }
11922 
11923  // Has to be public to enable the concatenating operators
11924  // below, because they are not friend of the RHS, only LHS,
11925  // and thus cannot access private fields of RHS
11926  std::array<void const *, sizeof...(MatcherTs)> m_matchers;
11927 
11929  template<typename... MatchersRHS>
11930  friend MatchAllOfGeneric<MatcherTs..., MatchersRHS...> operator&&(
11931  MatchAllOfGeneric<MatcherTs...> &&lhs CATCH_ATTR_LIFETIMEBOUND,
11932  MatchAllOfGeneric<MatchersRHS...> &&rhs CATCH_ATTR_LIFETIMEBOUND) {
11933  return MatchAllOfGeneric<MatcherTs..., MatchersRHS...>{array_cat(CATCH_MOVE(lhs.m_matchers), CATCH_MOVE(rhs.m_matchers))};
11934  }
11935 
11937  template<typename MatcherRHS>
11938  friend std::enable_if_t<is_matcher_v<MatcherRHS>,
11939  MatchAllOfGeneric<MatcherTs..., MatcherRHS>>
11940  operator&&(
11941  MatchAllOfGeneric<MatcherTs...> &&lhs CATCH_ATTR_LIFETIMEBOUND,
11942  MatcherRHS const &rhs CATCH_ATTR_LIFETIMEBOUND) {
11943  return MatchAllOfGeneric<MatcherTs..., MatcherRHS>{array_cat(CATCH_MOVE(lhs.m_matchers), static_cast<void const *>(&rhs))};
11944  }
11945 
11947  template<typename MatcherLHS>
11948  friend std::enable_if_t<is_matcher_v<MatcherLHS>,
11949  MatchAllOfGeneric<MatcherLHS, MatcherTs...>>
11950  operator&&(
11951  MatcherLHS const &lhs CATCH_ATTR_LIFETIMEBOUND,
11952  MatchAllOfGeneric<MatcherTs...> &&rhs CATCH_ATTR_LIFETIMEBOUND) {
11953  return MatchAllOfGeneric<MatcherLHS, MatcherTs...>{array_cat(static_cast<void const *>(std::addressof(lhs)), CATCH_MOVE(rhs.m_matchers))};
11954  }
11955  };
11956 
11957  template<typename... MatcherTs>
11958  class MatchAnyOfGeneric final : public MatcherGenericBase {
11959  public:
11960  MatchAnyOfGeneric(MatchAnyOfGeneric const &) = delete;
11961  MatchAnyOfGeneric &operator=(MatchAnyOfGeneric const &) = delete;
11962  MatchAnyOfGeneric(MatchAnyOfGeneric &&) = default;
11963  MatchAnyOfGeneric &operator=(MatchAnyOfGeneric &&) = default;
11964 
11965  MatchAnyOfGeneric(MatcherTs const &...matchers CATCH_ATTR_LIFETIMEBOUND)
11966  : m_matchers{{std::addressof(matchers)...}} {}
11967  explicit MatchAnyOfGeneric(std::array<void const *, sizeof...(MatcherTs)> matchers)
11968  : m_matchers{matchers} {}
11969 
11970  template<typename Arg>
11971  bool match(Arg &&arg) const {
11972  return match_any_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
11973  }
11974 
11975  std::string describe() const override {
11976  return describe_multi_matcher<MatcherTs...>(" or "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
11977  }
11978 
11979  // Has to be public to enable the concatenating operators
11980  // below, because they are not friend of the RHS, only LHS,
11981  // and thus cannot access private fields of RHS
11982  std::array<void const *, sizeof...(MatcherTs)> m_matchers;
11983 
11985  template<typename... MatchersRHS>
11986  friend MatchAnyOfGeneric<MatcherTs..., MatchersRHS...> operator||(
11987  MatchAnyOfGeneric<MatcherTs...> &&lhs CATCH_ATTR_LIFETIMEBOUND,
11988  MatchAnyOfGeneric<MatchersRHS...> &&rhs CATCH_ATTR_LIFETIMEBOUND) {
11989  return MatchAnyOfGeneric<MatcherTs..., MatchersRHS...>{array_cat(CATCH_MOVE(lhs.m_matchers), CATCH_MOVE(rhs.m_matchers))};
11990  }
11991 
11993  template<typename MatcherRHS>
11994  friend std::enable_if_t<is_matcher_v<MatcherRHS>,
11995  MatchAnyOfGeneric<MatcherTs..., MatcherRHS>>
11996  operator||(
11997  MatchAnyOfGeneric<MatcherTs...> &&lhs CATCH_ATTR_LIFETIMEBOUND,
11998  MatcherRHS const &rhs CATCH_ATTR_LIFETIMEBOUND) {
11999  return MatchAnyOfGeneric<MatcherTs..., MatcherRHS>{array_cat(CATCH_MOVE(lhs.m_matchers), static_cast<void const *>(std::addressof(rhs)))};
12000  }
12001 
12003  template<typename MatcherLHS>
12004  friend std::enable_if_t<is_matcher_v<MatcherLHS>,
12005  MatchAnyOfGeneric<MatcherLHS, MatcherTs...>>
12006  operator||(
12007  MatcherLHS const &lhs CATCH_ATTR_LIFETIMEBOUND,
12008  MatchAnyOfGeneric<MatcherTs...> &&rhs CATCH_ATTR_LIFETIMEBOUND) {
12009  return MatchAnyOfGeneric<MatcherLHS, MatcherTs...>{array_cat(static_cast<void const *>(std::addressof(lhs)), CATCH_MOVE(rhs.m_matchers))};
12010  }
12011  };
12012 
12013  template<typename MatcherT>
12014  class MatchNotOfGeneric final : public MatcherGenericBase {
12015  MatcherT const &m_matcher;
12016 
12017  public:
12018  MatchNotOfGeneric(MatchNotOfGeneric const &) = delete;
12019  MatchNotOfGeneric &operator=(MatchNotOfGeneric const &) = delete;
12020  MatchNotOfGeneric(MatchNotOfGeneric &&) = default;
12021  MatchNotOfGeneric &operator=(MatchNotOfGeneric &&) = default;
12022 
12023  explicit MatchNotOfGeneric(MatcherT const &matcher CATCH_ATTR_LIFETIMEBOUND)
12024  : m_matcher{matcher} {}
12025 
12026  template<typename Arg>
12027  bool match(Arg &&arg) const {
12028  return !m_matcher.match(arg);
12029  }
12030 
12031  std::string describe() const override {
12032  return "not " + m_matcher.toString();
12033  }
12034 
12036  friend MatcherT const &
12037  operator!(MatchNotOfGeneric<MatcherT> const &matcher
12038  CATCH_ATTR_LIFETIMEBOUND) {
12039  return matcher.m_matcher;
12040  }
12041  };
12042  } // namespace Detail
12043 
12044  // compose only generic matchers
12045  template<typename MatcherLHS, typename MatcherRHS>
12046  std::enable_if_t<Detail::are_generic_matchers_v<MatcherLHS, MatcherRHS>, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>
12047  operator&&(MatcherLHS const &lhs CATCH_ATTR_LIFETIMEBOUND,
12048  MatcherRHS const &rhs CATCH_ATTR_LIFETIMEBOUND) {
12049  return {lhs, rhs};
12050  }
12051 
12052  template<typename MatcherLHS, typename MatcherRHS>
12053  std::enable_if_t<Detail::are_generic_matchers_v<MatcherLHS, MatcherRHS>, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>
12054  operator||(MatcherLHS const &lhs CATCH_ATTR_LIFETIMEBOUND,
12055  MatcherRHS const &rhs CATCH_ATTR_LIFETIMEBOUND) {
12056  return {lhs, rhs};
12057  }
12058 
12060  template<typename MatcherT>
12061  std::enable_if_t<Detail::is_generic_matcher_v<MatcherT>, Detail::MatchNotOfGeneric<MatcherT>>
12062  operator!(MatcherT const &matcher CATCH_ATTR_LIFETIMEBOUND) {
12063  return Detail::MatchNotOfGeneric<MatcherT>{matcher};
12064  }
12065 
12066  // compose mixed generic and non-generic matchers
12067  template<typename MatcherLHS, typename ArgRHS>
12068  std::enable_if_t<Detail::is_generic_matcher_v<MatcherLHS>, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
12069  operator&&(MatcherLHS const &lhs CATCH_ATTR_LIFETIMEBOUND,
12070  MatcherBase<ArgRHS> const &rhs CATCH_ATTR_LIFETIMEBOUND) {
12071  return {lhs, rhs};
12072  }
12073 
12074  template<typename ArgLHS, typename MatcherRHS>
12075  std::enable_if_t<Detail::is_generic_matcher_v<MatcherRHS>, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
12076  operator&&(MatcherBase<ArgLHS> const &lhs CATCH_ATTR_LIFETIMEBOUND,
12077  MatcherRHS const &rhs CATCH_ATTR_LIFETIMEBOUND) {
12078  return {lhs, rhs};
12079  }
12080 
12081  template<typename MatcherLHS, typename ArgRHS>
12082  std::enable_if_t<Detail::is_generic_matcher_v<MatcherLHS>, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
12083  operator||(MatcherLHS const &lhs CATCH_ATTR_LIFETIMEBOUND,
12084  MatcherBase<ArgRHS> const &rhs CATCH_ATTR_LIFETIMEBOUND) {
12085  return {lhs, rhs};
12086  }
12087 
12088  template<typename ArgLHS, typename MatcherRHS>
12089  std::enable_if_t<Detail::is_generic_matcher_v<MatcherRHS>, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
12090  operator||(MatcherBase<ArgLHS> const &lhs CATCH_ATTR_LIFETIMEBOUND,
12091  MatcherRHS const &rhs CATCH_ATTR_LIFETIMEBOUND) {
12092  return {lhs, rhs};
12093  }
12094 
12095  } // namespace Matchers
12096 } // namespace Catch
12097 
12098 #endif // CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
12099 
12100 namespace Catch {
12101  namespace Matchers {
12102 
12103  class IsEmptyMatcher final : public MatcherGenericBase {
12104  public:
12105  template<typename RangeLike>
12106  bool match(RangeLike &&rng) const {
12107 #if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
12108  using Catch::Detail::empty;
12109 #else
12110  using std::empty;
12111 #endif
12112  return empty(rng);
12113  }
12114 
12115  std::string describe() const override;
12116  };
12117 
12118  class HasSizeMatcher final : public MatcherGenericBase {
12119  std::size_t m_target_size;
12120 
12121  public:
12122  explicit HasSizeMatcher(std::size_t target_size)
12123  : m_target_size(target_size) {}
12124 
12125  template<typename RangeLike>
12126  bool match(RangeLike &&rng) const {
12127 #if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
12128  using Catch::Detail::size;
12129 #else
12130  using std::size;
12131 #endif
12132  return size(rng) == m_target_size;
12133  }
12134 
12135  std::string describe() const override;
12136  };
12137 
12138  template<typename Matcher>
12139  class SizeMatchesMatcher final : public MatcherGenericBase {
12140  Matcher m_matcher;
12141 
12142  public:
12143  explicit SizeMatchesMatcher(Matcher m)
12144  : m_matcher(CATCH_MOVE(m)) {}
12145 
12146  template<typename RangeLike>
12147  bool match(RangeLike &&rng) const {
12148 #if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
12149  using Catch::Detail::size;
12150 #else
12151  using std::size;
12152 #endif
12153  return m_matcher.match(size(rng));
12154  }
12155 
12156  std::string describe() const override {
12157  return "size matches " + m_matcher.describe();
12158  }
12159  };
12160 
12162  IsEmptyMatcher IsEmpty();
12164  HasSizeMatcher SizeIs(std::size_t sz);
12165  template<typename Matcher>
12166  std::enable_if_t<Detail::is_matcher_v<Matcher>,
12167  SizeMatchesMatcher<Matcher>>
12168  SizeIs(Matcher &&m) {
12169  return SizeMatchesMatcher<Matcher>{CATCH_FORWARD(m)};
12170  }
12171 
12172  } // end namespace Matchers
12173 } // end namespace Catch
12174 
12175 #endif // CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
12176 
12177 #ifndef CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
12178 #define CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
12179 
12180 #include <functional>
12181 #include <type_traits>
12182 
12183 namespace Catch {
12184  namespace Matchers {
12186  template<typename T, typename Equality>
12187  class ContainsElementMatcher final : public MatcherGenericBase {
12188  T m_desired;
12189  Equality m_eq;
12190 
12191  public:
12192  template<typename T2, typename Equality2>
12193  ContainsElementMatcher(T2 &&target, Equality2 &&predicate)
12194  : m_desired(CATCH_FORWARD(target)), m_eq(CATCH_FORWARD(predicate)) {}
12195 
12196  std::string describe() const override {
12197  return "contains element " + Catch::Detail::stringify(m_desired);
12198  }
12199 
12200  template<typename RangeLike>
12201  bool match(RangeLike &&rng) const {
12202  for (auto &&elem : rng) {
12203  if (m_eq(elem, m_desired)) { return true; }
12204  }
12205  return false;
12206  }
12207  };
12208 
12210  template<typename Matcher>
12211  class ContainsMatcherMatcher final : public MatcherGenericBase {
12212  Matcher m_matcher;
12213 
12214  public:
12215  // Note that we do a copy+move to avoid having to SFINAE this
12216  // constructor (and also avoid some perfect forwarding failure
12217  // cases)
12218  ContainsMatcherMatcher(Matcher matcher)
12219  : m_matcher(CATCH_MOVE(matcher)) {}
12220 
12221  template<typename RangeLike>
12222  bool match(RangeLike &&rng) const {
12223  for (auto &&elem : rng) {
12224  if (m_matcher.match(elem)) {
12225  return true;
12226  }
12227  }
12228  return false;
12229  }
12230 
12231  std::string describe() const override {
12232  return "contains element matching " + m_matcher.describe();
12233  }
12234  };
12235 
12241  template<typename T>
12242  std::enable_if_t<!Detail::is_matcher_v<T>,
12243  ContainsElementMatcher<T, std::equal_to<>>>
12244  Contains(T &&elem) {
12245  return {CATCH_FORWARD(elem), std::equal_to<>{}};
12246  }
12247 
12249  template<typename Matcher>
12250  std::enable_if_t<Detail::is_matcher_v<Matcher>,
12251  ContainsMatcherMatcher<Matcher>>
12252  Contains(Matcher &&matcher) {
12253  return {CATCH_FORWARD(matcher)};
12254  }
12255 
12261  template<typename T, typename Equality>
12262  ContainsElementMatcher<T, Equality> Contains(T &&elem, Equality &&eq) {
12263  return {CATCH_FORWARD(elem), CATCH_FORWARD(eq)};
12264  }
12265 
12266  } // namespace Matchers
12267 } // namespace Catch
12268 
12269 #endif // CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
12270 
12271 #ifndef CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
12272 #define CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
12273 
12274 namespace Catch {
12275  namespace Matchers {
12276 
12277  class ExceptionMessageMatcher final : public MatcherBase<std::exception> {
12278  std::string m_message;
12279 
12280  public:
12281  ExceptionMessageMatcher(std::string const &message)
12282  : m_message(message) {}
12283 
12284  bool match(std::exception const &ex) const override;
12285 
12286  std::string describe() const override;
12287  };
12288 
12290  ExceptionMessageMatcher Message(std::string const &message);
12291 
12292  template<typename StringMatcherType>
12293  class ExceptionMessageMatchesMatcher final
12294  : public MatcherBase<std::exception> {
12295  StringMatcherType m_matcher;
12296 
12297  public:
12298  ExceptionMessageMatchesMatcher(StringMatcherType matcher)
12299  : m_matcher(CATCH_MOVE(matcher)) {}
12300 
12301  bool match(std::exception const &ex) const override {
12302  return m_matcher.match(ex.what());
12303  }
12304 
12305  std::string describe() const override {
12306  return " matches \"" + m_matcher.describe() + '"';
12307  }
12308  };
12309 
12312  template<typename StringMatcherType>
12313  ExceptionMessageMatchesMatcher<StringMatcherType>
12314  MessageMatches(StringMatcherType &&matcher) {
12315  return {CATCH_FORWARD(matcher)};
12316  }
12317 
12318  } // namespace Matchers
12319 } // namespace Catch
12320 
12321 #endif // CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
12322 
12323 #ifndef CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
12324 #define CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
12325 
12326 namespace Catch {
12327  namespace Matchers {
12328 
12329  namespace Detail {
12330  enum class FloatingPointKind : uint8_t;
12331  }
12332 
12333  class WithinAbsMatcher final : public MatcherBase<double> {
12334  public:
12335  WithinAbsMatcher(double target, double margin);
12336  bool match(double const &matchee) const override;
12337  std::string describe() const override;
12338 
12339  private:
12340  double m_target;
12341  double m_margin;
12342  };
12343 
12345  WithinAbsMatcher WithinAbs(double target, double margin);
12346 
12347  class WithinUlpsMatcher final : public MatcherBase<double> {
12348  public:
12349  WithinUlpsMatcher(double target,
12350  uint64_t ulps,
12351  Detail::FloatingPointKind baseType);
12352  bool match(double const &matchee) const override;
12353  std::string describe() const override;
12354 
12355  private:
12356  double m_target;
12357  uint64_t m_ulps;
12358  Detail::FloatingPointKind m_type;
12359  };
12360 
12362  WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
12364  WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
12365 
12366  // Given IEEE-754 format for floats and doubles, we can assume
12367  // that float -> double promotion is lossless. Given this, we can
12368  // assume that if we do the standard relative comparison of
12369  // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
12370  // the same result if we do this for floats, as if we do this for
12371  // doubles that were promoted from floats.
12372  class WithinRelMatcher final : public MatcherBase<double> {
12373  public:
12374  WithinRelMatcher(double target, double epsilon);
12375  bool match(double const &matchee) const override;
12376  std::string describe() const override;
12377 
12378  private:
12379  double m_target;
12380  double m_epsilon;
12381  };
12382 
12384  WithinRelMatcher WithinRel(double target, double eps);
12386  WithinRelMatcher WithinRel(double target);
12388  WithinRelMatcher WithinRel(float target, float eps);
12390  WithinRelMatcher WithinRel(float target);
12391 
12392  class IsNaNMatcher final : public MatcherBase<double> {
12393  public:
12394  IsNaNMatcher() = default;
12395  bool match(double const &matchee) const override;
12396  std::string describe() const override;
12397  };
12398 
12399  IsNaNMatcher IsNaN();
12400 
12401  } // namespace Matchers
12402 } // namespace Catch
12403 
12404 #endif // CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
12405 
12406 #ifndef CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
12407 #define CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
12408 
12409 #include <string>
12410 
12411 namespace Catch {
12412  namespace Matchers {
12413 
12414  namespace Detail {
12415  std::string finalizeDescription(const std::string &desc);
12416  } // namespace Detail
12417 
12418  template<typename T, typename Predicate>
12419  class PredicateMatcher final : public MatcherBase<T> {
12420  Predicate m_predicate;
12421  std::string m_description;
12422 
12423  public:
12424  PredicateMatcher(Predicate &&elem, std::string const &descr)
12425  : m_predicate(CATCH_FORWARD(elem)), m_description(Detail::finalizeDescription(descr)) {}
12426 
12427  bool match(T const &item) const override {
12428  return m_predicate(item);
12429  }
12430 
12431  std::string describe() const override {
12432  return m_description;
12433  }
12434  };
12435 
12441  template<typename T, typename Pred>
12442  PredicateMatcher<T, Pred> Predicate(Pred &&predicate, std::string const &description = "") {
12443  static_assert(is_callable<Pred(T)>::value, "Predicate not callable with argument T");
12444  static_assert(std::is_same<bool, FunctionReturnType<Pred, T>>::value, "Predicate does not return bool");
12445  return PredicateMatcher<T, Pred>(CATCH_FORWARD(predicate), description);
12446  }
12447 
12448  } // namespace Matchers
12449 } // namespace Catch
12450 
12451 #endif // CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
12452 
12453 #ifndef CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
12454 #define CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
12455 
12456 namespace Catch {
12457  namespace Matchers {
12458  // Matcher for checking that all elements in range matches a given matcher.
12459  template<typename Matcher>
12460  class AllMatchMatcher final : public MatcherGenericBase {
12461  Matcher m_matcher;
12462 
12463  public:
12464  AllMatchMatcher(Matcher matcher)
12465  : m_matcher(CATCH_MOVE(matcher)) {}
12466 
12467  std::string describe() const override {
12468  return "all match " + m_matcher.describe();
12469  }
12470 
12471  template<typename RangeLike>
12472  bool match(RangeLike &&rng) const {
12473  for (auto &&elem : rng) {
12474  if (!m_matcher.match(elem)) {
12475  return false;
12476  }
12477  }
12478  return true;
12479  }
12480  };
12481 
12482  // Matcher for checking that no element in range matches a given matcher.
12483  template<typename Matcher>
12484  class NoneMatchMatcher final : public MatcherGenericBase {
12485  Matcher m_matcher;
12486 
12487  public:
12488  NoneMatchMatcher(Matcher matcher)
12489  : m_matcher(CATCH_MOVE(matcher)) {}
12490 
12491  std::string describe() const override {
12492  return "none match " + m_matcher.describe();
12493  }
12494 
12495  template<typename RangeLike>
12496  bool match(RangeLike &&rng) const {
12497  for (auto &&elem : rng) {
12498  if (m_matcher.match(elem)) {
12499  return false;
12500  }
12501  }
12502  return true;
12503  }
12504  };
12505 
12506  // Matcher for checking that at least one element in range matches a given matcher.
12507  template<typename Matcher>
12508  class AnyMatchMatcher final : public MatcherGenericBase {
12509  Matcher m_matcher;
12510 
12511  public:
12512  AnyMatchMatcher(Matcher matcher)
12513  : m_matcher(CATCH_MOVE(matcher)) {}
12514 
12515  std::string describe() const override {
12516  return "any match " + m_matcher.describe();
12517  }
12518 
12519  template<typename RangeLike>
12520  bool match(RangeLike &&rng) const {
12521  for (auto &&elem : rng) {
12522  if (m_matcher.match(elem)) {
12523  return true;
12524  }
12525  }
12526  return false;
12527  }
12528  };
12529 
12530  // Matcher for checking that all elements in range are true.
12531  class AllTrueMatcher final : public MatcherGenericBase {
12532  public:
12533  std::string describe() const override;
12534 
12535  template<typename RangeLike>
12536  bool match(RangeLike &&rng) const {
12537  for (auto &&elem : rng) {
12538  if (!elem) {
12539  return false;
12540  }
12541  }
12542  return true;
12543  }
12544  };
12545 
12546  // Matcher for checking that no element in range is true.
12547  class NoneTrueMatcher final : public MatcherGenericBase {
12548  public:
12549  std::string describe() const override;
12550 
12551  template<typename RangeLike>
12552  bool match(RangeLike &&rng) const {
12553  for (auto &&elem : rng) {
12554  if (elem) {
12555  return false;
12556  }
12557  }
12558  return true;
12559  }
12560  };
12561 
12562  // Matcher for checking that any element in range is true.
12563  class AnyTrueMatcher final : public MatcherGenericBase {
12564  public:
12565  std::string describe() const override;
12566 
12567  template<typename RangeLike>
12568  bool match(RangeLike &&rng) const {
12569  for (auto &&elem : rng) {
12570  if (elem) {
12571  return true;
12572  }
12573  }
12574  return false;
12575  }
12576  };
12577 
12578  // Creates a matcher that checks whether all elements in a range match a matcher
12579  template<typename Matcher>
12580  AllMatchMatcher<Matcher> AllMatch(Matcher &&matcher) {
12581  return {CATCH_FORWARD(matcher)};
12582  }
12583 
12584  // Creates a matcher that checks whether no element in a range matches a matcher.
12585  template<typename Matcher>
12586  NoneMatchMatcher<Matcher> NoneMatch(Matcher &&matcher) {
12587  return {CATCH_FORWARD(matcher)};
12588  }
12589 
12590  // Creates a matcher that checks whether any element in a range matches a matcher.
12591  template<typename Matcher>
12592  AnyMatchMatcher<Matcher> AnyMatch(Matcher &&matcher) {
12593  return {CATCH_FORWARD(matcher)};
12594  }
12595 
12596  // Creates a matcher that checks whether all elements in a range are true
12597  AllTrueMatcher AllTrue();
12598 
12599  // Creates a matcher that checks whether no element in a range is true
12600  NoneTrueMatcher NoneTrue();
12601 
12602  // Creates a matcher that checks whether any element in a range is true
12603  AnyTrueMatcher AnyTrue();
12604  } // namespace Matchers
12605 } // namespace Catch
12606 
12607 #endif // CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
12608 
12609 #ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
12610 #define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
12611 
12612 #include <functional>
12613 
12614 namespace Catch {
12615  namespace Matchers {
12616 
12621  template<typename TargetRangeLike, typename Equality>
12622  class RangeEqualsMatcher final : public MatcherGenericBase {
12623  TargetRangeLike m_desired;
12624  Equality m_predicate;
12625 
12626  public:
12627  template<typename TargetRangeLike2, typename Equality2>
12628  constexpr RangeEqualsMatcher(TargetRangeLike2 &&range,
12629  Equality2 &&predicate)
12630  : m_desired(CATCH_FORWARD(range)), m_predicate(CATCH_FORWARD(predicate)) {}
12631 
12632  template<typename RangeLike>
12633  constexpr bool match(RangeLike &&rng) const {
12634  auto rng_start = begin(rng);
12635  const auto rng_end = end(rng);
12636  auto target_start = begin(m_desired);
12637  const auto target_end = end(m_desired);
12638 
12639  while (rng_start != rng_end && target_start != target_end) {
12640  if (!m_predicate(*rng_start, *target_start)) {
12641  return false;
12642  }
12643  ++rng_start;
12644  ++target_start;
12645  }
12646  return rng_start == rng_end && target_start == target_end;
12647  }
12648 
12649  std::string describe() const override {
12650  return "elements are " + Catch::Detail::stringify(m_desired);
12651  }
12652  };
12653 
12658  template<typename TargetRangeLike, typename Equality>
12659  class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
12660  TargetRangeLike m_desired;
12661  Equality m_predicate;
12662 
12663  public:
12664  template<typename TargetRangeLike2, typename Equality2>
12665  constexpr UnorderedRangeEqualsMatcher(TargetRangeLike2 &&range,
12666  Equality2 &&predicate)
12667  : m_desired(CATCH_FORWARD(range)), m_predicate(CATCH_FORWARD(predicate)) {}
12668 
12669  template<typename RangeLike>
12670  constexpr bool match(RangeLike &&rng) const {
12671  using std::begin;
12672  using std::end;
12673  return Catch::Detail::is_permutation(begin(m_desired),
12674  end(m_desired),
12675  begin(rng),
12676  end(rng),
12677  m_predicate);
12678  }
12679 
12680  std::string describe() const override {
12681  return "unordered elements are " + ::Catch::Detail::stringify(m_desired);
12682  }
12683  };
12684 
12692  template<typename RangeLike,
12693  typename Equality = decltype(std::equal_to<>{})>
12694  constexpr RangeEqualsMatcher<RangeLike, Equality>
12695  RangeEquals(RangeLike &&range,
12696  Equality &&predicate = std::equal_to<>{}) {
12697  return {CATCH_FORWARD(range), CATCH_FORWARD(predicate)};
12698  }
12699 
12707  template<typename T,
12708  typename Equality = decltype(std::equal_to<>{})>
12709  constexpr RangeEqualsMatcher<std::initializer_list<T>, Equality>
12710  RangeEquals(std::initializer_list<T> range,
12711  Equality &&predicate = std::equal_to<>{}) {
12712  return {range, CATCH_FORWARD(predicate)};
12713  }
12714 
12722  template<typename RangeLike,
12723  typename Equality = decltype(std::equal_to<>{})>
12724  constexpr UnorderedRangeEqualsMatcher<RangeLike, Equality>
12725  UnorderedRangeEquals(RangeLike &&range,
12726  Equality &&predicate = std::equal_to<>{}) {
12727  return {CATCH_FORWARD(range), CATCH_FORWARD(predicate)};
12728  }
12729 
12737  template<typename T,
12738  typename Equality = decltype(std::equal_to<>{})>
12739  constexpr UnorderedRangeEqualsMatcher<std::initializer_list<T>, Equality>
12740  UnorderedRangeEquals(std::initializer_list<T> range,
12741  Equality &&predicate = std::equal_to<>{}) {
12742  return {range, CATCH_FORWARD(predicate)};
12743  }
12744  } // namespace Matchers
12745 } // namespace Catch
12746 
12747 #endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
12748 
12749 #ifndef CATCH_MATCHERS_STRING_HPP_INCLUDED
12750 #define CATCH_MATCHERS_STRING_HPP_INCLUDED
12751 
12752 #include <string>
12753 
12754 namespace Catch {
12755  namespace Matchers {
12756 
12757  struct CasedString {
12758  CasedString(std::string const &str, CaseSensitive caseSensitivity);
12759  std::string adjustString(std::string const &str) const;
12760  StringRef caseSensitivitySuffix() const;
12761 
12762  CaseSensitive m_caseSensitivity;
12763  std::string m_str;
12764  };
12765 
12766  class StringMatcherBase : public MatcherBase<std::string> {
12767  protected:
12768  CasedString m_comparator;
12769  StringRef m_operation;
12770 
12771  public:
12772  StringMatcherBase(StringRef operation,
12773  CasedString const &comparator);
12774  std::string describe() const override;
12775  };
12776 
12777  class StringEqualsMatcher final : public StringMatcherBase {
12778  public:
12779  StringEqualsMatcher(CasedString const &comparator);
12780  bool match(std::string const &source) const override;
12781  };
12782  class StringContainsMatcher final : public StringMatcherBase {
12783  public:
12784  StringContainsMatcher(CasedString const &comparator);
12785  bool match(std::string const &source) const override;
12786  };
12787  class StartsWithMatcher final : public StringMatcherBase {
12788  public:
12789  StartsWithMatcher(CasedString const &comparator);
12790  bool match(std::string const &source) const override;
12791  };
12792  class EndsWithMatcher final : public StringMatcherBase {
12793  public:
12794  EndsWithMatcher(CasedString const &comparator);
12795  bool match(std::string const &source) const override;
12796  };
12797 
12798  class RegexMatcher final : public MatcherBase<std::string> {
12799  std::string m_regex;
12800  CaseSensitive m_caseSensitivity;
12801 
12802  public:
12803  RegexMatcher(std::string regex, CaseSensitive caseSensitivity);
12804  bool match(std::string const &matchee) const override;
12805  std::string describe() const override;
12806  };
12807 
12809  StringEqualsMatcher Equals(std::string const &str, CaseSensitive caseSensitivity = CaseSensitive::Yes);
12811  StringContainsMatcher ContainsSubstring(std::string const &str, CaseSensitive caseSensitivity = CaseSensitive::Yes);
12813  EndsWithMatcher EndsWith(std::string const &str, CaseSensitive caseSensitivity = CaseSensitive::Yes);
12815  StartsWithMatcher StartsWith(std::string const &str, CaseSensitive caseSensitivity = CaseSensitive::Yes);
12817  RegexMatcher Matches(std::string const &regex, CaseSensitive caseSensitivity = CaseSensitive::Yes);
12818 
12819  } // namespace Matchers
12820 } // namespace Catch
12821 
12822 #endif // CATCH_MATCHERS_STRING_HPP_INCLUDED
12823 
12824 #ifndef CATCH_MATCHERS_VECTOR_HPP_INCLUDED
12825 #define CATCH_MATCHERS_VECTOR_HPP_INCLUDED
12826 
12827 #include <algorithm>
12828 
12829 namespace Catch {
12830  namespace Matchers {
12831 
12832  template<typename T, typename Alloc>
12833  class VectorContainsElementMatcher final : public MatcherBase<std::vector<T, Alloc>> {
12834  T const &m_comparator;
12835 
12836  public:
12837  VectorContainsElementMatcher(T const &comparator)
12838  : m_comparator(comparator) {}
12839 
12840  bool match(std::vector<T, Alloc> const &v) const override {
12841  for (auto const &el : v) {
12842  if (el == m_comparator) {
12843  return true;
12844  }
12845  }
12846  return false;
12847  }
12848 
12849  std::string describe() const override {
12850  return "Contains: " + ::Catch::Detail::stringify(m_comparator);
12851  }
12852  };
12853 
12854  template<typename T, typename AllocComp, typename AllocMatch>
12855  class ContainsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12856  std::vector<T, AllocComp> const &m_comparator;
12857 
12858  public:
12859  ContainsMatcher(std::vector<T, AllocComp> const &comparator)
12860  : m_comparator(comparator) {}
12861 
12862  bool match(std::vector<T, AllocMatch> const &v) const override {
12863  // !TBD: see note in EqualsMatcher
12864  if (m_comparator.size() > v.size())
12865  return false;
12866  for (auto const &comparator : m_comparator) {
12867  auto present = false;
12868  for (const auto &el : v) {
12869  if (el == comparator) {
12870  present = true;
12871  break;
12872  }
12873  }
12874  if (!present) {
12875  return false;
12876  }
12877  }
12878  return true;
12879  }
12880  std::string describe() const override {
12881  return "Contains: " + ::Catch::Detail::stringify(m_comparator);
12882  }
12883  };
12884 
12885  template<typename T, typename AllocComp, typename AllocMatch>
12886  class EqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12887  std::vector<T, AllocComp> const &m_comparator;
12888 
12889  public:
12890  EqualsMatcher(std::vector<T, AllocComp> const &comparator)
12891  : m_comparator(comparator) {}
12892 
12893  bool match(std::vector<T, AllocMatch> const &v) const override {
12894  // !TBD: This currently works if all elements can be compared using !=
12895  // - a more general approach would be via a compare template that defaults
12896  // to using !=. but could be specialised for, e.g. std::vector<T> etc
12897  // - then just call that directly
12898  if (m_comparator.size() != v.size()) { return false; }
12899  for (std::size_t i = 0; i < v.size(); ++i) {
12900  if (!(m_comparator[i] == v[i])) { return false; }
12901  }
12902  return true;
12903  }
12904  std::string describe() const override {
12905  return "Equals: " + ::Catch::Detail::stringify(m_comparator);
12906  }
12907  };
12908 
12909  template<typename T, typename AllocComp, typename AllocMatch>
12910  class ApproxMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12911  std::vector<T, AllocComp> const &m_comparator;
12912  mutable Catch::Approx approx = Catch::Approx::custom();
12913 
12914  public:
12915  ApproxMatcher(std::vector<T, AllocComp> const &comparator)
12916  : m_comparator(comparator) {}
12917 
12918  bool match(std::vector<T, AllocMatch> const &v) const override {
12919  if (m_comparator.size() != v.size())
12920  return false;
12921  for (std::size_t i = 0; i < v.size(); ++i)
12922  if (m_comparator[i] != approx(v[i]))
12923  return false;
12924  return true;
12925  }
12926  std::string describe() const override {
12927  return "is approx: " + ::Catch::Detail::stringify(m_comparator);
12928  }
12929  template<typename = std::enable_if_t<std::is_constructible<double, T>::value>>
12930  ApproxMatcher &epsilon(T const &newEpsilon) {
12931  approx.epsilon(static_cast<double>(newEpsilon));
12932  return *this;
12933  }
12934  template<typename = std::enable_if_t<std::is_constructible<double, T>::value>>
12935  ApproxMatcher &margin(T const &newMargin) {
12936  approx.margin(static_cast<double>(newMargin));
12937  return *this;
12938  }
12939  template<typename = std::enable_if_t<std::is_constructible<double, T>::value>>
12940  ApproxMatcher &scale(T const &newScale) {
12941  approx.scale(static_cast<double>(newScale));
12942  return *this;
12943  }
12944  };
12945 
12946  template<typename T, typename AllocComp, typename AllocMatch>
12947  class UnorderedEqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12948  std::vector<T, AllocComp> const &m_target;
12949 
12950  public:
12951  UnorderedEqualsMatcher(std::vector<T, AllocComp> const &target)
12952  : m_target(target) {}
12953  bool match(std::vector<T, AllocMatch> const &vec) const override {
12954  if (m_target.size() != vec.size()) {
12955  return false;
12956  }
12957  return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
12958  }
12959 
12960  std::string describe() const override {
12961  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
12962  }
12963  };
12964 
12965  // The following functions create the actual matcher objects.
12966  // This allows the types to be inferred
12967 
12969  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
12970  ContainsMatcher<T, AllocComp, AllocMatch> Contains(std::vector<T, AllocComp> const &comparator) {
12971  return ContainsMatcher<T, AllocComp, AllocMatch>(comparator);
12972  }
12973 
12975  template<typename T, typename Alloc = std::allocator<T>>
12976  VectorContainsElementMatcher<T, Alloc> VectorContains(T const &comparator) {
12977  return VectorContainsElementMatcher<T, Alloc>(comparator);
12978  }
12979 
12981  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
12982  EqualsMatcher<T, AllocComp, AllocMatch> Equals(std::vector<T, AllocComp> const &comparator) {
12983  return EqualsMatcher<T, AllocComp, AllocMatch>(comparator);
12984  }
12985 
12987  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
12988  ApproxMatcher<T, AllocComp, AllocMatch> Approx(std::vector<T, AllocComp> const &comparator) {
12989  return ApproxMatcher<T, AllocComp, AllocMatch>(comparator);
12990  }
12991 
12993  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
12994  UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const &target) {
12995  return UnorderedEqualsMatcher<T, AllocComp, AllocMatch>(target);
12996  }
12997 
12998  } // namespace Matchers
12999 } // namespace Catch
13000 
13001 #endif // CATCH_MATCHERS_VECTOR_HPP_INCLUDED
13002 
13003 #endif // CATCH_MATCHERS_ALL_HPP_INCLUDED
13004 
13018 #ifndef CATCH_REPORTERS_ALL_HPP_INCLUDED
13019 #define CATCH_REPORTERS_ALL_HPP_INCLUDED
13020 
13021 #ifndef CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
13022 #define CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
13023 
13024 #ifndef CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
13025 #define CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
13026 
13027 #ifndef CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
13028 #define CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
13029 
13030 #include <map>
13031 #include <string>
13032 
13033 namespace Catch {
13034  class ColourImpl;
13035 
13046  class ReporterBase : public IEventListener {
13047  protected:
13049  Detail::unique_ptr<IStream> m_wrapped_stream;
13052  std::ostream &m_stream;
13056  std::map<std::string, std::string> m_customOptions;
13057 
13058  public:
13059  ReporterBase(ReporterConfig &&config);
13060  ~ReporterBase() override; // = default;
13061 
13068  void listReporters(
13069  std::vector<ReporterDescription> const &descriptions) override;
13076  void listListeners(
13077  std::vector<ListenerDescription> const &descriptions) override;
13085  void listTests(std::vector<TestCaseHandle> const &tests) override;
13092  void listTags(std::vector<TagInfo> const &tags) override;
13093  };
13094 } // namespace Catch
13095 
13096 #endif // CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
13097 
13098 #include <vector>
13099 
13100 namespace Catch {
13101 
13102  class StreamingReporterBase : public ReporterBase {
13103  public:
13104  // GCC5 compat: we cannot use inherited constructor, because it
13105  // doesn't implement backport of P0136
13106  StreamingReporterBase(ReporterConfig &&_config)
13107  : ReporterBase(CATCH_MOVE(_config)) {}
13108  ~StreamingReporterBase() override;
13109 
13110  void benchmarkPreparing(StringRef) override {}
13111  void benchmarkStarting(BenchmarkInfo const &) override {}
13112  void benchmarkEnded(BenchmarkStats<> const &) override {}
13113  void benchmarkFailed(StringRef) override {}
13114 
13115  void fatalErrorEncountered(StringRef /*error*/) override {}
13116  void noMatchingTestCases(StringRef /*unmatchedSpec*/) override {}
13117  void reportInvalidTestSpec(StringRef /*invalidArgument*/) override {}
13118 
13119  void testRunStarting(TestRunInfo const &_testRunInfo) override;
13120 
13121  void testCaseStarting(TestCaseInfo const &_testInfo) override {
13122  currentTestCaseInfo = &_testInfo;
13123  }
13124  void testCasePartialStarting(TestCaseInfo const &, uint64_t) override {}
13125  void sectionStarting(SectionInfo const &_sectionInfo) override {
13126  m_sectionStack.push_back(_sectionInfo);
13127  }
13128 
13129  void assertionStarting(AssertionInfo const &) override {}
13130  void assertionEnded(AssertionStats const &) override {}
13131 
13132  void sectionEnded(SectionStats const & /* _sectionStats */) override {
13133  m_sectionStack.pop_back();
13134  }
13135  void testCasePartialEnded(TestCaseStats const &, uint64_t) override {}
13136  void testCaseEnded(TestCaseStats const & /* _testCaseStats */) override {
13137  currentTestCaseInfo = nullptr;
13138  }
13139  void testRunEnded(TestRunStats const & /* _testRunStats */) override;
13140 
13141  void skipTest(TestCaseInfo const &) override {
13142  // Don't do anything with this by default.
13143  // It can optionally be overridden in the derived class.
13144  }
13145 
13146  protected:
13147  TestRunInfo currentTestRunInfo{"test run has not started yet"_sr};
13148  TestCaseInfo const *currentTestCaseInfo = nullptr;
13149 
13151  std::vector<SectionInfo> m_sectionStack;
13152  };
13153 
13154 } // end namespace Catch
13155 
13156 #endif // CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
13157 
13158 #include <string>
13159 
13160 namespace Catch {
13161 
13162  class AutomakeReporter final : public StreamingReporterBase {
13163  public:
13164  // GCC5 compat: we cannot use inherited constructor, because it
13165  // doesn't implement backport of P0136
13166  AutomakeReporter(ReporterConfig &&_config)
13167  : StreamingReporterBase(CATCH_MOVE(_config)) {
13168  m_preferences.shouldReportAllAssertionStarts = false;
13169  }
13170 
13171  ~AutomakeReporter() override;
13172 
13173  static std::string getDescription() {
13174  using namespace std::string_literals;
13175  return "Reports test results in the format of Automake .trs files"s;
13176  }
13177 
13178  void testCaseEnded(TestCaseStats const &_testCaseStats) override;
13179  void skipTest(TestCaseInfo const &testInfo) override;
13180  };
13181 
13182 } // end namespace Catch
13183 
13184 #endif // CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
13185 
13186 #ifndef CATCH_REPORTER_COMPACT_HPP_INCLUDED
13187 #define CATCH_REPORTER_COMPACT_HPP_INCLUDED
13188 
13189 namespace Catch {
13190 
13191  class CompactReporter final : public StreamingReporterBase {
13192  public:
13193  CompactReporter(ReporterConfig &&_config)
13194  : StreamingReporterBase(CATCH_MOVE(_config)) {
13195  m_preferences.shouldReportAllAssertionStarts = false;
13196  }
13197 
13198  ~CompactReporter() override;
13199 
13200  static std::string getDescription();
13201 
13202  void noMatchingTestCases(StringRef unmatchedSpec) override;
13203 
13204  void testRunStarting(TestRunInfo const &_testInfo) override;
13205 
13206  void assertionEnded(AssertionStats const &_assertionStats) override;
13207 
13208  void sectionEnded(SectionStats const &_sectionStats) override;
13209 
13210  void testRunEnded(TestRunStats const &_testRunStats) override;
13211  };
13212 
13213 } // end namespace Catch
13214 
13215 #endif // CATCH_REPORTER_COMPACT_HPP_INCLUDED
13216 
13217 #ifndef CATCH_REPORTER_CONSOLE_HPP_INCLUDED
13218 #define CATCH_REPORTER_CONSOLE_HPP_INCLUDED
13219 
13220 namespace Catch {
13221  // Fwd decls
13222  class TablePrinter;
13223 
13224  class ConsoleReporter final : public StreamingReporterBase {
13225  Detail::unique_ptr<TablePrinter> m_tablePrinter;
13226 
13227  public:
13228  ConsoleReporter(ReporterConfig &&config);
13229  ~ConsoleReporter() override;
13230  static std::string getDescription();
13231 
13232  void noMatchingTestCases(StringRef unmatchedSpec) override;
13233  void reportInvalidTestSpec(StringRef arg) override;
13234 
13235  void assertionEnded(AssertionStats const &_assertionStats) override;
13236 
13237  void sectionStarting(SectionInfo const &_sectionInfo) override;
13238  void sectionEnded(SectionStats const &_sectionStats) override;
13239 
13240  void benchmarkPreparing(StringRef name) override;
13241  void benchmarkStarting(BenchmarkInfo const &info) override;
13242  void benchmarkEnded(BenchmarkStats<> const &stats) override;
13243  void benchmarkFailed(StringRef error) override;
13244 
13245  void testCaseEnded(TestCaseStats const &_testCaseStats) override;
13246  void testRunEnded(TestRunStats const &_testRunStats) override;
13247  void testRunStarting(TestRunInfo const &_testRunInfo) override;
13248 
13249  private:
13250  void lazyPrint();
13251 
13252  void lazyPrintWithoutClosingBenchmarkTable();
13253  void lazyPrintRunInfo();
13254  void printTestCaseAndSectionHeader();
13255 
13256  void printClosedHeader(std::string const &_name);
13257  void printOpenHeader(std::string const &_name);
13258 
13259  // if string has a : in first line will set indent to follow it on
13260  // subsequent lines
13261  void printHeaderString(std::string const &_string, std::size_t indent = 0);
13262 
13263  void printTotalsDivider(Totals const &totals);
13264 
13265  bool m_headerPrinted = false;
13266  bool m_testRunInfoPrinted = false;
13267  };
13268 
13269 } // end namespace Catch
13270 
13271 #endif // CATCH_REPORTER_CONSOLE_HPP_INCLUDED
13272 
13273 #ifndef CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
13274 #define CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
13275 
13276 #include <string>
13277 #include <vector>
13278 
13279 namespace Catch {
13280 
13281  namespace Detail {
13282 
13284  class AssertionOrBenchmarkResult {
13285  // This should really be a variant, but this is much faster
13286  // to write and the data layout here is already terrible
13287  // enough that we do not have to care about the object size.
13288  Optional<AssertionStats> m_assertion;
13289  Optional<BenchmarkStats<>> m_benchmark;
13290 
13291  public:
13292  AssertionOrBenchmarkResult(AssertionStats const &assertion);
13293  AssertionOrBenchmarkResult(BenchmarkStats<> const &benchmark);
13294 
13295  bool isAssertion() const;
13296  bool isBenchmark() const;
13297 
13298  AssertionStats const &asAssertion() const;
13299  BenchmarkStats<> const &asBenchmark() const;
13300  };
13301  } // namespace Detail
13302 
13323  class CumulativeReporterBase : public ReporterBase {
13324  public:
13325  template<typename T, typename ChildNodeT>
13326  struct Node {
13327  explicit Node(T const &_value)
13328  : value(_value) {}
13329 
13330  using ChildNodes = std::vector<Detail::unique_ptr<ChildNodeT>>;
13331  T value;
13332  ChildNodes children;
13333  };
13334  struct SectionNode {
13335  explicit SectionNode(SectionStats const &_stats)
13336  : stats(_stats) {}
13337 
13338  bool operator==(SectionNode const &other) const {
13339  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
13340  }
13341 
13342  bool hasAnyAssertions() const;
13343 
13344  SectionStats stats;
13345  std::vector<Detail::unique_ptr<SectionNode>> childSections;
13346  std::vector<Detail::AssertionOrBenchmarkResult> assertionsAndBenchmarks;
13347  std::string stdOut;
13348  std::string stdErr;
13349  };
13350 
13351  using TestCaseNode = Node<TestCaseStats, SectionNode>;
13352  using TestRunNode = Node<TestRunStats, TestCaseNode>;
13353 
13354  // GCC5 compat: we cannot use inherited constructor, because it
13355  // doesn't implement backport of P0136
13356  CumulativeReporterBase(ReporterConfig &&_config)
13357  : ReporterBase(CATCH_MOVE(_config)) {}
13358  ~CumulativeReporterBase() override;
13359 
13360  void benchmarkPreparing(StringRef) override {}
13361  void benchmarkStarting(BenchmarkInfo const &) override {}
13362  void benchmarkEnded(BenchmarkStats<> const &benchmarkStats) override;
13363  void benchmarkFailed(StringRef) override {}
13364 
13365  void noMatchingTestCases(StringRef) override {}
13366  void reportInvalidTestSpec(StringRef) override {}
13367  void fatalErrorEncountered(StringRef /*error*/) override {}
13368 
13369  void testRunStarting(TestRunInfo const &) override {}
13370 
13371  void testCaseStarting(TestCaseInfo const &) override {}
13372  void testCasePartialStarting(TestCaseInfo const &, uint64_t) override {}
13373  void sectionStarting(SectionInfo const &sectionInfo) override;
13374 
13375  void assertionStarting(AssertionInfo const &) override {}
13376 
13377  void assertionEnded(AssertionStats const &assertionStats) override;
13378  void sectionEnded(SectionStats const &sectionStats) override;
13379  void testCasePartialEnded(TestCaseStats const &, uint64_t) override {}
13380  void testCaseEnded(TestCaseStats const &testCaseStats) override;
13381  void testRunEnded(TestRunStats const &testRunStats) override;
13383  virtual void testRunEndedCumulative() = 0;
13384 
13385  void skipTest(TestCaseInfo const &) override {}
13386 
13387  protected:
13389  bool m_shouldStoreSuccesfulAssertions = true;
13391  bool m_shouldStoreFailedAssertions = true;
13392 
13393  // We need lazy construction here. We should probably refactor it
13394  // later, after the events are redone.
13397 
13398  private:
13399  // Note: We rely on pointer identity being stable, which is why
13400  // we store pointers to the nodes rather than the values.
13401  std::vector<Detail::unique_ptr<TestCaseNode>> m_testCases;
13402  // Root section of the _current_ test case
13403  Detail::unique_ptr<SectionNode> m_rootSection;
13404  // Deepest section of the _current_ test case
13405  SectionNode *m_deepestSection = nullptr;
13406  // Stack of _active_ sections in the _current_ test case
13407  std::vector<SectionNode *> m_sectionStack;
13408  };
13409 
13410 } // end namespace Catch
13411 
13412 #endif // CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
13413 
13414 #ifndef CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
13415 #define CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
13416 
13417 namespace Catch {
13418 
13426  class EventListenerBase : public IEventListener {
13427  public:
13428  using IEventListener::IEventListener;
13429 
13430  void reportInvalidTestSpec(StringRef unmatchedSpec) override;
13431  void fatalErrorEncountered(StringRef error) override;
13432 
13433  void benchmarkPreparing(StringRef name) override;
13434  void benchmarkStarting(BenchmarkInfo const &benchmarkInfo) override;
13435  void benchmarkEnded(BenchmarkStats<> const &benchmarkStats) override;
13436  void benchmarkFailed(StringRef error) override;
13437 
13438  void assertionStarting(AssertionInfo const &assertionInfo) override;
13439  void assertionEnded(AssertionStats const &assertionStats) override;
13440 
13441  void listReporters(
13442  std::vector<ReporterDescription> const &descriptions) override;
13443  void listListeners(
13444  std::vector<ListenerDescription> const &descriptions) override;
13445  void listTests(std::vector<TestCaseHandle> const &tests) override;
13446  void listTags(std::vector<TagInfo> const &tagInfos) override;
13447 
13448  void noMatchingTestCases(StringRef unmatchedSpec) override;
13449  void testRunStarting(TestRunInfo const &testRunInfo) override;
13450  void testCaseStarting(TestCaseInfo const &testInfo) override;
13451  void testCasePartialStarting(TestCaseInfo const &testInfo,
13452  uint64_t partNumber) override;
13453  void sectionStarting(SectionInfo const &sectionInfo) override;
13454  void sectionEnded(SectionStats const &sectionStats) override;
13455  void testCasePartialEnded(TestCaseStats const &testCaseStats,
13456  uint64_t partNumber) override;
13457  void testCaseEnded(TestCaseStats const &testCaseStats) override;
13458  void testRunEnded(TestRunStats const &testRunStats) override;
13459  void skipTest(TestCaseInfo const &testInfo) override;
13460  };
13461 
13462 } // end namespace Catch
13463 
13464 #endif // CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
13465 
13466 #ifndef CATCH_REPORTER_HELPERS_HPP_INCLUDED
13467 #define CATCH_REPORTER_HELPERS_HPP_INCLUDED
13468 
13469 #include <iosfwd>
13470 #include <string>
13471 #include <vector>
13472 
13473 namespace Catch {
13474 
13475  class IConfig;
13476  class TestCaseHandle;
13477  class ColourImpl;
13478 
13479  // Returns double formatted as %.3f (format expected on output)
13480  std::string getFormattedDuration(double duration);
13481 
13483  bool shouldShowDuration(IConfig const &config, double duration);
13484 
13485  std::string serializeFilters(std::vector<std::string> const &filters);
13486 
13487  struct lineOfChars {
13488  char c;
13489  constexpr lineOfChars(char c_)
13490  : c(c_) {}
13491 
13492  friend std::ostream &operator<<(std::ostream &out, lineOfChars value);
13493  };
13494 
13503  void
13504  defaultListReporters(std::ostream &out,
13505  std::vector<ReporterDescription> const &descriptions,
13506  Verbosity verbosity);
13507 
13512  void defaultListListeners(std::ostream &out,
13513  std::vector<ListenerDescription> const &descriptions,
13514  Verbosity verbosity);
13515 
13523  void defaultListTags(std::ostream &out,
13524  std::vector<TagInfo> const &tags,
13525  bool isFiltered,
13526  Verbosity verbosity);
13527 
13537  void defaultListTests(std::ostream &out,
13538  ColourImpl *streamColour,
13539  std::vector<TestCaseHandle> const &tests,
13540  bool isFiltered,
13541  Verbosity verbosity);
13542 
13548  void printTestRunTotals(std::ostream &stream,
13549  ColourImpl &streamColour,
13550  Totals const &totals);
13551 
13552 } // end namespace Catch
13553 
13554 #endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED
13555 
13556 #ifndef CATCH_REPORTER_JSON_HPP_INCLUDED
13557 #define CATCH_REPORTER_JSON_HPP_INCLUDED
13558 
13559 #include <stack>
13560 
13561 namespace Catch {
13562  class JsonReporter : public StreamingReporterBase {
13563  public:
13564  JsonReporter(ReporterConfig &&config);
13565 
13566  ~JsonReporter() override;
13567 
13568  static std::string getDescription();
13569 
13570  public: // StreamingReporterBase
13571  void testRunStarting(TestRunInfo const &runInfo) override;
13572  void testRunEnded(TestRunStats const &runStats) override;
13573 
13574  void testCaseStarting(TestCaseInfo const &tcInfo) override;
13575  void testCaseEnded(TestCaseStats const &tcStats) override;
13576 
13577  void testCasePartialStarting(TestCaseInfo const &tcInfo,
13578  uint64_t index) override;
13579  void testCasePartialEnded(TestCaseStats const &tcStats,
13580  uint64_t index) override;
13581 
13582  void sectionStarting(SectionInfo const &sectionInfo) override;
13583  void sectionEnded(SectionStats const &sectionStats) override;
13584 
13585  void assertionEnded(AssertionStats const &assertionStats) override;
13586 
13587  // void testRunEndedCumulative() override;
13588 
13589  void benchmarkPreparing(StringRef name) override;
13590  void benchmarkStarting(BenchmarkInfo const &) override;
13591  void benchmarkEnded(BenchmarkStats<> const &) override;
13592  void benchmarkFailed(StringRef error) override;
13593 
13594  void listReporters(
13595  std::vector<ReporterDescription> const &descriptions) override;
13596  void listListeners(
13597  std::vector<ListenerDescription> const &descriptions) override;
13598  void listTests(std::vector<TestCaseHandle> const &tests) override;
13599  void listTags(std::vector<TagInfo> const &tags) override;
13600 
13601  private:
13602  Timer m_testCaseTimer;
13603  enum class Writer {
13604  Object,
13605  Array
13606  };
13607 
13608  JsonArrayWriter &startArray();
13609  JsonArrayWriter &startArray(StringRef key);
13610 
13611  JsonObjectWriter &startObject();
13612  JsonObjectWriter &startObject(StringRef key);
13613 
13614  void endObject();
13615  void endArray();
13616 
13617  bool isInside(Writer writer);
13618 
13619  void startListing();
13620  void endListing();
13621 
13622  // Invariant:
13623  // When m_writers is not empty and its top element is
13624  // - Writer::Object, then m_objectWriters is not be empty
13625  // - Writer::Array, then m_arrayWriters shall not be empty
13626  std::stack<JsonObjectWriter> m_objectWriters{};
13627  std::stack<JsonArrayWriter> m_arrayWriters{};
13628  std::stack<Writer> m_writers{};
13629 
13630  bool m_startedListing = false;
13631 
13632  // std::size_t m_sectionDepth = 0;
13633  // std::size_t m_sectionStarted = 0;
13634  };
13635 } // namespace Catch
13636 
13637 #endif // CATCH_REPORTER_JSON_HPP_INCLUDED
13638 
13639 #ifndef CATCH_REPORTER_JUNIT_HPP_INCLUDED
13640 #define CATCH_REPORTER_JUNIT_HPP_INCLUDED
13641 
13642 namespace Catch {
13643 
13644  class JunitReporter final : public CumulativeReporterBase {
13645  public:
13646  JunitReporter(ReporterConfig &&_config);
13647 
13648  static std::string getDescription();
13649 
13650  void testRunStarting(TestRunInfo const &runInfo) override;
13651 
13652  void testCaseStarting(TestCaseInfo const &testCaseInfo) override;
13653  void assertionEnded(AssertionStats const &assertionStats) override;
13654 
13655  void testCaseEnded(TestCaseStats const &testCaseStats) override;
13656 
13657  void testRunEndedCumulative() override;
13658 
13659  private:
13660  void writeRun(TestRunNode const &testRunNode, double suiteTime);
13661 
13662  void writeTestCase(TestCaseNode const &testCaseNode);
13663 
13664  void writeSection(std::string const &className,
13665  std::string const &rootName,
13666  SectionNode const &sectionNode,
13667  bool testOkToFail);
13668 
13669  void writeAssertions(SectionNode const &sectionNode);
13670  bool writeAssertion(AssertionStats const &stats);
13671 
13672  XmlWriter xml;
13673  Timer suiteTimer;
13674  std::string stdOutForSuite;
13675  std::string stdErrForSuite;
13676  unsigned int unexpectedExceptions = 0;
13677  bool m_okToFail = false;
13678  };
13679 
13680 } // end namespace Catch
13681 
13682 #endif // CATCH_REPORTER_JUNIT_HPP_INCLUDED
13683 
13684 #ifndef CATCH_REPORTER_MULTI_HPP_INCLUDED
13685 #define CATCH_REPORTER_MULTI_HPP_INCLUDED
13686 
13687 namespace Catch {
13688 
13689  class MultiReporter final : public IEventListener {
13690  /*
13691  * Stores all added reporters and listeners
13692  *
13693  * All Listeners are stored before all reporters, and individual
13694  * listeners/reporters are stored in order of insertion.
13695  */
13696  std::vector<IEventListenerPtr> m_reporterLikes;
13697  bool m_haveNoncapturingReporters = false;
13698 
13699  // Keep track of how many listeners we have already inserted,
13700  // so that we can insert them into the main vector at the right place
13701  size_t m_insertedListeners = 0;
13702 
13703  void updatePreferences(IEventListener const &reporterish);
13704 
13705  public:
13706  MultiReporter(IConfig const *config)
13707  : IEventListener(config) {
13708  m_preferences.shouldReportAllAssertionStarts = false;
13709  }
13710 
13711  using IEventListener::IEventListener;
13712 
13713  void addListener(IEventListenerPtr &&listener);
13714  void addReporter(IEventListenerPtr &&reporter);
13715 
13716  public: // IEventListener
13717  void noMatchingTestCases(StringRef unmatchedSpec) override;
13718  void fatalErrorEncountered(StringRef error) override;
13719  void reportInvalidTestSpec(StringRef arg) override;
13720 
13721  void benchmarkPreparing(StringRef name) override;
13722  void benchmarkStarting(BenchmarkInfo const &benchmarkInfo) override;
13723  void benchmarkEnded(BenchmarkStats<> const &benchmarkStats) override;
13724  void benchmarkFailed(StringRef error) override;
13725 
13726  void testRunStarting(TestRunInfo const &testRunInfo) override;
13727  void testCaseStarting(TestCaseInfo const &testInfo) override;
13728  void testCasePartialStarting(TestCaseInfo const &testInfo, uint64_t partNumber) override;
13729  void sectionStarting(SectionInfo const &sectionInfo) override;
13730  void assertionStarting(AssertionInfo const &assertionInfo) override;
13731 
13732  void assertionEnded(AssertionStats const &assertionStats) override;
13733  void sectionEnded(SectionStats const &sectionStats) override;
13734  void testCasePartialEnded(TestCaseStats const &testStats, uint64_t partNumber) override;
13735  void testCaseEnded(TestCaseStats const &testCaseStats) override;
13736  void testRunEnded(TestRunStats const &testRunStats) override;
13737 
13738  void skipTest(TestCaseInfo const &testInfo) override;
13739 
13740  void listReporters(std::vector<ReporterDescription> const &descriptions) override;
13741  void listListeners(std::vector<ListenerDescription> const &descriptions) override;
13742  void listTests(std::vector<TestCaseHandle> const &tests) override;
13743  void listTags(std::vector<TagInfo> const &tags) override;
13744  };
13745 
13746 } // end namespace Catch
13747 
13748 #endif // CATCH_REPORTER_MULTI_HPP_INCLUDED
13749 
13750 #ifndef CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
13751 #define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
13752 
13753 #include <type_traits>
13754 
13755 namespace Catch {
13756 
13757  namespace Detail {
13758 
13759  template<typename T, typename = void>
13760  struct has_description : std::false_type {};
13761 
13762  template<typename T>
13763  struct has_description<
13764  T,
13765  void_t<decltype(T::getDescription())>>
13766  : std::true_type {};
13767 
13770  void registerReporterImpl(std::string const &name,
13771  IReporterFactoryPtr reporterPtr);
13773  void registerListenerImpl(Detail::unique_ptr<EventListenerFactory> listenerFactory);
13774  } // namespace Detail
13775 
13776  class IEventListener;
13777  using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
13778 
13779  template<typename T>
13780  class ReporterFactory : public IReporterFactory {
13781  IEventListenerPtr create(ReporterConfig &&config) const override {
13782  return Detail::make_unique<T>(CATCH_MOVE(config));
13783  }
13784 
13785  std::string getDescription() const override {
13786  return T::getDescription();
13787  }
13788  };
13789 
13790  template<typename T>
13791  class ReporterRegistrar {
13792  public:
13793  explicit ReporterRegistrar(std::string const &name) {
13794  registerReporterImpl(name,
13795  Detail::make_unique<ReporterFactory<T>>());
13796  }
13797  };
13798 
13799  template<typename T>
13800  class ListenerRegistrar {
13801  class TypedListenerFactory : public EventListenerFactory {
13802  StringRef m_listenerName;
13803 
13804  std::string getDescriptionImpl(std::true_type) const {
13805  return T::getDescription();
13806  }
13807 
13808  std::string getDescriptionImpl(std::false_type) const {
13809  return "(No description provided)";
13810  }
13811 
13812  public:
13813  TypedListenerFactory(StringRef listenerName)
13814  : m_listenerName(listenerName) {}
13815 
13816  IEventListenerPtr create(IConfig const *config) const override {
13817  return Detail::make_unique<T>(config);
13818  }
13819 
13820  StringRef getName() const override {
13821  return m_listenerName;
13822  }
13823 
13824  std::string getDescription() const override {
13825  return getDescriptionImpl(Detail::has_description<T>{});
13826  }
13827  };
13828 
13829  public:
13830  ListenerRegistrar(StringRef listenerName) {
13831  registerListenerImpl(Detail::make_unique<TypedListenerFactory>(listenerName));
13832  }
13833  };
13834 } // namespace Catch
13835 
13836 #if !defined(CATCH_CONFIG_DISABLE)
13837 
13838 #define CATCH_REGISTER_REPORTER(name, reporterType) \
13839  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
13840  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
13841  namespace { \
13842  const Catch::ReporterRegistrar<reporterType> \
13843  INTERNAL_CATCH_UNIQUE_NAME(catch_internal_RegistrarFor)( \
13844  name); \
13845  } \
13846  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
13847 
13848 #define CATCH_REGISTER_LISTENER(listenerType) \
13849  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
13850  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
13851  namespace { \
13852  const Catch::ListenerRegistrar<listenerType> \
13853  INTERNAL_CATCH_UNIQUE_NAME(catch_internal_RegistrarFor)( \
13854  #listenerType##_catch_sr); \
13855  } \
13856  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
13857 
13858 #else // CATCH_CONFIG_DISABLE
13859 
13860 #define CATCH_REGISTER_REPORTER(name, reporterType)
13861 #define CATCH_REGISTER_LISTENER(listenerType)
13862 
13863 #endif // CATCH_CONFIG_DISABLE
13864 
13865 #endif // CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
13866 
13867 #ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
13868 #define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
13869 
13870 namespace Catch {
13871 
13872  class SonarQubeReporter final : public CumulativeReporterBase {
13873  public:
13874  SonarQubeReporter(ReporterConfig &&config)
13875  : CumulativeReporterBase(CATCH_MOVE(config))
13876  , xml(m_stream) {
13877  m_preferences.shouldRedirectStdOut = true;
13878  m_preferences.shouldReportAllAssertions = false;
13879  m_preferences.shouldReportAllAssertionStarts = false;
13880  m_shouldStoreSuccesfulAssertions = false;
13881  }
13882 
13883  static std::string getDescription() {
13884  using namespace std::string_literals;
13885  return "Reports test results in the Generic Test Data SonarQube XML format"s;
13886  }
13887 
13888  void testRunStarting(TestRunInfo const &testRunInfo) override;
13889 
13890  void testRunEndedCumulative() override {
13891  writeRun(*m_testRun);
13892  xml.endElement();
13893  }
13894 
13895  void writeRun(TestRunNode const &runNode);
13896 
13897  void writeTestFile(StringRef filename, std::vector<TestCaseNode const *> const &testCaseNodes);
13898 
13899  void writeTestCase(TestCaseNode const &testCaseNode);
13900 
13901  void writeSection(std::string const &rootName, SectionNode const &sectionNode, bool okToFail);
13902 
13903  void writeAssertions(SectionNode const &sectionNode, bool okToFail);
13904 
13905  void writeAssertion(AssertionStats const &stats, bool okToFail);
13906 
13907  private:
13908  XmlWriter xml;
13909  };
13910 
13911 } // end namespace Catch
13912 
13913 #endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
13914 
13915 #ifndef CATCH_REPORTER_TAP_HPP_INCLUDED
13916 #define CATCH_REPORTER_TAP_HPP_INCLUDED
13917 
13918 namespace Catch {
13919 
13920  class TAPReporter final : public StreamingReporterBase {
13921  public:
13922  TAPReporter(ReporterConfig &&config)
13923  : StreamingReporterBase(CATCH_MOVE(config)) {
13924  m_preferences.shouldReportAllAssertions = true;
13925  m_preferences.shouldReportAllAssertionStarts = false;
13926  }
13927 
13928  static std::string getDescription() {
13929  using namespace std::string_literals;
13930  return "Reports test results in TAP format, suitable for test harnesses"s;
13931  }
13932 
13933  void testRunStarting(TestRunInfo const &testInfo) override;
13934 
13935  void noMatchingTestCases(StringRef unmatchedSpec) override;
13936 
13937  void assertionEnded(AssertionStats const &_assertionStats) override;
13938 
13939  void testRunEnded(TestRunStats const &_testRunStats) override;
13940 
13941  private:
13942  std::size_t counter = 0;
13943  };
13944 
13945 } // end namespace Catch
13946 
13947 #endif // CATCH_REPORTER_TAP_HPP_INCLUDED
13948 
13949 #ifndef CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
13950 #define CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
13951 
13952 #include <cstring>
13953 
13954 #ifdef __clang__
13955 #pragma clang diagnostic push
13956 #pragma clang diagnostic ignored "-Wpadded"
13957 #endif
13958 
13959 namespace Catch {
13960 
13961  class TeamCityReporter final : public StreamingReporterBase {
13962  public:
13963  TeamCityReporter(ReporterConfig &&_config)
13964  : StreamingReporterBase(CATCH_MOVE(_config)) {
13965  m_preferences.shouldRedirectStdOut = true;
13966  m_preferences.shouldReportAllAssertionStarts = false;
13967  }
13968 
13969  ~TeamCityReporter() override;
13970 
13971  static std::string getDescription() {
13972  using namespace std::string_literals;
13973  return "Reports test results as TeamCity service messages"s;
13974  }
13975 
13976  void testRunStarting(TestRunInfo const &runInfo) override;
13977  void testRunEnded(TestRunStats const &runStats) override;
13978 
13979  void assertionEnded(AssertionStats const &assertionStats) override;
13980 
13981  void sectionStarting(SectionInfo const &sectionInfo) override {
13982  m_headerPrintedForThisSection = false;
13983  StreamingReporterBase::sectionStarting(sectionInfo);
13984  }
13985 
13986  void testCaseStarting(TestCaseInfo const &testInfo) override;
13987 
13988  void testCaseEnded(TestCaseStats const &testCaseStats) override;
13989 
13990  private:
13991  void printSectionHeader(std::ostream &os);
13992 
13993  bool m_headerPrintedForThisSection = false;
13994  Timer m_testTimer;
13995  };
13996 
13997 } // end namespace Catch
13998 
13999 #ifdef __clang__
14000 #pragma clang diagnostic pop
14001 #endif
14002 
14003 #endif // CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
14004 
14005 #ifndef CATCH_REPORTER_XML_HPP_INCLUDED
14006 #define CATCH_REPORTER_XML_HPP_INCLUDED
14007 
14008 namespace Catch {
14009  class XmlReporter : public StreamingReporterBase {
14010  public:
14011  XmlReporter(ReporterConfig &&_config);
14012 
14013  ~XmlReporter() override;
14014 
14015  static std::string getDescription();
14016 
14017  virtual std::string getStylesheetRef() const;
14018 
14019  void writeSourceInfo(SourceLineInfo const &sourceInfo);
14020 
14021  public: // StreamingReporterBase
14022  void testRunStarting(TestRunInfo const &testInfo) override;
14023 
14024  void testCaseStarting(TestCaseInfo const &testInfo) override;
14025 
14026  void sectionStarting(SectionInfo const &sectionInfo) override;
14027 
14028  void assertionEnded(AssertionStats const &assertionStats) override;
14029 
14030  void sectionEnded(SectionStats const &sectionStats) override;
14031 
14032  void testCaseEnded(TestCaseStats const &testCaseStats) override;
14033 
14034  void testRunEnded(TestRunStats const &testRunStats) override;
14035 
14036  void benchmarkPreparing(StringRef name) override;
14037  void benchmarkStarting(BenchmarkInfo const &) override;
14038  void benchmarkEnded(BenchmarkStats<> const &) override;
14039  void benchmarkFailed(StringRef error) override;
14040 
14041  void listReporters(std::vector<ReporterDescription> const &descriptions) override;
14042  void listListeners(std::vector<ListenerDescription> const &descriptions) override;
14043  void listTests(std::vector<TestCaseHandle> const &tests) override;
14044  void listTags(std::vector<TagInfo> const &tags) override;
14045 
14046  private:
14047  Timer m_testCaseTimer;
14048  XmlWriter m_xml;
14049  int m_sectionDepth = 0;
14050  };
14051 
14052 } // end namespace Catch
14053 
14054 #endif // CATCH_REPORTER_XML_HPP_INCLUDED
14055 
14056 #endif // CATCH_REPORTERS_ALL_HPP_INCLUDED
14057 
14058 #endif // CATCH_ALL_HPP_INCLUDED
14059 #endif // CATCH_AMALGAMATED_HPP_INCLUDED
#define CATCH_FORWARD(...)
Replacement for std::forward with better compile time performance.
Definition: catch_amalgamated.hpp:594
Definition: catch_amalgamated.hpp:1552
Definition: catch_amalgamated.hpp:5331
Definition: catch_amalgamated.hpp:4174
Definition: catch_amalgamated.hpp:8076
Definition: catch_amalgamated.hpp:1707
Definition: catch_amalgamated.hpp:4586
What
Definition: catch_amalgamated.hpp:1137
Definition: catch_amalgamated.hpp:3689
#define CATCH_MOVE(...)
Replacement for std::move with better compile time performance.
Definition: catch_amalgamated.hpp:591
Definition: catch_amalgamated.hpp:4721
Definition: catch_amalgamated.hpp:5232
Definition: catch_amalgamated.hpp:1257
Definition: catch_amalgamated.hpp:3183
Definition: catch_amalgamated.hpp:1245
Definition: catch_amalgamated.hpp:7631
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:8031
Definition: catch_amalgamated.hpp:1328
Definition: catch_amalgamated.hpp:2386
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7611
Definition: catch_amalgamated.hpp:3737
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7585
Definition: catch_amalgamated.hpp:7202
Definition: catch_amalgamated.hpp:3208
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7798
ResultType
Denotes type of a parsing result.
Definition: catch_amalgamated.hpp:4236
Definition: catch_amalgamated.cpp:9260
Used to signal that an assertion macro failed.
Definition: catch_amalgamated.hpp:604
Definition: catch_amalgamated.hpp:5260
Definition: catch_amalgamated.hpp:2356
Definition: catch_amalgamated.hpp:4821
Definition: catch_amalgamated.hpp:4939
Definition: catch_amalgamated.hpp:2863
Definition: catch_amalgamated.hpp:1018
Definition: catch_amalgamated.hpp:5534
Definition: catch_amalgamated.hpp:7547
Definition: catch_amalgamated.hpp:2497
Definition: catch_amalgamated.hpp:7775
Definition: catch_amalgamated.hpp:4746
ReporterSpec but with the defaults filled in.
Definition: catch_amalgamated.hpp:3676
Definition: catch_amalgamated.hpp:4594
Definition: catch_amalgamated.hpp:1538
Definition: catch_amalgamated.hpp:7589
Definition: catch_amalgamated.hpp:1759
Definition: catch_amalgamated.hpp:1168
Definition: catch_amalgamated.cpp:339
A non-owning string class (similar to the forthcoming std::string_view) Note that, because a StringRef may be a substring of another string, it may not be null terminated.
Definition: catch_amalgamated.hpp:708
Definition: catch_amalgamated.hpp:844
Optional< ReporterSpec > parseReporterSpec(StringRef reporterSpec)
Parses provided reporter spec string into.
Definition: catch_amalgamated.cpp:5445
Definition: catch_amalgamated.hpp:5952
Definition: catch_amalgamated.hpp:7529
Definition: catch_amalgamated.hpp:7511
Definition: catch_amalgamated.hpp:4452
We need to reinvent std::function because every piece of code that might add overhead in a measuremen...
Definition: catch_amalgamated.hpp:1601
Definition: catch_amalgamated.hpp:1670
void throw_test_failure_exception()
Outlines throwing of TestFailureException into a single TU.
Definition: catch_amalgamated.cpp:7194
Definition: catch_amalgamated.hpp:5756
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7890
Definition: catch_amalgamated.hpp:4260
Definition: catch_amalgamated.hpp:5528
Definition: catch_amalgamated.hpp:7701
Definition: catch_amalgamated.hpp:5896
Definition: catch_amalgamated.hpp:2051
Structured reporter spec that a reporter can be created from.
Definition: catch_amalgamated.hpp:3613
Definition: catch_amalgamated.hpp:1494
Definition: catch_amalgamated.hpp:554
Deriving classes become noncopyable and nonmovable.
Definition: catch_amalgamated.hpp:1108
Definition: catch_amalgamated.hpp:4090
Wrapper over the test case information and the test case invoker.
Definition: catch_amalgamated.hpp:7160
Definition: catch_amalgamated.hpp:5917
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7949
Definition: catch_amalgamated.hpp:7965
Definition: catch_amalgamated.hpp:1719
Definition: catch_amalgamated.hpp:5230
Definition: catch_amalgamated.hpp:3549
Definition: catch_amalgamated.hpp:4542
Definition: catch_amalgamated.hpp:3237
Definition: memory_leak_test.cpp:28
Definition: catch_amalgamated.hpp:5344
Definition: catch_amalgamated.hpp:4152
Definition: catch_amalgamated.hpp:5071
Definition: catch_amalgamated.hpp:4061
Definition: catch_amalgamated.hpp:4572
Definition: catch_amalgamated.hpp:1310
Definition: catch_amalgamated.hpp:7822
Definition: catch_amalgamated.hpp:7233
Definition: catch_amalgamated.hpp:2083
GeneratorWrapper(IGenerator< T > *generator)
Takes ownership of the passed pointer.
Definition: catch_amalgamated.hpp:7552
Definition: catch_amalgamated.hpp:7569
Definition: catch_amalgamated.hpp:5216
Definition: catch_amalgamated.hpp:8008
std::uint32_t getSeed()
Returns Catch2&#39;s current RNG seed.
Definition: catch_amalgamated.cpp:1003
Definition: catch_amalgamated.hpp:3306
Definition: catch_amalgamated.hpp:3398
Definition: catch_amalgamated.hpp:4441
Used to signal that the remainder of a test should be skipped.
Definition: catch_amalgamated.hpp:606
Definition: catch_amalgamated.hpp:1136
Definition: catch_amalgamated.hpp:3161
Definition: catch_amalgamated.hpp:4922
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7998
Definition: catch_amalgamated.hpp:4446
Definition: catch_amalgamated.hpp:1385
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7854
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7672
Definition: catch_amalgamated.hpp:2376
Definition: catch_amalgamated.hpp:7227
Definition: catch_amalgamated.hpp:5861
Definition: catch_amalgamated.hpp:2309
Definition: catch_amalgamated.hpp:4403
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7987
Definition: catch_amalgamated.hpp:4525
A view of a tag string that provides case insensitive comparisons.
Definition: catch_amalgamated.hpp:7089
Definition: catch_amalgamated.hpp:5773
Definition: catch_amalgamated.hpp:4381
Definition: catch_amalgamated.hpp:1181
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:8040
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7581
A reimplementation of std::unique_ptr for improved compilation performance.
Definition: catch_amalgamated.hpp:884
Definition: catch_amalgamated.hpp:4328
Definition: catch_amalgamated.hpp:5061
Definition: catch_amalgamated.hpp:3338
Definition: catch_amalgamated.hpp:4549
Definition: catch_amalgamated.hpp:4482
Definition: catch_amalgamated.hpp:1502
Definition: catch_amalgamated.hpp:1837
Definition: catch_amalgamated.hpp:812
Definition: catch_amalgamated.hpp:2925
Definition: catch_amalgamated.hpp:1912
Definition: catch_amalgamated.hpp:4492
Various metadata about the test case.
Definition: catch_amalgamated.hpp:7120
Definition: catch_amalgamated.hpp:7383
Definition: catch_amalgamated.hpp:1519
Definition: catch_amalgamated.hpp:7323
Definition: catch_amalgamated.hpp:4436
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7813
Wrapper over argc + argv, assumes that the inputs outlive it.
Definition: catch_amalgamated.hpp:4807
std::string str() const
Returns the serialized state.
Definition: catch_amalgamated.cpp:5557
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7845
Definition: catch_amalgamated.hpp:7923
Definition: catch_amalgamated.hpp:4670
Definition: catch_amalgamated.hpp:7863
Definition: catch_amalgamated.hpp:5063
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7616
Definition: catch_amalgamated.hpp:4078
Definition: catch_amalgamated.hpp:7425
Definition: catch_amalgamated.hpp:3877
Definition: catch_amalgamated.hpp:2870
Definition: catch_amalgamated.hpp:4203
Definition: catch_amalgamated.hpp:3441
Definition: catch_amalgamated.hpp:5944
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7914
bool next() override
Attempts to move the generator to the next element.
Definition: catch_amalgamated.hpp:7944
bool isFinite() const override
Returns true if calls to next will eventually return false.
Definition: catch_amalgamated.hpp:7683
Definition: catch_amalgamated.hpp:3250
Definition: catch_amalgamated.hpp:3921
Definition: catch_amalgamated.hpp:1351
Definition: catch_amalgamated.hpp:6391
Definition: catch_amalgamated.hpp:3038
Definition: catch_amalgamated.hpp:4659
Definition: catch_amalgamated.hpp:2417
Definition: catch_amalgamated.hpp:5069
Definition: catch_amalgamated.hpp:5077
Definition: catch_amalgamated.hpp:1528
Definition: catch_amalgamated.hpp:4870
virtual void streamReconstructedExpression(std::ostream &os) const
This function has to be overridden by the derived class.
Definition: catch_amalgamated.cpp:3852
Definition: catch_amalgamated.hpp:5495
Definition: catch_amalgamated.hpp:7251
Definition: catch_amalgamated.hpp:4047
void throw_test_skip_exception()
Outlines throwing of TestSkipException into a single TU.
Definition: catch_amalgamated.cpp:7202
Definition: catch_amalgamated.hpp:990
Definition: catch_amalgamated.hpp:1389
Definition: catch_amalgamated.hpp:2203
Definition: catch_amalgamated.hpp:1492