Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
563b9f27334fd6d7e52a8122334c19d094afe5e6
[simgrid.git] / src / 3rd-party / catch.hpp
1 /*
2  *  Catch v2.13.5
3  *  Generated: 2021-04-10 23:43:17.560525
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved.
7  *
8  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
9  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 // start catch.hpp
14
15 #define CATCH_VERSION_MAJOR 2
16 #define CATCH_VERSION_MINOR 13
17 #define CATCH_VERSION_PATCH 5
18
19 #ifdef __clang__
20 #pragma clang system_header
21 #elif defined __GNUC__
22 #pragma GCC system_header
23 #endif
24
25 // start catch_suppress_warnings.h
26
27 #ifdef __clang__
28 #ifdef __ICC // icpc defines the __clang__ macro
29 #pragma warning(push)
30 #pragma warning(disable : 161 1682)
31 #else // __ICC
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wpadded"
34 #pragma clang diagnostic ignored "-Wswitch-enum"
35 #pragma clang diagnostic ignored "-Wcovered-switch-default"
36 #endif
37 #elif defined __GNUC__
38 // Because REQUIREs trigger GCC's -Wparentheses, and because still
39 // supported version of g++ have only buggy support for _Pragmas,
40 // Wparentheses have to be suppressed globally.
41 #pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
42
43 #pragma GCC diagnostic push
44 #pragma GCC diagnostic ignored "-Wunused-variable"
45 #pragma GCC diagnostic ignored "-Wpadded"
46 #endif
47 // end catch_suppress_warnings.h
48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
49 #define CATCH_IMPL
50 #define CATCH_CONFIG_ALL_PARTS
51 #endif
52
53 // In the impl file, we want to have access to all parts of the headers
54 // Can also be used to sanely support PCHs
55 #if defined(CATCH_CONFIG_ALL_PARTS)
56 #define CATCH_CONFIG_EXTERNAL_INTERFACES
57 #if defined(CATCH_CONFIG_DISABLE_MATCHERS)
58 #undef CATCH_CONFIG_DISABLE_MATCHERS
59 #endif
60 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
61 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
62 #endif
63 #endif
64
65 #if !defined(CATCH_CONFIG_IMPL_ONLY)
66 // start catch_platform.h
67
68 // See e.g.:
69 // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
70 #ifdef __APPLE__
71 #include <TargetConditionals.h>
72 #if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
73 #define CATCH_PLATFORM_MAC
74 #elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
75 #define CATCH_PLATFORM_IPHONE
76 #endif
77
78 #elif defined(linux) || defined(__linux) || defined(__linux__)
79 #define CATCH_PLATFORM_LINUX
80
81 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
82 #define CATCH_PLATFORM_WINDOWS
83 #endif
84
85 // end catch_platform.h
86
87 #ifdef CATCH_IMPL
88 #ifndef CLARA_CONFIG_MAIN
89 #define CLARA_CONFIG_MAIN_NOT_DEFINED
90 #define CLARA_CONFIG_MAIN
91 #endif
92 #endif
93
94 // start catch_user_interfaces.h
95
96 namespace Catch {
97 unsigned int rngSeed();
98 }
99
100 // end catch_user_interfaces.h
101 // start catch_tag_alias_autoregistrar.h
102
103 // start catch_common.h
104
105 // start catch_compiler_capabilities.h
106
107 // Detect a number of compiler features - by compiler
108 // The following features are defined:
109 //
110 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
111 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
112 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
113 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
114 // ****************
115 // Note to maintainers: if new toggles are added please document them
116 // in configuration.md, too
117 // ****************
118
119 // In general each macro has a _NO_<feature name> form
120 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
121 // Many features, at point of detection, define an _INTERNAL_ macro, so they
122 // can be combined, en-mass, with the _NO_ forms later.
123
124 #ifdef __cplusplus
125
126 #if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
127 #define CATCH_CPP14_OR_GREATER
128 #endif
129
130 #if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
131 #define CATCH_CPP17_OR_GREATER
132 #endif
133
134 #endif
135
136 // Only GCC compiler should be used in this block, so other compilers trying to
137 // mask themselves as GCC should be ignored.
138 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
139 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic push")
140 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic pop")
141
142 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
143
144 #endif
145
146 #if defined(__clang__)
147
148 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("clang diagnostic push")
149 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("clang diagnostic pop")
150
151 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
152 // which results in calls to destructors being emitted for each temporary,
153 // without a matching initialization. In practice, this can result in something
154 // like `std::string::~string` being called on an uninitialized value.
155 //
156 // For example, this code will likely segfault under IBM XL:
157 // ```
158 // REQUIRE(std::string("12") + "34" == "1234")
159 // ```
160 //
161 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
162 #if !defined(__ibmxl__) && !defined(__CUDACC__)
163 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...)                                                                            \
164   (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
165 #endif
166
167 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                       \
168   _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"")                                                      \
169       _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"")
170
171 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma("clang diagnostic ignored \"-Wparentheses\"")
172
173 #define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS _Pragma("clang diagnostic ignored \"-Wunused-variable\"")
174
175 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                                                                 \
176   _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"")
177
178 #define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS _Pragma("clang diagnostic ignored \"-Wunused-template\"")
179
180 #endif // __clang__
181
182 ////////////////////////////////////////////////////////////////////////////////
183 // Assume that non-Windows platforms support posix signals by default
184 #if !defined(CATCH_PLATFORM_WINDOWS)
185 #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
186 #endif
187
188 ////////////////////////////////////////////////////////////////////////////////
189 // We know some environments not to support full POSIX signals
190 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
191 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
192 #endif
193
194 #ifdef __OS400__
195 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
196 #define CATCH_CONFIG_COLOUR_NONE
197 #endif
198
199 ////////////////////////////////////////////////////////////////////////////////
200 // Android somehow still does not support std::to_string
201 #if defined(__ANDROID__)
202 #define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
203 #define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
204 #endif
205
206 ////////////////////////////////////////////////////////////////////////////////
207 // Not all Windows environments support SEH properly
208 #if defined(__MINGW32__)
209 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
210 #endif
211
212 ////////////////////////////////////////////////////////////////////////////////
213 // PS4
214 #if defined(__ORBIS__)
215 #define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
216 #endif
217
218 ////////////////////////////////////////////////////////////////////////////////
219 // Cygwin
220 #ifdef __CYGWIN__
221
222 // Required for some versions of Cygwin to declare gettimeofday
223 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
224 #define _BSD_SOURCE
225 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
226 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
227 #if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
228
229 #define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
230
231 #endif
232 #endif // __CYGWIN__
233
234 ////////////////////////////////////////////////////////////////////////////////
235 // Visual C++
236 #if defined(_MSC_VER)
237
238 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma(warning(push))
239 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma(warning(pop))
240
241 // Universal Windows platform does not support SEH
242 // Or console colours (or console at all...)
243 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
244 #define CATCH_CONFIG_COLOUR_NONE
245 #else
246 #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
247 #endif
248
249 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
250 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
251 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
252 #if !defined(__clang__) // Handle Clang masquerading for msvc
253 #if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
254 #define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
255 #endif // MSVC_TRADITIONAL
256 #endif // __clang__
257
258 #endif // _MSC_VER
259
260 #if defined(_REENTRANT) || defined(_MSC_VER)
261 // Enable async processing, as -pthread is specified or no additional linking is required
262 #define CATCH_INTERNAL_CONFIG_USE_ASYNC
263 #endif // _MSC_VER
264
265 ////////////////////////////////////////////////////////////////////////////////
266 // Check if we are compiled with -fno-exceptions or equivalent
267 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
268 #define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
269 #endif
270
271 ////////////////////////////////////////////////////////////////////////////////
272 // DJGPP
273 #ifdef __DJGPP__
274 #define CATCH_INTERNAL_CONFIG_NO_WCHAR
275 #endif // __DJGPP__
276
277 ////////////////////////////////////////////////////////////////////////////////
278 // Embarcadero C++Build
279 #if defined(__BORLANDC__)
280 #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
281 #endif
282
283 ////////////////////////////////////////////////////////////////////////////////
284
285 // Use of __COUNTER__ is suppressed during code analysis in
286 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
287 // handled by it.
288 // Otherwise all supported compilers support COUNTER macro,
289 // but user still might want to turn it off
290 #if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L)
291 #define CATCH_INTERNAL_CONFIG_COUNTER
292 #endif
293
294 ////////////////////////////////////////////////////////////////////////////////
295
296 // RTX is a special version of Windows that is real time.
297 // This means that it is detected as Windows, but does not provide
298 // the same set of capabilities as real Windows does.
299 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
300 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
301 #define CATCH_INTERNAL_CONFIG_NO_ASYNC
302 #define CATCH_CONFIG_COLOUR_NONE
303 #endif
304
305 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
306 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
307 #endif
308
309 // Various stdlib support checks that require __has_include
310 #if defined(__has_include)
311 // Check if string_view is available and usable
312 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
313 #define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
314 #endif
315
316 // Check if optional is available and usable
317 #if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
318 #define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
319 #endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
320
321 // Check if byte is available and usable
322 #if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
323 #include <cstddef>
324 #if __cpp_lib_byte > 0
325 #define CATCH_INTERNAL_CONFIG_CPP17_BYTE
326 #endif
327 #endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
328
329 // Check if variant is available and usable
330 #if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
331 #if defined(__clang__) && (__clang_major__ < 8)
332 // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
333 // fix should be in clang 8, workaround in libstdc++ 8.2
334 #include <ciso646>
335 #if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
336 #define CATCH_CONFIG_NO_CPP17_VARIANT
337 #else
338 #define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
339 #endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
340 #else
341 #define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
342 #endif // defined(__clang__) && (__clang_major__ < 8)
343 #endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
344 #endif // defined(__has_include)
345
346 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
347 #define CATCH_CONFIG_COUNTER
348 #endif
349 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) &&                             \
350     !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
351 #define CATCH_CONFIG_WINDOWS_SEH
352 #endif
353 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
354 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) &&                \
355     !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
356 #define CATCH_CONFIG_POSIX_SIGNALS
357 #endif
358 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
359 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
360 #define CATCH_CONFIG_WCHAR
361 #endif
362
363 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) &&                 \
364     !defined(CATCH_CONFIG_CPP11_TO_STRING)
365 #define CATCH_CONFIG_CPP11_TO_STRING
366 #endif
367
368 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) &&                       \
369     !defined(CATCH_CONFIG_CPP17_OPTIONAL)
370 #define CATCH_CONFIG_CPP17_OPTIONAL
371 #endif
372
373 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) &&                 \
374     !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
375 #define CATCH_CONFIG_CPP17_STRING_VIEW
376 #endif
377
378 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) &&                         \
379     !defined(CATCH_CONFIG_CPP17_VARIANT)
380 #define CATCH_CONFIG_CPP17_VARIANT
381 #endif
382
383 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) &&                               \
384     !defined(CATCH_CONFIG_CPP17_BYTE)
385 #define CATCH_CONFIG_CPP17_BYTE
386 #endif
387
388 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
389 #define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
390 #endif
391
392 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) &&                    \
393     !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
394 #define CATCH_CONFIG_NEW_CAPTURE
395 #endif
396
397 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
398 #define CATCH_CONFIG_DISABLE_EXCEPTIONS
399 #endif
400
401 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) &&                       \
402     !defined(CATCH_CONFIG_POLYFILL_ISNAN)
403 #define CATCH_CONFIG_POLYFILL_ISNAN
404 #endif
405
406 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) &&                            \
407     !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
408 #define CATCH_CONFIG_USE_ASYNC
409 #endif
410
411 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) &&                   \
412     !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
413 #define CATCH_CONFIG_ANDROID_LOGWRITE
414 #endif
415
416 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) &&                   \
417     !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
418 #define CATCH_CONFIG_GLOBAL_NEXTAFTER
419 #endif
420
421 // Even if we do not think the compiler has that warning, we still have
422 // to provide a macro that can be used by the code.
423 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
424 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
425 #endif
426 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
427 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
428 #endif
429 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
430 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
431 #endif
432 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
433 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
434 #endif
435 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
436 #define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
437 #endif
438 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
439 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
440 #endif
441
442 // The goal of this macro is to avoid evaluation of the arguments, but
443 // still have the compiler warn on problems inside...
444 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
445 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
446 #endif
447
448 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
449 #undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
450 #elif defined(__clang__) && (__clang_major__ < 5)
451 #undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
452 #endif
453
454 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
455 #define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
456 #endif
457
458 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
459 #define CATCH_TRY if ((true))
460 #define CATCH_CATCH_ALL if ((false))
461 #define CATCH_CATCH_ANON(type) if ((false))
462 #else
463 #define CATCH_TRY try
464 #define CATCH_CATCH_ALL catch (...)
465 #define CATCH_CATCH_ANON(type) catch (type)
466 #endif
467
468 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) &&                                                    \
469     !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
470 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
471 #endif
472
473 // end catch_compiler_capabilities.h
474 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line
475 #define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line)
476 #ifdef CATCH_CONFIG_COUNTER
477 #define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__)
478 #else
479 #define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__)
480 #endif
481
482 #include <cstdint>
483 #include <iosfwd>
484 #include <string>
485
486 // We need a dummy global operator<< so we can bring it into Catch namespace later
487 struct Catch_global_namespace_dummy {};
488 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
489
490 namespace Catch {
491
492 struct CaseSensitive {
493   enum Choice { Yes, No };
494 };
495
496 class NonCopyable {
497   NonCopyable(NonCopyable const&)            = delete;
498   NonCopyable(NonCopyable&&)                 = delete;
499   NonCopyable& operator=(NonCopyable const&) = delete;
500   NonCopyable& operator=(NonCopyable&&)      = delete;
501
502 protected:
503   NonCopyable();
504   virtual ~NonCopyable();
505 };
506
507 struct SourceLineInfo {
508
509   SourceLineInfo() = delete;
510   SourceLineInfo(char const* _file, std::size_t _line) noexcept : file(_file), line(_line) {}
511
512   SourceLineInfo(SourceLineInfo const& other)          = default;
513   SourceLineInfo& operator=(SourceLineInfo const&)     = default;
514   SourceLineInfo(SourceLineInfo&&) noexcept            = default;
515   SourceLineInfo& operator=(SourceLineInfo&&) noexcept = default;
516
517   bool empty() const noexcept { return file[0] == '\0'; }
518   bool operator==(SourceLineInfo const& other) const noexcept;
519   bool operator<(SourceLineInfo const& other) const noexcept;
520
521   char const* file;
522   std::size_t line;
523 };
524
525 std::ostream& operator<<(std::ostream& os, SourceLineInfo const& info);
526
527 // Bring in operator<< from global namespace into Catch namespace
528 // This is necessary because the overload of operator<< above makes
529 // lookup stop at namespace Catch
530 using ::operator<<;
531
532 // Use this in variadic streaming macros to allow
533 //    >> +StreamEndStop
534 // as well as
535 //    >> stuff +StreamEndStop
536 struct StreamEndStop {
537   std::string operator+() const;
538 };
539 template <typename T> T const& operator+(T const& value, StreamEndStop)
540 {
541   return value;
542 }
543 } // namespace Catch
544
545 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo(__FILE__, static_cast<std::size_t>(__LINE__))
546
547 // end catch_common.h
548 namespace Catch {
549
550 struct RegistrarForTagAliases {
551   RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo);
552 };
553
554 } // end namespace Catch
555
556 #define CATCH_REGISTER_TAG_ALIAS(alias, spec)                                                                          \
557   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
558   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
559   namespace {                                                                                                          \
560   Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME(AutoRegisterTagAlias)(alias, spec,                          \
561                                                                                  CATCH_INTERNAL_LINEINFO);             \
562   }                                                                                                                    \
563   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
564
565 // end catch_tag_alias_autoregistrar.h
566 // start catch_test_registry.h
567
568 // start catch_interfaces_testcase.h
569
570 #include <vector>
571
572 namespace Catch {
573
574 class TestSpec;
575
576 struct ITestInvoker {
577   virtual void invoke() const = 0;
578   virtual ~ITestInvoker();
579 };
580
581 class TestCase;
582 struct IConfig;
583
584 struct ITestCaseRegistry {
585   virtual ~ITestCaseRegistry();
586   virtual std::vector<TestCase> const& getAllTests() const                            = 0;
587   virtual std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const = 0;
588 };
589
590 bool isThrowSafe(TestCase const& testCase, IConfig const& config);
591 bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
592 std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec,
593                                   IConfig const& config);
594 std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
595
596 } // namespace Catch
597
598 // end catch_interfaces_testcase.h
599 // start catch_stringref.h
600
601 #include <cassert>
602 #include <cstddef>
603 #include <iosfwd>
604 #include <string>
605
606 namespace Catch {
607
608 /// A non-owning string class (similar to the forthcoming std::string_view)
609 /// Note that, because a StringRef may be a substring of another string,
610 /// it may not be null terminated.
611 class StringRef {
612 public:
613   using size_type      = std::size_t;
614   using const_iterator = const char*;
615
616 private:
617   static constexpr char const* const s_empty = "";
618
619   char const* m_start = s_empty;
620   size_type m_size    = 0;
621
622 public: // construction
623   constexpr StringRef() noexcept = default;
624
625   StringRef(char const* rawChars) noexcept;
626
627   constexpr StringRef(char const* rawChars, size_type size) noexcept : m_start(rawChars), m_size(size) {}
628
629   StringRef(std::string const& stdString) noexcept : m_start(stdString.c_str()), m_size(stdString.size()) {}
630
631   explicit operator std::string() const { return std::string(m_start, m_size); }
632
633 public: // operators
634   auto operator==(StringRef const& other) const noexcept -> bool;
635   auto operator!=(StringRef const& other) const noexcept -> bool { return !(*this == other); }
636
637   auto operator[](size_type index) const noexcept -> char
638   {
639     assert(index < m_size);
640     return m_start[index];
641   }
642
643 public: // named queries
644   constexpr auto empty() const noexcept -> bool { return m_size == 0; }
645   constexpr auto size() const noexcept -> size_type { return m_size; }
646
647   // Returns the current start pointer. If the StringRef is not
648   // null-terminated, throws std::domain_exception
649   auto c_str() const -> char const*;
650
651 public: // substrings and searches
652   // Returns a substring of [start, start + length).
653   // If start + length > size(), then the substring is [start, size()).
654   // If start > size(), then the substring is empty.
655   auto substr(size_type start, size_type length) const noexcept -> StringRef;
656
657   // Returns the current start pointer. May not be null-terminated.
658   auto data() const noexcept -> char const*;
659
660   constexpr auto isNullTerminated() const noexcept -> bool { return m_start[m_size] == '\0'; }
661
662 public: // iterators
663   constexpr const_iterator begin() const { return m_start; }
664   constexpr const_iterator end() const { return m_start + m_size; }
665 };
666
667 auto operator+=(std::string& lhs, StringRef const& sr) -> std::string&;
668 auto operator<<(std::ostream& os, StringRef const& sr) -> std::ostream&;
669
670 constexpr auto operator"" _sr(char const* rawChars, std::size_t size) noexcept -> StringRef
671 {
672   return StringRef(rawChars, size);
673 }
674 } // namespace Catch
675
676 constexpr auto operator"" _catch_sr(char const* rawChars, std::size_t size) noexcept -> Catch::StringRef
677 {
678   return Catch::StringRef(rawChars, size);
679 }
680
681 // end catch_stringref.h
682 // start catch_preprocessor.hpp
683
684 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
685 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
686 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
687 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
688 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
689 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
690
691 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
692 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
693 // MSVC needs more evaluations
694 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
695 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
696 #else
697 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
698 #endif
699
700 #define CATCH_REC_END(...)
701 #define CATCH_REC_OUT
702
703 #define CATCH_EMPTY()
704 #define CATCH_DEFER(id) id CATCH_EMPTY()
705
706 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
707 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
708 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
709 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
710 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER(CATCH_REC_NEXT0)(test, next, 0)
711 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
712
713 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
714 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0))(f, peek, __VA_ARGS__)
715 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
716
717 #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...)                                                                  \
718   , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__)
719 #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...)                                                                  \
720   , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD))(f, userdata, peek, __VA_ARGS__)
721 #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)                                                                  \
722   f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__)
723
724 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
725 // and passes userdata as the first parameter to each invocation,
726 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
727 #define CATCH_REC_LIST_UD(f, userdata, ...)                                                                            \
728   CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
729
730 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
731
732 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
733 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__
734 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
735 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
736 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
737 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
738 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
739 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
740 #else
741 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
742 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
743 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
744 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param)                                                                 \
745   (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
746 #endif
747
748 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
749 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
750
751 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
752
753 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
754 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
755 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
756 #else
757 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...)                                                                            \
758   INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
759 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...)                                                                             \
760   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
761 #endif
762
763 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...) CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST, __VA_ARGS__)
764
765 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
766 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1)                                                                     \
767   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
768 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2)                                                                 \
769   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
770 #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3)                                                             \
771   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
772 #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4)                                                         \
773   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
774 #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5)                                                     \
775   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
776 #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6)                                                 \
777   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
778 #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7)                                             \
779   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
780 #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8)                                         \
781   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
782 #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9)                                    \
783   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
784 #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10)                               \
785   INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
786
787 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
788
789 #define INTERNAL_CATCH_TYPE_GEN                                                                                        \
790   template <typename...> struct TypeList {                                                                             \
791   };                                                                                                                   \
792   template <typename... Ts> constexpr auto get_wrapper() noexcept->TypeList<Ts...>                                     \
793   {                                                                                                                    \
794     return {};                                                                                                         \
795   }                                                                                                                    \
796   template <template <typename...> class...> struct TemplateTypeList {                                                 \
797   };                                                                                                                   \
798   template <template <typename...> class... Cs> constexpr auto get_wrapper() noexcept->TemplateTypeList<Cs...>         \
799   {                                                                                                                    \
800     return {};                                                                                                         \
801   }                                                                                                                    \
802   template <typename...> struct append;                                                                                \
803   template <typename...> struct rewrap;                                                                                \
804   template <template <typename...> class, typename...> struct create;                                                  \
805   template <template <typename...> class, typename> struct convert;                                                    \
806                                                                                                                        \
807   template <typename T> struct append<T> {                                                                             \
808     using type = T;                                                                                                    \
809   };                                                                                                                   \
810   template <template <typename...> class L1, typename... E1, template <typename...> class L2, typename... E2,          \
811             typename... Rest>                                                                                          \
812   struct append<L1<E1...>, L2<E2...>, Rest...> {                                                                       \
813     using type = typename append<L1<E1..., E2...>, Rest...>::type;                                                     \
814   };                                                                                                                   \
815   template <template <typename...> class L1, typename... E1, typename... Rest>                                         \
816   struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> {                                                              \
817     using type = L1<E1...>;                                                                                            \
818   };                                                                                                                   \
819                                                                                                                        \
820   template <template <typename...> class Container, template <typename...> class List, typename... elems>              \
821   struct rewrap<TemplateTypeList<Container>, List<elems...>> {                                                         \
822     using type = TypeList<Container<elems...>>;                                                                        \
823   };                                                                                                                   \
824   template <template <typename...> class Container, template <typename...> class List, class... Elems,                 \
825             typename... Elements>                                                                                      \
826   struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> {                                            \
827     using type = typename append<TypeList<Container<Elems...>>,                                                        \
828                                  typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type;               \
829   };                                                                                                                   \
830                                                                                                                        \
831   template <template <typename...> class Final, template <typename...> class... Containers, typename... Types>         \
832   struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> {                                          \
833     using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type;     \
834   };                                                                                                                   \
835   template <template <typename...> class Final, template <typename...> class List, typename... Ts>                     \
836   struct convert<Final, List<Ts...>> {                                                                                 \
837     using type = typename append<Final<>, TypeList<Ts>...>::type;                                                      \
838   };
839
840 #define INTERNAL_CATCH_NTTP_1(signature, ...)                                                                          \
841   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp {                                                     \
842   };                                                                                                                   \
843   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> constexpr auto get_wrapper() noexcept->Nttp<__VA_ARGS__>          \
844   {                                                                                                                    \
845     return {};                                                                                                         \
846   }                                                                                                                    \
847   template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList {                 \
848   };                                                                                                                   \
849   template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Cs>                                            \
850   constexpr auto get_wrapper() noexcept->NttpTemplateTypeList<Cs...>                                                   \
851   {                                                                                                                    \
852     return {};                                                                                                         \
853   }                                                                                                                    \
854                                                                                                                        \
855   template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container,                                        \
856             template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>    \
857   struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> {                                                  \
858     using type = TypeList<Container<__VA_ARGS__>>;                                                                     \
859   };                                                                                                                   \
860   template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container,                                        \
861             template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature),    \
862             typename... Elements>                                                                                      \
863   struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> {                                     \
864     using type = typename append<TypeList<Container<__VA_ARGS__>>,                                                     \
865                                  typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type;           \
866   };                                                                                                                   \
867   template <template <typename...> class Final,                                                                        \
868             template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Containers, typename... Types>                 \
869   struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> {                                      \
870     using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; \
871   };
872
873 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
874 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)                                                          \
875   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
876 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)                                                    \
877   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
878
879 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
880 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)                                                           \
881   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
882 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature, ...)                                                     \
883   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
884
885 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)                                                             \
886   template <typename Type> void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)                               \
887   {                                                                                                                    \
888     Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags); \
889   }
890
891 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)                                                         \
892   template <INTERNAL_CATCH_REMOVE_PARENS(signature)> void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)  \
893   {                                                                                                                    \
894     Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(),        \
895                    nameAndTags);                                                                                       \
896   }
897
898 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)                                                 \
899   template <typename Type> void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)   \
900   {                                                                                                                    \
901     Catch::AutoReg(Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);    \
902   }
903
904 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)                                                  \
905   template <INTERNAL_CATCH_REMOVE_PARENS(signature)>                                                                   \
906   void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)                         \
907   {                                                                                                                    \
908     Catch::AutoReg(Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className,           \
909                    nameAndTags);                                                                                       \
910   }
911
912 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
913 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)                                        \
914   template <typename TestType> struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> {                   \
915     void test();                                                                                                       \
916   }
917
918 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)                                  \
919   template <INTERNAL_CATCH_REMOVE_PARENS(signature)>                                                                   \
920   struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> {                                             \
921     void test();                                                                                                       \
922   }
923
924 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
925 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)                                                    \
926   template <typename TestType> void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
927 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)                                              \
928   template <INTERNAL_CATCH_REMOVE_PARENS(signature)>                                                                   \
929   void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
930
931 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
932 #define INTERNAL_CATCH_NTTP_0
933 #define INTERNAL_CATCH_NTTP_GEN(...)                                                                                   \
934   INTERNAL_CATCH_VA_NARGS_IMPL(                                                                                        \
935       __VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__),                             \
936       INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__),      \
937       INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__),      \
938       INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_0)
939 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...)                                                           \
940   INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,                          \
941                                INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,       \
942                                INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,       \
943                                INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,       \
944                                INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,       \
945                                INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)         \
946   (TestName, __VA_ARGS__)
947 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...)                                               \
948   INTERNAL_CATCH_VA_NARGS_IMPL("dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,                         \
949                                INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,     \
950                                INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,     \
951                                INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,     \
952                                INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,     \
953                                INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)       \
954   (TestName, ClassName, __VA_ARGS__)
955 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...)                                                              \
956   INTERNAL_CATCH_VA_NARGS_IMPL(                                                                                        \
957       "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD,                  \
958       INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD,   \
959       INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD,   \
960       INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0) \
961   (TestName, __VA_ARGS__)
962 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...)                                                                     \
963   INTERNAL_CATCH_VA_NARGS_IMPL(                                                                                        \
964       "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER,  \
965       INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER,                        \
966       INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER,                        \
967       INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)                                                    \
968   (TestFunc, __VA_ARGS__)
969 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...)                                                                  \
970   INTERNAL_CATCH_VA_NARGS_IMPL(                                                                                        \
971       "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,                        \
972       INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,            \
973       INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,            \
974       INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)              \
975   (TestName, __VA_ARGS__)
976 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...)                                                                 \
977   INTERNAL_CATCH_VA_NARGS_IMPL(                                                                                        \
978       "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X,                      \
979       INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X,         \
980       INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X,          \
981       INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)           \
982   (TestName, __VA_ARGS__)
983 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...)                                                                          \
984   INTERNAL_CATCH_VA_NARGS_IMPL(                                                                                        \
985       __VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG, INTERNAL_CATCH_REMOVE_PARENS_10_ARG,                           \
986       INTERNAL_CATCH_REMOVE_PARENS_9_ARG, INTERNAL_CATCH_REMOVE_PARENS_8_ARG, INTERNAL_CATCH_REMOVE_PARENS_7_ARG,      \
987       INTERNAL_CATCH_REMOVE_PARENS_6_ARG, INTERNAL_CATCH_REMOVE_PARENS_5_ARG, INTERNAL_CATCH_REMOVE_PARENS_4_ARG,      \
988       INTERNAL_CATCH_REMOVE_PARENS_3_ARG, INTERNAL_CATCH_REMOVE_PARENS_2_ARG, INTERNAL_CATCH_REMOVE_PARENS_1_ARG)      \
989   (__VA_ARGS__)
990 #else
991 #define INTERNAL_CATCH_NTTP_0(signature)
992 #define INTERNAL_CATCH_NTTP_GEN(...)                                                                                   \
993   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
994       __VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,         \
995       INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,                      \
996       INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)(__VA_ARGS__))
997 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...)                                                           \
998   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
999       "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,          \
1000       INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,                                \
1001       INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,                                \
1002       INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,                                \
1003       INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1,                                 \
1004       INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
1005 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...)                                               \
1006   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
1007       "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,        \
1008       INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,                              \
1009       INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,                              \
1010       INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,                              \
1011       INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1,                               \
1012       INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
1013 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...)                                                              \
1014   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
1015       "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD,                  \
1016       INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD,   \
1017       INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD,   \
1018       INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0,                                       \
1019       INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
1020 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...)                                                                     \
1021   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
1022       "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER,  \
1023       INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER,                        \
1024       INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER,                        \
1025       INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
1026 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...)                                                                  \
1027   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
1028       "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,                        \
1029       INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,            \
1030       INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,            \
1031       INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST1,                                               \
1032       INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
1033 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...)                                                                 \
1034   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
1035       "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X,                      \
1036       INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X,         \
1037       INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X,          \
1038       INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1,                                             \
1039       INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
1040 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...)                                                                          \
1041   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(                                                            \
1042       __VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG, INTERNAL_CATCH_REMOVE_PARENS_10_ARG,                           \
1043       INTERNAL_CATCH_REMOVE_PARENS_9_ARG, INTERNAL_CATCH_REMOVE_PARENS_8_ARG, INTERNAL_CATCH_REMOVE_PARENS_7_ARG,      \
1044       INTERNAL_CATCH_REMOVE_PARENS_6_ARG, INTERNAL_CATCH_REMOVE_PARENS_5_ARG, INTERNAL_CATCH_REMOVE_PARENS_4_ARG,      \
1045       INTERNAL_CATCH_REMOVE_PARENS_3_ARG, INTERNAL_CATCH_REMOVE_PARENS_2_ARG,                                          \
1046       INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
1047 #endif
1048
1049 // end catch_preprocessor.hpp
1050 // start catch_meta.hpp
1051
1052 #include <type_traits>
1053
1054 namespace Catch {
1055 template <typename T> struct always_false : std::false_type {
1056 };
1057
1058 template <typename> struct true_given : std::true_type {
1059 };
1060 struct is_callable_tester {
1061   template <typename Fun, typename... Args>
1062   true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
1063   template <typename...> std::false_type static test(...);
1064 };
1065
1066 template <typename T> struct is_callable;
1067
1068 template <typename Fun, typename... Args>
1069 struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {
1070 };
1071
1072 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
1073 // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
1074 // replaced with std::invoke_result here.
1075 template <typename Func, typename... U>
1076 using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
1077 #else
1078 // Keep ::type here because we still support C++11
1079 template <typename Func, typename... U>
1080 using FunctionReturnType =
1081     typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
1082 #endif
1083
1084 } // namespace Catch
1085
1086 namespace mpl_ {
1087 struct na;
1088 }
1089
1090 // end catch_meta.hpp
1091 namespace Catch {
1092
1093 template <typename C> class TestInvokerAsMethod : public ITestInvoker {
1094   void (C::*m_testAsMethod)();
1095
1096 public:
1097   TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod) {}
1098
1099   void invoke() const override
1100   {
1101     C obj;
1102     (obj.*m_testAsMethod)();
1103   }
1104 };
1105
1106 auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker*;
1107
1108 template <typename C> auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker*
1109 {
1110   return new (std::nothrow) TestInvokerAsMethod<C>(testAsMethod);
1111 }
1112
1113 struct NameAndTags {
1114   NameAndTags(StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef()) noexcept;
1115   StringRef name;
1116   StringRef tags;
1117 };
1118
1119 struct AutoReg : NonCopyable {
1120   AutoReg(ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod,
1121           NameAndTags const& nameAndTags) noexcept;
1122   ~AutoReg();
1123 };
1124
1125 } // end namespace Catch
1126
1127 #if defined(CATCH_CONFIG_DISABLE)
1128 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(TestName, ...) static void TestName()
1129 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(TestName, ClassName, ...)                                       \
1130   namespace {                                                                                                          \
1131   struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) {                                                          \
1132     void test();                                                                                                       \
1133   };                                                                                                                   \
1134   }                                                                                                                    \
1135   void TestName::test()
1136 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(TestName, TestFunc, Name, Tags, Signature, ...)            \
1137   INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1138 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(TestNameClass, TestName, ClassName, Name, Tags,     \
1139                                                                    Signature, ...)                                     \
1140   namespace {                                                                                                          \
1141   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName)                                                                    \
1142   {                                                                                                                    \
1143     INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));              \
1144   }                                                                                                                    \
1145   }                                                                                                                    \
1146   INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1147
1148 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1149 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...)                                             \
1150   INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(                                                                 \
1151       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1152       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags,              \
1153       typename TestType, __VA_ARGS__)
1154 #else
1155 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...)                                             \
1156   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(                                     \
1157       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1158       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags,              \
1159       typename TestType, __VA_ARGS__))
1160 #endif
1161
1162 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1163 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...)                              \
1164   INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(                                                                 \
1165       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1166       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, Signature,   \
1167       __VA_ARGS__)
1168 #else
1169 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...)                              \
1170   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(                                     \
1171       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1172       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, Signature,   \
1173       __VA_ARGS__))
1174 #endif
1175
1176 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1177 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...)                           \
1178   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(                                                          \
1179       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1180       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, typename T,  \
1181       __VA_ARGS__)
1182 #else
1183 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...)                           \
1184   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(                              \
1185       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1186       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, typename T,  \
1187       __VA_ARGS__))
1188 #endif
1189
1190 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1191 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(ClassName, Name, Tags, Signature, ...)            \
1192   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(                                                          \
1193       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1194       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, Signature,   \
1195       __VA_ARGS__)
1196 #else
1197 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(ClassName, Name, Tags, Signature, ...)            \
1198   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(                              \
1199       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1200       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, Signature,   \
1201       __VA_ARGS__))
1202 #endif
1203 #endif
1204
1205 ///////////////////////////////////////////////////////////////////////////////
1206 #define INTERNAL_CATCH_TESTCASE2(TestName, ...)                                                                        \
1207   static void TestName();                                                                                              \
1208   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1209   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1210   namespace {                                                                                                          \
1211   Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName), CATCH_INTERNAL_LINEINFO, \
1212                                                            Catch::StringRef(), Catch::NameAndTags{__VA_ARGS__});       \
1213   } /* NOLINT */                                                                                                       \
1214   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1215   static void TestName()
1216 #define INTERNAL_CATCH_TESTCASE(...)                                                                                   \
1217   INTERNAL_CATCH_TESTCASE2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), __VA_ARGS__)
1218
1219 ///////////////////////////////////////////////////////////////////////////////
1220 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE(QualifiedMethod, ...)                                                       \
1221   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1222   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1223   namespace {                                                                                                          \
1224   Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&QualifiedMethod),                   \
1225                                                            CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod,              \
1226                                                            Catch::NameAndTags{__VA_ARGS__});                           \
1227   } /* NOLINT */                                                                                                       \
1228   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1229
1230 ///////////////////////////////////////////////////////////////////////////////
1231 #define INTERNAL_CATCH_TEST_CASE_METHOD2(TestName, ClassName, ...)                                                     \
1232   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1233   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1234   namespace {                                                                                                          \
1235   struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) {                                                          \
1236     void test();                                                                                                       \
1237   };                                                                                                                   \
1238   Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName::test),                    \
1239                                                            CATCH_INTERNAL_LINEINFO, #ClassName,                        \
1240                                                            Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */              \
1241   }                                                                                                                    \
1242   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1243   void TestName::test()
1244 #define INTERNAL_CATCH_TEST_CASE_METHOD(ClassName, ...)                                                                \
1245   INTERNAL_CATCH_TEST_CASE_METHOD2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), ClassName, __VA_ARGS__)
1246
1247 ///////////////////////////////////////////////////////////////////////////////
1248 #define INTERNAL_CATCH_REGISTER_TESTCASE(Function, ...)                                                                \
1249   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1250   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1251   Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(Function), CATCH_INTERNAL_LINEINFO,  \
1252                                                            Catch::StringRef(),                                         \
1253                                                            Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */              \
1254   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1255
1256 ///////////////////////////////////////////////////////////////////////////////
1257 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ...)                            \
1258   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1259   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1260   CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                                                                       \
1261   CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                                                                     \
1262   INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));                                  \
1263   namespace {                                                                                                          \
1264   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName)                                                                    \
1265   {                                                                                                                    \
1266     INTERNAL_CATCH_TYPE_GEN                                                                                            \
1267     INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))                                                   \
1268     INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))                                     \
1269     template <typename... Types> struct TestName {                                                                     \
1270       TestName()                                                                                                       \
1271       {                                                                                                                \
1272         int index                          = 0;                                                                        \
1273         constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};   \
1274         using expander                     = int[];                                                                    \
1275         (void)expander{(reg_test(Types{}, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), Tags}),      \
1276                         index++)...}; /* NOLINT */                                                                     \
1277       }                                                                                                                \
1278     };                                                                                                                 \
1279     static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() {                                                    \
1280       TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();                                              \
1281       return 0;                                                                                                        \
1282     }();                                                                                                               \
1283   }                                                                                                                    \
1284   }                                                                                                                    \
1285   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1286   INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1287
1288 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1289 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...)                                                             \
1290   INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(                                                                                 \
1291       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1292       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags,              \
1293       typename TestType, __VA_ARGS__)
1294 #else
1295 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...)                                                             \
1296   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(                                                     \
1297       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1298       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags,              \
1299       typename TestType, __VA_ARGS__))
1300 #endif
1301
1302 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1303 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...)                                              \
1304   INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(                                                                                 \
1305       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1306       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, Signature,   \
1307       __VA_ARGS__)
1308 #else
1309 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...)                                              \
1310   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(                                                     \
1311       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1312       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, Signature,   \
1313       __VA_ARGS__))
1314 #endif
1315
1316 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes,           \
1317                                                    TypesList)                                                          \
1318   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1319   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1320   CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                                                                       \
1321   CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                                                                     \
1322   template <typename TestType> static void TestFuncName();                                                             \
1323   namespace {                                                                                                          \
1324   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName)                                                                    \
1325   {                                                                                                                    \
1326     INTERNAL_CATCH_TYPE_GEN                                                                                            \
1327     INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))                                                   \
1328     template <typename... Types> struct TestName {                                                                     \
1329       void reg_tests()                                                                                                 \
1330       {                                                                                                                \
1331         int index                          = 0;                                                                        \
1332         using expander                     = int[];                                                                    \
1333         constexpr char const* tmpl_types[] = {                                                                         \
1334             CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};         \
1335         constexpr char const* types_list[] = {                                                                         \
1336             CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};         \
1337         constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);                                         \
1338         (void)expander{                                                                                                \
1339             (Catch::AutoReg(Catch::makeTestInvoker(&TestFuncName<Types>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), \
1340                             Catch::NameAndTags{Name " - " + std::string(tmpl_types[index / num_types]) + "<" +         \
1341                                                    std::string(types_list[index % num_types]) + ">",                   \
1342                                                Tags}),                                                                 \
1343              index++)...}; /* NOLINT */                                                                                \
1344       }                                                                                                                \
1345     };                                                                                                                 \
1346     static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() {                                                    \
1347       using TestInit = typename create<                                                                                \
1348           TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()),                                  \
1349           TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;         \
1350       TestInit t;                                                                                                      \
1351       t.reg_tests();                                                                                                   \
1352       return 0;                                                                                                        \
1353     }();                                                                                                               \
1354   }                                                                                                                    \
1355   }                                                                                                                    \
1356   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1357   template <typename TestType> static void TestFuncName()
1358
1359 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1360 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)                                                     \
1361   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(                                                                          \
1362       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1363       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, typename T,  \
1364       __VA_ARGS__)
1365 #else
1366 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)                                                     \
1367   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(                                              \
1368       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1369       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, typename T,  \
1370       __VA_ARGS__))
1371 #endif
1372
1373 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1374 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)                                      \
1375   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(                                                                          \
1376       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1377       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, Signature,   \
1378       __VA_ARGS__)
1379 #else
1380 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)                                      \
1381   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(                                              \
1382       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1383       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, Signature,   \
1384       __VA_ARGS__))
1385 #endif
1386
1387 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)                             \
1388   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1389   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1390   CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                                                                     \
1391   template <typename TestType> static void TestFunc();                                                                 \
1392   namespace {                                                                                                          \
1393   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName)                                                                    \
1394   {                                                                                                                    \
1395     INTERNAL_CATCH_TYPE_GEN                                                                                            \
1396     template <typename... Types> struct TestName {                                                                     \
1397       void reg_tests()                                                                                                 \
1398       {                                                                                                                \
1399         int index      = 0;                                                                                            \
1400         using expander = int[];                                                                                        \
1401         (void)expander{                                                                                                \
1402             (Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Types>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(),     \
1403                             Catch::NameAndTags{Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " +  \
1404                                                    std::to_string(index),                                              \
1405                                                Tags}),                                                                 \
1406              index++)...}; /* NOLINT */                                                                                \
1407       }                                                                                                                \
1408     };                                                                                                                 \
1409     static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() {                                                    \
1410       using TestInit = typename convert<TestName, TmplList>::type;                                                     \
1411       TestInit t;                                                                                                      \
1412       t.reg_tests();                                                                                                   \
1413       return 0;                                                                                                        \
1414     }();                                                                                                               \
1415   }                                                                                                                    \
1416   }                                                                                                                    \
1417   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1418   template <typename TestType> static void TestFunc()
1419
1420 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList)                                                   \
1421   INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(                                                                            \
1422       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1423       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), Name, Tags, TmplList)
1424
1425 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, ...)     \
1426   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1427   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1428   CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                                                                       \
1429   CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                                                                     \
1430   namespace {                                                                                                          \
1431   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName)                                                                    \
1432   {                                                                                                                    \
1433     INTERNAL_CATCH_TYPE_GEN                                                                                            \
1434     INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))                                                   \
1435     INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));              \
1436     INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))                              \
1437     template <typename... Types> struct TestNameClass {                                                                \
1438       TestNameClass()                                                                                                  \
1439       {                                                                                                                \
1440         int index                          = 0;                                                                        \
1441         constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};   \
1442         using expander                     = int[];                                                                    \
1443         (void)expander{                                                                                                \
1444             (reg_test(Types{}, #ClassName, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), Tags}),     \
1445              index++)...}; /* NOLINT */                                                                                \
1446       }                                                                                                                \
1447     };                                                                                                                 \
1448     static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() {                                                    \
1449       TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();                                         \
1450       return 0;                                                                                                        \
1451     }();                                                                                                               \
1452   }                                                                                                                    \
1453   }                                                                                                                    \
1454   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1455   INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1456
1457 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1458 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...)                                           \
1459   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(                                                                          \
1460       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1461       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, typename T,  \
1462       __VA_ARGS__)
1463 #else
1464 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...)                                           \
1465   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(                                              \
1466       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1467       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, typename T,  \
1468       __VA_ARGS__))
1469 #endif
1470
1471 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1472 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...)                            \
1473   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(                                                                          \
1474       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1475       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, Signature,   \
1476       __VA_ARGS__)
1477 #else
1478 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...)                            \
1479   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(                                              \
1480       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____),                        \
1481       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), ClassName, Name, Tags, Signature,   \
1482       __VA_ARGS__))
1483 #endif
1484
1485 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature,  \
1486                                                            TmplTypes, TypesList)                                       \
1487   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1488   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1489   CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                                                                       \
1490   CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                                                                     \
1491   template <typename TestType> struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) {                   \
1492     void test();                                                                                                       \
1493   };                                                                                                                   \
1494   namespace {                                                                                                          \
1495   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass)                                                               \
1496   {                                                                                                                    \
1497     INTERNAL_CATCH_TYPE_GEN                                                                                            \
1498     INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))                                                   \
1499     template <typename... Types> struct TestNameClass {                                                                \
1500       void reg_tests()                                                                                                 \
1501       {                                                                                                                \
1502         int index                          = 0;                                                                        \
1503         using expander                     = int[];                                                                    \
1504         constexpr char const* tmpl_types[] = {                                                                         \
1505             CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};         \
1506         constexpr char const* types_list[] = {                                                                         \
1507             CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};         \
1508         constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);                                         \
1509         (void)expander{                                                                                                \
1510             (Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), CATCH_INTERNAL_LINEINFO, #ClassName,       \
1511                             Catch::NameAndTags{Name " - " + std::string(tmpl_types[index / num_types]) + "<" +         \
1512                                                    std::string(types_list[index % num_types]) + ">",                   \
1513                                                Tags}),                                                                 \
1514              index++)...}; /* NOLINT */                                                                                \
1515       }                                                                                                                \
1516     };                                                                                                                 \
1517     static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() {                                                    \
1518       using TestInit = typename create<                                                                                \
1519           TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()),                             \
1520           TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;         \
1521       TestInit t;                                                                                                      \
1522       t.reg_tests();                                                                                                   \
1523       return 0;                                                                                                        \
1524     }();                                                                                                               \
1525   }                                                                                                                    \
1526   }                                                                                                                    \
1527   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1528   template <typename TestType> void TestName<TestType>::test()
1529
1530 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1531 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...)                                   \
1532   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(                                                                  \
1533       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1534       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), ClassName, Name, Tags,   \
1535       typename T, __VA_ARGS__)
1536 #else
1537 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...)                                   \
1538   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(                                      \
1539       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1540       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), ClassName, Name, Tags,   \
1541       typename T, __VA_ARGS__))
1542 #endif
1543
1544 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1545 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...)                    \
1546   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(                                                                  \
1547       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1548       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), ClassName, Name, Tags,   \
1549       Signature, __VA_ARGS__)
1550 #else
1551 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...)                    \
1552   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(                                      \
1553       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1554       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), ClassName, Name, Tags,   \
1555       Signature, __VA_ARGS__))
1556 #endif
1557
1558 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplList)      \
1559   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
1560   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
1561   CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS                                                                     \
1562   template <typename TestType> struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) {                   \
1563     void test();                                                                                                       \
1564   };                                                                                                                   \
1565   namespace {                                                                                                          \
1566   namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName)                                                                    \
1567   {                                                                                                                    \
1568     INTERNAL_CATCH_TYPE_GEN                                                                                            \
1569     template <typename... Types> struct TestNameClass {                                                                \
1570       void reg_tests()                                                                                                 \
1571       {                                                                                                                \
1572         int index      = 0;                                                                                            \
1573         using expander = int[];                                                                                        \
1574         (void)expander{                                                                                                \
1575             (Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), CATCH_INTERNAL_LINEINFO, #ClassName,       \
1576                             Catch::NameAndTags{Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " +  \
1577                                                    std::to_string(index),                                              \
1578                                                Tags}),                                                                 \
1579              index++)...}; /* NOLINT */                                                                                \
1580       }                                                                                                                \
1581     };                                                                                                                 \
1582     static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() {                                                    \
1583       using TestInit = typename convert<TestNameClass, TmplList>::type;                                                \
1584       TestInit t;                                                                                                      \
1585       t.reg_tests();                                                                                                   \
1586       return 0;                                                                                                        \
1587     }();                                                                                                               \
1588   }                                                                                                                    \
1589   }                                                                                                                    \
1590   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
1591   template <typename TestType> void TestName<TestType>::test()
1592
1593 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList)                                 \
1594   INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2(                                                                     \
1595       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____),                                     \
1596       INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), ClassName, Name, Tags,   \
1597       TmplList)
1598
1599 // end catch_test_registry.h
1600 // start catch_capture.hpp
1601
1602 // start catch_assertionhandler.h
1603
1604 // start catch_assertioninfo.h
1605
1606 // start catch_result_type.h
1607
1608 namespace Catch {
1609
1610 // ResultWas::OfType enum
1611 struct ResultWas {
1612   enum OfType {
1613     Unknown = -1,
1614     Ok      = 0,
1615     Info    = 1,
1616     Warning = 2,
1617
1618     FailureBit = 0x10,
1619
1620     ExpressionFailed = FailureBit | 1,
1621     ExplicitFailure  = FailureBit | 2,
1622
1623     Exception = 0x100 | FailureBit,
1624
1625     ThrewException      = Exception | 1,
1626     DidntThrowException = Exception | 2,
1627
1628     FatalErrorCondition = 0x200 | FailureBit
1629
1630   };
1631 };
1632
1633 bool isOk(ResultWas::OfType resultType);
1634 bool isJustInfo(int flags);
1635
1636 // ResultDisposition::Flags enum
1637 struct ResultDisposition {
1638   enum Flags {
1639     Normal = 0x01,
1640
1641     ContinueOnFailure = 0x02, // Failures fail test, but execution continues
1642     FalseTest         = 0x04, // Prefix expression with !
1643     SuppressFail      = 0x08  // Failures are reported but do not fail the test
1644   };
1645 };
1646
1647 ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs);
1648
1649 bool shouldContinueOnFailure(int flags);
1650 inline bool isFalseTest(int flags)
1651 {
1652   return (flags & ResultDisposition::FalseTest) != 0;
1653 }
1654 bool shouldSuppressFailure(int flags);
1655
1656 } // end namespace Catch
1657
1658 // end catch_result_type.h
1659 namespace Catch {
1660
1661 struct AssertionInfo {
1662   StringRef macroName;
1663   SourceLineInfo lineInfo;
1664   StringRef capturedExpression;
1665   ResultDisposition::Flags resultDisposition;
1666
1667   // We want to delete this constructor but a compiler bug in 4.8 means
1668   // the struct is then treated as non-aggregate
1669   // AssertionInfo() = delete;
1670 };
1671
1672 } // end namespace Catch
1673
1674 // end catch_assertioninfo.h
1675 // start catch_decomposer.h
1676
1677 // start catch_tostring.h
1678
1679 #include <cstddef>
1680 #include <string>
1681 #include <type_traits>
1682 #include <vector>
1683 // start catch_stream.h
1684
1685 #include <cstddef>
1686 #include <iosfwd>
1687 #include <ostream>
1688
1689 namespace Catch {
1690
1691 std::ostream& cout();
1692 std::ostream& cerr();
1693 std::ostream& clog();
1694
1695 class StringRef;
1696
1697 struct IStream {
1698   virtual ~IStream();
1699   virtual std::ostream& stream() const = 0;
1700 };
1701
1702 auto makeStream(StringRef const& filename) -> IStream const*;
1703
1704 class ReusableStringStream : NonCopyable {
1705   std::size_t m_index;
1706   std::ostream* m_oss;
1707
1708 public:
1709   ReusableStringStream();
1710   ~ReusableStringStream();
1711
1712   auto str() const -> std::string;
1713
1714   template <typename T> auto operator<<(T const& value) -> ReusableStringStream&
1715   {
1716     *m_oss << value;
1717     return *this;
1718   }
1719   auto get() -> std::ostream& { return *m_oss; }
1720 };
1721 } // namespace Catch
1722
1723 // end catch_stream.h
1724 // start catch_interfaces_enum_values_registry.h
1725
1726 #include <vector>
1727
1728 namespace Catch {
1729
1730 namespace Detail {
1731 struct EnumInfo {
1732   StringRef m_name;
1733   std::vector<std::pair<int, StringRef>> m_values;
1734
1735   ~EnumInfo();
1736
1737   StringRef lookup(int value) const;
1738 };
1739 } // namespace Detail
1740
1741 struct IMutableEnumValuesRegistry {
1742   virtual ~IMutableEnumValuesRegistry();
1743
1744   virtual Detail::EnumInfo const& registerEnum(StringRef enumName, StringRef allEnums,
1745                                                std::vector<int> const& values) = 0;
1746
1747   template <typename E>
1748   Detail::EnumInfo const& registerEnum(StringRef enumName, StringRef allEnums, std::initializer_list<E> values)
1749   {
1750     static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1751     std::vector<int> intValues;
1752     intValues.reserve(values.size());
1753     for (auto enumValue : values)
1754       intValues.push_back(static_cast<int>(enumValue));
1755     return registerEnum(enumName, allEnums, intValues);
1756   }
1757 };
1758
1759 } // namespace Catch
1760
1761 // end catch_interfaces_enum_values_registry.h
1762
1763 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1764 #include <string_view>
1765 #endif
1766
1767 #ifdef __OBJC__
1768 // start catch_objc_arc.hpp
1769
1770 #import <Foundation/Foundation.h>
1771
1772 #ifdef __has_feature
1773 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1774 #else
1775 #define CATCH_ARC_ENABLED 0
1776 #endif
1777
1778 void arcSafeRelease(NSObject* obj);
1779 id performOptionalSelector(id obj, SEL sel);
1780
1781 #if !CATCH_ARC_ENABLED
1782 inline void arcSafeRelease(NSObject* obj)
1783 {
1784   [obj release];
1785 }
1786 inline id performOptionalSelector(id obj, SEL sel)
1787 {
1788   if ([obj respondsToSelector:sel])
1789     return [obj performSelector:sel];
1790   return nil;
1791 }
1792 #define CATCH_UNSAFE_UNRETAINED
1793 #define CATCH_ARC_STRONG
1794 #else
1795 inline void arcSafeRelease(NSObject*) {}
1796 inline id performOptionalSelector(id obj, SEL sel)
1797 {
1798 #ifdef __clang__
1799 #pragma clang diagnostic push
1800 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1801 #endif
1802   if ([obj respondsToSelector:sel])
1803     return [obj performSelector:sel];
1804 #ifdef __clang__
1805 #pragma clang diagnostic pop
1806 #endif
1807   return nil;
1808 }
1809 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1810 #define CATCH_ARC_STRONG __strong
1811 #endif
1812
1813 // end catch_objc_arc.hpp
1814 #endif
1815
1816 #ifdef _MSC_VER
1817 #pragma warning(push)
1818 #pragma warning(                                                                                                       \
1819     disable : 4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1820 #endif
1821
1822 namespace Catch {
1823 namespace Detail {
1824
1825 extern const std::string unprintableString;
1826
1827 std::string rawMemoryToString(const void* object, std::size_t size);
1828
1829 template <typename T> std::string rawMemoryToString(const T& object)
1830 {
1831   return rawMemoryToString(&object, sizeof(object));
1832 }
1833
1834 template <typename T> class IsStreamInsertable {
1835   template <typename Stream, typename U>
1836   static auto test(int) -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
1837
1838   template <typename, typename> static auto test(...) -> std::false_type;
1839
1840 public:
1841   static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1842 };
1843
1844 template <typename E> std::string convertUnknownEnumToString(E e);
1845
1846 template <typename T>
1847 typename std::enable_if<!std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value, std::string>::type
1848 convertUnstreamable(T const&)
1849 {
1850   return Detail::unprintableString;
1851 }
1852 template <typename T>
1853 typename std::enable_if<!std::is_enum<T>::value && std::is_base_of<std::exception, T>::value, std::string>::type
1854 convertUnstreamable(T const& ex)
1855 {
1856   return ex.what();
1857 }
1858
1859 template <typename T>
1860 typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable(T const& value)
1861 {
1862   return convertUnknownEnumToString(value);
1863 }
1864
1865 #if defined(_MANAGED)
1866 //! Convert a CLR string to a utf8 std::string
1867 template <typename T> std::string clrReferenceToString(T ^ ref)
1868 {
1869   if (ref == nullptr)
1870     return std::string("null");
1871   auto bytes                   = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1872   cli::pin_ptr<System::Byte> p = &bytes[0];
1873   return std::string(reinterpret_cast<char const*>(p), bytes->Length);
1874 }
1875 #endif
1876
1877 } // namespace Detail
1878
1879 // If we decide for C++14, change these to enable_if_ts
1880 template <typename T, typename = void> struct StringMaker {
1881   template <typename Fake = T>
1882   static typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1883   convert(const Fake& value)
1884   {
1885     ReusableStringStream rss;
1886     // NB: call using the function-like syntax to avoid ambiguity with
1887     // user-defined templated operator<< under clang.
1888     rss.operator<<(value);
1889     return rss.str();
1890   }
1891
1892   template <typename Fake = T>
1893   static typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1894   convert(const Fake& value)
1895   {
1896 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1897     return Detail::convertUnstreamable(value);
1898 #else
1899     return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1900 #endif
1901   }
1902 };
1903
1904 namespace Detail {
1905
1906 // This function dispatches all stringification requests inside of Catch.
1907 // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1908 template <typename T> std::string stringify(const T& e)
1909 {
1910   return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1911 }
1912
1913 template <typename E> std::string convertUnknownEnumToString(E e)
1914 {
1915   return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1916 }
1917
1918 #if defined(_MANAGED)
1919 template <typename T> std::string stringify(T ^ e)
1920 {
1921   return ::Catch::StringMaker<T ^>::convert(e);
1922 }
1923 #endif
1924
1925 } // namespace Detail
1926
1927 // Some predefined specializations
1928
1929 template <> struct StringMaker<std::string> {
1930   static std::string convert(const std::string& str);
1931 };
1932
1933 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1934 template <> struct StringMaker<std::string_view> {
1935   static std::string convert(std::string_view str);
1936 };
1937 #endif
1938
1939 template <> struct StringMaker<char const*> {
1940   static std::string convert(char const* str);
1941 };
1942 template <> struct StringMaker<char*> {
1943   static std::string convert(char* str);
1944 };
1945
1946 #ifdef CATCH_CONFIG_WCHAR
1947 template <> struct StringMaker<std::wstring> {
1948   static std::string convert(const std::wstring& wstr);
1949 };
1950
1951 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1952 template <> struct StringMaker<std::wstring_view> {
1953   static std::string convert(std::wstring_view str);
1954 };
1955 #endif
1956
1957 template <> struct StringMaker<wchar_t const*> {
1958   static std::string convert(wchar_t const* str);
1959 };
1960 template <> struct StringMaker<wchar_t*> {
1961   static std::string convert(wchar_t* str);
1962 };
1963 #endif
1964
1965 // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1966 //      while keeping string semantics?
1967 template <int SZ> struct StringMaker<char[SZ]> {
1968   static std::string convert(char const* str) { return ::Catch::Detail::stringify(std::string{str}); }
1969 };
1970 template <int SZ> struct StringMaker<signed char[SZ]> {
1971   static std::string convert(signed char const* str)
1972   {
1973     return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const*>(str)});
1974   }
1975 };
1976 template <int SZ> struct StringMaker<unsigned char[SZ]> {
1977   static std::string convert(unsigned char const* str)
1978   {
1979     return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const*>(str)});
1980   }
1981 };
1982
1983 #if defined(CATCH_CONFIG_CPP17_BYTE)
1984 template <> struct StringMaker<std::byte> {
1985   static std::string convert(std::byte value);
1986 };
1987 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
1988 template <> struct StringMaker<int> {
1989   static std::string convert(int value);
1990 };
1991 template <> struct StringMaker<long> {
1992   static std::string convert(long value);
1993 };
1994 template <> struct StringMaker<long long> {
1995   static std::string convert(long long value);
1996 };
1997 template <> struct StringMaker<unsigned int> {
1998   static std::string convert(unsigned int value);
1999 };
2000 template <> struct StringMaker<unsigned long> {
2001   static std::string convert(unsigned long value);
2002 };
2003 template <> struct StringMaker<unsigned long long> {
2004   static std::string convert(unsigned long long value);
2005 };
2006
2007 template <> struct StringMaker<bool> {
2008   static std::string convert(bool b);
2009 };
2010
2011 template <> struct StringMaker<char> {
2012   static std::string convert(char c);
2013 };
2014 template <> struct StringMaker<signed char> {
2015   static std::string convert(signed char c);
2016 };
2017 template <> struct StringMaker<unsigned char> {
2018   static std::string convert(unsigned char c);
2019 };
2020
2021 template <> struct StringMaker<std::nullptr_t> {
2022   static std::string convert(std::nullptr_t);
2023 };
2024
2025 template <> struct StringMaker<float> {
2026   static std::string convert(float value);
2027   static int precision;
2028 };
2029
2030 template <> struct StringMaker<double> {
2031   static std::string convert(double value);
2032   static int precision;
2033 };
2034
2035 template <typename T> struct StringMaker<T*> {
2036   template <typename U> static std::string convert(U* p)
2037   {
2038     if (p) {
2039       return ::Catch::Detail::rawMemoryToString(p);
2040     } else {
2041       return "nullptr";
2042     }
2043   }
2044 };
2045
2046 template <typename R, typename C> struct StringMaker<R C::*> {
2047   static std::string convert(R C::*p)
2048   {
2049     if (p) {
2050       return ::Catch::Detail::rawMemoryToString(p);
2051     } else {
2052       return "nullptr";
2053     }
2054   }
2055 };
2056
2057 #if defined(_MANAGED)
2058 template <typename T> struct StringMaker<T ^> {
2059   static std::string convert(T ^ ref) { return ::Catch::Detail::clrReferenceToString(ref); }
2060 };
2061 #endif
2062
2063 namespace Detail {
2064 template <typename InputIterator, typename Sentinel = InputIterator>
2065 std::string rangeToString(InputIterator first, Sentinel last)
2066 {
2067   ReusableStringStream rss;
2068   rss << "{ ";
2069   if (first != last) {
2070     rss << ::Catch::Detail::stringify(*first);
2071     for (++first; first != last; ++first)
2072       rss << ", " << ::Catch::Detail::stringify(*first);
2073   }
2074   rss << " }";
2075   return rss.str();
2076 }
2077 } // namespace Detail
2078
2079 #ifdef __OBJC__
2080 template <> struct StringMaker<NSString*> {
2081   static std::string convert(NSString* nsstring)
2082   {
2083     if (!nsstring)
2084       return "nil";
2085     return std::string("@") + [nsstring UTF8String];
2086   }
2087 };
2088 template <> struct StringMaker<NSObject*> {
2089   static std::string convert(NSObject* nsObject) { return ::Catch::Detail::stringify([nsObject description]); }
2090 };
2091 namespace Detail {
2092 inline std::string stringify(NSString* nsstring)
2093 {
2094   return StringMaker<NSString*>::convert(nsstring);
2095 }
2096
2097 } // namespace Detail
2098 #endif // __OBJC__
2099
2100 } // namespace Catch
2101
2102 //////////////////////////////////////////////////////
2103 // Separate std-lib types stringification, so it can be selectively enabled
2104 // This means that we do not bring in
2105
2106 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
2107 #define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2108 #define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2109 #define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2110 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2111 #define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2112 #endif
2113
2114 // Separate std::pair specialization
2115 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
2116 #include <utility>
2117 namespace Catch {
2118 template <typename T1, typename T2> struct StringMaker<std::pair<T1, T2>> {
2119   static std::string convert(const std::pair<T1, T2>& pair)
2120   {
2121     ReusableStringStream rss;
2122     rss << "{ " << ::Catch::Detail::stringify(pair.first) << ", " << ::Catch::Detail::stringify(pair.second) << " }";
2123     return rss.str();
2124   }
2125 };
2126 } // namespace Catch
2127 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2128
2129 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
2130 #include <optional>
2131 namespace Catch {
2132 template <typename T> struct StringMaker<std::optional<T>> {
2133   static std::string convert(const std::optional<T>& optional)
2134   {
2135     ReusableStringStream rss;
2136     if (optional.has_value()) {
2137       rss << ::Catch::Detail::stringify(*optional);
2138     } else {
2139       rss << "{ }";
2140     }
2141     return rss.str();
2142   }
2143 };
2144 } // namespace Catch
2145 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2146
2147 // Separate std::tuple specialization
2148 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
2149 #include <tuple>
2150 namespace Catch {
2151 namespace Detail {
2152 template <typename Tuple, std::size_t N = 0, bool = (N < std::tuple_size<Tuple>::value)> struct TupleElementPrinter {
2153   static void print(const Tuple& tuple, std::ostream& os)
2154   {
2155     os << (N ? ", " : " ") << ::Catch::Detail::stringify(std::get<N>(tuple));
2156     TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
2157   }
2158 };
2159
2160 template <typename Tuple, std::size_t N> struct TupleElementPrinter<Tuple, N, false> {
2161   static void print(const Tuple&, std::ostream&) {}
2162 };
2163
2164 } // namespace Detail
2165
2166 template <typename... Types> struct StringMaker<std::tuple<Types...>> {
2167   static std::string convert(const std::tuple<Types...>& tuple)
2168   {
2169     ReusableStringStream rss;
2170     rss << '{';
2171     Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
2172     rss << " }";
2173     return rss.str();
2174   }
2175 };
2176 } // namespace Catch
2177 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2178
2179 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
2180 #include <variant>
2181 namespace Catch {
2182 template <> struct StringMaker<std::monostate> {
2183   static std::string convert(const std::monostate&) { return "{ }"; }
2184 };
2185
2186 template <typename... Elements> struct StringMaker<std::variant<Elements...>> {
2187   static std::string convert(const std::variant<Elements...>& variant)
2188   {
2189     if (variant.valueless_by_exception()) {
2190       return "{valueless variant}";
2191     } else {
2192       return std::visit([](const auto& value) { return ::Catch::Detail::stringify(value); }, variant);
2193     }
2194   }
2195 };
2196 } // namespace Catch
2197 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2198
2199 namespace Catch {
2200 // Import begin/ end from std here
2201 using std::begin;
2202 using std::end;
2203
2204 namespace detail {
2205 template <typename...> struct void_type {
2206   using type = void;
2207 };
2208
2209 template <typename T, typename = void> struct is_range_impl : std::false_type {
2210 };
2211
2212 template <typename T>
2213 struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {
2214 };
2215 } // namespace detail
2216
2217 template <typename T> struct is_range : detail::is_range_impl<T> {
2218 };
2219
2220 #if defined(_MANAGED) // Managed types are never ranges
2221 template <typename T> struct is_range<T ^> {
2222   static const bool value = false;
2223 };
2224 #endif
2225
2226 template <typename Range> std::string rangeToString(Range const& range)
2227 {
2228   return ::Catch::Detail::rangeToString(begin(range), end(range));
2229 }
2230
2231 // Handle vector<bool> specially
2232 template <typename Allocator> std::string rangeToString(std::vector<bool, Allocator> const& v)
2233 {
2234   ReusableStringStream rss;
2235   rss << "{ ";
2236   bool first = true;
2237   for (bool b : v) {
2238     if (first)
2239       first = false;
2240     else
2241       rss << ", ";
2242     rss << ::Catch::Detail::stringify(b);
2243   }
2244   rss << " }";
2245   return rss.str();
2246 }
2247
2248 template <typename R>
2249 struct StringMaker<
2250     R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
2251   static std::string convert(R const& range) { return rangeToString(range); }
2252 };
2253
2254 template <typename T, int SZ> struct StringMaker<T[SZ]> {
2255   static std::string convert(T const (&arr)[SZ]) { return rangeToString(arr); }
2256 };
2257
2258 } // namespace Catch
2259
2260 // Separate std::chrono::duration specialization
2261 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2262 #include <chrono>
2263 #include <ctime>
2264 #include <ratio>
2265
2266 namespace Catch {
2267
2268 template <class Ratio> struct ratio_string {
2269   static std::string symbol();
2270 };
2271
2272 template <class Ratio> std::string ratio_string<Ratio>::symbol()
2273 {
2274   Catch::ReusableStringStream rss;
2275   rss << '[' << Ratio::num << '/' << Ratio::den << ']';
2276   return rss.str();
2277 }
2278 template <> struct ratio_string<std::atto> {
2279   static std::string symbol();
2280 };
2281 template <> struct ratio_string<std::femto> {
2282   static std::string symbol();
2283 };
2284 template <> struct ratio_string<std::pico> {
2285   static std::string symbol();
2286 };
2287 template <> struct ratio_string<std::nano> {
2288   static std::string symbol();
2289 };
2290 template <> struct ratio_string<std::micro> {
2291   static std::string symbol();
2292 };
2293 template <> struct ratio_string<std::milli> {
2294   static std::string symbol();
2295 };
2296
2297 ////////////
2298 // std::chrono::duration specializations
2299 template <typename Value, typename Ratio> struct StringMaker<std::chrono::duration<Value, Ratio>> {
2300   static std::string convert(std::chrono::duration<Value, Ratio> const& duration)
2301   {
2302     ReusableStringStream rss;
2303     rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2304     return rss.str();
2305   }
2306 };
2307 template <typename Value> struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2308   static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration)
2309   {
2310     ReusableStringStream rss;
2311     rss << duration.count() << " s";
2312     return rss.str();
2313   }
2314 };
2315 template <typename Value> struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2316   static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration)
2317   {
2318     ReusableStringStream rss;
2319     rss << duration.count() << " m";
2320     return rss.str();
2321   }
2322 };
2323 template <typename Value> struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2324   static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration)
2325   {
2326     ReusableStringStream rss;
2327     rss << duration.count() << " h";
2328     return rss.str();
2329   }
2330 };
2331
2332 ////////////
2333 // std::chrono::time_point specialization
2334 // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2335 template <typename Clock, typename Duration> struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2336   static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point)
2337   {
2338     return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2339   }
2340 };
2341 // std::chrono::time_point<system_clock> specialization
2342 template <typename Duration> struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
2343   static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point)
2344   {
2345     auto converted = std::chrono::system_clock::to_time_t(time_point);
2346
2347 #ifdef _MSC_VER
2348     std::tm timeInfo = {};
2349     gmtime_s(&timeInfo, &converted);
2350 #else
2351     std::tm* timeInfo = std::gmtime(&converted);
2352 #endif
2353
2354     auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2355     char timeStamp[timeStampSize];
2356     const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
2357
2358 #ifdef _MSC_VER
2359     std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2360 #else
2361     std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2362 #endif
2363     return std::string(timeStamp);
2364   }
2365 };
2366 } // namespace Catch
2367 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2368
2369 #define INTERNAL_CATCH_REGISTER_ENUM(enumName, ...)                                                                    \
2370   namespace Catch {                                                                                                    \
2371   template <> struct StringMaker<enumName> {                                                                           \
2372     static std::string convert(enumName value)                                                                         \
2373     {                                                                                                                  \
2374       static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum(      \
2375           #enumName, #__VA_ARGS__, {__VA_ARGS__});                                                                     \
2376       return static_cast<std::string>(enumInfo.lookup(static_cast<int>(value)));                                       \
2377     }                                                                                                                  \
2378   };                                                                                                                   \
2379   }
2380
2381 #define CATCH_REGISTER_ENUM(enumName, ...) INTERNAL_CATCH_REGISTER_ENUM(enumName, __VA_ARGS__)
2382
2383 #ifdef _MSC_VER
2384 #pragma warning(pop)
2385 #endif
2386
2387 // end catch_tostring.h
2388 #include <iosfwd>
2389
2390 #ifdef _MSC_VER
2391 #pragma warning(push)
2392 #pragma warning(disable : 4389) // '==' : signed/unsigned mismatch
2393 #pragma warning(disable : 4018) // more "signed/unsigned mismatch"
2394 #pragma warning(disable : 4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2395 #pragma warning(disable : 4180) // qualifier applied to function type has no meaning
2396 #pragma warning(disable : 4800) // Forcing result to true or false
2397 #endif
2398
2399 namespace Catch {
2400
2401 struct ITransientExpression {
2402   auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
2403   auto getResult() const -> bool { return m_result; }
2404   virtual void streamReconstructedExpression(std::ostream& os) const = 0;
2405
2406   ITransientExpression(bool isBinaryExpression, bool result)
2407       : m_isBinaryExpression(isBinaryExpression), m_result(result)
2408   {
2409   }
2410
2411   // We don't actually need a virtual destructor, but many static analysers
2412   // complain if it's not here :-(
2413   virtual ~ITransientExpression();
2414
2415   bool m_isBinaryExpression;
2416   bool m_result;
2417 };
2418
2419 void formatReconstructedExpression(std::ostream& os, std::string const& lhs, StringRef op, std::string const& rhs);
2420
2421 template <typename LhsT, typename RhsT> class BinaryExpr : public ITransientExpression {
2422   LhsT m_lhs;
2423   StringRef m_op;
2424   RhsT m_rhs;
2425
2426   void streamReconstructedExpression(std::ostream& os) const override
2427   {
2428     formatReconstructedExpression(os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
2429   }
2430
2431 public:
2432   BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
2433       : ITransientExpression{true, comparisonResult}, m_lhs(lhs), m_op(op), m_rhs(rhs)
2434   {
2435   }
2436
2437   template <typename T> auto operator&&(T) const -> BinaryExpr<LhsT, RhsT const&> const
2438   {
2439     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2440                                           "wrap the expression inside parentheses, or decompose it");
2441   }
2442
2443   template <typename T> auto operator||(T) const -> BinaryExpr<LhsT, RhsT const&> const
2444   {
2445     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2446                                           "wrap the expression inside parentheses, or decompose it");
2447   }
2448
2449   template <typename T> auto operator==(T) const -> BinaryExpr<LhsT, RhsT const&> const
2450   {
2451     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2452                                           "wrap the expression inside parentheses, or decompose it");
2453   }
2454
2455   template <typename T> auto operator!=(T) const -> BinaryExpr<LhsT, RhsT const&> const
2456   {
2457     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2458                                           "wrap the expression inside parentheses, or decompose it");
2459   }
2460
2461   template <typename T> auto operator>(T) const -> BinaryExpr<LhsT, RhsT const&> const
2462   {
2463     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2464                                           "wrap the expression inside parentheses, or decompose it");
2465   }
2466
2467   template <typename T> auto operator<(T) const -> BinaryExpr<LhsT, RhsT const&> const
2468   {
2469     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2470                                           "wrap the expression inside parentheses, or decompose it");
2471   }
2472
2473   template <typename T> auto operator>=(T) const -> BinaryExpr<LhsT, RhsT const&> const
2474   {
2475     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2476                                           "wrap the expression inside parentheses, or decompose it");
2477   }
2478
2479   template <typename T> auto operator<=(T) const -> BinaryExpr<LhsT, RhsT const&> const
2480   {
2481     static_assert(always_false<T>::value, "chained comparisons are not supported inside assertions, "
2482                                           "wrap the expression inside parentheses, or decompose it");
2483   }
2484 };
2485
2486 template <typename LhsT> class UnaryExpr : public ITransientExpression {
2487   LhsT m_lhs;
2488
2489   void streamReconstructedExpression(std::ostream& os) const override { os << Catch::Detail::stringify(m_lhs); }
2490
2491 public:
2492   explicit UnaryExpr(LhsT lhs) : ITransientExpression{false, static_cast<bool>(lhs)}, m_lhs(lhs) {}
2493 };
2494
2495 // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2496 template <typename LhsT, typename RhsT> auto compareEqual(LhsT const& lhs, RhsT const& rhs) -> bool
2497 {
2498   return static_cast<bool>(lhs == rhs);
2499 }
2500 template <typename T> auto compareEqual(T* const& lhs, int rhs) -> bool
2501 {
2502   return lhs == reinterpret_cast<void const*>(rhs);
2503 }
2504 template <typename T> auto compareEqual(T* const& lhs, long rhs) -> bool
2505 {
2506   return lhs == reinterpret_cast<void const*>(rhs);
2507 }
2508 template <typename T> auto compareEqual(int lhs, T* const& rhs) -> bool
2509 {
2510   return reinterpret_cast<void const*>(lhs) == rhs;
2511 }
2512 template <typename T> auto compareEqual(long lhs, T* const& rhs) -> bool
2513 {
2514   return reinterpret_cast<void const*>(lhs) == rhs;
2515 }
2516
2517 template <typename LhsT, typename RhsT> auto compareNotEqual(LhsT const& lhs, RhsT&& rhs) -> bool
2518 {
2519   return static_cast<bool>(lhs != rhs);
2520 }
2521 template <typename T> auto compareNotEqual(T* const& lhs, int rhs) -> bool
2522 {
2523   return lhs != reinterpret_cast<void const*>(rhs);
2524 }
2525 template <typename T> auto compareNotEqual(T* const& lhs, long rhs) -> bool
2526 {
2527   return lhs != reinterpret_cast<void const*>(rhs);
2528 }
2529 template <typename T> auto compareNotEqual(int lhs, T* const& rhs) -> bool
2530 {
2531   return reinterpret_cast<void const*>(lhs) != rhs;
2532 }
2533 template <typename T> auto compareNotEqual(long lhs, T* const& rhs) -> bool
2534 {
2535   return reinterpret_cast<void const*>(lhs) != rhs;
2536 }
2537
2538 template <typename LhsT> class ExprLhs {
2539   LhsT m_lhs;
2540
2541 public:
2542   explicit ExprLhs(LhsT lhs) : m_lhs(lhs) {}
2543
2544   template <typename RhsT> auto operator==(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2545   {
2546     return {compareEqual(m_lhs, rhs), m_lhs, "==", rhs};
2547   }
2548   auto operator==(bool rhs) -> BinaryExpr<LhsT, bool> const { return {m_lhs == rhs, m_lhs, "==", rhs}; }
2549
2550   template <typename RhsT> auto operator!=(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2551   {
2552     return {compareNotEqual(m_lhs, rhs), m_lhs, "!=", rhs};
2553   }
2554   auto operator!=(bool rhs) -> BinaryExpr<LhsT, bool> const { return {m_lhs != rhs, m_lhs, "!=", rhs}; }
2555
2556   template <typename RhsT> auto operator>(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2557   {
2558     return {static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs};
2559   }
2560   template <typename RhsT> auto operator<(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2561   {
2562     return {static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs};
2563   }
2564   template <typename RhsT> auto operator>=(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2565   {
2566     return {static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs};
2567   }
2568   template <typename RhsT> auto operator<=(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2569   {
2570     return {static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs};
2571   }
2572   template <typename RhsT> auto operator|(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2573   {
2574     return {static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs};
2575   }
2576   template <typename RhsT> auto operator&(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2577   {
2578     return {static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs};
2579   }
2580   template <typename RhsT> auto operator^(RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const
2581   {
2582     return {static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs};
2583   }
2584
2585   template <typename RhsT> auto operator&&(RhsT const&) -> BinaryExpr<LhsT, RhsT const&> const
2586   {
2587     static_assert(always_false<RhsT>::value, "operator&& is not supported inside assertions, "
2588                                              "wrap the expression inside parentheses, or decompose it");
2589   }
2590
2591   template <typename RhsT> auto operator||(RhsT const&) -> BinaryExpr<LhsT, RhsT const&> const
2592   {
2593     static_assert(always_false<RhsT>::value, "operator|| is not supported inside assertions, "
2594                                              "wrap the expression inside parentheses, or decompose it");
2595   }
2596
2597   auto makeUnaryExpr() const -> UnaryExpr<LhsT> { return UnaryExpr<LhsT>{m_lhs}; }
2598 };
2599
2600 void handleExpression(ITransientExpression const& expr);
2601
2602 template <typename T> void handleExpression(ExprLhs<T> const& expr)
2603 {
2604   handleExpression(expr.makeUnaryExpr());
2605 }
2606
2607 struct Decomposer {
2608   template <typename T> auto operator<=(T const& lhs) -> ExprLhs<T const&> { return ExprLhs<T const&>{lhs}; }
2609
2610   auto operator<=(bool value) -> ExprLhs<bool> { return ExprLhs<bool>{value}; }
2611 };
2612
2613 } // end namespace Catch
2614
2615 #ifdef _MSC_VER
2616 #pragma warning(pop)
2617 #endif
2618
2619 // end catch_decomposer.h
2620 // start catch_interfaces_capture.h
2621
2622 #include <chrono>
2623 #include <string>
2624
2625 namespace Catch {
2626
2627 class AssertionResult;
2628 struct AssertionInfo;
2629 struct SectionInfo;
2630 struct SectionEndInfo;
2631 struct MessageInfo;
2632 struct MessageBuilder;
2633 struct Counts;
2634 struct AssertionReaction;
2635 struct SourceLineInfo;
2636
2637 struct ITransientExpression;
2638 struct IGeneratorTracker;
2639
2640 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2641 struct BenchmarkInfo;
2642 template <typename Duration = std::chrono::duration<double, std::nano>> struct BenchmarkStats;
2643 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2644
2645 struct IResultCapture {
2646
2647   virtual ~IResultCapture();
2648
2649   virtual bool sectionStarted(SectionInfo const& sectionInfo, Counts& assertions) = 0;
2650   virtual void sectionEnded(SectionEndInfo const& endInfo)                        = 0;
2651   virtual void sectionEndedEarly(SectionEndInfo const& endInfo)                   = 0;
2652
2653   virtual auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo)
2654       -> IGeneratorTracker& = 0;
2655
2656 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2657   virtual void benchmarkPreparing(std::string const& name)   = 0;
2658   virtual void benchmarkStarting(BenchmarkInfo const& info)  = 0;
2659   virtual void benchmarkEnded(BenchmarkStats<> const& stats) = 0;
2660   virtual void benchmarkFailed(std::string const& error)     = 0;
2661 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2662
2663   virtual void pushScopedMessage(MessageInfo const& message) = 0;
2664   virtual void popScopedMessage(MessageInfo const& message)  = 0;
2665
2666   virtual void emplaceUnscopedMessage(MessageBuilder const& builder) = 0;
2667
2668   virtual void handleFatalErrorCondition(StringRef message) = 0;
2669
2670   virtual void handleExpr(AssertionInfo const& info, ITransientExpression const& expr, AssertionReaction& reaction) = 0;
2671   virtual void handleMessage(AssertionInfo const& info, ResultWas::OfType resultType, StringRef const& message,
2672                              AssertionReaction& reaction)                                                           = 0;
2673   virtual void handleUnexpectedExceptionNotThrown(AssertionInfo const& info, AssertionReaction& reaction)           = 0;
2674   virtual void handleUnexpectedInflightException(AssertionInfo const& info, std::string const& message,
2675                                                  AssertionReaction& reaction)                                       = 0;
2676   virtual void handleIncomplete(AssertionInfo const& info)                                                          = 0;
2677   virtual void handleNonExpr(AssertionInfo const& info, ResultWas::OfType resultType, AssertionReaction& reaction)  = 0;
2678
2679   virtual bool lastAssertionPassed() = 0;
2680   virtual void assertionPassed()     = 0;
2681
2682   // Deprecated, do not use:
2683   virtual std::string getCurrentTestName() const       = 0;
2684   virtual const AssertionResult* getLastResult() const = 0;
2685   virtual void exceptionEarlyReported()                = 0;
2686 };
2687
2688 IResultCapture& getResultCapture();
2689 } // namespace Catch
2690
2691 // end catch_interfaces_capture.h
2692 namespace Catch {
2693
2694 struct TestFailureException {};
2695 struct AssertionResultData;
2696 struct IResultCapture;
2697 class RunContext;
2698
2699 class LazyExpression {
2700   friend class AssertionHandler;
2701   friend struct AssertionStats;
2702   friend class RunContext;
2703
2704   ITransientExpression const* m_transientExpression = nullptr;
2705   bool m_isNegated;
2706
2707 public:
2708   LazyExpression(bool isNegated);
2709   LazyExpression(LazyExpression const& other);
2710   LazyExpression& operator=(LazyExpression const&) = delete;
2711
2712   explicit operator bool() const;
2713
2714   friend auto operator<<(std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream&;
2715 };
2716
2717 struct AssertionReaction {
2718   bool shouldDebugBreak = false;
2719   bool shouldThrow      = false;
2720 };
2721
2722 class AssertionHandler {
2723   AssertionInfo m_assertionInfo;
2724   AssertionReaction m_reaction;
2725   bool m_completed = false;
2726   IResultCapture& m_resultCapture;
2727
2728 public:
2729   AssertionHandler(StringRef const& macroName, SourceLineInfo const& lineInfo, StringRef capturedExpression,
2730                    ResultDisposition::Flags resultDisposition);
2731   ~AssertionHandler()
2732   {
2733     if (!m_completed) {
2734       m_resultCapture.handleIncomplete(m_assertionInfo);
2735     }
2736   }
2737
2738   template <typename T> void handleExpr(ExprLhs<T> const& expr) { handleExpr(expr.makeUnaryExpr()); }
2739   void handleExpr(ITransientExpression const& expr);
2740
2741   void handleMessage(ResultWas::OfType resultType, StringRef const& message);
2742
2743   void handleExceptionThrownAsExpected();
2744   void handleUnexpectedExceptionNotThrown();
2745   void handleExceptionNotThrownAsExpected();
2746   void handleThrowingCallSkipped();
2747   void handleUnexpectedInflightException();
2748
2749   void complete();
2750   void setCompleted();
2751
2752   // query
2753   auto allowThrows() const -> bool;
2754 };
2755
2756 void handleExceptionMatchExpr(AssertionHandler& handler, std::string const& str, StringRef const& matcherString);
2757
2758 } // namespace Catch
2759
2760 // end catch_assertionhandler.h
2761 // start catch_message.h
2762
2763 #include <string>
2764 #include <vector>
2765
2766 namespace Catch {
2767
2768 struct MessageInfo {
2769   MessageInfo(StringRef const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type);
2770
2771   StringRef macroName;
2772   std::string message;
2773   SourceLineInfo lineInfo;
2774   ResultWas::OfType type;
2775   unsigned int sequence;
2776
2777   bool operator==(MessageInfo const& other) const;
2778   bool operator<(MessageInfo const& other) const;
2779
2780 private:
2781   static unsigned int globalCount;
2782 };
2783
2784 struct MessageStream {
2785
2786   template <typename T> MessageStream& operator<<(T const& value)
2787   {
2788     m_stream << value;
2789     return *this;
2790   }
2791
2792   ReusableStringStream m_stream;
2793 };
2794
2795 struct MessageBuilder : MessageStream {
2796   MessageBuilder(StringRef const& macroName, SourceLineInfo const& lineInfo, ResultWas::OfType type);
2797
2798   template <typename T> MessageBuilder& operator<<(T const& value)
2799   {
2800     m_stream << value;
2801     return *this;
2802   }
2803
2804   MessageInfo m_info;
2805 };
2806
2807 class ScopedMessage {
2808 public:
2809   explicit ScopedMessage(MessageBuilder const& builder);
2810   ScopedMessage(ScopedMessage& duplicate) = delete;
2811   ScopedMessage(ScopedMessage&& old);
2812   ~ScopedMessage();
2813
2814   MessageInfo m_info;
2815   bool m_moved;
2816 };
2817
2818 class Capturer {
2819   std::vector<MessageInfo> m_messages;
2820   IResultCapture& m_resultCapture = getResultCapture();
2821   size_t m_captured               = 0;
2822
2823 public:
2824   Capturer(StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names);
2825   ~Capturer();
2826
2827   void captureValue(size_t index, std::string const& value);
2828
2829   template <typename T> void captureValues(size_t index, T const& value)
2830   {
2831     captureValue(index, Catch::Detail::stringify(value));
2832   }
2833
2834   template <typename T, typename... Ts> void captureValues(size_t index, T const& value, Ts const&... values)
2835   {
2836     captureValue(index, Catch::Detail::stringify(value));
2837     captureValues(index + 1, values...);
2838   }
2839 };
2840
2841 } // end namespace Catch
2842
2843 // end catch_message.h
2844 #if !defined(CATCH_CONFIG_DISABLE)
2845
2846 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2847 #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2848 #else
2849 #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2850 #endif
2851
2852 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2853
2854 ///////////////////////////////////////////////////////////////////////////////
2855 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2856 // macros.
2857 #define INTERNAL_CATCH_TRY
2858 #define INTERNAL_CATCH_CATCH(capturer)
2859
2860 #else // CATCH_CONFIG_FAST_COMPILE
2861
2862 #define INTERNAL_CATCH_TRY try
2863 #define INTERNAL_CATCH_CATCH(handler)                                                                                  \
2864   catch (...)                                                                                                          \
2865   {                                                                                                                    \
2866     handler.handleUnexpectedInflightException();                                                                       \
2867   }
2868
2869 #endif
2870
2871 #define INTERNAL_CATCH_REACT(handler) handler.complete();
2872
2873 ///////////////////////////////////////////////////////////////////////////////
2874 #define INTERNAL_CATCH_TEST(macroName, resultDisposition, ...)                                                         \
2875   do {                                                                                                                 \
2876     CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__);                                                                       \
2877     Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                       \
2878                                                   CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition);           \
2879     INTERNAL_CATCH_TRY                                                                                                 \
2880     {                                                                                                                  \
2881       CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                        \
2882       CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS                                                                     \
2883       catchAssertionHandler.handleExpr(Catch::Decomposer() <= __VA_ARGS__);                                            \
2884       CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                         \
2885     }                                                                                                                  \
2886     INTERNAL_CATCH_CATCH(catchAssertionHandler)                                                                        \
2887     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
2888   } while ((void)0, (false) && static_cast<bool>(!!(__VA_ARGS__)))
2889
2890 ///////////////////////////////////////////////////////////////////////////////
2891 #define INTERNAL_CATCH_IF(macroName, resultDisposition, ...)                                                           \
2892   INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__);                                                      \
2893   if (Catch::getResultCapture().lastAssertionPassed())
2894
2895 ///////////////////////////////////////////////////////////////////////////////
2896 #define INTERNAL_CATCH_ELSE(macroName, resultDisposition, ...)                                                         \
2897   INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__);                                                      \
2898   if (!Catch::getResultCapture().lastAssertionPassed())
2899
2900 ///////////////////////////////////////////////////////////////////////////////
2901 #define INTERNAL_CATCH_NO_THROW(macroName, resultDisposition, ...)                                                     \
2902   do {                                                                                                                 \
2903     Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                       \
2904                                                   CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition);           \
2905     try {                                                                                                              \
2906       static_cast<void>(__VA_ARGS__);                                                                                  \
2907       catchAssertionHandler.handleExceptionNotThrownAsExpected();                                                      \
2908     } catch (...) {                                                                                                    \
2909       catchAssertionHandler.handleUnexpectedInflightException();                                                       \
2910     }                                                                                                                  \
2911     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
2912   } while (false)
2913
2914 ///////////////////////////////////////////////////////////////////////////////
2915 #define INTERNAL_CATCH_THROWS(macroName, resultDisposition, ...)                                                       \
2916   do {                                                                                                                 \
2917     Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                       \
2918                                                   CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition);           \
2919     if (catchAssertionHandler.allowThrows())                                                                           \
2920       try {                                                                                                            \
2921         static_cast<void>(__VA_ARGS__);                                                                                \
2922         catchAssertionHandler.handleUnexpectedExceptionNotThrown();                                                    \
2923       } catch (...) {                                                                                                  \
2924         catchAssertionHandler.handleExceptionThrownAsExpected();                                                       \
2925       }                                                                                                                \
2926     else                                                                                                               \
2927       catchAssertionHandler.handleThrowingCallSkipped();                                                               \
2928     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
2929   } while (false)
2930
2931 ///////////////////////////////////////////////////////////////////////////////
2932 #define INTERNAL_CATCH_THROWS_AS(macroName, exceptionType, resultDisposition, expr)                                    \
2933   do {                                                                                                                 \
2934     Catch::AssertionHandler catchAssertionHandler(                                                                     \
2935         macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                                                                 \
2936         CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition);               \
2937     if (catchAssertionHandler.allowThrows())                                                                           \
2938       try {                                                                                                            \
2939         static_cast<void>(expr);                                                                                       \
2940         catchAssertionHandler.handleUnexpectedExceptionNotThrown();                                                    \
2941       } catch (exceptionType const&) {                                                                                 \
2942         catchAssertionHandler.handleExceptionThrownAsExpected();                                                       \
2943       } catch (...) {                                                                                                  \
2944         catchAssertionHandler.handleUnexpectedInflightException();                                                     \
2945       }                                                                                                                \
2946     else                                                                                                               \
2947       catchAssertionHandler.handleThrowingCallSkipped();                                                               \
2948     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
2949   } while (false)
2950
2951 ///////////////////////////////////////////////////////////////////////////////
2952 #define INTERNAL_CATCH_MSG(macroName, messageType, resultDisposition, ...)                                             \
2953   do {                                                                                                                 \
2954     Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(),   \
2955                                                   resultDisposition);                                                  \
2956     catchAssertionHandler.handleMessage(                                                                               \
2957         messageType, (Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop()).m_stream.str());               \
2958     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
2959   } while (false)
2960
2961 ///////////////////////////////////////////////////////////////////////////////
2962 #define INTERNAL_CATCH_CAPTURE(varName, macroName, ...)                                                                \
2963   auto varName = Catch::Capturer(macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__);            \
2964   varName.captureValues(0, __VA_ARGS__)
2965
2966 ///////////////////////////////////////////////////////////////////////////////
2967 #define INTERNAL_CATCH_INFO(macroName, log)                                                                            \
2968   Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME(scopedMessage)(                                                      \
2969       Catch::MessageBuilder(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log);
2970
2971 ///////////////////////////////////////////////////////////////////////////////
2972 #define INTERNAL_CATCH_UNSCOPED_INFO(macroName, log)                                                                   \
2973   Catch::getResultCapture().emplaceUnscopedMessage(                                                                    \
2974       Catch::MessageBuilder(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log)
2975
2976 ///////////////////////////////////////////////////////////////////////////////
2977 // Although this is matcher-based, it can be used with just a string
2978 #define INTERNAL_CATCH_THROWS_STR_MATCHES(macroName, resultDisposition, matcher, ...)                                  \
2979   do {                                                                                                                 \
2980     Catch::AssertionHandler catchAssertionHandler(                                                                     \
2981         macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                                                                 \
2982         CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition);              \
2983     if (catchAssertionHandler.allowThrows())                                                                           \
2984       try {                                                                                                            \
2985         static_cast<void>(__VA_ARGS__);                                                                                \
2986         catchAssertionHandler.handleUnexpectedExceptionNotThrown();                                                    \
2987       } catch (...) {                                                                                                  \
2988         Catch::handleExceptionMatchExpr(catchAssertionHandler, matcher, #matcher##_catch_sr);                          \
2989       }                                                                                                                \
2990     else                                                                                                               \
2991       catchAssertionHandler.handleThrowingCallSkipped();                                                               \
2992     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
2993   } while (false)
2994
2995 #endif // CATCH_CONFIG_DISABLE
2996
2997 // end catch_capture.hpp
2998 // start catch_section.h
2999
3000 // start catch_section_info.h
3001
3002 // start catch_totals.h
3003
3004 #include <cstddef>
3005
3006 namespace Catch {
3007
3008 struct Counts {
3009   Counts operator-(Counts const& other) const;
3010   Counts& operator+=(Counts const& other);
3011
3012   std::size_t total() const;
3013   bool allPassed() const;
3014   bool allOk() const;
3015
3016   std::size_t passed      = 0;
3017   std::size_t failed      = 0;
3018   std::size_t failedButOk = 0;
3019 };
3020
3021 struct Totals {
3022
3023   Totals operator-(Totals const& other) const;
3024   Totals& operator+=(Totals const& other);
3025
3026   Totals delta(Totals const& prevTotals) const;
3027
3028   int error = 0;
3029   Counts assertions;
3030   Counts testCases;
3031 };
3032 } // namespace Catch
3033
3034 // end catch_totals.h
3035 #include <string>
3036
3037 namespace Catch {
3038
3039 struct SectionInfo {
3040   SectionInfo(SourceLineInfo const& _lineInfo, std::string const& _name);
3041
3042   // Deprecated
3043   SectionInfo(SourceLineInfo const& _lineInfo, std::string const& _name, std::string const&)
3044       : SectionInfo(_lineInfo, _name)
3045   {
3046   }
3047
3048   std::string name;
3049   std::string description; // !Deprecated: this will always be empty
3050   SourceLineInfo lineInfo;
3051 };
3052
3053 struct SectionEndInfo {
3054   SectionInfo sectionInfo;
3055   Counts prevAssertions;
3056   double durationInSeconds;
3057 };
3058
3059 } // end namespace Catch
3060
3061 // end catch_section_info.h
3062 // start catch_timer.h
3063
3064 #include <cstdint>
3065
3066 namespace Catch {
3067
3068 auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
3069 auto getEstimatedClockResolution() -> uint64_t;
3070
3071 class Timer {
3072   uint64_t m_nanoseconds = 0;
3073
3074 public:
3075   void start();
3076   auto getElapsedNanoseconds() const -> uint64_t;
3077   auto getElapsedMicroseconds() const -> uint64_t;
3078   auto getElapsedMilliseconds() const -> unsigned int;
3079   auto getElapsedSeconds() const -> double;
3080 };
3081
3082 } // namespace Catch
3083
3084 // end catch_timer.h
3085 #include <string>
3086
3087 namespace Catch {
3088
3089 class Section : NonCopyable {
3090 public:
3091   Section(SectionInfo const& info);
3092   ~Section();
3093
3094   // This indicates whether the section should be executed or not
3095   explicit operator bool() const;
3096
3097 private:
3098   SectionInfo m_info;
3099
3100   std::string m_name;
3101   Counts m_assertions;
3102   bool m_sectionIncluded;
3103   Timer m_timer;
3104 };
3105
3106 } // end namespace Catch
3107
3108 #define INTERNAL_CATCH_SECTION(...)                                                                                    \
3109   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
3110   CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS                                                                              \
3111   if (Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME(catch_internal_Section) =                                       \
3112           Catch::SectionInfo(CATCH_INTERNAL_LINEINFO, __VA_ARGS__))                                                    \
3113   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
3114
3115 #define INTERNAL_CATCH_DYNAMIC_SECTION(...)                                                                            \
3116   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
3117   CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS                                                                              \
3118   if (Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME(catch_internal_Section) =                                       \
3119           Catch::SectionInfo(CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str()))           \
3120   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
3121
3122 // end catch_section.h
3123 // start catch_interfaces_exception.h
3124
3125 // start catch_interfaces_registry_hub.h
3126
3127 #include <memory>
3128 #include <string>
3129
3130 namespace Catch {
3131
3132 class TestCase;
3133 struct ITestCaseRegistry;
3134 struct IExceptionTranslatorRegistry;
3135 struct IExceptionTranslator;
3136 struct IReporterRegistry;
3137 struct IReporterFactory;
3138 struct ITagAliasRegistry;
3139 struct IMutableEnumValuesRegistry;
3140
3141 class StartupExceptionRegistry;
3142
3143 using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
3144
3145 struct IRegistryHub {
3146   virtual ~IRegistryHub();
3147
3148   virtual IReporterRegistry const& getReporterRegistry() const                       = 0;
3149   virtual ITestCaseRegistry const& getTestCaseRegistry() const                       = 0;
3150   virtual ITagAliasRegistry const& getTagAliasRegistry() const                       = 0;
3151   virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
3152
3153   virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
3154 };
3155
3156 struct IMutableRegistryHub {
3157   virtual ~IMutableRegistryHub();
3158   virtual void registerReporter(std::string const& name, IReporterFactoryPtr const& factory)                      = 0;
3159   virtual void registerListener(IReporterFactoryPtr const& factory)                                               = 0;
3160   virtual void registerTest(TestCase const& testInfo)                                                             = 0;
3161   virtual void registerTranslator(const IExceptionTranslator* translator)                                         = 0;
3162   virtual void registerTagAlias(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) = 0;
3163   virtual void registerStartupException() noexcept                                                                = 0;
3164   virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry()                                              = 0;
3165 };
3166
3167 IRegistryHub const& getRegistryHub();
3168 IMutableRegistryHub& getMutableRegistryHub();
3169 void cleanUp();
3170 std::string translateActiveException();
3171
3172 } // namespace Catch
3173
3174 // end catch_interfaces_registry_hub.h
3175 #if defined(CATCH_CONFIG_DISABLE)
3176 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(translatorName, signature)                                           \
3177   static std::string translatorName(signature)
3178 #endif
3179
3180 #include <exception>
3181 #include <string>
3182 #include <vector>
3183
3184 namespace Catch {
3185 using exceptionTranslateFunction = std::string (*)();
3186
3187 struct IExceptionTranslator;
3188 using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
3189
3190 struct IExceptionTranslator {
3191   virtual ~IExceptionTranslator();
3192   virtual std::string translate(ExceptionTranslators::const_iterator it,
3193                                 ExceptionTranslators::const_iterator itEnd) const = 0;
3194 };
3195
3196 struct IExceptionTranslatorRegistry {
3197   virtual ~IExceptionTranslatorRegistry();
3198
3199   virtual std::string translateActiveException() const = 0;
3200 };
3201
3202 class ExceptionTranslatorRegistrar {
3203   template <typename T> class ExceptionTranslator : public IExceptionTranslator {
3204   public:
3205     ExceptionTranslator(std::string (*translateFunction)(T&)) : m_translateFunction(translateFunction) {}
3206
3207     std::string translate(ExceptionTranslators::const_iterator it,
3208                           ExceptionTranslators::const_iterator itEnd) const override
3209     {
3210 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3211       return "";
3212 #else
3213       try {
3214         if (it == itEnd)
3215           std::rethrow_exception(std::current_exception());
3216         else
3217           return (*it)->translate(it + 1, itEnd);
3218       } catch (T& ex) {
3219         return m_translateFunction(ex);
3220       }
3221 #endif
3222     }
3223
3224   protected:
3225     std::string (*m_translateFunction)(T&);
3226   };
3227
3228 public:
3229   template <typename T> ExceptionTranslatorRegistrar(std::string (*translateFunction)(T&))
3230   {
3231     getMutableRegistryHub().registerTranslator(new ExceptionTranslator<T>(translateFunction));
3232   }
3233 };
3234 } // namespace Catch
3235
3236 ///////////////////////////////////////////////////////////////////////////////
3237 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2(translatorName, signature)                                                 \
3238   static std::string translatorName(signature);                                                                        \
3239   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
3240   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
3241   namespace {                                                                                                          \
3242   Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionRegistrar)(&translatorName);  \
3243   }                                                                                                                    \
3244   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                                                                             \
3245   static std::string translatorName(signature)
3246
3247 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature)                                                                  \
3248   INTERNAL_CATCH_TRANSLATE_EXCEPTION2(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature)
3249
3250 // end catch_interfaces_exception.h
3251 // start catch_approx.h
3252
3253 #include <type_traits>
3254
3255 namespace Catch {
3256 namespace Detail {
3257
3258 class Approx {
3259 private:
3260   bool equalityComparisonImpl(double other) const;
3261   // Validates the new margin (margin >= 0)
3262   // out-of-line to avoid including stdexcept in the header
3263   void setMargin(double margin);
3264   // Validates the new epsilon (0 < epsilon < 1)
3265   // out-of-line to avoid including stdexcept in the header
3266   void setEpsilon(double epsilon);
3267
3268 public:
3269   explicit Approx(double value);
3270
3271   static Approx custom();
3272
3273   Approx operator-() const;
3274
3275   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3276   Approx operator()(T const& value)
3277   {
3278     Approx approx(static_cast<double>(value));
3279     approx.m_epsilon = m_epsilon;
3280     approx.m_margin  = m_margin;
3281     approx.m_scale   = m_scale;
3282     return approx;
3283   }
3284
3285   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3286   explicit Approx(T const& value) : Approx(static_cast<double>(value))
3287   {
3288   }
3289
3290   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3291   friend bool operator==(const T& lhs, Approx const& rhs)
3292   {
3293     auto lhs_v = static_cast<double>(lhs);
3294     return rhs.equalityComparisonImpl(lhs_v);
3295   }
3296
3297   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3298   friend bool operator==(Approx const& lhs, const T& rhs)
3299   {
3300     return operator==(rhs, lhs);
3301   }
3302
3303   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3304   friend bool operator!=(T const& lhs, Approx const& rhs)
3305   {
3306     return !operator==(lhs, rhs);
3307   }
3308
3309   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3310   friend bool operator!=(Approx const& lhs, T const& rhs)
3311   {
3312     return !operator==(rhs, lhs);
3313   }
3314
3315   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3316   friend bool operator<=(T const& lhs, Approx const& rhs)
3317   {
3318     return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3319   }
3320
3321   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3322   friend bool operator<=(Approx const& lhs, T const& rhs)
3323   {
3324     return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3325   }
3326
3327   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3328   friend bool operator>=(T const& lhs, Approx const& rhs)
3329   {
3330     return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3331   }
3332
3333   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3334   friend bool operator>=(Approx const& lhs, T const& rhs)
3335   {
3336     return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3337   }
3338
3339   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3340   Approx& epsilon(T const& newEpsilon)
3341   {
3342     double epsilonAsDouble = static_cast<double>(newEpsilon);
3343     setEpsilon(epsilonAsDouble);
3344     return *this;
3345   }
3346
3347   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3348   Approx& margin(T const& newMargin)
3349   {
3350     double marginAsDouble = static_cast<double>(newMargin);
3351     setMargin(marginAsDouble);
3352     return *this;
3353   }
3354
3355   template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3356   Approx& scale(T const& newScale)
3357   {
3358     m_scale = static_cast<double>(newScale);
3359     return *this;
3360   }
3361
3362   std::string toString() const;
3363
3364 private:
3365   double m_epsilon;
3366   double m_margin;
3367   double m_scale;
3368   double m_value;
3369 };
3370 } // end namespace Detail
3371
3372 namespace literals {
3373 Detail::Approx operator"" _a(long double val);
3374 Detail::Approx operator"" _a(unsigned long long val);
3375 } // end namespace literals
3376
3377 template <> struct StringMaker<Catch::Detail::Approx> {
3378   static std::string convert(Catch::Detail::Approx const& value);
3379 };
3380
3381 } // end namespace Catch
3382
3383 // end catch_approx.h
3384 // start catch_string_manip.h
3385
3386 #include <iosfwd>
3387 #include <string>
3388 #include <vector>
3389
3390 namespace Catch {
3391
3392 bool startsWith(std::string const& s, std::string const& prefix);
3393 bool startsWith(std::string const& s, char prefix);
3394 bool endsWith(std::string const& s, std::string const& suffix);
3395 bool endsWith(std::string const& s, char suffix);
3396 bool contains(std::string const& s, std::string const& infix);
3397 void toLowerInPlace(std::string& s);
3398 std::string toLower(std::string const& s);
3399 //! Returns a new string without whitespace at the start/end
3400 std::string trim(std::string const& str);
3401 //! Returns a substring of the original ref without whitespace. Beware lifetimes!
3402 StringRef trim(StringRef ref);
3403
3404 // !!! Be aware, returns refs into original string - make sure original string outlives them
3405 std::vector<StringRef> splitStringRef(StringRef str, char delimiter);
3406 bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis);
3407
3408 struct pluralise {
3409   pluralise(std::size_t count, std::string const& label);
3410
3411   friend std::ostream& operator<<(std::ostream& os, pluralise const& pluraliser);
3412
3413   std::size_t m_count;
3414   std::string m_label;
3415 };
3416 } // namespace Catch
3417
3418 // end catch_string_manip.h
3419 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
3420 // start catch_capture_matchers.h
3421
3422 // start catch_matchers.h
3423
3424 #include <string>
3425 #include <vector>
3426
3427 namespace Catch {
3428 namespace Matchers {
3429 namespace Impl {
3430
3431 template <typename ArgT> struct MatchAllOf;
3432 template <typename ArgT> struct MatchAnyOf;
3433 template <typename ArgT> struct MatchNotOf;
3434
3435 class MatcherUntypedBase {
3436 public:
3437   MatcherUntypedBase()                                     = default;
3438   MatcherUntypedBase(MatcherUntypedBase const&)            = default;
3439   MatcherUntypedBase& operator=(MatcherUntypedBase const&) = delete;
3440   std::string toString() const;
3441
3442 protected:
3443   virtual ~MatcherUntypedBase();
3444   virtual std::string describe() const = 0;
3445   mutable std::string m_cachedToString;
3446 };
3447
3448 #ifdef __clang__
3449 #pragma clang diagnostic push
3450 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
3451 #endif
3452
3453 template <typename ObjectT> struct MatcherMethod {
3454   virtual bool match(ObjectT const& arg) const = 0;
3455 };
3456
3457 #if defined(__OBJC__)
3458 // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
3459 // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks
3460 // compilation
3461 template <> struct MatcherMethod<NSString*> {
3462   virtual bool match(NSString* arg) const = 0;
3463 };
3464 #endif
3465
3466 #ifdef __clang__
3467 #pragma clang diagnostic pop
3468 #endif
3469
3470 template <typename T> struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
3471
3472   MatchAllOf<T> operator&&(MatcherBase const& other) const;
3473   MatchAnyOf<T> operator||(MatcherBase const& other) const;
3474   MatchNotOf<T> operator!() const;
3475 };
3476
3477 template <typename ArgT> struct MatchAllOf : MatcherBase<ArgT> {
3478   bool match(ArgT const& arg) const override
3479   {
3480     for (auto matcher : m_matchers) {
3481       if (!matcher->match(arg))
3482         return false;
3483     }
3484     return true;
3485   }
3486   std::string describe() const override
3487   {
3488     std::string description;
3489     description.reserve(4 + m_matchers.size() * 32);
3490     description += "( ";
3491     bool first = true;
3492     for (auto matcher : m_matchers) {
3493       if (first)
3494         first = false;
3495       else
3496         description += " and ";
3497       description += matcher->toString();
3498     }
3499     description += " )";
3500     return description;
3501   }
3502
3503   MatchAllOf<ArgT> operator&&(MatcherBase<ArgT> const& other)
3504   {
3505     auto copy(*this);
3506     copy.m_matchers.push_back(&other);
3507     return copy;
3508   }
3509
3510   std::vector<MatcherBase<ArgT> const*> m_matchers;
3511 };
3512 template <typename ArgT> struct MatchAnyOf : MatcherBase<ArgT> {
3513
3514   bool match(ArgT const& arg) const override
3515   {
3516     for (auto matcher : m_matchers) {
3517       if (matcher->match(arg))
3518         return true;
3519     }
3520     return false;
3521   }
3522   std::string describe() const override
3523   {
3524     std::string description;
3525     description.reserve(4 + m_matchers.size() * 32);
3526     description += "( ";
3527     bool first = true;
3528     for (auto matcher : m_matchers) {
3529       if (first)
3530         first = false;
3531       else
3532         description += " or ";
3533       description += matcher->toString();
3534     }
3535     description += " )";
3536     return description;
3537   }
3538
3539   MatchAnyOf<ArgT> operator||(MatcherBase<ArgT> const& other)
3540   {
3541     auto copy(*this);
3542     copy.m_matchers.push_back(&other);
3543     return copy;
3544   }
3545
3546   std::vector<MatcherBase<ArgT> const*> m_matchers;
3547 };
3548
3549 template <typename ArgT> struct MatchNotOf : MatcherBase<ArgT> {
3550
3551   MatchNotOf(MatcherBase<ArgT> const& underlyingMatcher) : m_underlyingMatcher(underlyingMatcher) {}
3552
3553   bool match(ArgT const& arg) const override { return !m_underlyingMatcher.match(arg); }
3554
3555   std::string describe() const override { return "not " + m_underlyingMatcher.toString(); }
3556   MatcherBase<ArgT> const& m_underlyingMatcher;
3557 };
3558
3559 template <typename T> MatchAllOf<T> MatcherBase<T>::operator&&(MatcherBase const& other) const
3560 {
3561   return MatchAllOf<T>() && *this && other;
3562 }
3563 template <typename T> MatchAnyOf<T> MatcherBase<T>::operator||(MatcherBase const& other) const
3564 {
3565   return MatchAnyOf<T>() || *this || other;
3566 }
3567 template <typename T> MatchNotOf<T> MatcherBase<T>::operator!() const
3568 {
3569   return MatchNotOf<T>(*this);
3570 }
3571
3572 } // namespace Impl
3573
3574 } // namespace Matchers
3575
3576 using namespace Matchers;
3577 using Matchers::Impl::MatcherBase;
3578
3579 } // namespace Catch
3580
3581 // end catch_matchers.h
3582 // start catch_matchers_exception.hpp
3583
3584 namespace Catch {
3585 namespace Matchers {
3586 namespace Exception {
3587
3588 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
3589   std::string m_message;
3590
3591 public:
3592   ExceptionMessageMatcher(std::string const& message) : m_message(message) {}
3593
3594   bool match(std::exception const& ex) const override;
3595
3596   std::string describe() const override;
3597 };
3598
3599 } // namespace Exception
3600
3601 Exception::ExceptionMessageMatcher Message(std::string const& message);
3602
3603 } // namespace Matchers
3604 } // namespace Catch
3605
3606 // end catch_matchers_exception.hpp
3607 // start catch_matchers_floating.h
3608
3609 namespace Catch {
3610 namespace Matchers {
3611
3612 namespace Floating {
3613
3614 enum class FloatingPointKind : uint8_t;
3615
3616 struct WithinAbsMatcher : MatcherBase<double> {
3617   WithinAbsMatcher(double target, double margin);
3618   bool match(double const& matchee) const override;
3619   std::string describe() const override;
3620
3621 private:
3622   double m_target;
3623   double m_margin;
3624 };
3625
3626 struct WithinUlpsMatcher : MatcherBase<double> {
3627   WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
3628   bool match(double const& matchee) const override;
3629   std::string describe() const override;
3630
3631 private:
3632   double m_target;
3633   uint64_t m_ulps;
3634   FloatingPointKind m_type;
3635 };
3636
3637 // Given IEEE-754 format for floats and doubles, we can assume
3638 // that float -> double promotion is lossless. Given this, we can
3639 // assume that if we do the standard relative comparison of
3640 // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
3641 // the same result if we do this for floats, as if we do this for
3642 // doubles that were promoted from floats.
3643 struct WithinRelMatcher : MatcherBase<double> {
3644   WithinRelMatcher(double target, double epsilon);
3645   bool match(double const& matchee) const override;
3646   std::string describe() const override;
3647
3648 private:
3649   double m_target;
3650   double m_epsilon;
3651 };
3652
3653 } // namespace Floating
3654
3655 // The following functions create the actual matcher objects.
3656 // This allows the types to be inferred
3657 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
3658 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
3659 Floating::WithinAbsMatcher WithinAbs(double target, double margin);
3660 Floating::WithinRelMatcher WithinRel(double target, double eps);
3661 // defaults epsilon to 100*numeric_limits<double>::epsilon()
3662 Floating::WithinRelMatcher WithinRel(double target);
3663 Floating::WithinRelMatcher WithinRel(float target, float eps);
3664 // defaults epsilon to 100*numeric_limits<float>::epsilon()
3665 Floating::WithinRelMatcher WithinRel(float target);
3666
3667 } // namespace Matchers
3668 } // namespace Catch
3669
3670 // end catch_matchers_floating.h
3671 // start catch_matchers_generic.hpp
3672
3673 #include <functional>
3674 #include <string>
3675
3676 namespace Catch {
3677 namespace Matchers {
3678 namespace Generic {
3679
3680 namespace Detail {
3681 std::string finalizeDescription(const std::string& desc);
3682 }
3683
3684 template <typename T> class PredicateMatcher : public MatcherBase<T> {
3685   std::function<bool(T const&)> m_predicate;
3686   std::string m_description;
3687
3688 public:
3689   PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
3690       : m_predicate(std::move(elem)), m_description(Detail::finalizeDescription(descr))
3691   {
3692   }
3693
3694   bool match(T const& item) const override { return m_predicate(item); }
3695
3696   std::string describe() const override { return m_description; }
3697 };
3698
3699 } // namespace Generic
3700
3701 // The following functions create the actual matcher objects.
3702 // The user has to explicitly specify type to the function, because
3703 // inferring std::function<bool(T const&)> is hard (but possible) and
3704 // requires a lot of TMP.
3705 template <typename T>
3706 Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate,
3707                                        std::string const& description = "")
3708 {
3709   return Generic::PredicateMatcher<T>(predicate, description);
3710 }
3711
3712 } // namespace Matchers
3713 } // namespace Catch
3714
3715 // end catch_matchers_generic.hpp
3716 // start catch_matchers_string.h
3717
3718 #include <string>
3719
3720 namespace Catch {
3721 namespace Matchers {
3722
3723 namespace StdString {
3724
3725 struct CasedString {
3726   CasedString(std::string const& str, CaseSensitive::Choice caseSensitivity);
3727   std::string adjustString(std::string const& str) const;
3728   std::string caseSensitivitySuffix() const;
3729
3730   CaseSensitive::Choice m_caseSensitivity;
3731   std::string m_str;
3732 };
3733
3734 struct StringMatcherBase : MatcherBase<std::string> {
3735   StringMatcherBase(std::string const& operation, CasedString const& comparator);
3736   std::string describe() const override;
3737
3738   CasedString m_comparator;
3739   std::string m_operation;
3740 };
3741
3742 struct EqualsMatcher : StringMatcherBase {
3743   EqualsMatcher(CasedString const& comparator);
3744   bool match(std::string const& source) const override;
3745 };
3746 struct ContainsMatcher : StringMatcherBase {
3747   ContainsMatcher(CasedString const& comparator);
3748   bool match(std::string const& source) const override;
3749 };
3750 struct StartsWithMatcher : StringMatcherBase {
3751   StartsWithMatcher(CasedString const& comparator);
3752   bool match(std::string const& source) const override;
3753 };
3754 struct EndsWithMatcher : StringMatcherBase {
3755   EndsWithMatcher(CasedString const& comparator);
3756   bool match(std::string const& source) const override;
3757 };
3758
3759 struct RegexMatcher : MatcherBase<std::string> {
3760   RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity);
3761   bool match(std::string const& matchee) const override;
3762   std::string describe() const override;
3763
3764 private:
3765   std::string m_regex;
3766   CaseSensitive::Choice m_caseSensitivity;
3767 };
3768
3769 } // namespace StdString
3770
3771 // The following functions create the actual matcher objects.
3772 // This allows the types to be inferred
3773
3774 StdString::EqualsMatcher Equals(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
3775 StdString::ContainsMatcher Contains(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
3776 StdString::EndsWithMatcher EndsWith(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
3777 StdString::StartsWithMatcher StartsWith(std::string const& str,
3778                                         CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
3779 StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
3780
3781 } // namespace Matchers
3782 } // namespace Catch
3783
3784 // end catch_matchers_string.h
3785 // start catch_matchers_vector.h
3786
3787 #include <algorithm>
3788
3789 namespace Catch {
3790 namespace Matchers {
3791
3792 namespace Vector {
3793 template <typename T, typename Alloc> struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
3794
3795   ContainsElementMatcher(T const& comparator) : m_comparator(comparator) {}
3796
3797   bool match(std::vector<T, Alloc> const& v) const override
3798   {
3799     for (auto const& el : v) {
3800       if (el == m_comparator) {
3801         return true;
3802       }
3803     }
3804     return false;
3805   }
3806
3807   std::string describe() const override { return "Contains: " + ::Catch::Detail::stringify(m_comparator); }
3808
3809   T const& m_comparator;
3810 };
3811
3812 template <typename T, typename AllocComp, typename AllocMatch>
3813 struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3814
3815   ContainsMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator(comparator) {}
3816
3817   bool match(std::vector<T, AllocMatch> const& v) const override
3818   {
3819     // !TBD: see note in EqualsMatcher
3820     if (m_comparator.size() > v.size())
3821       return false;
3822     for (auto const& comparator : m_comparator) {
3823       auto present = false;
3824       for (const auto& el : v) {
3825         if (el == comparator) {
3826           present = true;
3827           break;
3828         }
3829       }
3830       if (!present) {
3831         return false;
3832       }
3833     }
3834     return true;
3835   }
3836   std::string describe() const override { return "Contains: " + ::Catch::Detail::stringify(m_comparator); }
3837
3838   std::vector<T, AllocComp> const& m_comparator;
3839 };
3840
3841 template <typename T, typename AllocComp, typename AllocMatch>
3842 struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3843
3844   EqualsMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator(comparator) {}
3845
3846   bool match(std::vector<T, AllocMatch> const& v) const override
3847   {
3848     // !TBD: This currently works if all elements can be compared using !=
3849     // - a more general approach would be via a compare template that defaults
3850     // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
3851     // - then just call that directly
3852     if (m_comparator.size() != v.size())
3853       return false;
3854     for (std::size_t i = 0; i < v.size(); ++i)
3855       if (m_comparator[i] != v[i])
3856         return false;
3857     return true;
3858   }
3859   std::string describe() const override { return "Equals: " + ::Catch::Detail::stringify(m_comparator); }
3860   std::vector<T, AllocComp> const& m_comparator;
3861 };
3862
3863 template <typename T, typename AllocComp, typename AllocMatch>
3864 struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3865
3866   ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator(comparator) {}
3867
3868   bool match(std::vector<T, AllocMatch> const& v) const override
3869   {
3870     if (m_comparator.size() != v.size())
3871       return false;
3872     for (std::size_t i = 0; i < v.size(); ++i)
3873       if (m_comparator[i] != approx(v[i]))
3874         return false;
3875     return true;
3876   }
3877   std::string describe() const override { return "is approx: " + ::Catch::Detail::stringify(m_comparator); }
3878   template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3879   ApproxMatcher& epsilon(T const& newEpsilon)
3880   {
3881     approx.epsilon(newEpsilon);
3882     return *this;
3883   }
3884   template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3885   ApproxMatcher& margin(T const& newMargin)
3886   {
3887     approx.margin(newMargin);
3888     return *this;
3889   }
3890   template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3891   ApproxMatcher& scale(T const& newScale)
3892   {
3893     approx.scale(newScale);
3894     return *this;
3895   }
3896
3897   std::vector<T, AllocComp> const& m_comparator;
3898   mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
3899 };
3900
3901 template <typename T, typename AllocComp, typename AllocMatch>
3902 struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3903   UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
3904   bool match(std::vector<T, AllocMatch> const& vec) const override
3905   {
3906     if (m_target.size() != vec.size()) {
3907       return false;
3908     }
3909     return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
3910   }
3911
3912   std::string describe() const override { return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); }
3913
3914 private:
3915   std::vector<T, AllocComp> const& m_target;
3916 };
3917
3918 } // namespace Vector
3919
3920 // The following functions create the actual matcher objects.
3921 // This allows the types to be inferred
3922
3923 template <typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3924 Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains(std::vector<T, AllocComp> const& comparator)
3925 {
3926   return Vector::ContainsMatcher<T, AllocComp, AllocMatch>(comparator);
3927 }
3928
3929 template <typename T, typename Alloc = std::allocator<T>>
3930 Vector::ContainsElementMatcher<T, Alloc> VectorContains(T const& comparator)
3931 {
3932   return Vector::ContainsElementMatcher<T, Alloc>(comparator);
3933 }
3934
3935 template <typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3936 Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals(std::vector<T, AllocComp> const& comparator)
3937 {
3938   return Vector::EqualsMatcher<T, AllocComp, AllocMatch>(comparator);
3939 }
3940
3941 template <typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3942 Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx(std::vector<T, AllocComp> const& comparator)
3943 {
3944   return Vector::ApproxMatcher<T, AllocComp, AllocMatch>(comparator);
3945 }
3946
3947 template <typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3948 Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target)
3949 {
3950   return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>(target);
3951 }
3952
3953 } // namespace Matchers
3954 } // namespace Catch
3955
3956 // end catch_matchers_vector.h
3957 namespace Catch {
3958
3959 template <typename ArgT, typename MatcherT> class MatchExpr : public ITransientExpression {
3960   ArgT const& m_arg;
3961   MatcherT m_matcher;
3962   StringRef m_matcherString;
3963
3964 public:
3965   MatchExpr(ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString)
3966       : ITransientExpression{true, matcher.match(arg)}, m_arg(arg), m_matcher(matcher), m_matcherString(matcherString)
3967   {
3968   }
3969
3970   void streamReconstructedExpression(std::ostream& os) const override
3971   {
3972     auto matcherAsString = m_matcher.toString();
3973     os << Catch::Detail::stringify(m_arg) << ' ';
3974     if (matcherAsString == Detail::unprintableString)
3975       os << m_matcherString;
3976     else
3977       os << matcherAsString;
3978   }
3979 };
3980
3981 using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
3982
3983 void handleExceptionMatchExpr(AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString);
3984
3985 template <typename ArgT, typename MatcherT>
3986 auto makeMatchExpr(ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString)
3987     -> MatchExpr<ArgT, MatcherT>
3988 {
3989   return MatchExpr<ArgT, MatcherT>(arg, matcher, matcherString);
3990 }
3991
3992 } // namespace Catch
3993
3994 ///////////////////////////////////////////////////////////////////////////////
3995 #define INTERNAL_CHECK_THAT(macroName, matcher, resultDisposition, arg)                                                \
3996   do {                                                                                                                 \
3997     Catch::AssertionHandler catchAssertionHandler(                                                                     \
3998         macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                                                                 \
3999         CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition);                      \
4000     INTERNAL_CATCH_TRY                                                                                                 \
4001     {                                                                                                                  \
4002       catchAssertionHandler.handleExpr(Catch::makeMatchExpr(arg, matcher, #matcher##_catch_sr));                       \
4003     }                                                                                                                  \
4004     INTERNAL_CATCH_CATCH(catchAssertionHandler)                                                                        \
4005     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
4006   } while (false)
4007
4008 ///////////////////////////////////////////////////////////////////////////////
4009 #define INTERNAL_CATCH_THROWS_MATCHES(macroName, exceptionType, resultDisposition, matcher, ...)                       \
4010   do {                                                                                                                 \
4011     Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO,                       \
4012                                                   CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY( \
4013                                                       exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher),           \
4014                                                   resultDisposition);                                                  \
4015     if (catchAssertionHandler.allowThrows())                                                                           \
4016       try {                                                                                                            \
4017         static_cast<void>(__VA_ARGS__);                                                                                \
4018         catchAssertionHandler.handleUnexpectedExceptionNotThrown();                                                    \
4019       } catch (exceptionType const& ex) {                                                                              \
4020         catchAssertionHandler.handleExpr(Catch::makeMatchExpr(ex, matcher, #matcher##_catch_sr));                      \
4021       } catch (...) {                                                                                                  \
4022         catchAssertionHandler.handleUnexpectedInflightException();                                                     \
4023       }                                                                                                                \
4024     else                                                                                                               \
4025       catchAssertionHandler.handleThrowingCallSkipped();                                                               \
4026     INTERNAL_CATCH_REACT(catchAssertionHandler)                                                                        \
4027   } while (false)
4028
4029 // end catch_capture_matchers.h
4030 #endif
4031 // start catch_generators.hpp
4032
4033 // start catch_interfaces_generatortracker.h
4034
4035 #include <memory>
4036
4037 namespace Catch {
4038
4039 namespace Generators {
4040 class GeneratorUntypedBase {
4041 public:
4042   GeneratorUntypedBase() = default;
4043   virtual ~GeneratorUntypedBase();
4044   // Attempts to move the generator to the next element
4045   //
4046   // Returns true iff the move succeeded (and a valid element
4047   // can be retrieved).
4048   virtual bool next() = 0;
4049 };
4050 using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
4051
4052 } // namespace Generators
4053
4054 struct IGeneratorTracker {
4055   virtual ~IGeneratorTracker();
4056   virtual auto hasGenerator() const -> bool                                = 0;
4057   virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
4058   virtual void setGenerator(Generators::GeneratorBasePtr&& generator)      = 0;
4059 };
4060
4061 } // namespace Catch
4062
4063 // end catch_interfaces_generatortracker.h
4064 // start catch_enforce.h
4065
4066 #include <exception>
4067
4068 namespace Catch {
4069 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
4070 template <typename Ex> [[noreturn]] void throw_exception(Ex const& e)
4071 {
4072   throw e;
4073 }
4074 #else // ^^ Exceptions are enabled //  Exceptions are disabled vv
4075 [[noreturn]] void throw_exception(std::exception const& e);
4076 #endif
4077
4078 [[noreturn]] void throw_logic_error(std::string const& msg);
4079 [[noreturn]] void throw_domain_error(std::string const& msg);
4080 [[noreturn]] void throw_runtime_error(std::string const& msg);
4081
4082 } // namespace Catch
4083
4084 #define CATCH_MAKE_MSG(...) (Catch::ReusableStringStream() << __VA_ARGS__).str()
4085
4086 #define CATCH_INTERNAL_ERROR(...)                                                                                      \
4087   Catch::throw_logic_error(CATCH_MAKE_MSG(CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
4088
4089 #define CATCH_ERROR(...) Catch::throw_domain_error(CATCH_MAKE_MSG(__VA_ARGS__))
4090
4091 #define CATCH_RUNTIME_ERROR(...) Catch::throw_runtime_error(CATCH_MAKE_MSG(__VA_ARGS__))
4092
4093 #define CATCH_ENFORCE(condition, ...)                                                                                  \
4094   do {                                                                                                                 \
4095     if (!(condition))                                                                                                  \
4096       CATCH_ERROR(__VA_ARGS__);                                                                                        \
4097   } while (false)
4098
4099 // end catch_enforce.h
4100 #include <cassert>
4101 #include <memory>
4102 #include <vector>
4103
4104 #include <exception>
4105 #include <utility>
4106
4107 namespace Catch {
4108
4109 class GeneratorException : public std::exception {
4110   const char* const m_msg = "";
4111
4112 public:
4113   GeneratorException(const char* msg) : m_msg(msg) {}
4114
4115   const char* what() const noexcept override final;
4116 };
4117
4118 namespace Generators {
4119
4120 // !TBD move this into its own location?
4121 namespace pf {
4122 template <typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args)
4123 {
4124   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
4125 }
4126 } // namespace pf
4127
4128 template <typename T> struct IGenerator : GeneratorUntypedBase {
4129   virtual ~IGenerator() = default;
4130
4131   // Returns the current element of the generator
4132   //
4133   // \Precondition The generator is either freshly constructed,
4134   // or the last call to `next()` returned true
4135   virtual T const& get() const = 0;
4136   using type                   = T;
4137 };
4138
4139 template <typename T> class SingleValueGenerator final : public IGenerator<T> {
4140   T m_value;
4141
4142 public:
4143   SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
4144
4145   T const& get() const override { return m_value; }
4146   bool next() override { return false; }
4147 };
4148
4149 template <typename T> class FixedValuesGenerator final : public IGenerator<T> {
4150   static_assert(!std::is_same<T, bool>::value,
4151                 "FixedValuesGenerator does not support bools because of std::vector<bool>"
4152                 "specialization, use SingleValue Generator instead.");
4153   std::vector<T> m_values;
4154   size_t m_idx = 0;
4155
4156 public:
4157   FixedValuesGenerator(std::initializer_list<T> values) : m_values(values) {}
4158
4159   T const& get() const override { return m_values[m_idx]; }
4160   bool next() override
4161   {
4162     ++m_idx;
4163     return m_idx < m_values.size();
4164   }
4165 };
4166
4167 template <typename T> class GeneratorWrapper final {
4168   std::unique_ptr<IGenerator<T>> m_generator;
4169
4170 public:
4171   GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator) : m_generator(std::move(generator)) {}
4172   T const& get() const { return m_generator->get(); }
4173   bool next() { return m_generator->next(); }
4174 };
4175
4176 template <typename T> GeneratorWrapper<T> value(T&& value)
4177 {
4178   return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
4179 }
4180 template <typename T> GeneratorWrapper<T> values(std::initializer_list<T> values)
4181 {
4182   return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
4183 }
4184
4185 template <typename T> class Generators : public IGenerator<T> {
4186   std::vector<GeneratorWrapper<T>> m_generators;
4187   size_t m_current = 0;
4188
4189   void populate(GeneratorWrapper<T>&& generator) { m_generators.emplace_back(std::move(generator)); }
4190   void populate(T&& val) { m_generators.emplace_back(value(std::forward<T>(val))); }
4191   template <typename U> void populate(U&& val) { populate(T(std::forward<U>(val))); }
4192   template <typename U, typename... Gs> void populate(U&& valueOrGenerator, Gs&&... moreGenerators)
4193   {
4194     populate(std::forward<U>(valueOrGenerator));
4195     populate(std::forward<Gs>(moreGenerators)...);
4196   }
4197
4198 public:
4199   template <typename... Gs> Generators(Gs&&... moreGenerators)
4200   {
4201     m_generators.reserve(sizeof...(Gs));
4202     populate(std::forward<Gs>(moreGenerators)...);
4203   }
4204
4205   T const& get() const override { return m_generators[m_current].get(); }
4206
4207   bool next() override
4208   {
4209     if (m_current >= m_generators.size()) {
4210       return false;
4211     }
4212     const bool current_status = m_generators[m_current].next();
4213     if (!current_status) {
4214       ++m_current;
4215     }
4216     return m_current < m_generators.size();
4217   }
4218 };
4219
4220 template <typename... Ts>
4221 GeneratorWrapper<std::tuple<Ts...>> table(std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples)
4222 {
4223   return values<std::tuple<Ts...>>(tuples);
4224 }
4225
4226 // Tag type to signal that a generator sequence should convert arguments to a specific type
4227 template <typename T> struct as {
4228 };
4229
4230 template <typename T, typename... Gs>
4231 auto makeGenerators(GeneratorWrapper<T>&& generator, Gs&&... moreGenerators) -> Generators<T>
4232 {
4233   return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
4234 }
4235 template <typename T> auto makeGenerators(GeneratorWrapper<T>&& generator) -> Generators<T>
4236 {
4237   return Generators<T>(std::move(generator));
4238 }
4239 template <typename T, typename... Gs> auto makeGenerators(T&& val, Gs&&... moreGenerators) -> Generators<T>
4240 {
4241   return makeGenerators(value(std::forward<T>(val)), std::forward<Gs>(moreGenerators)...);
4242 }
4243 template <typename T, typename U, typename... Gs>
4244 auto makeGenerators(as<T>, U&& val, Gs&&... moreGenerators) -> Generators<T>
4245 {
4246   return makeGenerators(value(T(std::forward<U>(val))), std::forward<Gs>(moreGenerators)...);
4247 }
4248
4249 auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo) -> IGeneratorTracker&;
4250
4251 template <typename L>
4252 // Note: The type after -> is weird, because VS2015 cannot parse
4253 //       the expression used in the typedef inside, when it is in
4254 //       return type. Yeah.
4255 auto generate(StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression)
4256     -> decltype(std::declval<decltype(generatorExpression())>().get())
4257 {
4258   using UnderlyingType = typename decltype(generatorExpression())::type;
4259
4260   IGeneratorTracker& tracker = acquireGeneratorTracker(generatorName, lineInfo);
4261   if (!tracker.hasGenerator()) {
4262     tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
4263   }
4264
4265   auto const& generator = static_cast<IGenerator<UnderlyingType> const&>(*tracker.getGenerator());
4266   return generator.get();
4267 }
4268
4269 } // namespace Generators
4270 } // namespace Catch
4271
4272 #define GENERATE(...)                                                                                                  \
4273   Catch::Generators::generate(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)),                         \
4274                               CATCH_INTERNAL_LINEINFO, [] {                                                            \
4275                                 using namespace Catch::Generators;                                                     \
4276                                 return makeGenerators(__VA_ARGS__);                                                    \
4277                               }) // NOLINT(google-build-using-namespace)
4278 #define GENERATE_COPY(...)                                                                                             \
4279   Catch::Generators::generate(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)),                         \
4280                               CATCH_INTERNAL_LINEINFO, [=] {                                                           \
4281                                 using namespace Catch::Generators;                                                     \
4282                                 return makeGenerators(__VA_ARGS__);                                                    \
4283                               }) // NOLINT(google-build-using-namespace)
4284 #define GENERATE_REF(...)                                                                                              \
4285   Catch::Generators::generate(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)),                         \
4286                               CATCH_INTERNAL_LINEINFO, [&] {                                                           \
4287                                 using namespace Catch::Generators;                                                     \
4288                                 return makeGenerators(__VA_ARGS__);                                                    \
4289                               }) // NOLINT(google-build-using-namespace)
4290
4291 // end catch_generators.hpp
4292 // start catch_generators_generic.hpp
4293
4294 namespace Catch {
4295 namespace Generators {
4296
4297 template <typename T> class TakeGenerator : public IGenerator<T> {
4298   GeneratorWrapper<T> m_generator;
4299   size_t m_returned = 0;
4300   size_t m_target;
4301
4302 public:
4303   TakeGenerator(size_t target, GeneratorWrapper<T>&& generator) : m_generator(std::move(generator)), m_target(target)
4304   {
4305     assert(target != 0 && "Empty generators are not allowed");
4306   }
4307   T const& get() const override { return m_generator.get(); }
4308   bool next() override
4309   {
4310     ++m_returned;
4311     if (m_returned >= m_target) {
4312       return false;
4313     }
4314
4315     const auto success = m_generator.next();
4316     // If the underlying generator does not contain enough values
4317     // then we cut short as well
4318     if (!success) {
4319       m_returned = m_target;
4320     }
4321     return success;
4322   }
4323 };
4324
4325 template <typename T> GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator)
4326 {
4327   return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
4328 }
4329
4330 template <typename T, typename Predicate> class FilterGenerator : public IGenerator<T> {
4331   GeneratorWrapper<T> m_generator;
4332   Predicate m_predicate;
4333
4334 public:
4335   template <typename P = Predicate>
4336   FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator)
4337       : m_generator(std::move(generator)), m_predicate(std::forward<P>(pred))
4338   {
4339     if (!m_predicate(m_generator.get())) {
4340       // It might happen that there are no values that pass the
4341       // filter. In that case we throw an exception.
4342       auto has_initial_value = next();
4343       if (!has_initial_value) {
4344         Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
4345       }
4346     }
4347   }
4348
4349   T const& get() const override { return m_generator.get(); }
4350
4351   bool next() override
4352   {
4353     bool success = m_generator.next();
4354     if (!success) {
4355       return false;
4356     }
4357     while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true)
4358       ;
4359     return success;
4360   }
4361 };
4362
4363 template <typename T, typename Predicate> GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator)
4364 {
4365   return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(
4366       pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
4367 }
4368
4369 template <typename T> class RepeatGenerator : public IGenerator<T> {
4370   static_assert(!std::is_same<T, bool>::value, "RepeatGenerator currently does not support bools"
4371                                                "because of std::vector<bool> specialization");
4372   GeneratorWrapper<T> m_generator;
4373   mutable std::vector<T> m_returned;
4374   size_t m_target_repeats;
4375   size_t m_current_repeat = 0;
4376   size_t m_repeat_index   = 0;
4377
4378 public:
4379   RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator)
4380       : m_generator(std::move(generator)), m_target_repeats(repeats)
4381   {
4382     assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
4383   }
4384
4385   T const& get() const override
4386   {
4387     if (m_current_repeat == 0) {
4388       m_returned.push_back(m_generator.get());
4389       return m_returned.back();
4390     }
4391     return m_returned[m_repeat_index];
4392   }
4393
4394   bool next() override
4395   {
4396     // There are 2 basic cases:
4397     // 1) We are still reading the generator
4398     // 2) We are reading our own cache
4399
4400     // In the first case, we need to poke the underlying generator.
4401     // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
4402     if (m_current_repeat == 0) {
4403       const auto success = m_generator.next();
4404       if (!success) {
4405         ++m_current_repeat;
4406       }
4407       return m_current_repeat < m_target_repeats;
4408     }
4409
4410     // In the second case, we need to move indices forward and check that we haven't run up against the end
4411     ++m_repeat_index;
4412     if (m_repeat_index == m_returned.size()) {
4413       m_repeat_index = 0;
4414       ++m_current_repeat;
4415     }
4416     return m_current_repeat < m_target_repeats;
4417   }
4418 };
4419
4420 template <typename T> GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator)
4421 {
4422   return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
4423 }
4424
4425 template <typename T, typename U, typename Func> class MapGenerator : public IGenerator<T> {
4426   // TBD: provide static assert for mapping function, for friendly error message
4427   GeneratorWrapper<U> m_generator;
4428   Func m_function;
4429   // To avoid returning dangling reference, we have to save the values
4430   T m_cache;
4431
4432 public:
4433   template <typename F2 = Func>
4434   MapGenerator(F2&& function, GeneratorWrapper<U>&& generator)
4435       : m_generator(std::move(generator))
4436       , m_function(std::forward<F2>(function))
4437       , m_cache(m_function(m_generator.get()))
4438   {
4439   }
4440
4441   T const& get() const override { return m_cache; }
4442   bool next() override
4443   {
4444     const auto success = m_generator.next();
4445     if (success) {
4446       m_cache = m_function(m_generator.get());
4447     }
4448     return success;
4449   }
4450 };
4451
4452 template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
4453 GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator)
4454 {
4455   return GeneratorWrapper<T>(
4456       pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)));
4457 }
4458
4459 template <typename T, typename U, typename Func>
4460 GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator)
4461 {
4462   return GeneratorWrapper<T>(
4463       pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)));
4464 }
4465
4466 template <typename T> class ChunkGenerator final : public IGenerator<std::vector<T>> {
4467   std::vector<T> m_chunk;
4468   size_t m_chunk_size;
4469   GeneratorWrapper<T> m_generator;
4470   bool m_used_up = false;
4471
4472 public:
4473   ChunkGenerator(size_t size, GeneratorWrapper<T> generator) : m_chunk_size(size), m_generator(std::move(generator))
4474   {
4475     m_chunk.reserve(m_chunk_size);
4476     if (m_chunk_size != 0) {
4477       m_chunk.push_back(m_generator.get());
4478       for (size_t i = 1; i < m_chunk_size; ++i) {
4479         if (!m_generator.next()) {
4480           Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
4481         }
4482         m_chunk.push_back(m_generator.get());
4483       }
4484     }
4485   }
4486   std::vector<T> const& get() const override { return m_chunk; }
4487   bool next() override
4488   {
4489     m_chunk.clear();
4490     for (size_t idx = 0; idx < m_chunk_size; ++idx) {
4491       if (!m_generator.next()) {
4492         return false;
4493       }
4494       m_chunk.push_back(m_generator.get());
4495     }
4496     return true;
4497   }
4498 };
4499
4500 template <typename T> GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator)
4501 {
4502   return GeneratorWrapper<std::vector<T>>(pf::make_unique<ChunkGenerator<T>>(size, std::move(generator)));
4503 }
4504
4505 } // namespace Generators
4506 } // namespace Catch
4507
4508 // end catch_generators_generic.hpp
4509 // start catch_generators_specific.hpp
4510
4511 // start catch_context.h
4512
4513 #include <memory>
4514
4515 namespace Catch {
4516
4517 struct IResultCapture;
4518 struct IRunner;
4519 struct IConfig;
4520 struct IMutableContext;
4521
4522 using IConfigPtr = std::shared_ptr<IConfig const>;
4523
4524 struct IContext {
4525   virtual ~IContext();
4526
4527   virtual IResultCapture* getResultCapture()  = 0;
4528   virtual IRunner* getRunner()                = 0;
4529   virtual IConfigPtr const& getConfig() const = 0;
4530 };
4531
4532 struct IMutableContext : IContext {
4533   virtual ~IMutableContext();
4534   virtual void setResultCapture(IResultCapture* resultCapture) = 0;
4535   virtual void setRunner(IRunner* runner)                      = 0;
4536   virtual void setConfig(IConfigPtr const& config)             = 0;
4537
4538 private:
4539   static IMutableContext* currentContext;
4540   friend IMutableContext& getCurrentMutableContext();
4541   friend void cleanUpContext();
4542   static void createContext();
4543 };
4544
4545 inline IMutableContext& getCurrentMutableContext()
4546 {
4547   if (!IMutableContext::currentContext)
4548     IMutableContext::createContext();
4549   // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
4550   return *IMutableContext::currentContext;
4551 }
4552
4553 inline IContext& getCurrentContext()
4554 {
4555   return getCurrentMutableContext();
4556 }
4557
4558 void cleanUpContext();
4559
4560 class SimplePcg32;
4561 SimplePcg32& rng();
4562 } // namespace Catch
4563
4564 // end catch_context.h
4565 // start catch_interfaces_config.h
4566
4567 // start catch_option.hpp
4568
4569 namespace Catch {
4570
4571 // An optional type
4572 template <typename T> class Option {
4573 public:
4574   Option() : nullableValue(nullptr) {}
4575   Option(T const& _value) : nullableValue(new (storage) T(_value)) {}
4576   Option(Option const& _other) : nullableValue(_other ? new (storage) T(*_other) : nullptr) {}
4577
4578   ~Option() { reset(); }
4579
4580   Option& operator=(Option const& _other)
4581   {
4582     if (&_other != this) {
4583       reset();
4584       if (_other)
4585         nullableValue = new (storage) T(*_other);
4586     }
4587     return *this;
4588   }
4589   Option& operator=(T const& _value)
4590   {
4591     reset();
4592     nullableValue = new (storage) T(_value);
4593     return *this;
4594   }
4595
4596   void reset()
4597   {
4598     if (nullableValue)
4599       nullableValue->~T();
4600     nullableValue = nullptr;
4601   }
4602
4603   T& operator*() { return *nullableValue; }
4604   T const& operator*() const { return *nullableValue; }
4605   T* operator->() { return nullableValue; }
4606   const T* operator->() const { return nullableValue; }
4607
4608   T valueOr(T const& defaultValue) const { return nullableValue ? *nullableValue : defaultValue; }
4609
4610   bool some() const { return nullableValue != nullptr; }
4611   bool none() const { return nullableValue == nullptr; }
4612
4613   bool operator!() const { return nullableValue == nullptr; }
4614   explicit operator bool() const { return some(); }
4615
4616 private:
4617   T* nullableValue;
4618   alignas(alignof(T)) char storage[sizeof(T)];
4619 };
4620
4621 } // end namespace Catch
4622
4623 // end catch_option.hpp
4624 #include <chrono>
4625 #include <iosfwd>
4626 #include <memory>
4627 #include <string>
4628 #include <vector>
4629
4630 namespace Catch {
4631
4632 enum class Verbosity { Quiet = 0, Normal, High };
4633
4634 struct WarnAbout {
4635   enum What { Nothing = 0x00, NoAssertions = 0x01, NoTests = 0x02 };
4636 };
4637
4638 struct ShowDurations {
4639   enum OrNot { DefaultForReporter, Always, Never };
4640 };
4641 struct RunTests {
4642   enum InWhatOrder { InDeclarationOrder, InLexicographicalOrder, InRandomOrder };
4643 };
4644 struct UseColour {
4645   enum YesOrNo { Auto, Yes, No };
4646 };
4647 struct WaitForKeypress {
4648   enum When { Never, BeforeStart = 1, BeforeExit = 2, BeforeStartAndExit = BeforeStart | BeforeExit };
4649 };
4650
4651 class TestSpec;
4652
4653 struct IConfig : NonCopyable {
4654
4655   virtual ~IConfig();
4656
4657   virtual bool allowThrows() const                                 = 0;
4658   virtual std::ostream& stream() const                             = 0;
4659   virtual std::string name() const                                 = 0;
4660   virtual bool includeSuccessfulResults() const                    = 0;
4661   virtual bool shouldDebugBreak() const                            = 0;
4662   virtual bool warnAboutMissingAssertions() const                  = 0;
4663   virtual bool warnAboutNoTests() const                            = 0;
4664   virtual int abortAfter() const                                   = 0;
4665   virtual bool showInvisibles() const                              = 0;
4666   virtual ShowDurations::OrNot showDurations() const               = 0;
4667   virtual double minDuration() const                               = 0;
4668   virtual TestSpec const& testSpec() const                         = 0;
4669   virtual bool hasTestFilters() const                              = 0;
4670   virtual std::vector<std::string> const& getTestsOrTags() const   = 0;
4671   virtual RunTests::InWhatOrder runOrder() const                   = 0;
4672   virtual unsigned int rngSeed() const                             = 0;
4673   virtual UseColour::YesOrNo useColour() const                     = 0;
4674   virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4675   virtual Verbosity verbosity() const                              = 0;
4676
4677   virtual bool benchmarkNoAnalysis() const                      = 0;
4678   virtual int benchmarkSamples() const                          = 0;
4679   virtual double benchmarkConfidenceInterval() const            = 0;
4680   virtual unsigned int benchmarkResamples() const               = 0;
4681   virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
4682 };
4683
4684 using IConfigPtr = std::shared_ptr<IConfig const>;
4685 } // namespace Catch
4686
4687 // end catch_interfaces_config.h
4688 // start catch_random_number_generator.h
4689
4690 #include <cstdint>
4691
4692 namespace Catch {
4693
4694 // This is a simple implementation of C++11 Uniform Random Number
4695 // Generator. It does not provide all operators, because Catch2
4696 // does not use it, but it should behave as expected inside stdlib's
4697 // distributions.
4698 // The implementation is based on the PCG family (http://pcg-random.org)
4699 class SimplePcg32 {
4700   using state_type = std::uint64_t;
4701
4702 public:
4703   using result_type = std::uint32_t;
4704   static constexpr result_type(min)() { return 0; }
4705   static constexpr result_type(max)() { return static_cast<result_type>(-1); }
4706
4707   // Provide some default initial state for the default constructor
4708   SimplePcg32() : SimplePcg32(0xed743cc4U) {}
4709
4710   explicit SimplePcg32(result_type seed_);
4711
4712   void seed(result_type seed_);
4713   void discard(uint64_t skip);
4714
4715   result_type operator()();
4716
4717 private:
4718   friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4719   friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4720
4721   // In theory we also need operator<< and operator>>
4722   // In practice we do not use them, so we will skip them for now
4723
4724   std::uint64_t m_state;
4725   // This part of the state determines which "stream" of the numbers
4726   // is chosen -- we take it as a constant for Catch2, so we only
4727   // need to deal with seeding the main state.
4728   // Picked by reading 8 bytes from `/dev/random` :-)
4729   static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
4730 };
4731
4732 } // end namespace Catch
4733
4734 // end catch_random_number_generator.h
4735 #include <random>
4736
4737 namespace Catch {
4738 namespace Generators {
4739
4740 template <typename Float> class RandomFloatingGenerator final : public IGenerator<Float> {
4741   Catch::SimplePcg32& m_rng;
4742   std::uniform_real_distribution<Float> m_dist;
4743   Float m_current_number;
4744
4745 public:
4746   RandomFloatingGenerator(Float a, Float b) : m_rng(rng()), m_dist(a, b) { static_cast<void>(next()); }
4747
4748   Float const& get() const override { return m_current_number; }
4749   bool next() override
4750   {
4751     m_current_number = m_dist(m_rng);
4752     return true;
4753   }
4754 };
4755
4756 template <typename Integer> class RandomIntegerGenerator final : public IGenerator<Integer> {
4757   Catch::SimplePcg32& m_rng;
4758   std::uniform_int_distribution<Integer> m_dist;
4759   Integer m_current_number;
4760
4761 public:
4762   RandomIntegerGenerator(Integer a, Integer b) : m_rng(rng()), m_dist(a, b) { static_cast<void>(next()); }
4763
4764   Integer const& get() const override { return m_current_number; }
4765   bool next() override
4766   {
4767     m_current_number = m_dist(m_rng);
4768     return true;
4769   }
4770 };
4771
4772 // TODO: Ideally this would be also constrained against the various char types,
4773 //       but I don't expect users to run into that in practice.
4774 template <typename T>
4775 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, GeneratorWrapper<T>>::type
4776 random(T a, T b)
4777 {
4778   return GeneratorWrapper<T>(pf::make_unique<RandomIntegerGenerator<T>>(a, b));
4779 }
4780
4781 template <typename T>
4782 typename std::enable_if<std::is_floating_point<T>::value, GeneratorWrapper<T>>::type random(T a, T b)
4783 {
4784   return GeneratorWrapper<T>(pf::make_unique<RandomFloatingGenerator<T>>(a, b));
4785 }
4786
4787 template <typename T> class RangeGenerator final : public IGenerator<T> {
4788   T m_current;
4789   T m_end;
4790   T m_step;
4791   bool m_positive;
4792
4793 public:
4794   RangeGenerator(T const& start, T const& end, T const& step)
4795       : m_current(start), m_end(end), m_step(step), m_positive(m_step > T(0))
4796   {
4797     assert(m_current != m_end && "Range start and end cannot be equal");
4798     assert(m_step != T(0) && "Step size cannot be zero");
4799     assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
4800   }
4801
4802   RangeGenerator(T const& start, T const& end) : RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) {}
4803
4804   T const& get() const override { return m_current; }
4805
4806   bool next() override
4807   {
4808     m_current += m_step;
4809     return (m_positive) ? (m_current < m_end) : (m_current > m_end);
4810   }
4811 };
4812
4813 template <typename T> GeneratorWrapper<T> range(T const& start, T const& end, T const& step)
4814 {
4815   static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
4816   return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
4817 }
4818
4819 template <typename T> GeneratorWrapper<T> range(T const& start, T const& end)
4820 {
4821   static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4822   return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
4823 }
4824
4825 template <typename T> class IteratorGenerator final : public IGenerator<T> {
4826   static_assert(!std::is_same<T, bool>::value, "IteratorGenerator currently does not support bools"
4827                                                "because of std::vector<bool> specialization");
4828
4829   std::vector<T> m_elems;
4830   size_t m_current = 0;
4831
4832 public:
4833   template <typename InputIterator, typename InputSentinel>
4834   IteratorGenerator(InputIterator first, InputSentinel last) : m_elems(first, last)
4835   {
4836     if (m_elems.empty()) {
4837       Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
4838     }
4839   }
4840
4841   T const& get() const override { return m_elems[m_current]; }
4842
4843   bool next() override
4844   {
4845     ++m_current;
4846     return m_current != m_elems.size();
4847   }
4848 };
4849
4850 template <typename InputIterator, typename InputSentinel,
4851           typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
4852 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to)
4853 {
4854   return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
4855 }
4856
4857 template <typename Container, typename ResultType = typename Container::value_type>
4858 GeneratorWrapper<ResultType> from_range(Container const& cnt)
4859 {
4860   return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
4861 }
4862
4863 } // namespace Generators
4864 } // namespace Catch
4865
4866 // end catch_generators_specific.hpp
4867
4868 // These files are included here so the single_include script doesn't put them
4869 // in the conditionally compiled sections
4870 // start catch_test_case_info.h
4871
4872 #include <memory>
4873 #include <string>
4874 #include <vector>
4875
4876 #ifdef __clang__
4877 #pragma clang diagnostic push
4878 #pragma clang diagnostic ignored "-Wpadded"
4879 #endif
4880
4881 namespace Catch {
4882
4883 struct ITestInvoker;
4884
4885 struct TestCaseInfo {
4886   enum SpecialProperties {
4887     None        = 0,
4888     IsHidden    = 1 << 1,
4889     ShouldFail  = 1 << 2,
4890     MayFail     = 1 << 3,
4891     Throws      = 1 << 4,
4892     NonPortable = 1 << 5,
4893     Benchmark   = 1 << 6
4894   };
4895
4896   TestCaseInfo(std::string const& _name, std::string const& _className, std::string const& _description,
4897                std::vector<std::string> const& _tags, SourceLineInfo const& _lineInfo);
4898
4899   friend void setTags(TestCaseInfo& testCaseInfo, std::vector<std::string> tags);
4900
4901   bool isHidden() const;
4902   bool throws() const;
4903   bool okToFail() const;
4904   bool expectedToFail() const;
4905
4906   std::string tagsAsString() const;
4907
4908   std::string name;
4909   std::string className;
4910   std::string description;
4911   std::vector<std::string> tags;
4912   std::vector<std::string> lcaseTags;
4913   SourceLineInfo lineInfo;
4914   SpecialProperties properties;
4915 };
4916
4917 class TestCase : public TestCaseInfo {
4918 public:
4919   TestCase(ITestInvoker* testCase, TestCaseInfo&& info);
4920
4921   TestCase withName(std::string const& _newName) const;
4922
4923   void invoke() const;
4924
4925   TestCaseInfo const& getTestCaseInfo() const;
4926
4927   bool operator==(TestCase const& other) const;
4928   bool operator<(TestCase const& other) const;
4929
4930 private:
4931   std::shared_ptr<ITestInvoker> test;
4932 };
4933
4934 TestCase makeTestCase(ITestInvoker* testCase, std::string const& className, NameAndTags const& nameAndTags,
4935                       SourceLineInfo const& lineInfo);
4936 } // namespace Catch
4937
4938 #ifdef __clang__
4939 #pragma clang diagnostic pop
4940 #endif
4941
4942 // end catch_test_case_info.h
4943 // start catch_interfaces_runner.h
4944
4945 namespace Catch {
4946
4947 struct IRunner {
4948   virtual ~IRunner();
4949   virtual bool aborting() const = 0;
4950 };
4951 } // namespace Catch
4952
4953 // end catch_interfaces_runner.h
4954
4955 #ifdef __OBJC__
4956 // start catch_objc.hpp
4957
4958 #import <objc/runtime.h>
4959
4960 #include <string>
4961
4962 // NB. Any general catch headers included here must be included
4963 // in catch.hpp first to make sure they are included by the single
4964 // header for non obj-usage
4965
4966 ///////////////////////////////////////////////////////////////////////////////
4967 // This protocol is really only here for (self) documenting purposes, since
4968 // all its methods are optional.
4969 @protocol OcFixture
4970
4971 @optional
4972
4973 - (void)setUp;
4974 - (void)tearDown;
4975
4976 @end
4977
4978 namespace Catch {
4979
4980 class OcMethod : public ITestInvoker {
4981
4982 public:
4983   OcMethod(Class cls, SEL sel) : m_cls(cls), m_sel(sel) {}
4984
4985   virtual void invoke() const
4986   {
4987     id obj = [[m_cls alloc] init];
4988
4989     performOptionalSelector(obj, @selector(setUp));
4990     performOptionalSelector(obj, m_sel);
4991     performOptionalSelector(obj, @selector(tearDown));
4992
4993     arcSafeRelease(obj);
4994   }
4995
4996 private:
4997   virtual ~OcMethod() {}
4998
4999   Class m_cls;
5000   SEL m_sel;
5001 };
5002
5003 namespace Detail {
5004
5005 inline std::string getAnnotation(Class cls, std::string const& annotationName, std::string const& testCaseName)
5006 {
5007   NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
5008   SEL sel          = NSSelectorFromString(selStr);
5009   arcSafeRelease(selStr);
5010   id value = performOptionalSelector(cls, sel);
5011   if (value)
5012     return [(NSString*)value UTF8String];
5013   return "";
5014 }
5015 } // namespace Detail
5016
5017 inline std::size_t registerTestMethods()
5018 {
5019   std::size_t noTestMethods = 0;
5020   int noClasses             = objc_getClassList(nullptr, 0);
5021
5022   Class* classes = (CATCH_UNSAFE_UNRETAINED Class*)malloc(sizeof(Class) * noClasses);
5023   objc_getClassList(classes, noClasses);
5024
5025   for (int c = 0; c < noClasses; c++) {
5026     Class cls = classes[c];
5027     {
5028       u_int count;
5029       Method* methods = class_copyMethodList(cls, &count);
5030       for (u_int m = 0; m < count; m++) {
5031         SEL selector           = method_getName(methods[m]);
5032         std::string methodName = sel_getName(selector);
5033         if (startsWith(methodName, "Catch_TestCase_")) {
5034           std::string testCaseName = methodName.substr(15);
5035           std::string name         = Detail::getAnnotation(cls, "Name", testCaseName);
5036           std::string desc         = Detail::getAnnotation(cls, "Description", testCaseName);
5037           const char* className    = class_getName(cls);
5038
5039           getMutableRegistryHub().registerTest(makeTestCase(
5040               new OcMethod(cls, selector), className, NameAndTags(name.c_str(), desc.c_str()), SourceLineInfo("", 0)));
5041           noTestMethods++;
5042         }
5043       }
5044       free(methods);
5045     }
5046   }
5047   return noTestMethods;
5048 }
5049
5050 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
5051
5052 namespace Matchers {
5053 namespace Impl {
5054 namespace NSStringMatchers {
5055
5056 struct StringHolder : MatcherBase<NSString*> {
5057   StringHolder(NSString* substr) : m_substr([substr copy]) {}
5058   StringHolder(StringHolder const& other) : m_substr([other.m_substr copy]) {}
5059   StringHolder() { arcSafeRelease(m_substr); }
5060
5061   bool match(NSString* str) const override { return false; }
5062
5063   NSString* CATCH_ARC_STRONG m_substr;
5064 };
5065
5066 struct Equals : StringHolder {
5067   Equals(NSString* substr) : StringHolder(substr) {}
5068
5069   bool match(NSString* str) const override { return (str != nil || m_substr == nil) && [str isEqualToString:m_substr]; }
5070
5071   std::string describe() const override { return "equals string: " + Catch::Detail::stringify(m_substr); }
5072 };
5073
5074 struct Contains : StringHolder {
5075   Contains(NSString* substr) : StringHolder(substr) {}
5076
5077   bool match(NSString* str) const override
5078   {
5079     return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location != NSNotFound;
5080   }
5081
5082   std::string describe() const override { return "contains string: " + Catch::Detail::stringify(m_substr); }
5083 };
5084
5085 struct StartsWith : StringHolder {
5086   StartsWith(NSString* substr) : StringHolder(substr) {}
5087
5088   bool match(NSString* str) const override
5089   {
5090     return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location == 0;
5091   }
5092
5093   std::string describe() const override { return "starts with: " + Catch::Detail::stringify(m_substr); }
5094 };
5095 struct EndsWith : StringHolder {
5096   EndsWith(NSString* substr) : StringHolder(substr) {}
5097
5098   bool match(NSString* str) const override
5099   {
5100     return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location == [str length] - [m_substr length];
5101   }
5102
5103   std::string describe() const override { return "ends with: " + Catch::Detail::stringify(m_substr); }
5104 };
5105
5106 } // namespace NSStringMatchers
5107 } // namespace Impl
5108
5109 inline Impl::NSStringMatchers::Equals Equals(NSString* substr)
5110 {
5111   return Impl::NSStringMatchers::Equals(substr);
5112 }
5113
5114 inline Impl::NSStringMatchers::Contains Contains(NSString* substr)
5115 {
5116   return Impl::NSStringMatchers::Contains(substr);
5117 }
5118
5119 inline Impl::NSStringMatchers::StartsWith StartsWith(NSString* substr)
5120 {
5121   return Impl::NSStringMatchers::StartsWith(substr);
5122 }
5123
5124 inline Impl::NSStringMatchers::EndsWith EndsWith(NSString* substr)
5125 {
5126   return Impl::NSStringMatchers::EndsWith(substr);
5127 }
5128
5129 } // namespace Matchers
5130
5131 using namespace Matchers;
5132
5133 #endif // CATCH_CONFIG_DISABLE_MATCHERS
5134
5135 } // namespace Catch
5136
5137 ///////////////////////////////////////////////////////////////////////////////
5138 #define OC_MAKE_UNIQUE_NAME(root, uniqueSuffix) root##uniqueSuffix
5139 #define OC_TEST_CASE2(name, desc, uniqueSuffix)                                                                        \
5140   +(NSString*)OC_MAKE_UNIQUE_NAME(Catch_Name_test_, uniqueSuffix)                                                      \
5141   {                                                                                                                    \
5142     return @name;                                                                                                      \
5143   }                                                                                                                    \
5144   +(NSString*)OC_MAKE_UNIQUE_NAME(Catch_Description_test_, uniqueSuffix)                                               \
5145   {                                                                                                                    \
5146     return @desc;                                                                                                      \
5147   }                                                                                                                    \
5148   -(void)OC_MAKE_UNIQUE_NAME(Catch_TestCase_test_, uniqueSuffix)
5149
5150 #define OC_TEST_CASE(name, desc) OC_TEST_CASE2(name, desc, __LINE__)
5151
5152 // end catch_objc.hpp
5153 #endif
5154
5155 // Benchmarking needs the externally-facing parts of reporters to work
5156 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5157 // start catch_external_interfaces.h
5158
5159 // start catch_reporter_bases.hpp
5160
5161 // start catch_interfaces_reporter.h
5162
5163 // start catch_config.hpp
5164
5165 // start catch_test_spec_parser.h
5166
5167 #ifdef __clang__
5168 #pragma clang diagnostic push
5169 #pragma clang diagnostic ignored "-Wpadded"
5170 #endif
5171
5172 // start catch_test_spec.h
5173
5174 #ifdef __clang__
5175 #pragma clang diagnostic push
5176 #pragma clang diagnostic ignored "-Wpadded"
5177 #endif
5178
5179 // start catch_wildcard_pattern.h
5180
5181 namespace Catch {
5182 class WildcardPattern {
5183   enum WildcardPosition {
5184     NoWildcard         = 0,
5185     WildcardAtStart    = 1,
5186     WildcardAtEnd      = 2,
5187     WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
5188   };
5189
5190 public:
5191   WildcardPattern(std::string const& pattern, CaseSensitive::Choice caseSensitivity);
5192   virtual ~WildcardPattern() = default;
5193   virtual bool matches(std::string const& str) const;
5194
5195 private:
5196   std::string normaliseString(std::string const& str) const;
5197   CaseSensitive::Choice m_caseSensitivity;
5198   WildcardPosition m_wildcard = NoWildcard;
5199   std::string m_pattern;
5200 };
5201 } // namespace Catch
5202
5203 // end catch_wildcard_pattern.h
5204 #include <memory>
5205 #include <string>
5206 #include <vector>
5207
5208 namespace Catch {
5209
5210 struct IConfig;
5211
5212 class TestSpec {
5213   class Pattern {
5214   public:
5215     explicit Pattern(std::string const& name);
5216     virtual ~Pattern();
5217     virtual bool matches(TestCaseInfo const& testCase) const = 0;
5218     std::string const& name() const;
5219
5220   private:
5221     std::string const m_name;
5222   };
5223   using PatternPtr = std::shared_ptr<Pattern>;
5224
5225   class NamePattern : public Pattern {
5226   public:
5227     explicit NamePattern(std::string const& name, std::string const& filterString);
5228     bool matches(TestCaseInfo const& testCase) const override;
5229
5230   private:
5231     WildcardPattern m_wildcardPattern;
5232   };
5233
5234   class TagPattern : public Pattern {
5235   public:
5236     explicit TagPattern(std::string const& tag, std::string const& filterString);
5237     bool matches(TestCaseInfo const& testCase) const override;
5238
5239   private:
5240     std::string m_tag;
5241   };
5242
5243   class ExcludedPattern : public Pattern {
5244   public:
5245     explicit ExcludedPattern(PatternPtr const& underlyingPattern);
5246     bool matches(TestCaseInfo const& testCase) const override;
5247
5248   private:
5249     PatternPtr m_underlyingPattern;
5250   };
5251
5252   struct Filter {
5253     std::vector<PatternPtr> m_patterns;
5254
5255     bool matches(TestCaseInfo const& testCase) const;
5256     std::string name() const;
5257   };
5258
5259 public:
5260   struct FilterMatch {
5261     std::string name;
5262     std::vector<TestCase const*> tests;
5263   };
5264   using Matches       = std::vector<FilterMatch>;
5265   using vectorStrings = std::vector<std::string>;
5266
5267   bool hasFilters() const;
5268   bool matches(TestCaseInfo const& testCase) const;
5269   Matches matchesByFilter(std::vector<TestCase> const& testCases, IConfig const& config) const;
5270   const vectorStrings& getInvalidArgs() const;
5271
5272 private:
5273   std::vector<Filter> m_filters;
5274   std::vector<std::string> m_invalidArgs;
5275   friend class TestSpecParser;
5276 };
5277 } // namespace Catch
5278
5279 #ifdef __clang__
5280 #pragma clang diagnostic pop
5281 #endif
5282
5283 // end catch_test_spec.h
5284 // start catch_interfaces_tag_alias_registry.h
5285
5286 #include <string>
5287
5288 namespace Catch {
5289
5290 struct TagAlias;
5291
5292 struct ITagAliasRegistry {
5293   virtual ~ITagAliasRegistry();
5294   // Nullptr if not present
5295   virtual TagAlias const* find(std::string const& alias) const                   = 0;
5296   virtual std::string expandAliases(std::string const& unexpandedTestSpec) const = 0;
5297
5298   static ITagAliasRegistry const& get();
5299 };
5300
5301 } // end namespace Catch
5302
5303 // end catch_interfaces_tag_alias_registry.h
5304 namespace Catch {
5305
5306 class TestSpecParser {
5307   enum Mode { None, Name, QuotedName, Tag, EscapedName };
5308   Mode m_mode                  = None;
5309   Mode lastMode                = None;
5310   bool m_exclusion             = false;
5311   std::size_t m_pos            = 0;
5312   std::size_t m_realPatternPos = 0;
5313   std::string m_arg;
5314   std::string m_substring;
5315   std::string m_patternName;
5316   std::vector<std::size_t> m_escapeChars;
5317   TestSpec::Filter m_currentFilter;
5318   TestSpec m_testSpec;
5319   ITagAliasRegistry const* m_tagAliases = nullptr;
5320
5321 public:
5322   TestSpecParser(ITagAliasRegistry const& tagAliases);
5323
5324   TestSpecParser& parse(std::string const& arg);
5325   TestSpec testSpec();
5326
5327 private:
5328   bool visitChar(char c);
5329   void startNewMode(Mode mode);
5330   bool processNoneChar(char c);
5331   void processNameChar(char c);
5332   bool processOtherChar(char c);
5333   void endMode();
5334   void escape();
5335   bool isControlChar(char c) const;
5336   void saveLastMode();
5337   void revertBackToLastMode();
5338   void addFilter();
5339   bool separate();
5340
5341   // Handles common preprocessing of the pattern for name/tag patterns
5342   std::string preprocessPattern();
5343   // Adds the current pattern as a test name
5344   void addNamePattern();
5345   // Adds the current pattern as a tag
5346   void addTagPattern();
5347
5348   inline void addCharToPattern(char c)
5349   {
5350     m_substring += c;
5351     m_patternName += c;
5352     m_realPatternPos++;
5353   }
5354 };
5355 TestSpec parseTestSpec(std::string const& arg);
5356
5357 } // namespace Catch
5358
5359 #ifdef __clang__
5360 #pragma clang diagnostic pop
5361 #endif
5362
5363 // end catch_test_spec_parser.h
5364 // Libstdc++ doesn't like incomplete classes for unique_ptr
5365
5366 #include <memory>
5367 #include <string>
5368 #include <vector>
5369
5370 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
5371 #define CATCH_CONFIG_CONSOLE_WIDTH 80
5372 #endif
5373
5374 namespace Catch {
5375
5376 struct IStream;
5377
5378 struct ConfigData {
5379   bool listTests         = false;
5380   bool listTags          = false;
5381   bool listReporters     = false;
5382   bool listTestNamesOnly = false;
5383
5384   bool showSuccessfulTests = false;
5385   bool shouldDebugBreak    = false;
5386   bool noThrow             = false;
5387   bool showHelp            = false;
5388   bool showInvisibles      = false;
5389   bool filenamesAsTags     = false;
5390   bool libIdentify         = false;
5391
5392   int abortAfter       = -1;
5393   unsigned int rngSeed = 0;
5394
5395   bool benchmarkNoAnalysis                           = false;
5396   unsigned int benchmarkSamples                      = 100;
5397   double benchmarkConfidenceInterval                 = 0.95;
5398   unsigned int benchmarkResamples                    = 100000;
5399   std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
5400
5401   Verbosity verbosity                   = Verbosity::Normal;
5402   WarnAbout::What warnings              = WarnAbout::Nothing;
5403   ShowDurations::OrNot showDurations    = ShowDurations::DefaultForReporter;
5404   double minDuration                    = -1;
5405   RunTests::InWhatOrder runOrder        = RunTests::InDeclarationOrder;
5406   UseColour::YesOrNo useColour          = UseColour::Auto;
5407   WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
5408
5409   std::string outputFilename;
5410   std::string name;
5411   std::string processName;
5412 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
5413 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
5414 #endif
5415   std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
5416 #undef CATCH_CONFIG_DEFAULT_REPORTER
5417
5418   std::vector<std::string> testsOrTags;
5419   std::vector<std::string> sectionsToRun;
5420 };
5421
5422 class Config : public IConfig {
5423 public:
5424   Config() = default;
5425   Config(ConfigData const& data);
5426   virtual ~Config() = default;
5427
5428   std::string const& getFilename() const;
5429
5430   bool listTests() const;
5431   bool listTestNamesOnly() const;
5432   bool listTags() const;
5433   bool listReporters() const;
5434
5435   std::string getProcessName() const;
5436   std::string const& getReporterName() const;
5437
5438   std::vector<std::string> const& getTestsOrTags() const override;
5439   std::vector<std::string> const& getSectionsToRun() const override;
5440
5441   TestSpec const& testSpec() const override;
5442   bool hasTestFilters() const override;
5443
5444   bool showHelp() const;
5445
5446   // IConfig interface
5447   bool allowThrows() const override;
5448   std::ostream& stream() const override;
5449   std::string name() const override;
5450   bool includeSuccessfulResults() const override;
5451   bool warnAboutMissingAssertions() const override;
5452   bool warnAboutNoTests() const override;
5453   ShowDurations::OrNot showDurations() const override;
5454   double minDuration() const override;
5455   RunTests::InWhatOrder runOrder() const override;
5456   unsigned int rngSeed() const override;
5457   UseColour::YesOrNo useColour() const override;
5458   bool shouldDebugBreak() const override;
5459   int abortAfter() const override;
5460   bool showInvisibles() const override;
5461   Verbosity verbosity() const override;
5462   bool benchmarkNoAnalysis() const override;
5463   int benchmarkSamples() const override;
5464   double benchmarkConfidenceInterval() const override;
5465   unsigned int benchmarkResamples() const override;
5466   std::chrono::milliseconds benchmarkWarmupTime() const override;
5467
5468 private:
5469   IStream const* openStream();
5470   ConfigData m_data;
5471
5472   std::unique_ptr<IStream const> m_stream;
5473   TestSpec m_testSpec;
5474   bool m_hasTestFilters = false;
5475 };
5476
5477 } // end namespace Catch
5478
5479 // end catch_config.hpp
5480 // start catch_assertionresult.h
5481
5482 #include <string>
5483
5484 namespace Catch {
5485
5486 struct AssertionResultData {
5487   AssertionResultData() = delete;
5488
5489   AssertionResultData(ResultWas::OfType _resultType, LazyExpression const& _lazyExpression);
5490
5491   std::string message;
5492   mutable std::string reconstructedExpression;
5493   LazyExpression lazyExpression;
5494   ResultWas::OfType resultType;
5495
5496   std::string reconstructExpression() const;
5497 };
5498
5499 class AssertionResult {
5500 public:
5501   AssertionResult() = delete;
5502   AssertionResult(AssertionInfo const& info, AssertionResultData const& data);
5503
5504   bool isOk() const;
5505   bool succeeded() const;
5506   ResultWas::OfType getResultType() const;
5507   bool hasExpression() const;
5508   bool hasMessage() const;
5509   std::string getExpression() const;
5510   std::string getExpressionInMacro() const;
5511   bool hasExpandedExpression() const;
5512   std::string getExpandedExpression() const;
5513   std::string getMessage() const;
5514   SourceLineInfo getSourceInfo() const;
5515   StringRef getTestMacroName() const;
5516
5517   // protected:
5518   AssertionInfo m_info;
5519   AssertionResultData m_resultData;
5520 };
5521
5522 } // end namespace Catch
5523
5524 // end catch_assertionresult.h
5525 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5526 // start catch_estimate.hpp
5527
5528 // Statistics estimates
5529
5530 namespace Catch {
5531 namespace Benchmark {
5532 template <typename Duration> struct Estimate {
5533   Duration point;
5534   Duration lower_bound;
5535   Duration upper_bound;
5536   double confidence_interval;
5537
5538   template <typename Duration2> operator Estimate<Duration2>() const
5539   {
5540     return {point, lower_bound, upper_bound, confidence_interval};
5541   }
5542 };
5543 } // namespace Benchmark
5544 } // namespace Catch
5545
5546 // end catch_estimate.hpp
5547 // start catch_outlier_classification.hpp
5548
5549 // Outlier information
5550
5551 namespace Catch {
5552 namespace Benchmark {
5553 struct OutlierClassification {
5554   int samples_seen = 0;
5555   int low_severe   = 0; // more than 3 times IQR below Q1
5556   int low_mild     = 0; // 1.5 to 3 times IQR below Q1
5557   int high_mild    = 0; // 1.5 to 3 times IQR above Q3
5558   int high_severe  = 0; // more than 3 times IQR above Q3
5559
5560   int total() const { return low_severe + low_mild + high_mild + high_severe; }
5561 };
5562 } // namespace Benchmark
5563 } // namespace Catch
5564
5565 // end catch_outlier_classification.hpp
5566 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5567
5568 #include <algorithm>
5569 #include <iosfwd>
5570 #include <map>
5571 #include <memory>
5572 #include <set>
5573 #include <string>
5574
5575 namespace Catch {
5576
5577 struct ReporterConfig {
5578   explicit ReporterConfig(IConfigPtr const& _fullConfig);
5579
5580   ReporterConfig(IConfigPtr const& _fullConfig, std::ostream& _stream);
5581
5582   std::ostream& stream() const;
5583   IConfigPtr fullConfig() const;
5584
5585 private:
5586   std::ostream* m_stream;
5587   IConfigPtr m_fullConfig;
5588 };
5589
5590 struct ReporterPreferences {
5591   bool shouldRedirectStdOut      = false;
5592   bool shouldReportAllAssertions = false;
5593 };
5594
5595 template <typename T> struct LazyStat : Option<T> {
5596   LazyStat& operator=(T const& _value)
5597   {
5598     Option<T>::operator=(_value);
5599     used = false;
5600     return *this;
5601   }
5602   void reset()
5603   {
5604     Option<T>::reset();
5605     used = false;
5606   }
5607   bool used = false;
5608 };
5609
5610 struct TestRunInfo {
5611   TestRunInfo(std::string const& _name);
5612   std::string name;
5613 };
5614 struct GroupInfo {
5615   GroupInfo(std::string const& _name, std::size_t _groupIndex, std::size_t _groupsCount);
5616
5617   std::string name;
5618   std::size_t groupIndex;
5619   std::size_t groupsCounts;
5620 };
5621
5622 struct AssertionStats {
5623   AssertionStats(AssertionResult const& _assertionResult, std::vector<MessageInfo> const& _infoMessages,
5624                  Totals const& _totals);
5625
5626   AssertionStats(AssertionStats const&)            = default;
5627   AssertionStats(AssertionStats&&)                 = default;
5628   AssertionStats& operator=(AssertionStats const&) = delete;
5629   AssertionStats& operator=(AssertionStats&&)      = delete;
5630   virtual ~AssertionStats();
5631
5632   AssertionResult assertionResult;
5633   std::vector<MessageInfo> infoMessages;
5634   Totals totals;
5635 };
5636
5637 struct SectionStats {
5638   SectionStats(SectionInfo const& _sectionInfo, Counts const& _assertions, double _durationInSeconds,
5639                bool _missingAssertions);
5640   SectionStats(SectionStats const&)            = default;
5641   SectionStats(SectionStats&&)                 = default;
5642   SectionStats& operator=(SectionStats const&) = default;
5643   SectionStats& operator=(SectionStats&&)      = default;
5644   virtual ~SectionStats();
5645
5646   SectionInfo sectionInfo;
5647   Counts assertions;
5648   double durationInSeconds;
5649   bool missingAssertions;
5650 };
5651
5652 struct TestCaseStats {
5653   TestCaseStats(TestCaseInfo const& _testInfo, Totals const& _totals, std::string const& _stdOut,
5654                 std::string const& _stdErr, bool _aborting);
5655
5656   TestCaseStats(TestCaseStats const&)            = default;
5657   TestCaseStats(TestCaseStats&&)                 = default;
5658   TestCaseStats& operator=(TestCaseStats const&) = default;
5659   TestCaseStats& operator=(TestCaseStats&&)      = default;
5660   virtual ~TestCaseStats();
5661
5662   TestCaseInfo testInfo;
5663   Totals totals;
5664   std::string stdOut;
5665   std::string stdErr;
5666   bool aborting;
5667 };
5668
5669 struct TestGroupStats {
5670   TestGroupStats(GroupInfo const& _groupInfo, Totals const& _totals, bool _aborting);
5671   TestGroupStats(GroupInfo const& _groupInfo);
5672
5673   TestGroupStats(TestGroupStats const&)            = default;
5674   TestGroupStats(TestGroupStats&&)                 = default;
5675   TestGroupStats& operator=(TestGroupStats const&) = default;
5676   TestGroupStats& operator=(TestGroupStats&&)      = default;
5677   virtual ~TestGroupStats();
5678
5679   GroupInfo groupInfo;
5680   Totals totals;
5681   bool aborting;
5682 };
5683
5684 struct TestRunStats {
5685   TestRunStats(TestRunInfo const& _runInfo, Totals const& _totals, bool _aborting);
5686
5687   TestRunStats(TestRunStats const&)            = default;
5688   TestRunStats(TestRunStats&&)                 = default;
5689   TestRunStats& operator=(TestRunStats const&) = default;
5690   TestRunStats& operator=(TestRunStats&&)      = default;
5691   virtual ~TestRunStats();
5692
5693   TestRunInfo runInfo;
5694   Totals totals;
5695   bool aborting;
5696 };
5697
5698 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5699 struct BenchmarkInfo {
5700   std::string name;
5701   double estimatedDuration;
5702   int iterations;
5703   int samples;
5704   unsigned int resamples;
5705   double clockResolution;
5706   double clockCost;
5707 };
5708
5709 template <class Duration> struct BenchmarkStats {
5710   BenchmarkInfo info;
5711
5712   std::vector<Duration> samples;
5713   Benchmark::Estimate<Duration> mean;
5714   Benchmark::Estimate<Duration> standardDeviation;
5715   Benchmark::OutlierClassification outliers;
5716   double outlierVariance;
5717
5718   template <typename Duration2> operator BenchmarkStats<Duration2>() const
5719   {
5720     std::vector<Duration2> samples2;
5721     samples2.reserve(samples.size());
5722     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2),
5723                    [](Duration d) { return Duration2(d); });
5724     return {
5725         info, std::move(samples2), mean, standardDeviation, outliers, outlierVariance,
5726     };
5727   }
5728 };
5729 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5730
5731 struct IStreamingReporter {
5732   virtual ~IStreamingReporter() = default;
5733
5734   // Implementing class must also provide the following static methods:
5735   // static std::string getDescription();
5736   // static std::set<Verbosity> getSupportedVerbosities()
5737
5738   virtual ReporterPreferences getPreferences() const = 0;
5739
5740   virtual void noMatchingTestCases(std::string const& spec) = 0;
5741
5742   virtual void reportInvalidArguments(std::string const&) {}
5743
5744   virtual void testRunStarting(TestRunInfo const& testRunInfo) = 0;
5745   virtual void testGroupStarting(GroupInfo const& groupInfo)   = 0;
5746
5747   virtual void testCaseStarting(TestCaseInfo const& testInfo)  = 0;
5748   virtual void sectionStarting(SectionInfo const& sectionInfo) = 0;
5749
5750 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5751   virtual void benchmarkPreparing(std::string const&) {}
5752   virtual void benchmarkStarting(BenchmarkInfo const&) {}
5753   virtual void benchmarkEnded(BenchmarkStats<> const&) {}
5754   virtual void benchmarkFailed(std::string const&) {}
5755 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5756
5757   virtual void assertionStarting(AssertionInfo const& assertionInfo) = 0;
5758
5759   // The return value indicates if the messages buffer should be cleared:
5760   virtual bool assertionEnded(AssertionStats const& assertionStats) = 0;
5761
5762   virtual void sectionEnded(SectionStats const& sectionStats)       = 0;
5763   virtual void testCaseEnded(TestCaseStats const& testCaseStats)    = 0;
5764   virtual void testGroupEnded(TestGroupStats const& testGroupStats) = 0;
5765   virtual void testRunEnded(TestRunStats const& testRunStats)       = 0;
5766
5767   virtual void skipTest(TestCaseInfo const& testInfo) = 0;
5768
5769   // Default empty implementation provided
5770   virtual void fatalErrorEncountered(StringRef name);
5771
5772   virtual bool isMulti() const;
5773 };
5774 using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
5775
5776 struct IReporterFactory {
5777   virtual ~IReporterFactory();
5778   virtual IStreamingReporterPtr create(ReporterConfig const& config) const = 0;
5779   virtual std::string getDescription() const                               = 0;
5780 };
5781 using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
5782
5783 struct IReporterRegistry {
5784   using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
5785   using Listeners  = std::vector<IReporterFactoryPtr>;
5786
5787   virtual ~IReporterRegistry();
5788   virtual IStreamingReporterPtr create(std::string const& name, IConfigPtr const& config) const = 0;
5789   virtual FactoryMap const& getFactories() const                                                = 0;
5790   virtual Listeners const& getListeners() const                                                 = 0;
5791 };
5792
5793 } // end namespace Catch
5794
5795 // end catch_interfaces_reporter.h
5796 #include <algorithm>
5797 #include <cassert>
5798 #include <cfloat>
5799 #include <cstdio>
5800 #include <cstring>
5801 #include <memory>
5802 #include <ostream>
5803
5804 namespace Catch {
5805 void prepareExpandedExpression(AssertionResult& result);
5806
5807 // Returns double formatted as %.3f (format expected on output)
5808 std::string getFormattedDuration(double duration);
5809
5810 //! Should the reporter show
5811 bool shouldShowDuration(IConfig const& config, double duration);
5812
5813 std::string serializeFilters(std::vector<std::string> const& container);
5814
5815 template <typename DerivedT> struct StreamingReporterBase : IStreamingReporter {
5816
5817   StreamingReporterBase(ReporterConfig const& _config) : m_config(_config.fullConfig()), stream(_config.stream())
5818   {
5819     m_reporterPrefs.shouldRedirectStdOut = false;
5820     if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity()))
5821       CATCH_ERROR("Verbosity level not supported by this reporter");
5822   }
5823
5824   ReporterPreferences getPreferences() const override { return m_reporterPrefs; }
5825
5826   static std::set<Verbosity> getSupportedVerbosities() { return {Verbosity::Normal}; }
5827
5828   ~StreamingReporterBase() override = default;
5829
5830   void noMatchingTestCases(std::string const&) override {}
5831
5832   void reportInvalidArguments(std::string const&) override {}
5833
5834   void testRunStarting(TestRunInfo const& _testRunInfo) override { currentTestRunInfo = _testRunInfo; }
5835
5836   void testGroupStarting(GroupInfo const& _groupInfo) override { currentGroupInfo = _groupInfo; }
5837
5838   void testCaseStarting(TestCaseInfo const& _testInfo) override { currentTestCaseInfo = _testInfo; }
5839   void sectionStarting(SectionInfo const& _sectionInfo) override { m_sectionStack.push_back(_sectionInfo); }
5840
5841   void sectionEnded(SectionStats const& /* _sectionStats */) override { m_sectionStack.pop_back(); }
5842   void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override { currentTestCaseInfo.reset(); }
5843   void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override { currentGroupInfo.reset(); }
5844   void testRunEnded(TestRunStats const& /* _testRunStats */) override
5845   {
5846     currentTestCaseInfo.reset();
5847     currentGroupInfo.reset();
5848     currentTestRunInfo.reset();
5849   }
5850
5851   void skipTest(TestCaseInfo const&) override
5852   {
5853     // Don't do anything with this by default.
5854     // It can optionally be overridden in the derived class.
5855   }
5856
5857   IConfigPtr m_config;
5858   std::ostream& stream;
5859
5860   LazyStat<TestRunInfo> currentTestRunInfo;
5861   LazyStat<GroupInfo> currentGroupInfo;
5862   LazyStat<TestCaseInfo> currentTestCaseInfo;
5863
5864   std::vector<SectionInfo> m_sectionStack;
5865   ReporterPreferences m_reporterPrefs;
5866 };
5867
5868 template <typename DerivedT> struct CumulativeReporterBase : IStreamingReporter {
5869   template <typename T, typename ChildNodeT> struct Node {
5870     explicit Node(T const& _value) : value(_value) {}
5871     virtual ~Node() {}
5872
5873     using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
5874     T value;
5875     ChildNodes children;
5876   };
5877   struct SectionNode {
5878     explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
5879     virtual ~SectionNode() = default;
5880
5881     bool operator==(SectionNode const& other) const
5882     {
5883       return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
5884     }
5885     bool operator==(std::shared_ptr<SectionNode> const& other) const { return operator==(*other); }
5886
5887     SectionStats stats;
5888     using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
5889     using Assertions    = std::vector<AssertionStats>;
5890     ChildSections childSections;
5891     Assertions assertions;
5892     std::string stdOut;
5893     std::string stdErr;
5894   };
5895
5896   struct BySectionInfo {
5897     BySectionInfo(SectionInfo const& other) : m_other(other) {}
5898     BySectionInfo(BySectionInfo const& other) : m_other(other.m_other) {}
5899     bool operator()(std::shared_ptr<SectionNode> const& node) const
5900     {
5901       return ((node->stats.sectionInfo.name == m_other.name) && (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
5902     }
5903     void operator=(BySectionInfo const&) = delete;
5904
5905   private:
5906     SectionInfo const& m_other;
5907   };
5908
5909   using TestCaseNode  = Node<TestCaseStats, SectionNode>;
5910   using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
5911   using TestRunNode   = Node<TestRunStats, TestGroupNode>;
5912
5913   CumulativeReporterBase(ReporterConfig const& _config) : m_config(_config.fullConfig()), stream(_config.stream())
5914   {
5915     m_reporterPrefs.shouldRedirectStdOut = false;
5916     if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity()))
5917       CATCH_ERROR("Verbosity level not supported by this reporter");
5918   }
5919   ~CumulativeReporterBase() override = default;
5920
5921   ReporterPreferences getPreferences() const override { return m_reporterPrefs; }
5922
5923   static std::set<Verbosity> getSupportedVerbosities() { return {Verbosity::Normal}; }
5924
5925   void testRunStarting(TestRunInfo const&) override {}
5926   void testGroupStarting(GroupInfo const&) override {}
5927
5928   void testCaseStarting(TestCaseInfo const&) override {}
5929
5930   void sectionStarting(SectionInfo const& sectionInfo) override
5931   {
5932     SectionStats incompleteStats(sectionInfo, Counts(), 0, false);
5933     std::shared_ptr<SectionNode> node;
5934     if (m_sectionStack.empty()) {
5935       if (!m_rootSection)
5936         m_rootSection = std::make_shared<SectionNode>(incompleteStats);
5937       node = m_rootSection;
5938     } else {
5939       SectionNode& parentNode = *m_sectionStack.back();
5940       auto it =
5941           std::find_if(parentNode.childSections.begin(), parentNode.childSections.end(), BySectionInfo(sectionInfo));
5942       if (it == parentNode.childSections.end()) {
5943         node = std::make_shared<SectionNode>(incompleteStats);
5944         parentNode.childSections.push_back(node);
5945       } else
5946         node = *it;
5947     }
5948     m_sectionStack.push_back(node);
5949     m_deepestSection = std::move(node);
5950   }
5951
5952   void assertionStarting(AssertionInfo const&) override {}
5953
5954   bool assertionEnded(AssertionStats const& assertionStats) override
5955   {
5956     assert(!m_sectionStack.empty());
5957     // AssertionResult holds a pointer to a temporary DecomposedExpression,
5958     // which getExpandedExpression() calls to build the expression string.
5959     // Our section stack copy of the assertionResult will likely outlive the
5960     // temporary, so it must be expanded or discarded now to avoid calling
5961     // a destroyed object later.
5962     prepareExpandedExpression(const_cast<AssertionResult&>(assertionStats.assertionResult));
5963     SectionNode& sectionNode = *m_sectionStack.back();
5964     sectionNode.assertions.push_back(assertionStats);
5965     return true;
5966   }
5967   void sectionEnded(SectionStats const& sectionStats) override
5968   {
5969     assert(!m_sectionStack.empty());
5970     SectionNode& node = *m_sectionStack.back();
5971     node.stats        = sectionStats;
5972     m_sectionStack.pop_back();
5973   }
5974   void testCaseEnded(TestCaseStats const& testCaseStats) override
5975   {
5976     auto node = std::make_shared<TestCaseNode>(testCaseStats);
5977     assert(m_sectionStack.size() == 0);
5978     node->children.push_back(m_rootSection);
5979     m_testCases.push_back(node);
5980     m_rootSection.reset();
5981
5982     assert(m_deepestSection);
5983     m_deepestSection->stdOut = testCaseStats.stdOut;
5984     m_deepestSection->stdErr = testCaseStats.stdErr;
5985   }
5986   void testGroupEnded(TestGroupStats const& testGroupStats) override
5987   {
5988     auto node = std::make_shared<TestGroupNode>(testGroupStats);
5989     node->children.swap(m_testCases);
5990     m_testGroups.push_back(node);
5991   }
5992   void testRunEnded(TestRunStats const& testRunStats) override
5993   {
5994     auto node = std::make_shared<TestRunNode>(testRunStats);
5995     node->children.swap(m_testGroups);
5996     m_testRuns.push_back(node);
5997     testRunEndedCumulative();
5998   }
5999   virtual void testRunEndedCumulative() = 0;
6000
6001   void skipTest(TestCaseInfo const&) override {}
6002
6003   IConfigPtr m_config;
6004   std::ostream& stream;
6005   std::vector<AssertionStats> m_assertions;
6006   std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
6007   std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
6008   std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
6009
6010   std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
6011
6012   std::shared_ptr<SectionNode> m_rootSection;
6013   std::shared_ptr<SectionNode> m_deepestSection;
6014   std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
6015   ReporterPreferences m_reporterPrefs;
6016 };
6017
6018 template <char C> char const* getLineOfChars()
6019 {
6020   static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
6021   if (!*line) {
6022     std::memset(line, C, CATCH_CONFIG_CONSOLE_WIDTH - 1);
6023     line[CATCH_CONFIG_CONSOLE_WIDTH - 1] = 0;
6024   }
6025   return line;
6026 }
6027
6028 struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
6029   TestEventListenerBase(ReporterConfig const& _config);
6030
6031   static std::set<Verbosity> getSupportedVerbosities();
6032
6033   void assertionStarting(AssertionInfo const&) override;
6034   bool assertionEnded(AssertionStats const&) override;
6035 };
6036
6037 } // end namespace Catch
6038
6039 // end catch_reporter_bases.hpp
6040 // start catch_console_colour.h
6041
6042 namespace Catch {
6043
6044 struct Colour {
6045   enum Code {
6046     None = 0,
6047
6048     White,
6049     Red,
6050     Green,
6051     Blue,
6052     Cyan,
6053     Yellow,
6054     Grey,
6055
6056     Bright = 0x10,
6057
6058     BrightRed    = Bright | Red,
6059     BrightGreen  = Bright | Green,
6060     LightGrey    = Bright | Grey,
6061     BrightWhite  = Bright | White,
6062     BrightYellow = Bright | Yellow,
6063
6064     // By intention
6065     FileName              = LightGrey,
6066     Warning               = BrightYellow,
6067     ResultError           = BrightRed,
6068     ResultSuccess         = BrightGreen,
6069     ResultExpectedFailure = Warning,
6070
6071     Error   = BrightRed,
6072     Success = Green,
6073
6074     OriginalExpression      = Cyan,
6075     ReconstructedExpression = BrightYellow,
6076
6077     SecondaryText = LightGrey,
6078     Headers       = White
6079   };
6080
6081   // Use constructed object for RAII guard
6082   Colour(Code _colourCode);
6083   Colour(Colour&& other) noexcept;
6084   Colour& operator=(Colour&& other) noexcept;
6085   ~Colour();
6086
6087   // Use static method for one-shot changes
6088   static void use(Code _colourCode);
6089
6090 private:
6091   bool m_moved = false;
6092 };
6093
6094 std::ostream& operator<<(std::ostream& os, Colour const&);
6095
6096 } // end namespace Catch
6097
6098 // end catch_console_colour.h
6099 // start catch_reporter_registrars.hpp
6100
6101 namespace Catch {
6102
6103 template <typename T> class ReporterRegistrar {
6104
6105   class ReporterFactory : public IReporterFactory {
6106
6107     IStreamingReporterPtr create(ReporterConfig const& config) const override
6108     {
6109       return std::unique_ptr<T>(new T(config));
6110     }
6111
6112     std::string getDescription() const override { return T::getDescription(); }
6113   };
6114
6115 public:
6116   explicit ReporterRegistrar(std::string const& name)
6117   {
6118     getMutableRegistryHub().registerReporter(name, std::make_shared<ReporterFactory>());
6119   }
6120 };
6121
6122 template <typename T> class ListenerRegistrar {
6123
6124   class ListenerFactory : public IReporterFactory {
6125
6126     IStreamingReporterPtr create(ReporterConfig const& config) const override
6127     {
6128       return std::unique_ptr<T>(new T(config));
6129     }
6130     std::string getDescription() const override { return std::string(); }
6131   };
6132
6133 public:
6134   ListenerRegistrar() { getMutableRegistryHub().registerListener(std::make_shared<ListenerFactory>()); }
6135 };
6136 } // namespace Catch
6137
6138 #if !defined(CATCH_CONFIG_DISABLE)
6139
6140 #define CATCH_REGISTER_REPORTER(name, reporterType)                                                                    \
6141   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
6142   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
6143   namespace {                                                                                                          \
6144   Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType(name);                              \
6145   }                                                                                                                    \
6146   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6147
6148 #define CATCH_REGISTER_LISTENER(listenerType)                                                                          \
6149   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                                                                            \
6150   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                                                                             \
6151   namespace {                                                                                                          \
6152   Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType;                                    \
6153   }                                                                                                                    \
6154   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6155 #else // CATCH_CONFIG_DISABLE
6156
6157 #define CATCH_REGISTER_REPORTER(name, reporterType)
6158 #define CATCH_REGISTER_LISTENER(listenerType)
6159
6160 #endif // CATCH_CONFIG_DISABLE
6161
6162 // end catch_reporter_registrars.hpp
6163 // Allow users to base their work off existing reporters
6164 // start catch_reporter_compact.h
6165
6166 namespace Catch {
6167
6168 struct CompactReporter : StreamingReporterBase<CompactReporter> {
6169
6170   using StreamingReporterBase::StreamingReporterBase;
6171
6172   ~CompactReporter() override;
6173
6174   static std::string getDescription();
6175
6176   void noMatchingTestCases(std::string const& spec) override;
6177
6178   void assertionStarting(AssertionInfo const&) override;
6179
6180   bool assertionEnded(AssertionStats const& _assertionStats) override;
6181
6182   void sectionEnded(SectionStats const& _sectionStats) override;
6183
6184   void testRunEnded(TestRunStats const& _testRunStats) override;
6185 };
6186
6187 } // end namespace Catch
6188
6189 // end catch_reporter_compact.h
6190 // start catch_reporter_console.h
6191
6192 #if defined(_MSC_VER)
6193 #pragma warning(push)
6194 #pragma warning(disable : 4061) // Not all labels are EXPLICITLY handled in switch
6195                                 // Note that 4062 (not all labels are handled
6196                                 // and default is missing) is enabled
6197 #endif
6198
6199 namespace Catch {
6200 // Fwd decls
6201 struct SummaryColumn;
6202 class TablePrinter;
6203
6204 struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
6205   std::unique_ptr<TablePrinter> m_tablePrinter;
6206
6207   ConsoleReporter(ReporterConfig const& config);
6208   ~ConsoleReporter() override;
6209   static std::string getDescription();
6210
6211   void noMatchingTestCases(std::string const& spec) override;
6212
6213   void reportInvalidArguments(std::string const& arg) override;
6214
6215   void assertionStarting(AssertionInfo const&) override;
6216
6217   bool assertionEnded(AssertionStats const& _assertionStats) override;
6218
6219   void sectionStarting(SectionInfo const& _sectionInfo) override;
6220   void sectionEnded(SectionStats const& _sectionStats) override;
6221
6222 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6223   void benchmarkPreparing(std::string const& name) override;
6224   void benchmarkStarting(BenchmarkInfo const& info) override;
6225   void benchmarkEnded(BenchmarkStats<> const& stats) override;
6226   void benchmarkFailed(std::string const& error) override;
6227 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6228
6229   void testCaseEnded(TestCaseStats const& _testCaseStats) override;
6230   void testGroupEnded(TestGroupStats const& _testGroupStats) override;
6231   void testRunEnded(TestRunStats const& _testRunStats) override;
6232   void testRunStarting(TestRunInfo const& _testRunInfo) override;
6233
6234 private:
6235   void lazyPrint();
6236
6237   void lazyPrintWithoutClosingBenchmarkTable();
6238   void lazyPrintRunInfo();
6239   void lazyPrintGroupInfo();
6240   void printTestCaseAndSectionHeader();
6241
6242   void printClosedHeader(std::string const& _name);
6243   void printOpenHeader(std::string const& _name);
6244
6245   // if string has a : in first line will set indent to follow it on
6246   // subsequent lines
6247   void printHeaderString(std::string const& _string, std::size_t indent = 0);
6248
6249   void printTotals(Totals const& totals);
6250   void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
6251
6252   void printTotalsDivider(Totals const& totals);
6253   void printSummaryDivider();
6254   void printTestFilters();
6255
6256 private:
6257   bool m_headerPrinted = false;
6258 };
6259
6260 } // end namespace Catch
6261
6262 #if defined(_MSC_VER)
6263 #pragma warning(pop)
6264 #endif
6265
6266 // end catch_reporter_console.h
6267 // start catch_reporter_junit.h
6268
6269 // start catch_xmlwriter.h
6270
6271 #include <vector>
6272
6273 namespace Catch {
6274 enum class XmlFormatting {
6275   None    = 0x00,
6276   Indent  = 0x01,
6277   Newline = 0x02,
6278 };
6279
6280 XmlFormatting operator|(XmlFormatting lhs, XmlFormatting rhs);
6281 XmlFormatting operator&(XmlFormatting lhs, XmlFormatting rhs);
6282
6283 class XmlEncode {
6284 public:
6285   enum ForWhat { ForTextNodes, ForAttributes };
6286
6287   XmlEncode(std::string const& str, ForWhat forWhat = ForTextNodes);
6288
6289   void encodeTo(std::ostream& os) const;
6290
6291   friend std::ostream& operator<<(std::ostream& os, XmlEncode const& xmlEncode);
6292
6293 private:
6294   std::string m_str;
6295   ForWhat m_forWhat;
6296 };
6297
6298 class XmlWriter {
6299 public:
6300   class ScopedElement {
6301   public:
6302     ScopedElement(XmlWriter* writer, XmlFormatting fmt);
6303
6304     ScopedElement(ScopedElement&& other) noexcept;
6305     ScopedElement& operator=(ScopedElement&& other) noexcept;
6306
6307     ~ScopedElement();
6308
6309     ScopedElement& writeText(std::string const& text,
6310                              XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6311
6312     template <typename T> ScopedElement& writeAttribute(std::string const& name, T const& attribute)
6313     {
6314       m_writer->writeAttribute(name, attribute);
6315       return *this;
6316     }
6317
6318   private:
6319     mutable XmlWriter* m_writer = nullptr;
6320     XmlFormatting m_fmt;
6321   };
6322
6323   XmlWriter(std::ostream& os = Catch::cout());
6324   ~XmlWriter();
6325
6326   XmlWriter(XmlWriter const&)            = delete;
6327   XmlWriter& operator=(XmlWriter const&) = delete;
6328
6329   XmlWriter& startElement(std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6330
6331   ScopedElement scopedElement(std::string const& name,
6332                               XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6333
6334   XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6335
6336   XmlWriter& writeAttribute(std::string const& name, std::string const& attribute);
6337
6338   XmlWriter& writeAttribute(std::string const& name, bool attribute);
6339
6340   template <typename T> XmlWriter& writeAttribute(std::string const& name, T const& attribute)
6341   {
6342     ReusableStringStream rss;
6343     rss << attribute;
6344     return writeAttribute(name, rss.str());
6345   }
6346
6347   XmlWriter& writeText(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6348
6349   XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6350
6351   void writeStylesheetRef(std::string const& url);
6352
6353   XmlWriter& writeBlankLine();
6354
6355   void ensureTagClosed();
6356
6357 private:
6358   void applyFormatting(XmlFormatting fmt);
6359
6360   void writeDeclaration();
6361
6362   void newlineIfNecessary();
6363
6364   bool m_tagIsOpen    = false;
6365   bool m_needsNewline = false;
6366   std::vector<std::string> m_tags;
6367   std::string m_indent;
6368   std::ostream& m_os;
6369 };
6370
6371 } // namespace Catch
6372
6373 // end catch_xmlwriter.h
6374 namespace Catch {
6375
6376 class JunitReporter : public CumulativeReporterBase<JunitReporter> {
6377 public:
6378   JunitReporter(ReporterConfig const& _config);
6379
6380   ~JunitReporter() override;
6381
6382   static std::string getDescription();
6383
6384   void noMatchingTestCases(std::string const& /*spec*/) override;
6385
6386   void testRunStarting(TestRunInfo const& runInfo) override;
6387
6388   void testGroupStarting(GroupInfo const& groupInfo) override;
6389
6390   void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
6391   bool assertionEnded(AssertionStats const& assertionStats) override;
6392
6393   void testCaseEnded(TestCaseStats const& testCaseStats) override;
6394
6395   void testGroupEnded(TestGroupStats const& testGroupStats) override;
6396
6397   void testRunEndedCumulative() override;
6398
6399   void writeGroup(TestGroupNode const& groupNode, double suiteTime);
6400
6401   void writeTestCase(TestCaseNode const& testCaseNode);
6402
6403   void writeSection(std::string const& className, std::string const& rootName, SectionNode const& sectionNode);
6404
6405   void writeAssertions(SectionNode const& sectionNode);
6406   void writeAssertion(AssertionStats const& stats);
6407
6408   XmlWriter xml;
6409   Timer suiteTimer;
6410   std::string stdOutForSuite;
6411   std::string stdErrForSuite;
6412   unsigned int unexpectedExceptions = 0;
6413   bool m_okToFail                   = false;
6414 };
6415
6416 } // end namespace Catch
6417
6418 // end catch_reporter_junit.h
6419 // start catch_reporter_xml.h
6420
6421 namespace Catch {
6422 class XmlReporter : public StreamingReporterBase<XmlReporter> {
6423 public:
6424   XmlReporter(ReporterConfig const& _config);
6425
6426   ~XmlReporter() override;
6427
6428   static std::string getDescription();
6429
6430   virtual std::string getStylesheetRef() const;
6431
6432   void writeSourceInfo(SourceLineInfo const& sourceInfo);
6433
6434 public: // StreamingReporterBase
6435   void noMatchingTestCases(std::string const& s) override;
6436
6437   void testRunStarting(TestRunInfo const& testInfo) override;
6438
6439   void testGroupStarting(GroupInfo const& groupInfo) override;
6440
6441   void testCaseStarting(TestCaseInfo const& testInfo) override;
6442
6443   void sectionStarting(SectionInfo const& sectionInfo) override;
6444
6445   void assertionStarting(AssertionInfo const&) override;
6446
6447   bool assertionEnded(AssertionStats const& assertionStats) override;
6448
6449   void sectionEnded(SectionStats const& sectionStats) override;
6450
6451   void testCaseEnded(TestCaseStats const& testCaseStats) override;
6452
6453   void testGroupEnded(TestGroupStats const& testGroupStats) override;
6454
6455   void testRunEnded(TestRunStats const& testRunStats) override;
6456
6457 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6458   void benchmarkPreparing(std::string const& name) override;
6459   void benchmarkStarting(BenchmarkInfo const&) override;
6460   void benchmarkEnded(BenchmarkStats<> const&) override;
6461   void benchmarkFailed(std::string const&) override;
6462 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6463
6464 private:
6465   Timer m_testCaseTimer;
6466   XmlWriter m_xml;
6467   int m_sectionDepth = 0;
6468 };
6469
6470 } // end namespace Catch
6471
6472 // end catch_reporter_xml.h
6473
6474 // end catch_external_interfaces.h
6475 #endif
6476
6477 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6478 // start catch_benchmarking_all.hpp
6479
6480 // A proxy header that includes all of the benchmarking headers to allow
6481 // concise include of the benchmarking features. You should prefer the
6482 // individual includes in standard use.
6483
6484 // start catch_benchmark.hpp
6485
6486 // Benchmark
6487
6488 // start catch_chronometer.hpp
6489
6490 // User-facing chronometer
6491
6492 // start catch_clock.hpp
6493
6494 // Clocks
6495
6496 #include <chrono>
6497 #include <ratio>
6498
6499 namespace Catch {
6500 namespace Benchmark {
6501 template <typename Clock> using ClockDuration = typename Clock::duration;
6502 template <typename Clock> using FloatDuration = std::chrono::duration<double, typename Clock::period>;
6503
6504 template <typename Clock> using TimePoint = typename Clock::time_point;
6505
6506 using default_clock = std::chrono::steady_clock;
6507
6508 template <typename Clock> struct now {
6509   TimePoint<Clock> operator()() const { return Clock::now(); }
6510 };
6511
6512 using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
6513 } // namespace Benchmark
6514 } // namespace Catch
6515
6516 // end catch_clock.hpp
6517 // start catch_optimizer.hpp
6518
6519 // Hinting the optimizer
6520
6521 #if defined(_MSC_VER)
6522 #include <atomic> // atomic_thread_fence
6523 #endif
6524
6525 namespace Catch {
6526 namespace Benchmark {
6527 #if defined(__GNUC__) || defined(__clang__)
6528 template <typename T> inline void keep_memory(T* p)
6529 {
6530   asm volatile("" : : "g"(p) : "memory");
6531 }
6532 inline void keep_memory()
6533 {
6534   asm volatile("" : : : "memory");
6535 }
6536
6537 namespace Detail {
6538 inline void optimizer_barrier()
6539 {
6540   keep_memory();
6541 }
6542 } // namespace Detail
6543 #elif defined(_MSC_VER)
6544
6545 #pragma optimize("", off)
6546 template <typename T> inline void keep_memory(T* p)
6547 {
6548   // thanks @milleniumbug
6549   *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
6550 }
6551 // TODO equivalent keep_memory()
6552 #pragma optimize("", on)
6553
6554 namespace Detail {
6555 inline void optimizer_barrier()
6556 {
6557   std::atomic_thread_fence(std::memory_order_seq_cst);
6558 }
6559 } // namespace Detail
6560
6561 #endif
6562
6563 template <typename T> inline void deoptimize_value(T&& x)
6564 {
6565   keep_memory(&x);
6566 }
6567
6568 template <typename Fn, typename... Args>
6569 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) ->
6570     typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type
6571 {
6572   deoptimize_value(std::forward<Fn>(fn)(std::forward<Args...>(args...)));
6573 }
6574
6575 template <typename Fn, typename... Args>
6576 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) ->
6577     typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type
6578 {
6579   std::forward<Fn>(fn)(std::forward<Args...>(args...));
6580 }
6581 } // namespace Benchmark
6582 } // namespace Catch
6583
6584 // end catch_optimizer.hpp
6585 // start catch_complete_invoke.hpp
6586
6587 // Invoke with a special case for void
6588
6589 #include <type_traits>
6590 #include <utility>
6591
6592 namespace Catch {
6593 namespace Benchmark {
6594 namespace Detail {
6595 template <typename T> struct CompleteType {
6596   using type = T;
6597 };
6598 template <> struct CompleteType<void> {
6599   struct type {};
6600 };
6601
6602 template <typename T> using CompleteType_t = typename CompleteType<T>::type;
6603
6604 template <typename Result> struct CompleteInvoker {
6605   template <typename Fun, typename... Args> static Result invoke(Fun&& fun, Args&&... args)
6606   {
6607     return std::forward<Fun>(fun)(std::forward<Args>(args)...);
6608   }
6609 };
6610 template <> struct CompleteInvoker<void> {
6611   template <typename Fun, typename... Args> static CompleteType_t<void> invoke(Fun&& fun, Args&&... args)
6612   {
6613     std::forward<Fun>(fun)(std::forward<Args>(args)...);
6614     return {};
6615   }
6616 };
6617
6618 // invoke and not return void :(
6619 template <typename Fun, typename... Args>
6620 CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args)
6621 {
6622   return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
6623 }
6624
6625 const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
6626 } // namespace Detail
6627
6628 template <typename Fun> Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun)
6629 {
6630   CATCH_TRY
6631   {
6632     return Detail::complete_invoke(std::forward<Fun>(fun));
6633   }
6634   CATCH_CATCH_ALL
6635   {
6636     getResultCapture().benchmarkFailed(translateActiveException());
6637     CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
6638   }
6639 }
6640 } // namespace Benchmark
6641 } // namespace Catch
6642
6643 // end catch_complete_invoke.hpp
6644 namespace Catch {
6645 namespace Benchmark {
6646 namespace Detail {
6647 struct ChronometerConcept {
6648   virtual void start()          = 0;
6649   virtual void finish()         = 0;
6650   virtual ~ChronometerConcept() = default;
6651 };
6652 template <typename Clock> struct ChronometerModel final : public ChronometerConcept {
6653   void start() override { started = Clock::now(); }
6654   void finish() override { finished = Clock::now(); }
6655
6656   ClockDuration<Clock> elapsed() const { return finished - started; }
6657
6658   TimePoint<Clock> started;
6659   TimePoint<Clock> finished;
6660 };
6661 } // namespace Detail
6662
6663 struct Chronometer {
6664 public:
6665   template <typename Fun> void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
6666
6667   int runs() const { return k; }
6668
6669   Chronometer(Detail::ChronometerConcept& meter, int k) : impl(&meter), k(k) {}
6670
6671 private:
6672   template <typename Fun> void measure(Fun&& fun, std::false_type)
6673   {
6674     measure([&fun](int) { return fun(); }, std::true_type());
6675   }
6676
6677   template <typename Fun> void measure(Fun&& fun, std::true_type)
6678   {
6679     Detail::optimizer_barrier();
6680     impl->start();
6681     for (int i = 0; i < k; ++i)
6682       invoke_deoptimized(fun, i);
6683     impl->finish();
6684     Detail::optimizer_barrier();
6685   }
6686
6687   Detail::ChronometerConcept* impl;
6688   int k;
6689 };
6690 } // namespace Benchmark
6691 } // namespace Catch
6692
6693 // end catch_chronometer.hpp
6694 // start catch_environment.hpp
6695
6696 // Environment information
6697
6698 namespace Catch {
6699 namespace Benchmark {
6700 template <typename Duration> struct EnvironmentEstimate {
6701   Duration mean;
6702   OutlierClassification outliers;
6703
6704   template <typename Duration2> operator EnvironmentEstimate<Duration2>() const { return {mean, outliers}; }
6705 };
6706 template <typename Clock> struct Environment {
6707   using clock_type = Clock;
6708   EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
6709   EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
6710 };
6711 } // namespace Benchmark
6712 } // namespace Catch
6713
6714 // end catch_environment.hpp
6715 // start catch_execution_plan.hpp
6716
6717 // Execution plan
6718
6719 // start catch_benchmark_function.hpp
6720
6721 // Dumb std::function implementation for consistent call overhead
6722
6723 #include <cassert>
6724 #include <memory>
6725 #include <type_traits>
6726 #include <utility>
6727
6728 namespace Catch {
6729 namespace Benchmark {
6730 namespace Detail {
6731 template <typename T> using Decay = typename std::decay<T>::type;
6732 template <typename T, typename U> struct is_related : std::is_same<Decay<T>, Decay<U>> {
6733 };
6734
6735 /// We need to reinvent std::function because every piece of code that might add overhead
6736 /// in a measurement context needs to have consistent performance characteristics so that we
6737 /// can account for it in the measurement.
6738 /// Implementations of std::function with optimizations that aren't always applicable, like
6739 /// small buffer optimizations, are not uncommon.
6740 /// This is effectively an implementation of std::function without any such optimizations;
6741 /// it may be slow, but it is consistently slow.
6742 struct BenchmarkFunction {
6743 private:
6744   struct callable {
6745     virtual void call(Chronometer meter) const = 0;
6746     virtual callable* clone() const            = 0;
6747     virtual ~callable()                        = default;
6748   };
6749   template <typename Fun> struct model : public callable {
6750     model(Fun&& fun) : fun(std::move(fun)) {}
6751     model(Fun const& fun) : fun(fun) {}
6752
6753     model<Fun>* clone() const override { return new model<Fun>(*this); }
6754
6755     void call(Chronometer meter) const override { call(meter, is_callable<Fun(Chronometer)>()); }
6756     void call(Chronometer meter, std::true_type) const { fun(meter); }
6757     void call(Chronometer meter, std::false_type) const { meter.measure(fun); }
6758
6759     Fun fun;
6760   };
6761
6762   struct do_nothing {
6763     void operator()() const {}
6764   };
6765
6766   template <typename T> BenchmarkFunction(model<T>* c) : f(c) {}
6767
6768 public:
6769   BenchmarkFunction() : f(new model<do_nothing>{{}}) {}
6770
6771   template <typename Fun, typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
6772   BenchmarkFunction(Fun&& fun) : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun)))
6773   {
6774   }
6775
6776   BenchmarkFunction(BenchmarkFunction&& that) : f(std::move(that.f)) {}
6777
6778   BenchmarkFunction(BenchmarkFunction const& that) : f(that.f->clone()) {}
6779
6780   BenchmarkFunction& operator=(BenchmarkFunction&& that)
6781   {
6782     f = std::move(that.f);
6783     return *this;
6784   }
6785
6786   BenchmarkFunction& operator=(BenchmarkFunction const& that)
6787   {
6788     f.reset(that.f->clone());
6789     return *this;
6790   }
6791
6792   void operator()(Chronometer meter) const { f->call(meter); }
6793
6794 private:
6795   std::unique_ptr<callable> f;
6796 };
6797 } // namespace Detail
6798 } // namespace Benchmark
6799 } // namespace Catch
6800
6801 // end catch_benchmark_function.hpp
6802 // start catch_repeat.hpp
6803
6804 // repeat algorithm
6805
6806 #include <type_traits>
6807 #include <utility>
6808
6809 namespace Catch {
6810 namespace Benchmark {
6811 namespace Detail {
6812 template <typename Fun> struct repeater {
6813   void operator()(int k) const
6814   {
6815     for (int i = 0; i < k; ++i) {
6816       fun();
6817     }
6818   }
6819   Fun fun;
6820 };
6821 template <typename Fun> repeater<typename std::decay<Fun>::type> repeat(Fun&& fun)
6822 {
6823   return {std::forward<Fun>(fun)};
6824 }
6825 } // namespace Detail
6826 } // namespace Benchmark
6827 } // namespace Catch
6828
6829 // end catch_repeat.hpp
6830 // start catch_run_for_at_least.hpp
6831
6832 // Run a function for a minimum amount of time
6833
6834 // start catch_measure.hpp
6835
6836 // Measure
6837
6838 // start catch_timing.hpp
6839
6840 // Timing
6841
6842 #include <tuple>
6843 #include <type_traits>
6844
6845 namespace Catch {
6846 namespace Benchmark {
6847 template <typename Duration, typename Result> struct Timing {
6848   Duration elapsed;
6849   Result result;
6850   int iterations;
6851 };
6852 template <typename Clock, typename Func, typename... Args>
6853 using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
6854 } // namespace Benchmark
6855 } // namespace Catch
6856
6857 // end catch_timing.hpp
6858 #include <utility>
6859
6860 namespace Catch {
6861 namespace Benchmark {
6862 namespace Detail {
6863 template <typename Clock, typename Fun, typename... Args>
6864 TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args)
6865 {
6866   auto start = Clock::now();
6867   auto&& r   = Detail::complete_invoke(fun, std::forward<Args>(args)...);
6868   auto end   = Clock::now();
6869   auto delta = end - start;
6870   return {delta, std::forward<decltype(r)>(r), 1};
6871 }
6872 } // namespace Detail
6873 } // namespace Benchmark
6874 } // namespace Catch
6875
6876 // end catch_measure.hpp
6877 #include <type_traits>
6878 #include <utility>
6879
6880 namespace Catch {
6881 namespace Benchmark {
6882 namespace Detail {
6883 template <typename Clock, typename Fun> TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type)
6884 {
6885   return Detail::measure<Clock>(fun, iters);
6886 }
6887 template <typename Clock, typename Fun>
6888 TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type)
6889 {
6890   Detail::ChronometerModel<Clock> meter;
6891   auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
6892
6893   return {meter.elapsed(), std::move(result), iters};
6894 }
6895
6896 template <typename Clock, typename Fun>
6897 using run_for_at_least_argument_t =
6898     typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
6899
6900 struct optimized_away_error : std::exception {
6901   const char* what() const noexcept override { return "could not measure benchmark, maybe it was optimized away"; }
6902 };
6903
6904 template <typename Clock, typename Fun>
6905 TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed,
6906                                                                                Fun&& fun)
6907 {
6908   auto iters = seed;
6909   while (iters < (1 << 30)) {
6910     auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
6911
6912     if (Timing.elapsed >= how_long) {
6913       return {Timing.elapsed, std::move(Timing.result), iters};
6914     }
6915     iters *= 2;
6916   }
6917   throw optimized_away_error{};
6918 }
6919 } // namespace Detail
6920 } // namespace Benchmark
6921 } // namespace Catch
6922
6923 // end catch_run_for_at_least.hpp
6924 #include <algorithm>
6925
6926 namespace Catch {
6927 namespace Benchmark {
6928 template <typename Duration> struct ExecutionPlan {
6929   int iterations_per_sample;
6930   Duration estimated_duration;
6931   Detail::BenchmarkFunction benchmark;
6932   Duration warmup_time;
6933   int warmup_iterations;
6934
6935   template <typename Duration2> operator ExecutionPlan<Duration2>() const
6936   {
6937     return {iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations};
6938   }
6939
6940   template <typename Clock>
6941   std::vector<FloatDuration<Clock>> run(const IConfig& cfg, Environment<FloatDuration<Clock>> env) const
6942   {
6943     // warmup a bit
6944     Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations,
6945                                     Detail::repeat(now<Clock>{}));
6946
6947     std::vector<FloatDuration<Clock>> times;
6948     times.reserve(cfg.benchmarkSamples());
6949     std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
6950       Detail::ChronometerModel<Clock> model;
6951       this->benchmark(Chronometer(model, iterations_per_sample));
6952       auto sample_time = model.elapsed() - env.clock_cost.mean;
6953       if (sample_time < FloatDuration<Clock>::zero())
6954         sample_time = FloatDuration<Clock>::zero();
6955       return sample_time / iterations_per_sample;
6956     });
6957     return times;
6958   }
6959 };
6960 } // namespace Benchmark
6961 } // namespace Catch
6962
6963 // end catch_execution_plan.hpp
6964 // start catch_estimate_clock.hpp
6965
6966 // Environment measurement
6967
6968 // start catch_stats.hpp
6969
6970 // Statistical analysis tools
6971
6972 #include <algorithm>
6973 #include <cmath>
6974 #include <cstddef>
6975 #include <functional>
6976 #include <iterator>
6977 #include <numeric>
6978 #include <random>
6979 #include <tuple>
6980 #include <utility>
6981 #include <vector>
6982
6983 namespace Catch {
6984 namespace Benchmark {
6985 namespace Detail {
6986 using sample = std::vector<double>;
6987
6988 double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
6989
6990 template <typename Iterator> OutlierClassification classify_outliers(Iterator first, Iterator last)
6991 {
6992   std::vector<double> copy(first, last);
6993
6994   auto q1  = weighted_average_quantile(1, 4, copy.begin(), copy.end());
6995   auto q3  = weighted_average_quantile(3, 4, copy.begin(), copy.end());
6996   auto iqr = q3 - q1;
6997   auto los = q1 - (iqr * 3.);
6998   auto lom = q1 - (iqr * 1.5);
6999   auto him = q3 + (iqr * 1.5);
7000   auto his = q3 + (iqr * 3.);
7001
7002   OutlierClassification o;
7003   for (; first != last; ++first) {
7004     auto&& t = *first;
7005     if (t < los)
7006       ++o.low_severe;
7007     else if (t < lom)
7008       ++o.low_mild;
7009     else if (t > his)
7010       ++o.high_severe;
7011     else if (t > him)
7012       ++o.high_mild;
7013     ++o.samples_seen;
7014   }
7015   return o;
7016 }
7017
7018 template <typename Iterator> double mean(Iterator first, Iterator last)
7019 {
7020   auto count = last - first;
7021   double sum = std::accumulate(first, last, 0.);
7022   return sum / count;
7023 }
7024
7025 template <typename URng, typename Iterator, typename Estimator>
7026 sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator)
7027 {
7028   auto n = last - first;
7029   std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
7030
7031   sample out;
7032   out.reserve(resamples);
7033   std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
7034     std::vector<double> resampled;
7035     resampled.reserve(n);
7036     std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
7037     return estimator(resampled.begin(), resampled.end());
7038   });
7039   std::sort(out.begin(), out.end());
7040   return out;
7041 }
7042
7043 template <typename Estimator, typename Iterator> sample jackknife(Estimator&& estimator, Iterator first, Iterator last)
7044 {
7045   auto n      = last - first;
7046   auto second = std::next(first);
7047   sample results;
7048   results.reserve(n);
7049
7050   for (auto it = first; it != last; ++it) {
7051     std::iter_swap(it, first);
7052     results.push_back(estimator(second, last));
7053   }
7054
7055   return results;
7056 }
7057
7058 inline double normal_cdf(double x)
7059 {
7060   return std::erfc(-x / std::sqrt(2.0)) / 2.0;
7061 }
7062
7063 double erfc_inv(double x);
7064
7065 double normal_quantile(double p);
7066
7067 template <typename Iterator, typename Estimator>
7068 Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample,
7069                            Estimator&& estimator)
7070 {
7071   auto n_samples = last - first;
7072
7073   double point = estimator(first, last);
7074   // Degenerate case with a single sample
7075   if (n_samples == 1)
7076     return {point, point, point, confidence_level};
7077
7078   sample jack      = jackknife(estimator, first, last);
7079   double jack_mean = mean(jack.begin(), jack.end());
7080   double sum_squares, sum_cubes;
7081   std::tie(sum_squares, sum_cubes) =
7082       std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.),
7083                       [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
7084                         auto d  = jack_mean - x;
7085                         auto d2 = d * d;
7086                         auto d3 = d2 * d;
7087                         return {sqcb.first + d2, sqcb.second + d3};
7088                       });
7089
7090   double accel  = sum_cubes / (6 * std::pow(sum_squares, 1.5));
7091   int n         = static_cast<int>(resample.size());
7092   double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
7093   // degenerate case with uniform samples
7094   if (prob_n == 0)
7095     return {point, point, point, confidence_level};
7096
7097   double bias = normal_quantile(prob_n);
7098   double z1   = normal_quantile((1. - confidence_level) / 2.);
7099
7100   auto cumn = [n](double x) -> int { return std::lround(normal_cdf(x) * n); };
7101   auto a    = [bias, accel](double b) { return bias + b / (1. - accel * b); };
7102   double b1 = bias + z1;
7103   double b2 = bias - z1;
7104   double a1 = a(b1);
7105   double a2 = a(b2);
7106   auto lo   = (std::max)(cumn(a1), 0);
7107   auto hi   = (std::min)(cumn(a2), n - 1);
7108
7109   return {point, resample[lo], resample[hi], confidence_level};
7110 }
7111
7112 double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
7113
7114 struct bootstrap_analysis {
7115   Estimate<double> mean;
7116   Estimate<double> standard_deviation;
7117   double outlier_variance;
7118 };
7119
7120 bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first,
7121                                    std::vector<double>::iterator last);
7122 } // namespace Detail
7123 } // namespace Benchmark
7124 } // namespace Catch
7125
7126 // end catch_stats.hpp
7127 #include <algorithm>
7128 #include <cmath>
7129 #include <iterator>
7130 #include <tuple>
7131 #include <vector>
7132
7133 namespace Catch {
7134 namespace Benchmark {
7135 namespace Detail {
7136 template <typename Clock> std::vector<double> resolution(int k)
7137 {
7138   std::vector<TimePoint<Clock>> times;
7139   times.reserve(k + 1);
7140   std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
7141
7142   std::vector<double> deltas;
7143   deltas.reserve(k);
7144   std::transform(std::next(times.begin()), times.end(), times.begin(), std::back_inserter(deltas),
7145                  [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
7146
7147   return deltas;
7148 }
7149
7150 const auto warmup_iterations                = 10000;
7151 const auto warmup_time                      = std::chrono::milliseconds(100);
7152 const auto minimum_ticks                    = 1000;
7153 const auto warmup_seed                      = 10000;
7154 const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
7155 const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
7156 const auto clock_cost_estimation_tick_limit = 100000;
7157 const auto clock_cost_estimation_time       = std::chrono::milliseconds(10);
7158 const auto clock_cost_estimation_iterations = 10000;
7159
7160 template <typename Clock> int warmup()
7161 {
7162   return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed,
7163                                  &resolution<Clock>)
7164       .iterations;
7165 }
7166 template <typename Clock> EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations)
7167 {
7168   auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time),
7169                                    iterations, &resolution<Clock>)
7170                .result;
7171   return {
7172       FloatDuration<Clock>(mean(r.begin(), r.end())),
7173       classify_outliers(r.begin(), r.end()),
7174   };
7175 }
7176 template <typename Clock> EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution)
7177 {
7178   auto time_limit =
7179       (std::min)(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
7180   auto time_clock = [](int k) {
7181     return Detail::measure<Clock>([k] {
7182              for (int i = 0; i < k; ++i) {
7183                volatile auto ignored = Clock::now();
7184                (void)ignored;
7185              }
7186            })
7187         .elapsed;
7188   };
7189   time_clock(1);
7190   int iters = clock_cost_estimation_iterations;
7191   auto&& r  = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time),
7192                                      iters, time_clock);
7193   std::vector<double> times;
7194   int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
7195   times.reserve(nsamples);
7196   std::generate_n(std::back_inserter(times), nsamples,
7197                   [time_clock, &r] { return static_cast<double>((time_clock(r.iterations) / r.iterations).count()); });
7198   return {
7199       FloatDuration<Clock>(mean(times.begin(), times.end())),
7200       classify_outliers(times.begin(), times.end()),
7201   };
7202 }
7203
7204 template <typename Clock> Environment<FloatDuration<Clock>> measure_environment()
7205 {
7206   static Environment<FloatDuration<Clock>>* env = nullptr;
7207   if (env) {
7208     return *env;
7209   }
7210
7211   auto iters      = Detail::warmup<Clock>();
7212   auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
7213   auto cost       = Detail::estimate_clock_cost<Clock>(resolution.mean);
7214
7215   env = new Environment<FloatDuration<Clock>>{resolution, cost};
7216   return *env;
7217 }
7218 } // namespace Detail
7219 } // namespace Benchmark
7220 } // namespace Catch
7221
7222 // end catch_estimate_clock.hpp
7223 // start catch_analyse.hpp
7224
7225 // Run and analyse one benchmark
7226
7227 // start catch_sample_analysis.hpp
7228
7229 // Benchmark results
7230
7231 #include <algorithm>
7232 #include <iterator>
7233 #include <string>
7234 #include <vector>
7235
7236 namespace Catch {
7237 namespace Benchmark {
7238 template <typename Duration> struct SampleAnalysis {
7239   std::vector<Duration> samples;
7240   Estimate<Duration> mean;
7241   Estimate<Duration> standard_deviation;
7242   OutlierClassification outliers;
7243   double outlier_variance;
7244
7245   template <typename Duration2> operator SampleAnalysis<Duration2>() const
7246   {
7247     std::vector<Duration2> samples2;
7248     samples2.reserve(samples.size());
7249     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2),
7250                    [](Duration d) { return Duration2(d); });
7251     return {
7252         std::move(samples2), mean, standard_deviation, outliers, outlier_variance,
7253     };
7254   }
7255 };
7256 } // namespace Benchmark
7257 } // namespace Catch
7258
7259 // end catch_sample_analysis.hpp
7260 #include <algorithm>
7261 #include <iterator>
7262 #include <vector>
7263
7264 namespace Catch {
7265 namespace Benchmark {
7266 namespace Detail {
7267 template <typename Duration, typename Iterator>
7268 SampleAnalysis<Duration> analyse(const IConfig& cfg, Environment<Duration>, Iterator first, Iterator last)
7269 {
7270   if (!cfg.benchmarkNoAnalysis()) {
7271     std::vector<double> samples;
7272     samples.reserve(last - first);
7273     std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
7274
7275     auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(),
7276                                                               cfg.benchmarkResamples(), samples.begin(), samples.end());
7277     auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
7278
7279     auto wrap_estimate = [](Estimate<double> e) {
7280       return Estimate<Duration>{
7281           Duration(e.point),
7282           Duration(e.lower_bound),
7283           Duration(e.upper_bound),
7284           e.confidence_interval,
7285       };
7286     };
7287     std::vector<Duration> samples2;
7288     samples2.reserve(samples.size());
7289     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
7290     return {
7291         std::move(samples2),       wrap_estimate(analysis.mean), wrap_estimate(analysis.standard_deviation), outliers,
7292         analysis.outlier_variance,
7293     };
7294   } else {
7295     std::vector<Duration> samples;
7296     samples.reserve(last - first);
7297
7298     Duration mean = Duration(0);
7299     int i         = 0;
7300     for (auto it = first; it < last; ++it, ++i) {
7301       samples.push_back(Duration(*it));
7302       mean += Duration(*it);
7303     }
7304     mean /= i;
7305
7306     return {std::move(samples), Estimate<Duration>{mean, mean, mean, 0.0},
7307             Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0}, OutlierClassification{}, 0.0};
7308   }
7309 }
7310 } // namespace Detail
7311 } // namespace Benchmark
7312 } // namespace Catch
7313
7314 // end catch_analyse.hpp
7315 #include <algorithm>
7316 #include <cmath>
7317 #include <functional>
7318 #include <string>
7319 #include <vector>
7320
7321 namespace Catch {
7322 namespace Benchmark {
7323 struct Benchmark {
7324   Benchmark(std::string&& name) : name(std::move(name)) {}
7325
7326   template <class FUN> Benchmark(std::string&& name, FUN&& func) : fun(std::move(func)), name(std::move(name)) {}
7327
7328   template <typename Clock>
7329   ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig& cfg, Environment<FloatDuration<Clock>> env) const
7330   {
7331     auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
7332     auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
7333     auto&& test   = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
7334     int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
7335     return {new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun,
7336             std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations};
7337   }
7338
7339   template <typename Clock = default_clock> void run()
7340   {
7341     IConfigPtr cfg = getCurrentContext().getConfig();
7342
7343     auto env = Detail::measure_environment<Clock>();
7344
7345     getResultCapture().benchmarkPreparing(name);
7346     CATCH_TRY
7347     {
7348       auto plan = user_code([&] { return prepare<Clock>(*cfg, env); });
7349
7350       BenchmarkInfo info{name,
7351                          plan.estimated_duration.count(),
7352                          plan.iterations_per_sample,
7353                          cfg->benchmarkSamples(),
7354                          cfg->benchmarkResamples(),
7355                          env.clock_resolution.mean.count(),
7356                          env.clock_cost.mean.count()};
7357
7358       getResultCapture().benchmarkStarting(info);
7359
7360       auto samples = user_code([&] { return plan.template run<Clock>(*cfg, env); });
7361
7362       auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
7363       BenchmarkStats<FloatDuration<Clock>> stats{info,
7364                                                  analysis.samples,
7365                                                  analysis.mean,
7366                                                  analysis.standard_deviation,
7367                                                  analysis.outliers,
7368                                                  analysis.outlier_variance};
7369       getResultCapture().benchmarkEnded(stats);
7370     }
7371     CATCH_CATCH_ALL
7372     {
7373       if (translateActiveException() !=
7374           Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
7375         std::rethrow_exception(std::current_exception());
7376     }
7377   }
7378
7379   // sets lambda to be used in fun *and* executes benchmark!
7380   template <typename Fun, typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
7381   Benchmark& operator=(Fun func)
7382   {
7383     fun = Detail::BenchmarkFunction(func);
7384     run();
7385     return *this;
7386   }
7387
7388   explicit operator bool() { return true; }
7389
7390 private:
7391   Detail::BenchmarkFunction fun;
7392   std::string name;
7393 };
7394 } // namespace Benchmark
7395 } // namespace Catch
7396
7397 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
7398 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
7399
7400 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)                                                  \
7401   if (Catch::Benchmark::Benchmark BenchmarkName{name})                                                                 \
7402   BenchmarkName = [&](int benchmarkIndex)
7403
7404 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)                                                         \
7405   if (Catch::Benchmark::Benchmark BenchmarkName{name})                                                                 \
7406   BenchmarkName = [&]
7407
7408 // end catch_benchmark.hpp
7409 // start catch_constructor.hpp
7410
7411 // Constructor and destructor helpers
7412
7413 #include <type_traits>
7414
7415 namespace Catch {
7416 namespace Benchmark {
7417 namespace Detail {
7418 template <typename T, bool Destruct> struct ObjectStorage {
7419   using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
7420
7421   ObjectStorage() : data() {}
7422
7423   ObjectStorage(const ObjectStorage& other) { new (&data) T(other.stored_object()); }
7424
7425   ObjectStorage(ObjectStorage&& other) { new (&data) T(std::move(other.stored_object())); }
7426
7427   ~ObjectStorage() { destruct_on_exit<T>(); }
7428
7429   template <typename... Args> void construct(Args&&... args) { new (&data) T(std::forward<Args>(args)...); }
7430
7431   template <bool AllowManualDestruction = !Destruct> typename std::enable_if<AllowManualDestruction>::type destruct()
7432   {
7433     stored_object().~T();
7434   }
7435
7436 private:
7437   // If this is a constructor benchmark, destruct the underlying object
7438   template <typename U> void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
7439   // Otherwise, don't
7440   template <typename U> void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) {}
7441
7442   T& stored_object() { return *static_cast<T*>(static_cast<void*>(&data)); }
7443
7444   T const& stored_object() const { return *static_cast<T*>(static_cast<void*>(&data)); }
7445
7446   TStorage data;
7447 };
7448 } // namespace Detail
7449
7450 template <typename T> using storage_for = Detail::ObjectStorage<T, true>;
7451
7452 template <typename T> using destructable_object = Detail::ObjectStorage<T, false>;
7453 } // namespace Benchmark
7454 } // namespace Catch
7455
7456 // end catch_constructor.hpp
7457 // end catch_benchmarking_all.hpp
7458 #endif
7459
7460 #endif // ! CATCH_CONFIG_IMPL_ONLY
7461
7462 #ifdef CATCH_IMPL
7463 // start catch_impl.hpp
7464
7465 #ifdef __clang__
7466 #pragma clang diagnostic push
7467 #pragma clang diagnostic ignored "-Wweak-vtables"
7468 #endif
7469
7470 // Keep these here for external reporters
7471 // start catch_test_case_tracker.h
7472
7473 #include <memory>
7474 #include <string>
7475 #include <vector>
7476
7477 namespace Catch {
7478 namespace TestCaseTracking {
7479
7480 struct NameAndLocation {
7481   std::string name;
7482   SourceLineInfo location;
7483
7484   NameAndLocation(std::string const& _name, SourceLineInfo const& _location);
7485   friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs)
7486   {
7487     return lhs.name == rhs.name && lhs.location == rhs.location;
7488   }
7489 };
7490
7491 class ITracker;
7492
7493 using ITrackerPtr = std::shared_ptr<ITracker>;
7494
7495 class ITracker {
7496   NameAndLocation m_nameAndLocation;
7497
7498 public:
7499   ITracker(NameAndLocation const& nameAndLoc) : m_nameAndLocation(nameAndLoc) {}
7500
7501   // static queries
7502   NameAndLocation const& nameAndLocation() const { return m_nameAndLocation; }
7503
7504   virtual ~ITracker();
7505
7506   // dynamic queries
7507   virtual bool isComplete() const              = 0; // Successfully completed or failed
7508   virtual bool isSuccessfullyCompleted() const = 0;
7509   virtual bool isOpen() const                  = 0; // Started but not complete
7510   virtual bool hasChildren() const             = 0;
7511   virtual bool hasStarted() const              = 0;
7512
7513   virtual ITracker& parent() = 0;
7514
7515   // actions
7516   virtual void close()                   = 0; // Successfully complete
7517   virtual void fail()                    = 0;
7518   virtual void markAsNeedingAnotherRun() = 0;
7519
7520   virtual void addChild(ITrackerPtr const& child)                       = 0;
7521   virtual ITrackerPtr findChild(NameAndLocation const& nameAndLocation) = 0;
7522   virtual void openChild()                                              = 0;
7523
7524   // Debug/ checking
7525   virtual bool isSectionTracker() const   = 0;
7526   virtual bool isGeneratorTracker() const = 0;
7527 };
7528
7529 class TrackerContext {
7530
7531   enum RunState { NotStarted, Executing, CompletedCycle };
7532
7533   ITrackerPtr m_rootTracker;
7534   ITracker* m_currentTracker = nullptr;
7535   RunState m_runState        = NotStarted;
7536
7537 public:
7538   ITracker& startRun();
7539   void endRun();
7540
7541   void startCycle();
7542   void completeCycle();
7543
7544   bool completedCycle() const;
7545   ITracker& currentTracker();
7546   void setCurrentTracker(ITracker* tracker);
7547 };
7548
7549 class TrackerBase : public ITracker {
7550 protected:
7551   enum CycleState { NotStarted, Executing, ExecutingChildren, NeedsAnotherRun, CompletedSuccessfully, Failed };
7552
7553   using Children = std::vector<ITrackerPtr>;
7554   TrackerContext& m_ctx;
7555   ITracker* m_parent;
7556   Children m_children;
7557   CycleState m_runState = NotStarted;
7558
7559 public:
7560   TrackerBase(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent);
7561
7562   bool isComplete() const override;
7563   bool isSuccessfullyCompleted() const override;
7564   bool isOpen() const override;
7565   bool hasChildren() const override;
7566   bool hasStarted() const override { return m_runState != NotStarted; }
7567
7568   void addChild(ITrackerPtr const& child) override;
7569
7570   ITrackerPtr findChild(NameAndLocation const& nameAndLocation) override;
7571   ITracker& parent() override;
7572
7573   void openChild() override;
7574
7575   bool isSectionTracker() const override;
7576   bool isGeneratorTracker() const override;
7577
7578   void open();
7579
7580   void close() override;
7581   void fail() override;
7582   void markAsNeedingAnotherRun() override;
7583
7584 private:
7585   void moveToParent();
7586   void moveToThis();
7587 };
7588
7589 class SectionTracker : public TrackerBase {
7590   std::vector<std::string> m_filters;
7591   std::string m_trimmed_name;
7592
7593 public:
7594   SectionTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent);
7595
7596   bool isSectionTracker() const override;
7597
7598   bool isComplete() const override;
7599
7600   static SectionTracker& acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation);
7601
7602   void tryOpen();
7603
7604   void addInitialFilters(std::vector<std::string> const& filters);
7605   void addNextFilters(std::vector<std::string> const& filters);
7606   //! Returns filters active in this tracker
7607   std::vector<std::string> const& getFilters() const;
7608   //! Returns whitespace-trimmed name of the tracked section
7609   std::string const& trimmedName() const;
7610 };
7611
7612 } // namespace TestCaseTracking
7613
7614 using TestCaseTracking::ITracker;
7615 using TestCaseTracking::SectionTracker;
7616 using TestCaseTracking::TrackerContext;
7617
7618 } // namespace Catch
7619
7620 // end catch_test_case_tracker.h
7621
7622 // start catch_leak_detector.h
7623
7624 namespace Catch {
7625
7626 struct LeakDetector {
7627   LeakDetector();
7628   ~LeakDetector();
7629 };
7630
7631 } // namespace Catch
7632 // end catch_leak_detector.h
7633 // Cpp files will be included in the single-header file here
7634 // start catch_stats.cpp
7635
7636 // Statistical analysis tools
7637
7638 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
7639
7640 #include <cassert>
7641 #include <random>
7642
7643 #if defined(CATCH_CONFIG_USE_ASYNC)
7644 #include <future>
7645 #endif
7646
7647 namespace {
7648 double erf_inv(double x)
7649 {
7650   // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
7651   double w, p;
7652
7653   w = -log((1.0 - x) * (1.0 + x));
7654
7655   if (w < 6.250000) {
7656     w = w - 3.125000;
7657     p = -3.6444120640178196996e-21;
7658     p = -1.685059138182016589e-19 + p * w;
7659     p = 1.2858480715256400167e-18 + p * w;
7660     p = 1.115787767802518096e-17 + p * w;
7661     p = -1.333171662854620906e-16 + p * w;
7662     p = 2.0972767875968561637e-17 + p * w;
7663     p = 6.6376381343583238325e-15 + p * w;
7664     p = -4.0545662729752068639e-14 + p * w;
7665     p = -8.1519341976054721522e-14 + p * w;
7666     p = 2.6335093153082322977e-12 + p * w;
7667     p = -1.2975133253453532498e-11 + p * w;
7668     p = -5.4154120542946279317e-11 + p * w;
7669     p = 1.051212273321532285e-09 + p * w;
7670     p = -4.1126339803469836976e-09 + p * w;
7671     p = -2.9070369957882005086e-08 + p * w;
7672     p = 4.2347877827932403518e-07 + p * w;
7673     p = -1.3654692000834678645e-06 + p * w;
7674     p = -1.3882523362786468719e-05 + p * w;
7675     p = 0.0001867342080340571352 + p * w;
7676     p = -0.00074070253416626697512 + p * w;
7677     p = -0.0060336708714301490533 + p * w;
7678     p = 0.24015818242558961693 + p * w;
7679     p = 1.6536545626831027356 + p * w;
7680   } else if (w < 16.000000) {
7681     w = sqrt(w) - 3.250000;
7682     p = 2.2137376921775787049e-09;
7683     p = 9.0756561938885390979e-08 + p * w;
7684     p = -2.7517406297064545428e-07 + p * w;
7685     p = 1.8239629214389227755e-08 + p * w;
7686     p = 1.5027403968909827627e-06 + p * w;
7687     p = -4.013867526981545969e-06 + p * w;
7688     p = 2.9234449089955446044e-06 + p * w;
7689     p = 1.2475304481671778723e-05 + p * w;
7690     p = -4.7318229009055733981e-05 + p * w;
7691     p = 6.8284851459573175448e-05 + p * w;
7692     p = 2.4031110387097893999e-05 + p * w;
7693     p = -0.0003550375203628474796 + p * w;
7694     p = 0.00095328937973738049703 + p * w;
7695     p = -0.0016882755560235047313 + p * w;
7696     p = 0.0024914420961078508066 + p * w;
7697     p = -0.0037512085075692412107 + p * w;
7698     p = 0.005370914553590063617 + p * w;
7699     p = 1.0052589676941592334 + p * w;
7700     p = 3.0838856104922207635 + p * w;
7701   } else {
7702     w = sqrt(w) - 5.000000;
7703     p = -2.7109920616438573243e-11;
7704     p = -2.5556418169965252055e-10 + p * w;
7705     p = 1.5076572693500548083e-09 + p * w;
7706     p = -3.7894654401267369937e-09 + p * w;
7707     p = 7.6157012080783393804e-09 + p * w;
7708     p = -1.4960026627149240478e-08 + p * w;
7709     p = 2.9147953450901080826e-08 + p * w;
7710     p = -6.7711997758452339498e-08 + p * w;
7711     p = 2.2900482228026654717e-07 + p * w;
7712     p = -9.9298272942317002539e-07 + p * w;
7713     p = 4.5260625972231537039e-06 + p * w;
7714     p = -1.9681778105531670567e-05 + p * w;
7715     p = 7.5995277030017761139e-05 + p * w;
7716     p = -0.00021503011930044477347 + p * w;
7717     p = -0.00013871931833623122026 + p * w;
7718     p = 1.0103004648645343977 + p * w;
7719     p = 4.8499064014085844221 + p * w;
7720   }
7721   return p * x;
7722 }
7723
7724 double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last)
7725 {
7726   auto m          = Catch::Benchmark::Detail::mean(first, last);
7727   double variance = std::accumulate(first, last, 0.,
7728                                     [m](double a, double b) {
7729                                       double diff = b - m;
7730                                       return a + diff * diff;
7731                                     }) /
7732                     (last - first);
7733   return std::sqrt(variance);
7734 }
7735
7736 } // namespace
7737
7738 namespace Catch {
7739 namespace Benchmark {
7740 namespace Detail {
7741
7742 double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last)
7743 {
7744   auto count = last - first;
7745   double idx = (count - 1) * k / static_cast<double>(q);
7746   int j      = static_cast<int>(idx);
7747   double g   = idx - j;
7748   std::nth_element(first, first + j, last);
7749   auto xj = first[j];
7750   if (g == 0)
7751     return xj;
7752
7753   auto xj1 = *std::min_element(first + (j + 1), last);
7754   return xj + g * (xj1 - xj);
7755 }
7756
7757 double erfc_inv(double x)
7758 {
7759   return erf_inv(1.0 - x);
7760 }
7761
7762 double normal_quantile(double p)
7763 {
7764   static const double ROOT_TWO = std::sqrt(2.0);
7765
7766   double result = 0.0;
7767   assert(p >= 0 && p <= 1);
7768   if (p < 0 || p > 1) {
7769     return result;
7770   }
7771
7772   result = -erfc_inv(2.0 * p);
7773   // result *= normal distribution standard deviation (1.0) * sqrt(2)
7774   result *= /*sd * */ ROOT_TWO;
7775   // result += normal disttribution mean (0)
7776   return result;
7777 }
7778
7779 double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n)
7780 {
7781   double sb     = stddev.point;
7782   double mn     = mean.point / n;
7783   double mg_min = mn / 2.;
7784   double sg     = (std::min)(mg_min / 4., sb / std::sqrt(n));
7785   double sg2    = sg * sg;
7786   double sb2    = sb * sb;
7787
7788   auto c_max = [n, mn, sb2, sg2](double x) -> double {
7789     double k   = mn - x;
7790     double d   = k * k;
7791     double nd  = n * d;
7792     double k0  = -n * nd;
7793     double k1  = sb2 - n * sg2 + nd;
7794     double det = k1 * k1 - 4 * sg2 * k0;
7795     return (int)(-2. * k0 / (k1 + std::sqrt(det)));
7796   };
7797
7798   auto var_out = [n, sb2, sg2](double c) {
7799     double nc = n - c;
7800     return (nc / n) * (sb2 - nc * sg2);
7801   };
7802
7803   return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
7804 }
7805
7806 bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first,
7807                                    std::vector<double>::iterator last)
7808 {
7809   CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
7810   CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
7811   static std::random_device entropy;
7812   CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
7813
7814   auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
7815
7816   auto mean   = &Detail::mean<std::vector<double>::iterator>;
7817   auto stddev = &standard_deviation;
7818
7819 #if defined(CATCH_CONFIG_USE_ASYNC)
7820   auto Estimate = [=](double (*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7821     auto seed = entropy();
7822     return std::async(std::launch::async, [=] {
7823       std::mt19937 rng(seed);
7824       auto resampled = resample(rng, n_resamples, first, last, f);
7825       return bootstrap(confidence_level, first, last, resampled, f);
7826     });
7827   };
7828
7829   auto mean_future   = Estimate(mean);
7830   auto stddev_future = Estimate(stddev);
7831
7832   auto mean_estimate   = mean_future.get();
7833   auto stddev_estimate = stddev_future.get();
7834 #else
7835   auto Estimate = [=](double (*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7836     auto seed = entropy();
7837     std::mt19937 rng(seed);
7838     auto resampled = resample(rng, n_resamples, first, last, f);
7839     return bootstrap(confidence_level, first, last, resampled, f);
7840   };
7841
7842   auto mean_estimate   = Estimate(mean);
7843   auto stddev_estimate = Estimate(stddev);
7844 #endif // CATCH_USE_ASYNC
7845
7846   double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
7847
7848   return {mean_estimate, stddev_estimate, outlier_variance};
7849 }
7850 } // namespace Detail
7851 } // namespace Benchmark
7852 } // namespace Catch
7853
7854 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
7855 // end catch_stats.cpp
7856 // start catch_approx.cpp
7857
7858 #include <cmath>
7859 #include <limits>
7860
7861 namespace {
7862
7863 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
7864 // But without the subtraction to allow for INFINITY in comparison
7865 bool marginComparison(double lhs, double rhs, double margin)
7866 {
7867   return (lhs + margin >= rhs) && (rhs + margin >= lhs);
7868 }
7869
7870 } // namespace
7871
7872 namespace Catch {
7873 namespace Detail {
7874
7875 Approx::Approx(double value)
7876     : m_epsilon(std::numeric_limits<float>::epsilon() * 100), m_margin(0.0), m_scale(0.0), m_value(value)
7877 {
7878 }
7879
7880 Approx Approx::custom()
7881 {
7882   return Approx(0);
7883 }
7884
7885 Approx Approx::operator-() const
7886 {
7887   auto temp(*this);
7888   temp.m_value = -temp.m_value;
7889   return temp;
7890 }
7891
7892 std::string Approx::toString() const
7893 {
7894   ReusableStringStream rss;
7895   rss << "Approx( " << ::Catch::Detail::stringify(m_value) << " )";
7896   return rss.str();
7897 }
7898
7899 bool Approx::equalityComparisonImpl(const double other) const
7900 {
7901   // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
7902   // Thanks to Richard Harris for his help refining the scaled margin value
7903   return marginComparison(m_value, other, m_margin) ||
7904          marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value) ? 0 : m_value)));
7905 }
7906
7907 void Approx::setMargin(double newMargin)
7908 {
7909   CATCH_ENFORCE(newMargin >= 0,
7910                 "Invalid Approx::margin: " << newMargin << '.' << " Approx::Margin has to be non-negative.");
7911   m_margin = newMargin;
7912 }
7913
7914 void Approx::setEpsilon(double newEpsilon)
7915 {
7916   CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
7917                 "Invalid Approx::epsilon: " << newEpsilon << '.' << " Approx::epsilon has to be in [0, 1]");
7918   m_epsilon = newEpsilon;
7919 }
7920
7921 } // end namespace Detail
7922
7923 namespace literals {
7924 Detail::Approx operator"" _a(long double val)
7925 {
7926   return Detail::Approx(val);
7927 }
7928 Detail::Approx operator"" _a(unsigned long long val)
7929 {
7930   return Detail::Approx(val);
7931 }
7932 } // end namespace literals
7933
7934 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value)
7935 {
7936   return value.toString();
7937 }
7938
7939 } // end namespace Catch
7940 // end catch_approx.cpp
7941 // start catch_assertionhandler.cpp
7942
7943 // start catch_debugger.h
7944
7945 namespace Catch {
7946 bool isDebuggerActive();
7947 }
7948
7949 #ifdef CATCH_PLATFORM_MAC
7950
7951 #if defined(__i386__) || defined(__x86_64__)
7952 #define CATCH_TRAP() __asm__("int $3\n" : :) /* NOLINT */
7953 #elif defined(__aarch64__)
7954 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
7955 #endif
7956
7957 #elif defined(CATCH_PLATFORM_IPHONE)
7958
7959 // use inline assembler
7960 #if defined(__i386__) || defined(__x86_64__)
7961 #define CATCH_TRAP() __asm__("int $3")
7962 #elif defined(__aarch64__)
7963 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
7964 #elif defined(__arm__) && !defined(__thumb__)
7965 #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
7966 #elif defined(__arm__) && defined(__thumb__)
7967 #define CATCH_TRAP() __asm__(".inst 0xde01")
7968 #endif
7969
7970 #elif defined(CATCH_PLATFORM_LINUX)
7971 // If we can use inline assembler, do it because this allows us to break
7972 // directly at the location of the failing check instead of breaking inside
7973 // raise() called from it, i.e. one stack frame below.
7974 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
7975 #define CATCH_TRAP() asm volatile("int $3") /* NOLINT */
7976 #else                                       // Fall back to the generic way.
7977 #include <signal.h>
7978
7979 #define CATCH_TRAP() raise(SIGTRAP)
7980 #endif
7981 #elif defined(_MSC_VER)
7982 #define CATCH_TRAP() __debugbreak()
7983 #elif defined(__MINGW32__)
7984 extern "C" __declspec(dllimport) void __stdcall DebugBreak();
7985 #define CATCH_TRAP() DebugBreak()
7986 #endif
7987
7988 #ifndef CATCH_BREAK_INTO_DEBUGGER
7989 #ifdef CATCH_TRAP
7990 #define CATCH_BREAK_INTO_DEBUGGER()                                                                                    \
7991   [] {                                                                                                                 \
7992     if (Catch::isDebuggerActive()) {                                                                                   \
7993       CATCH_TRAP();                                                                                                    \
7994     }                                                                                                                  \
7995   }()
7996 #else
7997 #define CATCH_BREAK_INTO_DEBUGGER() [] {}()
7998 #endif
7999 #endif
8000
8001 // end catch_debugger.h
8002 // start catch_run_context.h
8003
8004 // start catch_fatal_condition.h
8005
8006 #include <cassert>
8007
8008 namespace Catch {
8009
8010 // Wrapper for platform-specific fatal error (signals/SEH) handlers
8011 //
8012 // Tries to be cooperative with other handlers, and not step over
8013 // other handlers. This means that unknown structured exceptions
8014 // are passed on, previous signal handlers are called, and so on.
8015 //
8016 // Can only be instantiated once, and assumes that once a signal
8017 // is caught, the binary will end up terminating. Thus, there
8018 class FatalConditionHandler {
8019   bool m_started = false;
8020
8021   // Install/disengage implementation for specific platform.
8022   // Should be if-defed to work on current platform, can assume
8023   // engage-disengage 1:1 pairing.
8024   void engage_platform();
8025   void disengage_platform();
8026
8027 public:
8028   // Should also have platform-specific implementations as needed
8029   FatalConditionHandler();
8030   ~FatalConditionHandler();
8031
8032   void engage()
8033   {
8034     assert(!m_started && "Handler cannot be installed twice.");
8035     m_started = true;
8036     engage_platform();
8037   }
8038
8039   void disengage()
8040   {
8041     assert(m_started && "Handler cannot be uninstalled without being installed first");
8042     m_started = false;
8043     disengage_platform();
8044   }
8045 };
8046
8047 //! Simple RAII guard for (dis)engaging the FatalConditionHandler
8048 class FatalConditionHandlerGuard {
8049   FatalConditionHandler* m_handler;
8050
8051 public:
8052   FatalConditionHandlerGuard(FatalConditionHandler* handler) : m_handler(handler) { m_handler->engage(); }
8053   ~FatalConditionHandlerGuard() { m_handler->disengage(); }
8054 };
8055
8056 } // end namespace Catch
8057
8058 // end catch_fatal_condition.h
8059 #include <string>
8060
8061 namespace Catch {
8062
8063 struct IMutableContext;
8064
8065 ///////////////////////////////////////////////////////////////////////////
8066
8067 class RunContext : public IResultCapture, public IRunner {
8068
8069 public:
8070   RunContext(RunContext const&)            = delete;
8071   RunContext& operator=(RunContext const&) = delete;
8072
8073   explicit RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter);
8074
8075   ~RunContext() override;
8076
8077   void testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount);
8078   void testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex,
8079                       std::size_t groupsCount);
8080
8081   Totals runTest(TestCase const& testCase);
8082
8083   IConfigPtr config() const;
8084   IStreamingReporter& reporter() const;
8085
8086 public: // IResultCapture
8087   // Assertion handlers
8088   void handleExpr(AssertionInfo const& info, ITransientExpression const& expr, AssertionReaction& reaction) override;
8089   void handleMessage(AssertionInfo const& info, ResultWas::OfType resultType, StringRef const& message,
8090                      AssertionReaction& reaction) override;
8091   void handleUnexpectedExceptionNotThrown(AssertionInfo const& info, AssertionReaction& reaction) override;
8092   void handleUnexpectedInflightException(AssertionInfo const& info, std::string const& message,
8093                                          AssertionReaction& reaction) override;
8094   void handleIncomplete(AssertionInfo const& info) override;
8095   void handleNonExpr(AssertionInfo const& info, ResultWas::OfType resultType, AssertionReaction& reaction) override;
8096
8097   bool sectionStarted(SectionInfo const& sectionInfo, Counts& assertions) override;
8098
8099   void sectionEnded(SectionEndInfo const& endInfo) override;
8100   void sectionEndedEarly(SectionEndInfo const& endInfo) override;
8101
8102   auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo) -> IGeneratorTracker& override;
8103
8104 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
8105   void benchmarkPreparing(std::string const& name) override;
8106   void benchmarkStarting(BenchmarkInfo const& info) override;
8107   void benchmarkEnded(BenchmarkStats<> const& stats) override;
8108   void benchmarkFailed(std::string const& error) override;
8109 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
8110
8111   void pushScopedMessage(MessageInfo const& message) override;
8112   void popScopedMessage(MessageInfo const& message) override;
8113
8114   void emplaceUnscopedMessage(MessageBuilder const& builder) override;
8115
8116   std::string getCurrentTestName() const override;
8117
8118   const AssertionResult* getLastResult() const override;
8119
8120   void exceptionEarlyReported() override;
8121
8122   void handleFatalErrorCondition(StringRef message) override;
8123
8124   bool lastAssertionPassed() override;
8125
8126   void assertionPassed() override;
8127
8128 public:
8129   // !TBD We need to do this another way!
8130   bool aborting() const final;
8131
8132 private:
8133   void runCurrentTest(std::string& redirectedCout, std::string& redirectedCerr);
8134   void invokeActiveTestCase();
8135
8136   void resetAssertionInfo();
8137   bool testForMissingAssertions(Counts& assertions);
8138
8139   void assertionEnded(AssertionResult const& result);
8140   void reportExpr(AssertionInfo const& info, ResultWas::OfType resultType, ITransientExpression const* expr,
8141                   bool negated);
8142
8143   void populateReaction(AssertionReaction& reaction);
8144
8145 private:
8146   void handleUnfinishedSections();
8147
8148   TestRunInfo m_runInfo;
8149   IMutableContext& m_context;
8150   TestCase const* m_activeTestCase = nullptr;
8151   ITracker* m_testCaseTracker      = nullptr;
8152   Option<AssertionResult> m_lastResult;
8153
8154   IConfigPtr m_config;
8155   Totals m_totals;
8156   IStreamingReporterPtr m_reporter;
8157   std::vector<MessageInfo> m_messages;
8158   std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
8159   AssertionInfo m_lastAssertionInfo;
8160   std::vector<SectionEndInfo> m_unfinishedSections;
8161   std::vector<ITracker*> m_activeSections;
8162   TrackerContext m_trackerContext;
8163   FatalConditionHandler m_fatalConditionhandler;
8164   bool m_lastAssertionPassed    = false;
8165   bool m_shouldReportUnexpected = true;
8166   bool m_includeSuccessfulResults;
8167 };
8168
8169 void seedRng(IConfig const& config);
8170 unsigned int rngSeed();
8171 } // end namespace Catch
8172
8173 // end catch_run_context.h
8174 namespace Catch {
8175
8176 namespace {
8177 auto operator<<(std::ostream& os, ITransientExpression const& expr) -> std::ostream&
8178 {
8179   expr.streamReconstructedExpression(os);
8180   return os;
8181 }
8182 } // namespace
8183
8184 LazyExpression::LazyExpression(bool isNegated) : m_isNegated(isNegated) {}
8185
8186 LazyExpression::LazyExpression(LazyExpression const& other) : m_isNegated(other.m_isNegated) {}
8187
8188 LazyExpression::operator bool() const
8189 {
8190   return m_transientExpression != nullptr;
8191 }
8192
8193 auto operator<<(std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream&
8194 {
8195   if (lazyExpr.m_isNegated)
8196     os << "!";
8197
8198   if (lazyExpr) {
8199     if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression())
8200       os << "(" << *lazyExpr.m_transientExpression << ")";
8201     else
8202       os << *lazyExpr.m_transientExpression;
8203   } else {
8204     os << "{** error - unchecked empty expression requested **}";
8205   }
8206   return os;
8207 }
8208
8209 AssertionHandler::AssertionHandler(StringRef const& macroName, SourceLineInfo const& lineInfo,
8210                                    StringRef capturedExpression, ResultDisposition::Flags resultDisposition)
8211     : m_assertionInfo{macroName, lineInfo, capturedExpression, resultDisposition}, m_resultCapture(getResultCapture())
8212 {
8213 }
8214
8215 void AssertionHandler::handleExpr(ITransientExpression const& expr)
8216 {
8217   m_resultCapture.handleExpr(m_assertionInfo, expr, m_reaction);
8218 }
8219 void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message)
8220 {
8221   m_resultCapture.handleMessage(m_assertionInfo, resultType, message, m_reaction);
8222 }
8223
8224 auto AssertionHandler::allowThrows() const -> bool
8225 {
8226   return getCurrentContext().getConfig()->allowThrows();
8227 }
8228
8229 void AssertionHandler::complete()
8230 {
8231   setCompleted();
8232   if (m_reaction.shouldDebugBreak) {
8233
8234     // If you find your debugger stopping you here then go one level up on the
8235     // call-stack for the code that caused it (typically a failed assertion)
8236
8237     // (To go back to the test and change execution, jump over the throw, next)
8238     CATCH_BREAK_INTO_DEBUGGER();
8239   }
8240   if (m_reaction.shouldThrow) {
8241 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8242     throw Catch::TestFailureException();
8243 #else
8244     CATCH_ERROR("Test failure requires aborting test!");
8245 #endif
8246   }
8247 }
8248 void AssertionHandler::setCompleted()
8249 {
8250   m_completed = true;
8251 }
8252
8253 void AssertionHandler::handleUnexpectedInflightException()
8254 {
8255   m_resultCapture.handleUnexpectedInflightException(m_assertionInfo, Catch::translateActiveException(), m_reaction);
8256 }
8257
8258 void AssertionHandler::handleExceptionThrownAsExpected()
8259 {
8260   m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8261 }
8262 void AssertionHandler::handleExceptionNotThrownAsExpected()
8263 {
8264   m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8265 }
8266
8267 void AssertionHandler::handleUnexpectedExceptionNotThrown()
8268 {
8269   m_resultCapture.handleUnexpectedExceptionNotThrown(m_assertionInfo, m_reaction);
8270 }
8271
8272 void AssertionHandler::handleThrowingCallSkipped()
8273 {
8274   m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8275 }
8276
8277 // This is the overload that takes a string and infers the Equals matcher from it
8278 // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
8279 void handleExceptionMatchExpr(AssertionHandler& handler, std::string const& str, StringRef const& matcherString)
8280 {
8281   handleExceptionMatchExpr(handler, Matchers::Equals(str), matcherString);
8282 }
8283
8284 } // namespace Catch
8285 // end catch_assertionhandler.cpp
8286 // start catch_assertionresult.cpp
8287
8288 namespace Catch {
8289 AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const& _lazyExpression)
8290     : lazyExpression(_lazyExpression), resultType(_resultType)
8291 {
8292 }
8293
8294 std::string AssertionResultData::reconstructExpression() const
8295 {
8296
8297   if (reconstructedExpression.empty()) {
8298     if (lazyExpression) {
8299       ReusableStringStream rss;
8300       rss << lazyExpression;
8301       reconstructedExpression = rss.str();
8302     }
8303   }
8304   return reconstructedExpression;
8305 }
8306
8307 AssertionResult::AssertionResult(AssertionInfo const& info, AssertionResultData const& data)
8308     : m_info(info), m_resultData(data)
8309 {
8310 }
8311
8312 // Result was a success
8313 bool AssertionResult::succeeded() const
8314 {
8315   return Catch::isOk(m_resultData.resultType);
8316 }
8317
8318 // Result was a success, or failure is suppressed
8319 bool AssertionResult::isOk() const
8320 {
8321   return Catch::isOk(m_resultData.resultType) || shouldSuppressFailure(m_info.resultDisposition);
8322 }
8323
8324 ResultWas::OfType AssertionResult::getResultType() const
8325 {
8326   return m_resultData.resultType;
8327 }
8328
8329 bool AssertionResult::hasExpression() const
8330 {
8331   return !m_info.capturedExpression.empty();
8332 }
8333
8334 bool AssertionResult::hasMessage() const
8335 {
8336   return !m_resultData.message.empty();
8337 }
8338
8339 std::string AssertionResult::getExpression() const
8340 {
8341   // Possibly overallocating by 3 characters should be basically free
8342   std::string expr;
8343   expr.reserve(m_info.capturedExpression.size() + 3);
8344   if (isFalseTest(m_info.resultDisposition)) {
8345     expr += "!(";
8346   }
8347   expr += m_info.capturedExpression;
8348   if (isFalseTest(m_info.resultDisposition)) {
8349     expr += ')';
8350   }
8351   return expr;
8352 }
8353
8354 std::string AssertionResult::getExpressionInMacro() const
8355 {
8356   std::string expr;
8357   if (m_info.macroName.empty())
8358     expr = static_cast<std::string>(m_info.capturedExpression);
8359   else {
8360     expr.reserve(m_info.macroName.size() + m_info.capturedExpression.size() + 4);
8361     expr += m_info.macroName;
8362     expr += "( ";
8363     expr += m_info.capturedExpression;
8364     expr += " )";
8365   }
8366   return expr;
8367 }
8368
8369 bool AssertionResult::hasExpandedExpression() const
8370 {
8371   return hasExpression() && getExpandedExpression() != getExpression();
8372 }
8373
8374 std::string AssertionResult::getExpandedExpression() const
8375 {
8376   std::string expr = m_resultData.reconstructExpression();
8377   return expr.empty() ? getExpression() : expr;
8378 }
8379
8380 std::string AssertionResult::getMessage() const
8381 {
8382   return m_resultData.message;
8383 }
8384 SourceLineInfo AssertionResult::getSourceInfo() const
8385 {
8386   return m_info.lineInfo;
8387 }
8388
8389 StringRef AssertionResult::getTestMacroName() const
8390 {
8391   return m_info.macroName;
8392 }
8393
8394 } // end namespace Catch
8395 // end catch_assertionresult.cpp
8396 // start catch_capture_matchers.cpp
8397
8398 namespace Catch {
8399
8400 using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
8401
8402 // This is the general overload that takes a any string matcher
8403 // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
8404 // the Equals matcher (so the header does not mention matchers)
8405 void handleExceptionMatchExpr(AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString)
8406 {
8407   std::string exceptionMessage = Catch::translateActiveException();
8408   MatchExpr<std::string, StringMatcher const&> expr(exceptionMessage, matcher, matcherString);
8409   handler.handleExpr(expr);
8410 }
8411
8412 } // namespace Catch
8413 // end catch_capture_matchers.cpp
8414 // start catch_commandline.cpp
8415
8416 // start catch_commandline.h
8417
8418 // start catch_clara.h
8419
8420 // Use Catch's value for console width (store Clara's off to the side, if present)
8421 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
8422 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8423 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8424 #endif
8425 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - 1
8426
8427 #ifdef __clang__
8428 #pragma clang diagnostic push
8429 #pragma clang diagnostic ignored "-Wweak-vtables"
8430 #pragma clang diagnostic ignored "-Wexit-time-destructors"
8431 #pragma clang diagnostic ignored "-Wshadow"
8432 #endif
8433
8434 // start clara.hpp
8435 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
8436 //
8437 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8438 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8439 //
8440 // See https://github.com/philsquared/Clara for more details
8441
8442 // Clara v1.1.5
8443
8444 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8445 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
8446 #endif
8447
8448 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8449 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8450 #endif
8451
8452 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
8453 #ifdef __has_include
8454 #if __has_include(<optional>) && __cplusplus >= 201703L
8455 #include <optional>
8456 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
8457 #endif
8458 #endif
8459 #endif
8460
8461 // ----------- #included from clara_textflow.hpp -----------
8462
8463 // TextFlowCpp
8464 //
8465 // A single-header library for wrapping and laying out basic text, by Phil Nash
8466 //
8467 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8468 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8469 //
8470 // This project is hosted at https://github.com/philsquared/textflowcpp
8471
8472 #include <cassert>
8473 #include <ostream>
8474 #include <sstream>
8475 #include <vector>
8476
8477 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8478 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
8479 #endif
8480
8481 namespace Catch {
8482 namespace clara {
8483 namespace TextFlow {
8484
8485 inline auto isWhitespace(char c) -> bool
8486 {
8487   static std::string chars = " \t\n\r";
8488   return chars.find(c) != std::string::npos;
8489 }
8490 inline auto isBreakableBefore(char c) -> bool
8491 {
8492   static std::string chars = "[({<|";
8493   return chars.find(c) != std::string::npos;
8494 }
8495 inline auto isBreakableAfter(char c) -> bool
8496 {
8497   static std::string chars = "])}>.,:;*+-=&/\\";
8498   return chars.find(c) != std::string::npos;
8499 }
8500
8501 class Columns;
8502
8503 class Column {
8504   std::vector<std::string> m_strings;
8505   size_t m_width         = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
8506   size_t m_indent        = 0;
8507   size_t m_initialIndent = std::string::npos;
8508
8509 public:
8510   class iterator {
8511     friend Column;
8512
8513     Column const& m_column;
8514     size_t m_stringIndex = 0;
8515     size_t m_pos         = 0;
8516
8517     size_t m_len  = 0;
8518     size_t m_end  = 0;
8519     bool m_suffix = false;
8520
8521     iterator(Column const& column, size_t stringIndex) : m_column(column), m_stringIndex(stringIndex) {}
8522
8523     auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
8524
8525     auto isBoundary(size_t at) const -> bool
8526     {
8527       assert(at > 0);
8528       assert(at <= line().size());
8529
8530       return at == line().size() || (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
8531              isBreakableBefore(line()[at]) || isBreakableAfter(line()[at - 1]);
8532     }
8533
8534     void calcLength()
8535     {
8536       assert(m_stringIndex < m_column.m_strings.size());
8537
8538       m_suffix   = false;
8539       auto width = m_column.m_width - indent();
8540       m_end      = m_pos;
8541       if (line()[m_pos] == '\n') {
8542         ++m_end;
8543       }
8544       while (m_end < line().size() && line()[m_end] != '\n')
8545         ++m_end;
8546
8547       if (m_end < m_pos + width) {
8548         m_len = m_end - m_pos;
8549       } else {
8550         size_t len = width;
8551         while (len > 0 && !isBoundary(m_pos + len))
8552           --len;
8553         while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
8554           --len;
8555
8556         if (len > 0) {
8557           m_len = len;
8558         } else {
8559           m_suffix = true;
8560           m_len    = width - 1;
8561         }
8562       }
8563     }
8564
8565     auto indent() const -> size_t
8566     {
8567       auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
8568       return initial == std::string::npos ? m_column.m_indent : initial;
8569     }
8570
8571     auto addIndentAndSuffix(std::string const& plain) const -> std::string
8572     {
8573       return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
8574     }
8575
8576   public:
8577     using difference_type   = std::ptrdiff_t;
8578     using value_type        = std::string;
8579     using pointer           = value_type*;
8580     using reference         = value_type&;
8581     using iterator_category = std::forward_iterator_tag;
8582
8583     explicit iterator(Column const& column) : m_column(column)
8584     {
8585       assert(m_column.m_width > m_column.m_indent);
8586       assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
8587       calcLength();
8588       if (m_len == 0)
8589         m_stringIndex++; // Empty string
8590     }
8591
8592     auto operator*() const -> std::string
8593     {
8594       assert(m_stringIndex < m_column.m_strings.size());
8595       assert(m_pos <= m_end);
8596       return addIndentAndSuffix(line().substr(m_pos, m_len));
8597     }
8598
8599     auto operator++() -> iterator&
8600     {
8601       m_pos += m_len;
8602       if (m_pos < line().size() && line()[m_pos] == '\n')
8603         m_pos += 1;
8604       else
8605         while (m_pos < line().size() && isWhitespace(line()[m_pos]))
8606           ++m_pos;
8607
8608       if (m_pos == line().size()) {
8609         m_pos = 0;
8610         ++m_stringIndex;
8611       }
8612       if (m_stringIndex < m_column.m_strings.size())
8613         calcLength();
8614       return *this;
8615     }
8616     auto operator++(int) -> iterator
8617     {
8618       iterator prev(*this);
8619       operator++();
8620       return prev;
8621     }
8622
8623     auto operator==(iterator const& other) const -> bool
8624     {
8625       return m_pos == other.m_pos && m_stringIndex == other.m_stringIndex && &m_column == &other.m_column;
8626     }
8627     auto operator!=(iterator const& other) const -> bool { return !operator==(other); }
8628   };
8629   using const_iterator = iterator;
8630
8631   explicit Column(std::string const& text) { m_strings.push_back(text); }
8632
8633   auto width(size_t newWidth) -> Column&
8634   {
8635     assert(newWidth > 0);
8636     m_width = newWidth;
8637     return *this;
8638   }
8639   auto indent(size_t newIndent) -> Column&
8640   {
8641     m_indent = newIndent;
8642     return *this;
8643   }
8644   auto initialIndent(size_t newIndent) -> Column&
8645   {
8646     m_initialIndent = newIndent;
8647     return *this;
8648   }
8649
8650   auto width() const -> size_t { return m_width; }
8651   auto begin() const -> iterator { return iterator(*this); }
8652   auto end() const -> iterator { return {*this, m_strings.size()}; }
8653
8654   inline friend std::ostream& operator<<(std::ostream& os, Column const& col)
8655   {
8656     bool first = true;
8657     for (auto line : col) {
8658       if (first)
8659         first = false;
8660       else
8661         os << "\n";
8662       os << line;
8663     }
8664     return os;
8665   }
8666
8667   auto operator+(Column const& other) -> Columns;
8668
8669   auto toString() const -> std::string
8670   {
8671     std::ostringstream oss;
8672     oss << *this;
8673     return oss.str();
8674   }
8675 };
8676
8677 class Spacer : public Column {
8678
8679 public:
8680   explicit Spacer(size_t spaceWidth) : Column("") { width(spaceWidth); }
8681 };
8682
8683 class Columns {
8684   std::vector<Column> m_columns;
8685
8686 public:
8687   class iterator {
8688     friend Columns;
8689     struct EndTag {};
8690
8691     std::vector<Column> const& m_columns;
8692     std::vector<Column::iterator> m_iterators;
8693     size_t m_activeIterators;
8694
8695     iterator(Columns const& columns, EndTag) : m_columns(columns.m_columns), m_activeIterators(0)
8696     {
8697       m_iterators.reserve(m_columns.size());
8698
8699       for (auto const& col : m_columns)
8700         m_iterators.push_back(col.end());
8701     }
8702
8703   public:
8704     using difference_type   = std::ptrdiff_t;
8705     using value_type        = std::string;
8706     using pointer           = value_type*;
8707     using reference         = value_type&;
8708     using iterator_category = std::forward_iterator_tag;
8709
8710     explicit iterator(Columns const& columns) : m_columns(columns.m_columns), m_activeIterators(m_columns.size())
8711     {
8712       m_iterators.reserve(m_columns.size());
8713
8714       for (auto const& col : m_columns)
8715         m_iterators.push_back(col.begin());
8716     }
8717
8718     auto operator==(iterator const& other) const -> bool { return m_iterators == other.m_iterators; }
8719     auto operator!=(iterator const& other) const -> bool { return m_iterators != other.m_iterators; }
8720     auto operator*() const -> std::string
8721     {
8722       std::string row, padding;
8723
8724       for (size_t i = 0; i < m_columns.size(); ++i) {
8725         auto width = m_columns[i].width();
8726         if (m_iterators[i] != m_columns[i].end()) {
8727           std::string col = *m_iterators[i];
8728           row += padding + col;
8729           if (col.size() < width)
8730             padding = std::string(width - col.size(), ' ');
8731           else
8732             padding = "";
8733         } else {
8734           padding += std::string(width, ' ');
8735         }
8736       }
8737       return row;
8738     }
8739     auto operator++() -> iterator&
8740     {
8741       for (size_t i = 0; i < m_columns.size(); ++i) {
8742         if (m_iterators[i] != m_columns[i].end())
8743           ++m_iterators[i];
8744       }
8745       return *this;
8746     }
8747     auto operator++(int) -> iterator
8748     {
8749       iterator prev(*this);
8750       operator++();
8751       return prev;
8752     }
8753   };
8754   using const_iterator = iterator;
8755
8756   auto begin() const -> iterator { return iterator(*this); }
8757   auto end() const -> iterator { return {*this, iterator::EndTag()}; }
8758
8759   auto operator+=(Column const& col) -> Columns&
8760   {
8761     m_columns.push_back(col);
8762     return *this;
8763   }
8764   auto operator+(Column const& col) -> Columns
8765   {
8766     Columns combined = *this;
8767     combined += col;
8768     return combined;
8769   }
8770
8771   inline friend std::ostream& operator<<(std::ostream& os, Columns const& cols)
8772   {
8773
8774     bool first = true;
8775     for (auto line : cols) {
8776       if (first)
8777         first = false;
8778       else
8779         os << "\n";
8780       os << line;
8781     }
8782     return os;
8783   }
8784
8785   auto toString() const -> std::string
8786   {
8787     std::ostringstream oss;
8788     oss << *this;
8789     return oss.str();
8790   }
8791 };
8792
8793 inline auto Column::operator+(Column const& other) -> Columns
8794 {
8795   Columns cols;
8796   cols += *this;
8797   cols += other;
8798   return cols;
8799 }
8800 } // namespace TextFlow
8801
8802 } // namespace clara
8803 } // namespace Catch
8804
8805 // ----------- end of #include from clara_textflow.hpp -----------
8806 // ........... back in clara.hpp
8807
8808 #include <algorithm>
8809 #include <cctype>
8810 #include <memory>
8811 #include <set>
8812 #include <string>
8813
8814 #if !defined(CATCH_PLATFORM_WINDOWS) && (defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER))
8815 #define CATCH_PLATFORM_WINDOWS
8816 #endif
8817
8818 namespace Catch {
8819 namespace clara {
8820 namespace detail {
8821
8822 // Traits for extracting arg and return type of lambdas (for single argument lambdas)
8823 template <typename L> struct UnaryLambdaTraits : UnaryLambdaTraits<decltype(&L::operator())> {
8824 };
8825
8826 template <typename ClassT, typename ReturnT, typename... Args>
8827 struct UnaryLambdaTraits<ReturnT (ClassT::*)(Args...) const> {
8828   static const bool isValid = false;
8829 };
8830
8831 template <typename ClassT, typename ReturnT, typename ArgT> struct UnaryLambdaTraits<ReturnT (ClassT::*)(ArgT) const> {
8832   static const bool isValid = true;
8833   using ArgType             = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
8834   using ReturnType          = ReturnT;
8835 };
8836
8837 class TokenStream;
8838
8839 // Transport for raw args (copied from main args, or supplied via init list for testing)
8840 class Args {
8841   friend TokenStream;
8842   std::string m_exeName;
8843   std::vector<std::string> m_args;
8844
8845 public:
8846   Args(int argc, char const* const* argv) : m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
8847
8848   Args(std::initializer_list<std::string> args) : m_exeName(*args.begin()), m_args(args.begin() + 1, args.end()) {}
8849
8850   auto exeName() const -> std::string { return m_exeName; }
8851 };
8852
8853 // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
8854 // may encode an option + its argument if the : or = form is used
8855 enum class TokenType { Option, Argument };
8856 struct Token {
8857   TokenType type;
8858   std::string token;
8859 };
8860
8861 inline auto isOptPrefix(char c) -> bool
8862 {
8863   return c == '-'
8864 #ifdef CATCH_PLATFORM_WINDOWS
8865          || c == '/'
8866 #endif
8867       ;
8868 }
8869
8870 // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
8871 class TokenStream {
8872   using Iterator = std::vector<std::string>::const_iterator;
8873   Iterator it;
8874   Iterator itEnd;
8875   std::vector<Token> m_tokenBuffer;
8876
8877   void loadBuffer()
8878   {
8879     m_tokenBuffer.resize(0);
8880
8881     // Skip any empty strings
8882     while (it != itEnd && it->empty())
8883       ++it;
8884
8885     if (it != itEnd) {
8886       auto const& next = *it;
8887       if (isOptPrefix(next[0])) {
8888         auto delimiterPos = next.find_first_of(" :=");
8889         if (delimiterPos != std::string::npos) {
8890           m_tokenBuffer.push_back({TokenType::Option, next.substr(0, delimiterPos)});
8891           m_tokenBuffer.push_back({TokenType::Argument, next.substr(delimiterPos + 1)});
8892         } else {
8893           if (next[1] != '-' && next.size() > 2) {
8894             std::string opt = "- ";
8895             for (size_t i = 1; i < next.size(); ++i) {
8896               opt[1] = next[i];
8897               m_tokenBuffer.push_back({TokenType::Option, opt});
8898             }
8899           } else {
8900             m_tokenBuffer.push_back({TokenType::Option, next});
8901           }
8902         }
8903       } else {
8904         m_tokenBuffer.push_back({TokenType::Argument, next});
8905       }
8906     }
8907   }
8908
8909 public:
8910   explicit TokenStream(Args const& args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
8911
8912   TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) { loadBuffer(); }
8913
8914   explicit operator bool() const { return !m_tokenBuffer.empty() || it != itEnd; }
8915
8916   auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
8917
8918   auto operator*() const -> Token
8919   {
8920     assert(!m_tokenBuffer.empty());
8921     return m_tokenBuffer.front();
8922   }
8923
8924   auto operator->() const -> Token const*
8925   {
8926     assert(!m_tokenBuffer.empty());
8927     return &m_tokenBuffer.front();
8928   }
8929
8930   auto operator++() -> TokenStream&
8931   {
8932     if (m_tokenBuffer.size() >= 2) {
8933       m_tokenBuffer.erase(m_tokenBuffer.begin());
8934     } else {
8935       if (it != itEnd)
8936         ++it;
8937       loadBuffer();
8938     }
8939     return *this;
8940   }
8941 };
8942
8943 class ResultBase {
8944 public:
8945   enum Type { Ok, LogicError, RuntimeError };
8946
8947 protected:
8948   ResultBase(Type type) : m_type(type) {}
8949   virtual ~ResultBase() = default;
8950
8951   virtual void enforceOk() const = 0;
8952
8953   Type m_type;
8954 };
8955
8956 template <typename T> class ResultValueBase : public ResultBase {
8957 public:
8958   auto value() const -> T const&
8959   {
8960     enforceOk();
8961     return m_value;
8962   }
8963
8964 protected:
8965   ResultValueBase(Type type) : ResultBase(type) {}
8966
8967   ResultValueBase(ResultValueBase const& other) : ResultBase(other)
8968   {
8969     if (m_type == ResultBase::Ok)
8970       new (&m_value) T(other.m_value);
8971   }
8972
8973   ResultValueBase(Type, T const& value) : ResultBase(Ok) { new (&m_value) T(value); }
8974
8975   auto operator=(ResultValueBase const& other) -> ResultValueBase&
8976   {
8977     if (m_type == ResultBase::Ok)
8978       m_value.~T();
8979     ResultBase::operator=(other);
8980     if (m_type == ResultBase::Ok)
8981       new (&m_value) T(other.m_value);
8982     return *this;
8983   }
8984
8985   ~ResultValueBase() override
8986   {
8987     if (m_type == Ok)
8988       m_value.~T();
8989   }
8990
8991   union {
8992     T m_value;
8993   };
8994 };
8995
8996 template <> class ResultValueBase<void> : public ResultBase {
8997 protected:
8998   using ResultBase::ResultBase;
8999 };
9000
9001 template <typename T = void> class BasicResult : public ResultValueBase<T> {
9002 public:
9003   template <typename U>
9004   explicit BasicResult(BasicResult<U> const& other)
9005       : ResultValueBase<T>(other.type()), m_errorMessage(other.errorMessage())
9006   {
9007     assert(type() != ResultBase::Ok);
9008   }
9009
9010   template <typename U> static auto ok(U const& value) -> BasicResult { return {ResultBase::Ok, value}; }
9011   static auto ok() -> BasicResult { return {ResultBase::Ok}; }
9012   static auto logicError(std::string const& message) -> BasicResult { return {ResultBase::LogicError, message}; }
9013   static auto runtimeError(std::string const& message) -> BasicResult { return {ResultBase::RuntimeError, message}; }
9014
9015   explicit operator bool() const { return m_type == ResultBase::Ok; }
9016   auto type() const -> ResultBase::Type { return m_type; }
9017   auto errorMessage() const -> std::string { return m_errorMessage; }
9018
9019 protected:
9020   void enforceOk() const override
9021   {
9022
9023     // Errors shouldn't reach this point, but if they do
9024     // the actual error message will be in m_errorMessage
9025     assert(m_type != ResultBase::LogicError);
9026     assert(m_type != ResultBase::RuntimeError);
9027     if (m_type != ResultBase::Ok)
9028       std::abort();
9029   }
9030
9031   std::string m_errorMessage; // Only populated if resultType is an error
9032
9033   BasicResult(ResultBase::Type type, std::string const& message) : ResultValueBase<T>(type), m_errorMessage(message)
9034   {
9035     assert(m_type != ResultBase::Ok);
9036   }
9037
9038   using ResultValueBase<T>::ResultValueBase;
9039   using ResultBase::m_type;
9040 };
9041
9042 enum class ParseResultType { Matched, NoMatch, ShortCircuitAll, ShortCircuitSame };
9043
9044 class ParseState {
9045 public:
9046   ParseState(ParseResultType type, TokenStream const& remainingTokens)
9047       : m_type(type), m_remainingTokens(remainingTokens)
9048   {
9049   }
9050
9051   auto type() const -> ParseResultType { return m_type; }
9052   auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
9053
9054 private:
9055   ParseResultType m_type;
9056   TokenStream m_remainingTokens;
9057 };
9058
9059 using Result              = BasicResult<void>;
9060 using ParserResult        = BasicResult<ParseResultType>;
9061 using InternalParseResult = BasicResult<ParseState>;
9062
9063 struct HelpColumns {
9064   std::string left;
9065   std::string right;
9066 };
9067
9068 template <typename T> inline auto convertInto(std::string const& source, T& target) -> ParserResult
9069 {
9070   std::stringstream ss;
9071   ss << source;
9072   ss >> target;
9073   if (ss.fail())
9074     return ParserResult::runtimeError("Unable to convert '" + source + "' to destination type");
9075   else
9076     return ParserResult::ok(ParseResultType::Matched);
9077 }
9078 inline auto convertInto(std::string const& source, std::string& target) -> ParserResult
9079 {
9080   target = source;
9081   return ParserResult::ok(ParseResultType::Matched);
9082 }
9083 inline auto convertInto(std::string const& source, bool& target) -> ParserResult
9084 {
9085   std::string srcLC = source;
9086   std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(),
9087                  [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
9088   if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
9089     target = true;
9090   else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
9091     target = false;
9092   else
9093     return ParserResult::runtimeError("Expected a boolean value but did not recognise: '" + source + "'");
9094   return ParserResult::ok(ParseResultType::Matched);
9095 }
9096 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
9097 template <typename T>
9098 inline auto convertInto(std::string const& source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target) -> ParserResult
9099 {
9100   T temp;
9101   auto result = convertInto(source, temp);
9102   if (result)
9103     target = std::move(temp);
9104   return result;
9105 }
9106 #endif // CLARA_CONFIG_OPTIONAL_TYPE
9107
9108 struct NonCopyable {
9109   NonCopyable()                              = default;
9110   NonCopyable(NonCopyable const&)            = delete;
9111   NonCopyable(NonCopyable&&)                 = delete;
9112   NonCopyable& operator=(NonCopyable const&) = delete;
9113   NonCopyable& operator=(NonCopyable&&)      = delete;
9114 };
9115
9116 struct BoundRef : NonCopyable {
9117   virtual ~BoundRef() = default;
9118   virtual auto isContainer() const -> bool { return false; }
9119   virtual auto isFlag() const -> bool { return false; }
9120 };
9121 struct BoundValueRefBase : BoundRef {
9122   virtual auto setValue(std::string const& arg) -> ParserResult = 0;
9123 };
9124 struct BoundFlagRefBase : BoundRef {
9125   virtual auto setFlag(bool flag) -> ParserResult = 0;
9126   virtual auto isFlag() const -> bool { return true; }
9127 };
9128
9129 template <typename T> struct BoundValueRef : BoundValueRefBase {
9130   T& m_ref;
9131
9132   explicit BoundValueRef(T& ref) : m_ref(ref) {}
9133
9134   auto setValue(std::string const& arg) -> ParserResult override { return convertInto(arg, m_ref); }
9135 };
9136
9137 template <typename T> struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
9138   std::vector<T>& m_ref;
9139
9140   explicit BoundValueRef(std::vector<T>& ref) : m_ref(ref) {}
9141
9142   auto isContainer() const -> bool override { return true; }
9143
9144   auto setValue(std::string const& arg) -> ParserResult override
9145   {
9146     T temp;
9147     auto result = convertInto(arg, temp);
9148     if (result)
9149       m_ref.push_back(temp);
9150     return result;
9151   }
9152 };
9153
9154 struct BoundFlagRef : BoundFlagRefBase {
9155   bool& m_ref;
9156
9157   explicit BoundFlagRef(bool& ref) : m_ref(ref) {}
9158
9159   auto setFlag(bool flag) -> ParserResult override
9160   {
9161     m_ref = flag;
9162     return ParserResult::ok(ParseResultType::Matched);
9163   }
9164 };
9165
9166 template <typename ReturnType> struct LambdaInvoker {
9167   static_assert(std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult");
9168
9169   template <typename L, typename ArgType> static auto invoke(L const& lambda, ArgType const& arg) -> ParserResult
9170   {
9171     return lambda(arg);
9172   }
9173 };
9174
9175 template <> struct LambdaInvoker<void> {
9176   template <typename L, typename ArgType> static auto invoke(L const& lambda, ArgType const& arg) -> ParserResult
9177   {
9178     lambda(arg);
9179     return ParserResult::ok(ParseResultType::Matched);
9180   }
9181 };
9182
9183 template <typename ArgType, typename L>
9184 inline auto invokeLambda(L const& lambda, std::string const& arg) -> ParserResult
9185 {
9186   ArgType temp{};
9187   auto result = convertInto(arg, temp);
9188   return !result ? result : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(lambda, temp);
9189 }
9190
9191 template <typename L> struct BoundLambda : BoundValueRefBase {
9192   L m_lambda;
9193
9194   static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
9195   explicit BoundLambda(L const& lambda) : m_lambda(lambda) {}
9196
9197   auto setValue(std::string const& arg) -> ParserResult override
9198   {
9199     return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
9200   }
9201 };
9202
9203 template <typename L> struct BoundFlagLambda : BoundFlagRefBase {
9204   L m_lambda;
9205
9206   static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
9207   static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean");
9208
9209   explicit BoundFlagLambda(L const& lambda) : m_lambda(lambda) {}
9210
9211   auto setFlag(bool flag) -> ParserResult override
9212   {
9213     return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
9214   }
9215 };
9216
9217 enum class Optionality { Optional, Required };
9218
9219 struct Parser;
9220
9221 class ParserBase {
9222 public:
9223   virtual ~ParserBase() = default;
9224   virtual auto validate() const -> Result { return Result::ok(); }
9225   virtual auto parse(std::string const& exeName, TokenStream const& tokens) const -> InternalParseResult = 0;
9226   virtual auto cardinality() const -> size_t { return 1; }
9227
9228   auto parse(Args const& args) const -> InternalParseResult { return parse(args.exeName(), TokenStream(args)); }
9229 };
9230
9231 template <typename DerivedT> class ComposableParserImpl : public ParserBase {
9232 public:
9233   template <typename T> auto operator|(T const& other) const -> Parser;
9234
9235   template <typename T> auto operator+(T const& other) const -> Parser;
9236 };
9237
9238 // Common code and state for Args and Opts
9239 template <typename DerivedT> class ParserRefImpl : public ComposableParserImpl<DerivedT> {
9240 protected:
9241   Optionality m_optionality = Optionality::Optional;
9242   std::shared_ptr<BoundRef> m_ref;
9243   std::string m_hint;
9244   std::string m_description;
9245
9246   explicit ParserRefImpl(std::shared_ptr<BoundRef> const& ref) : m_ref(ref) {}
9247
9248 public:
9249   template <typename T>
9250   ParserRefImpl(T& ref, std::string const& hint) : m_ref(std::make_shared<BoundValueRef<T>>(ref)), m_hint(hint)
9251   {
9252   }
9253
9254   template <typename LambdaT>
9255   ParserRefImpl(LambdaT const& ref, std::string const& hint)
9256       : m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)), m_hint(hint)
9257   {
9258   }
9259
9260   auto operator()(std::string const& description) -> DerivedT&
9261   {
9262     m_description = description;
9263     return static_cast<DerivedT&>(*this);
9264   }
9265
9266   auto optional() -> DerivedT&
9267   {
9268     m_optionality = Optionality::Optional;
9269     return static_cast<DerivedT&>(*this);
9270   };
9271
9272   auto required() -> DerivedT&
9273   {
9274     m_optionality = Optionality::Required;
9275     return static_cast<DerivedT&>(*this);
9276   };
9277
9278   auto isOptional() const -> bool { return m_optionality == Optionality::Optional; }
9279
9280   auto cardinality() const -> size_t override
9281   {
9282     if (m_ref->isContainer())
9283       return 0;
9284     else
9285       return 1;
9286   }
9287
9288   auto hint() const -> std::string { return m_hint; }
9289 };
9290
9291 class ExeName : public ComposableParserImpl<ExeName> {
9292   std::shared_ptr<std::string> m_name;
9293   std::shared_ptr<BoundValueRefBase> m_ref;
9294
9295   template <typename LambdaT> static auto makeRef(LambdaT const& lambda) -> std::shared_ptr<BoundValueRefBase>
9296   {
9297     return std::make_shared<BoundLambda<LambdaT>>(lambda);
9298   }
9299
9300 public:
9301   ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
9302
9303   explicit ExeName(std::string& ref) : ExeName() { m_ref = std::make_shared<BoundValueRef<std::string>>(ref); }
9304
9305   template <typename LambdaT> explicit ExeName(LambdaT const& lambda) : ExeName()
9306   {
9307     m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
9308   }
9309
9310   // The exe name is not parsed out of the normal tokens, but is handled specially
9311   auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override
9312   {
9313     return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
9314   }
9315
9316   auto name() const -> std::string { return *m_name; }
9317   auto set(std::string const& newName) -> ParserResult
9318   {
9319
9320     auto lastSlash = newName.find_last_of("\\/");
9321     auto filename  = (lastSlash == std::string::npos) ? newName : newName.substr(lastSlash + 1);
9322
9323     *m_name = filename;
9324     if (m_ref)
9325       return m_ref->setValue(filename);
9326     else
9327       return ParserResult::ok(ParseResultType::Matched);
9328   }
9329 };
9330
9331 class Arg : public ParserRefImpl<Arg> {
9332 public:
9333   using ParserRefImpl::ParserRefImpl;
9334
9335   auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override
9336   {
9337     auto validationResult = validate();
9338     if (!validationResult)
9339       return InternalParseResult(validationResult);
9340
9341     auto remainingTokens = tokens;
9342     auto const& token    = *remainingTokens;
9343     if (token.type != TokenType::Argument)
9344       return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
9345
9346     assert(!m_ref->isFlag());
9347     auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
9348
9349     auto result = valueRef->setValue(remainingTokens->token);
9350     if (!result)
9351       return InternalParseResult(result);
9352     else
9353       return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
9354   }
9355 };
9356
9357 inline auto normaliseOpt(std::string const& optName) -> std::string
9358 {
9359 #ifdef CATCH_PLATFORM_WINDOWS
9360   if (optName[0] == '/')
9361     return "-" + optName.substr(1);
9362   else
9363 #endif
9364     return optName;
9365 }
9366
9367 class Opt : public ParserRefImpl<Opt> {
9368 protected:
9369   std::vector<std::string> m_optNames;
9370
9371 public:
9372   template <typename LambdaT>
9373   explicit Opt(LambdaT const& ref) : ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref))
9374   {
9375   }
9376
9377   explicit Opt(bool& ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
9378
9379   template <typename LambdaT> Opt(LambdaT const& ref, std::string const& hint) : ParserRefImpl(ref, hint) {}
9380
9381   template <typename T> Opt(T& ref, std::string const& hint) : ParserRefImpl(ref, hint) {}
9382
9383   auto operator[](std::string const& optName) -> Opt&
9384   {
9385     m_optNames.push_back(optName);
9386     return *this;
9387   }
9388
9389   auto getHelpColumns() const -> std::vector<HelpColumns>
9390   {
9391     std::ostringstream oss;
9392     bool first = true;
9393     for (auto const& opt : m_optNames) {
9394       if (first)
9395         first = false;
9396       else
9397         oss << ", ";
9398       oss << opt;
9399     }
9400     if (!m_hint.empty())
9401       oss << " <" << m_hint << ">";
9402     return {{oss.str(), m_description}};
9403   }
9404
9405   auto isMatch(std::string const& optToken) const -> bool
9406   {
9407     auto normalisedToken = normaliseOpt(optToken);
9408     for (auto const& name : m_optNames) {
9409       if (normaliseOpt(name) == normalisedToken)
9410         return true;
9411     }
9412     return false;
9413   }
9414
9415   using ParserBase::parse;
9416
9417   auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override
9418   {
9419     auto validationResult = validate();
9420     if (!validationResult)
9421       return InternalParseResult(validationResult);
9422
9423     auto remainingTokens = tokens;
9424     if (remainingTokens && remainingTokens->type == TokenType::Option) {
9425       auto const& token = *remainingTokens;
9426       if (isMatch(token.token)) {
9427         if (m_ref->isFlag()) {
9428           auto flagRef = static_cast<detail::BoundFlagRefBase*>(m_ref.get());
9429           auto result  = flagRef->setFlag(true);
9430           if (!result)
9431             return InternalParseResult(result);
9432           if (result.value() == ParseResultType::ShortCircuitAll)
9433             return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
9434         } else {
9435           auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
9436           ++remainingTokens;
9437           if (!remainingTokens)
9438             return InternalParseResult::runtimeError("Expected argument following " + token.token);
9439           auto const& argToken = *remainingTokens;
9440           if (argToken.type != TokenType::Argument)
9441             return InternalParseResult::runtimeError("Expected argument following " + token.token);
9442           auto result = valueRef->setValue(argToken.token);
9443           if (!result)
9444             return InternalParseResult(result);
9445           if (result.value() == ParseResultType::ShortCircuitAll)
9446             return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
9447         }
9448         return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
9449       }
9450     }
9451     return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
9452   }
9453
9454   auto validate() const -> Result override
9455   {
9456     if (m_optNames.empty())
9457       return Result::logicError("No options supplied to Opt");
9458     for (auto const& name : m_optNames) {
9459       if (name.empty())
9460         return Result::logicError("Option name cannot be empty");
9461 #ifdef CATCH_PLATFORM_WINDOWS
9462       if (name[0] != '-' && name[0] != '/')
9463         return Result::logicError("Option name must begin with '-' or '/'");
9464 #else
9465       if (name[0] != '-')
9466         return Result::logicError("Option name must begin with '-'");
9467 #endif
9468     }
9469     return ParserRefImpl::validate();
9470   }
9471 };
9472
9473 struct Help : Opt {
9474   Help(bool& showHelpFlag)
9475       : Opt([&](bool flag) {
9476         showHelpFlag = flag;
9477         return ParserResult::ok(ParseResultType::ShortCircuitAll);
9478       })
9479   {
9480     static_cast<Opt&> (*this)("display usage information")["-?"]["-h"]["--help"].optional();
9481   }
9482 };
9483
9484 struct Parser : ParserBase {
9485
9486   mutable ExeName m_exeName;
9487   std::vector<Opt> m_options;
9488   std::vector<Arg> m_args;
9489
9490   auto operator|=(ExeName const& exeName) -> Parser&
9491   {
9492     m_exeName = exeName;
9493     return *this;
9494   }
9495
9496   auto operator|=(Arg const& arg) -> Parser&
9497   {
9498     m_args.push_back(arg);
9499     return *this;
9500   }
9501
9502   auto operator|=(Opt const& opt) -> Parser&
9503   {
9504     m_options.push_back(opt);
9505     return *this;
9506   }
9507
9508   auto operator|=(Parser const& other) -> Parser&
9509   {
9510     m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
9511     m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
9512     return *this;
9513   }
9514
9515   template <typename T> auto operator|(T const& other) const -> Parser { return Parser(*this) |= other; }
9516
9517   // Forward deprecated interface with '+' instead of '|'
9518   template <typename T> auto operator+=(T const& other) -> Parser& { return operator|=(other); }
9519   template <typename T> auto operator+(T const& other) const -> Parser { return operator|(other); }
9520
9521   auto getHelpColumns() const -> std::vector<HelpColumns>
9522   {
9523     std::vector<HelpColumns> cols;
9524     for (auto const& o : m_options) {
9525       auto childCols = o.getHelpColumns();
9526       cols.insert(cols.end(), childCols.begin(), childCols.end());
9527     }
9528     return cols;
9529   }
9530
9531   void writeToStream(std::ostream& os) const
9532   {
9533     if (!m_exeName.name().empty()) {
9534       os << "usage:\n"
9535          << "  " << m_exeName.name() << " ";
9536       bool required = true, first = true;
9537       for (auto const& arg : m_args) {
9538         if (first)
9539           first = false;
9540         else
9541           os << " ";
9542         if (arg.isOptional() && required) {
9543           os << "[";
9544           required = false;
9545         }
9546         os << "<" << arg.hint() << ">";
9547         if (arg.cardinality() == 0)
9548           os << " ... ";
9549       }
9550       if (!required)
9551         os << "]";
9552       if (!m_options.empty())
9553         os << " options";
9554       os << "\n\nwhere options are:" << std::endl;
9555     }
9556
9557     auto rows           = getHelpColumns();
9558     size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
9559     size_t optWidth     = 0;
9560     for (auto const& cols : rows)
9561       optWidth = (std::max)(optWidth, cols.left.size() + 2);
9562
9563     optWidth = (std::min)(optWidth, consoleWidth / 2);
9564
9565     for (auto const& cols : rows) {
9566       auto row = TextFlow::Column(cols.left).width(optWidth).indent(2) + TextFlow::Spacer(4) +
9567                  TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
9568       os << row << std::endl;
9569     }
9570   }
9571
9572   friend auto operator<<(std::ostream& os, Parser const& parser) -> std::ostream&
9573   {
9574     parser.writeToStream(os);
9575     return os;
9576   }
9577
9578   auto validate() const -> Result override
9579   {
9580     for (auto const& opt : m_options) {
9581       auto result = opt.validate();
9582       if (!result)
9583         return result;
9584     }
9585     for (auto const& arg : m_args) {
9586       auto result = arg.validate();
9587       if (!result)
9588         return result;
9589     }
9590     return Result::ok();
9591   }
9592
9593   using ParserBase::parse;
9594
9595   auto parse(std::string const& exeName, TokenStream const& tokens) const -> InternalParseResult override
9596   {
9597
9598     struct ParserInfo {
9599       ParserBase const* parser = nullptr;
9600       size_t count             = 0;
9601     };
9602     const size_t totalParsers = m_options.size() + m_args.size();
9603     assert(totalParsers < 512);
9604     // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
9605     ParserInfo parseInfos[512];
9606
9607     {
9608       size_t i = 0;
9609       for (auto const& opt : m_options)
9610         parseInfos[i++].parser = &opt;
9611       for (auto const& arg : m_args)
9612         parseInfos[i++].parser = &arg;
9613     }
9614
9615     m_exeName.set(exeName);
9616
9617     auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
9618     while (result.value().remainingTokens()) {
9619       bool tokenParsed = false;
9620
9621       for (size_t i = 0; i < totalParsers; ++i) {
9622         auto& parseInfo = parseInfos[i];
9623         if (parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality()) {
9624           result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
9625           if (!result)
9626             return result;
9627           if (result.value().type() != ParseResultType::NoMatch) {
9628             tokenParsed = true;
9629             ++parseInfo.count;
9630             break;
9631           }
9632         }
9633       }
9634
9635       if (result.value().type() == ParseResultType::ShortCircuitAll)
9636         return result;
9637       if (!tokenParsed)
9638         return InternalParseResult::runtimeError("Unrecognised token: " + result.value().remainingTokens()->token);
9639     }
9640     // !TBD Check missing required options
9641     return result;
9642   }
9643 };
9644
9645 template <typename DerivedT>
9646 template <typename T>
9647 auto ComposableParserImpl<DerivedT>::operator|(T const& other) const -> Parser
9648 {
9649   return Parser() | static_cast<DerivedT const&>(*this) | other;
9650 }
9651 } // namespace detail
9652
9653 // A Combined parser
9654 using detail::Parser;
9655
9656 // A parser for options
9657 using detail::Opt;
9658
9659 // A parser for arguments
9660 using detail::Arg;
9661
9662 // Wrapper for argc, argv from main()
9663 using detail::Args;
9664
9665 // Specifies the name of the executable
9666 using detail::ExeName;
9667
9668 // Convenience wrapper for option parser that specifies the help option
9669 using detail::Help;
9670
9671 // enum of result types from a parse
9672 using detail::ParseResultType;
9673
9674 // Result type for parser operation
9675 using detail::ParserResult;
9676
9677 } // namespace clara
9678 } // namespace Catch
9679
9680 // end clara.hpp
9681 #ifdef __clang__
9682 #pragma clang diagnostic pop
9683 #endif
9684
9685 // Restore Clara's value for console width, if present
9686 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9687 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9688 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9689 #endif
9690
9691 // end catch_clara.h
9692 namespace Catch {
9693
9694 clara::Parser makeCommandLineParser(ConfigData& config);
9695
9696 } // end namespace Catch
9697
9698 // end catch_commandline.h
9699 #include <ctime>
9700 #include <fstream>
9701
9702 namespace Catch {
9703
9704 clara::Parser makeCommandLineParser(ConfigData& config)
9705 {
9706
9707   using namespace clara;
9708
9709   auto const setWarning = [&](std::string const& warning) {
9710     auto warningSet = [&]() {
9711       if (warning == "NoAssertions")
9712         return WarnAbout::NoAssertions;
9713
9714       if (warning == "NoTests")
9715         return WarnAbout::NoTests;
9716
9717       return WarnAbout::Nothing;
9718     }();
9719
9720     if (warningSet == WarnAbout::Nothing)
9721       return ParserResult::runtimeError("Unrecognised warning: '" + warning + "'");
9722     config.warnings = static_cast<WarnAbout::What>(config.warnings | warningSet);
9723     return ParserResult::ok(ParseResultType::Matched);
9724   };
9725   auto const loadTestNamesFromFile = [&](std::string const& filename) {
9726     std::ifstream f(filename.c_str());
9727     if (!f.is_open())
9728       return ParserResult::runtimeError("Unable to load input file: '" + filename + "'");
9729
9730     std::string line;
9731     while (std::getline(f, line)) {
9732       line = trim(line);
9733       if (!line.empty() && !startsWith(line, '#')) {
9734         if (!startsWith(line, '"'))
9735           line = '"' + line + '"';
9736         config.testsOrTags.push_back(line);
9737         config.testsOrTags.emplace_back(",");
9738       }
9739     }
9740     // Remove comma in the end
9741     if (!config.testsOrTags.empty())
9742       config.testsOrTags.erase(config.testsOrTags.end() - 1);
9743
9744     return ParserResult::ok(ParseResultType::Matched);
9745   };
9746   auto const setTestOrder = [&](std::string const& order) {
9747     if (startsWith("declared", order))
9748       config.runOrder = RunTests::InDeclarationOrder;
9749     else if (startsWith("lexical", order))
9750       config.runOrder = RunTests::InLexicographicalOrder;
9751     else if (startsWith("random", order))
9752       config.runOrder = RunTests::InRandomOrder;
9753     else
9754       return clara::ParserResult::runtimeError("Unrecognised ordering: '" + order + "'");
9755     return ParserResult::ok(ParseResultType::Matched);
9756   };
9757   auto const setRngSeed = [&](std::string const& seed) {
9758     if (seed != "time")
9759       return clara::detail::convertInto(seed, config.rngSeed);
9760     config.rngSeed = static_cast<unsigned int>(std::time(nullptr));
9761     return ParserResult::ok(ParseResultType::Matched);
9762   };
9763   auto const setColourUsage = [&](std::string const& useColour) {
9764     auto mode = toLower(useColour);
9765
9766     if (mode == "yes")
9767       config.useColour = UseColour::Yes;
9768     else if (mode == "no")
9769       config.useColour = UseColour::No;
9770     else if (mode == "auto")
9771       config.useColour = UseColour::Auto;
9772     else
9773       return ParserResult::runtimeError("colour mode must be one of: auto, yes or no. '" + useColour +
9774                                         "' not recognised");
9775     return ParserResult::ok(ParseResultType::Matched);
9776   };
9777   auto const setWaitForKeypress = [&](std::string const& keypress) {
9778     auto keypressLc = toLower(keypress);
9779     if (keypressLc == "never")
9780       config.waitForKeypress = WaitForKeypress::Never;
9781     else if (keypressLc == "start")
9782       config.waitForKeypress = WaitForKeypress::BeforeStart;
9783     else if (keypressLc == "exit")
9784       config.waitForKeypress = WaitForKeypress::BeforeExit;
9785     else if (keypressLc == "both")
9786       config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
9787     else
9788       return ParserResult::runtimeError("keypress argument must be one of: never, start, exit or both. '" + keypress +
9789                                         "' not recognised");
9790     return ParserResult::ok(ParseResultType::Matched);
9791   };
9792   auto const setVerbosity = [&](std::string const& verbosity) {
9793     auto lcVerbosity = toLower(verbosity);
9794     if (lcVerbosity == "quiet")
9795       config.verbosity = Verbosity::Quiet;
9796     else if (lcVerbosity == "normal")
9797       config.verbosity = Verbosity::Normal;
9798     else if (lcVerbosity == "high")
9799       config.verbosity = Verbosity::High;
9800     else
9801       return ParserResult::runtimeError("Unrecognised verbosity, '" + verbosity + "'");
9802     return ParserResult::ok(ParseResultType::Matched);
9803   };
9804   auto const setReporter = [&](std::string const& reporter) {
9805     IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
9806
9807     auto lcReporter = toLower(reporter);
9808     auto result     = factories.find(lcReporter);
9809
9810     if (factories.end() != result)
9811       config.reporterName = lcReporter;
9812     else
9813       return ParserResult::runtimeError("Unrecognized reporter, '" + reporter +
9814                                         "'. Check available with --list-reporters");
9815     return ParserResult::ok(ParseResultType::Matched);
9816   };
9817
9818   auto cli =
9819       ExeName(config.processName) | Help(config.showHelp) |
9820       Opt(config.listTests)["-l"]["--list-tests"]("list all/matching test cases") |
9821       Opt(config.listTags)["-t"]["--list-tags"]("list all/matching tags") |
9822       Opt(config.showSuccessfulTests)["-s"]["--success"]("include successful tests in output") |
9823       Opt(config.shouldDebugBreak)["-b"]["--break"]("break into debugger on failure") |
9824       Opt(config.noThrow)["-e"]["--nothrow"]("skip exception tests") |
9825       Opt(config.showInvisibles)["-i"]["--invisibles"]("show invisibles (tabs, newlines)") |
9826       Opt(config.outputFilename, "filename")["-o"]["--out"]("output filename") |
9827       Opt(setReporter, "name")["-r"]["--reporter"]("reporter to use (defaults to console)") |
9828       Opt(config.name, "name")["-n"]["--name"]("suite name") |
9829       Opt([&](bool) { config.abortAfter = 1; })["-a"]["--abort"]("abort at first failure") |
9830       Opt([&](int x) { config.abortAfter = x; }, "no. failures")["-x"]["--abortx"]("abort after x failures") |
9831       Opt(setWarning, "warning name")["-w"]["--warn"]("enable warnings") |
9832       Opt([&](bool flag) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; },
9833           "yes|no")["-d"]["--durations"]("show test durations") |
9834       Opt(config.minDuration, "seconds")["-D"]["--min-duration"](
9835           "show test durations for tests taking at least the given number of seconds") |
9836       Opt(loadTestNamesFromFile, "filename")["-f"]["--input-file"]("load test names to run from a file") |
9837       Opt(config.filenamesAsTags)["-#"]["--filenames-as-tags"]("adds a tag for the filename") |
9838       Opt(config.sectionsToRun, "section name")["-c"]["--section"]("specify section to run") |
9839       Opt(setVerbosity, "quiet|normal|high")["-v"]["--verbosity"]("set output verbosity") |
9840       Opt(config.listTestNamesOnly)["--list-test-names-only"]("list all/matching test cases names only") |
9841       Opt(config.listReporters)["--list-reporters"]("list all reporters") |
9842       Opt(setTestOrder, "decl|lex|rand")["--order"]("test case order (defaults to decl)") |
9843       Opt(setRngSeed, "'time'|number")["--rng-seed"]("set a specific seed for random numbers") |
9844       Opt(setColourUsage, "yes|no")["--use-colour"]("should output be colourised") |
9845       Opt(config.libIdentify)["--libidentify"]("report name and version according to libidentify standard") |
9846       Opt(setWaitForKeypress, "never|start|exit|both")["--wait-for-keypress"]("waits for a keypress before exiting") |
9847       Opt(config.benchmarkSamples, "samples")["--benchmark-samples"]("number of samples to collect (default: 100)") |
9848       Opt(config.benchmarkResamples,
9849           "resamples")["--benchmark-resamples"]("number of resamples for the bootstrap (default: 100000)") |
9850       Opt(config.benchmarkConfidenceInterval, "confidence interval")["--benchmark-confidence-interval"](
9851           "confidence interval for the bootstrap (between 0 and 1, default: 0.95)") |
9852       Opt(config.benchmarkNoAnalysis)["--benchmark-no-analysis"](
9853           "perform only measurements; do not perform any analysis") |
9854       Opt(config.benchmarkWarmupTime, "benchmarkWarmupTime")["--benchmark-warmup-time"](
9855           "amount of time in milliseconds spent on warming up each test (default: 100)") |
9856       Arg(config.testsOrTags, "test name|pattern|tags")("which test or tests to use");
9857
9858   return cli;
9859 }
9860
9861 } // end namespace Catch
9862 // end catch_commandline.cpp
9863 // start catch_common.cpp
9864
9865 #include <cstring>
9866 #include <ostream>
9867
9868 namespace Catch {
9869
9870 bool SourceLineInfo::operator==(SourceLineInfo const& other) const noexcept
9871 {
9872   return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
9873 }
9874 bool SourceLineInfo::operator<(SourceLineInfo const& other) const noexcept
9875 {
9876   // We can assume that the same file will usually have the same pointer.
9877   // Thus, if the pointers are the same, there is no point in calling the strcmp
9878   return line < other.line || (line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
9879 }
9880
9881 std::ostream& operator<<(std::ostream& os, SourceLineInfo const& info)
9882 {
9883 #ifndef __GNUG__
9884   os << info.file << '(' << info.line << ')';
9885 #else
9886   os << info.file << ':' << info.line;
9887 #endif
9888   return os;
9889 }
9890
9891 std::string StreamEndStop::operator+() const
9892 {
9893   return std::string();
9894 }
9895
9896 NonCopyable::NonCopyable()  = default;
9897 NonCopyable::~NonCopyable() = default;
9898
9899 } // namespace Catch
9900 // end catch_common.cpp
9901 // start catch_config.cpp
9902
9903 namespace Catch {
9904
9905 Config::Config(ConfigData const& data) : m_data(data), m_stream(openStream())
9906 {
9907   // We need to trim filter specs to avoid trouble with superfluous
9908   // whitespace (esp. important for bdd macros, as those are manually
9909   // aligned with whitespace).
9910
9911   for (auto& elem : m_data.testsOrTags) {
9912     elem = trim(elem);
9913   }
9914   for (auto& elem : m_data.sectionsToRun) {
9915     elem = trim(elem);
9916   }
9917
9918   TestSpecParser parser(ITagAliasRegistry::get());
9919   if (!m_data.testsOrTags.empty()) {
9920     m_hasTestFilters = true;
9921     for (auto const& testOrTags : m_data.testsOrTags) {
9922       parser.parse(testOrTags);
9923     }
9924   }
9925   m_testSpec = parser.testSpec();
9926 }
9927
9928 std::string const& Config::getFilename() const
9929 {
9930   return m_data.outputFilename;
9931 }
9932
9933 bool Config::listTests() const
9934 {
9935   return m_data.listTests;
9936 }
9937 bool Config::listTestNamesOnly() const
9938 {
9939   return m_data.listTestNamesOnly;
9940 }
9941 bool Config::listTags() const
9942 {
9943   return m_data.listTags;
9944 }
9945 bool Config::listReporters() const
9946 {
9947   return m_data.listReporters;
9948 }
9949
9950 std::string Config::getProcessName() const
9951 {
9952   return m_data.processName;
9953 }
9954 std::string const& Config::getReporterName() const
9955 {
9956   return m_data.reporterName;
9957 }
9958
9959 std::vector<std::string> const& Config::getTestsOrTags() const
9960 {
9961   return m_data.testsOrTags;
9962 }
9963 std::vector<std::string> const& Config::getSectionsToRun() const
9964 {
9965   return m_data.sectionsToRun;
9966 }
9967
9968 TestSpec const& Config::testSpec() const
9969 {
9970   return m_testSpec;
9971 }
9972 bool Config::hasTestFilters() const
9973 {
9974   return m_hasTestFilters;
9975 }
9976
9977 bool Config::showHelp() const
9978 {
9979   return m_data.showHelp;
9980 }
9981
9982 // IConfig interface
9983 bool Config::allowThrows() const
9984 {
9985   return !m_data.noThrow;
9986 }
9987 std::ostream& Config::stream() const
9988 {
9989   return m_stream->stream();
9990 }
9991 std::string Config::name() const
9992 {
9993   return m_data.name.empty() ? m_data.processName : m_data.name;
9994 }
9995 bool Config::includeSuccessfulResults() const
9996 {
9997   return m_data.showSuccessfulTests;
9998 }
9999 bool Config::warnAboutMissingAssertions() const
10000 {
10001   return !!(m_data.warnings & WarnAbout::NoAssertions);
10002 }
10003 bool Config::warnAboutNoTests() const
10004 {
10005   return !!(m_data.warnings & WarnAbout::NoTests);
10006 }
10007 ShowDurations::OrNot Config::showDurations() const
10008 {
10009   return m_data.showDurations;
10010 }
10011 double Config::minDuration() const
10012 {
10013   return m_data.minDuration;
10014 }
10015 RunTests::InWhatOrder Config::runOrder() const
10016 {
10017   return m_data.runOrder;
10018 }
10019 unsigned int Config::rngSeed() const
10020 {
10021   return m_data.rngSeed;
10022 }
10023 UseColour::YesOrNo Config::useColour() const
10024 {
10025   return m_data.useColour;
10026 }
10027 bool Config::shouldDebugBreak() const
10028 {
10029   return m_data.shouldDebugBreak;
10030 }
10031 int Config::abortAfter() const
10032 {
10033   return m_data.abortAfter;
10034 }
10035 bool Config::showInvisibles() const
10036 {
10037   return m_data.showInvisibles;
10038 }
10039 Verbosity Config::verbosity() const
10040 {
10041   return m_data.verbosity;
10042 }
10043
10044 bool Config::benchmarkNoAnalysis() const
10045 {
10046   return m_data.benchmarkNoAnalysis;
10047 }
10048 int Config::benchmarkSamples() const
10049 {
10050   return m_data.benchmarkSamples;
10051 }
10052 double Config::benchmarkConfidenceInterval() const
10053 {
10054   return m_data.benchmarkConfidenceInterval;
10055 }
10056 unsigned int Config::benchmarkResamples() const
10057 {
10058   return m_data.benchmarkResamples;
10059 }
10060 std::chrono::milliseconds Config::benchmarkWarmupTime() const
10061 {
10062   return std::chrono::milliseconds(m_data.benchmarkWarmupTime);
10063 }
10064
10065 IStream const* Config::openStream()
10066 {
10067   return Catch::makeStream(m_data.outputFilename);
10068 }
10069
10070 } // end namespace Catch
10071 // end catch_config.cpp
10072 // start catch_console_colour.cpp
10073
10074 #if defined(__clang__)
10075 #pragma clang diagnostic push
10076 #pragma clang diagnostic ignored "-Wexit-time-destructors"
10077 #endif
10078
10079 // start catch_errno_guard.h
10080
10081 namespace Catch {
10082
10083 class ErrnoGuard {
10084 public:
10085   ErrnoGuard();
10086   ~ErrnoGuard();
10087
10088 private:
10089   int m_oldErrno;
10090 };
10091
10092 } // namespace Catch
10093
10094 // end catch_errno_guard.h
10095 // start catch_windows_h_proxy.h
10096
10097 #if defined(CATCH_PLATFORM_WINDOWS)
10098
10099 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
10100 #define CATCH_DEFINED_NOMINMAX
10101 #define NOMINMAX
10102 #endif
10103 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
10104 #define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
10105 #define WIN32_LEAN_AND_MEAN
10106 #endif
10107
10108 #ifdef __AFXDLL
10109 #include <AfxWin.h>
10110 #else
10111 #include <windows.h>
10112 #endif
10113
10114 #ifdef CATCH_DEFINED_NOMINMAX
10115 #undef NOMINMAX
10116 #endif
10117 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
10118 #undef WIN32_LEAN_AND_MEAN
10119 #endif
10120
10121 #endif // defined(CATCH_PLATFORM_WINDOWS)
10122
10123 // end catch_windows_h_proxy.h
10124 #include <sstream>
10125
10126 namespace Catch {
10127 namespace {
10128
10129 struct IColourImpl {
10130   virtual ~IColourImpl()                     = default;
10131   virtual void use(Colour::Code _colourCode) = 0;
10132 };
10133
10134 struct NoColourImpl : IColourImpl {
10135   void use(Colour::Code) override {}
10136
10137   static IColourImpl* instance()
10138   {
10139     static NoColourImpl s_instance;
10140     return &s_instance;
10141   }
10142 };
10143
10144 } // namespace
10145 } // namespace Catch
10146
10147 #if !defined(CATCH_CONFIG_COLOUR_NONE) && !defined(CATCH_CONFIG_COLOUR_WINDOWS) && !defined(CATCH_CONFIG_COLOUR_ANSI)
10148 #ifdef CATCH_PLATFORM_WINDOWS
10149 #define CATCH_CONFIG_COLOUR_WINDOWS
10150 #else
10151 #define CATCH_CONFIG_COLOUR_ANSI
10152 #endif
10153 #endif
10154
10155 #if defined(CATCH_CONFIG_COLOUR_WINDOWS) /////////////////////////////////////////
10156
10157 namespace Catch {
10158 namespace {
10159
10160 class Win32ColourImpl : public IColourImpl {
10161 public:
10162   Win32ColourImpl() : stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE))
10163   {
10164     CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
10165     GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
10166     originalForegroundAttributes =
10167         csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
10168     originalBackgroundAttributes =
10169         csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
10170   }
10171
10172   void use(Colour::Code _colourCode) override
10173   {
10174     switch (_colourCode) {
10175       case Colour::None:
10176         return setTextAttribute(originalForegroundAttributes);
10177       case Colour::White:
10178         return setTextAttribute(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
10179       case Colour::Red:
10180         return setTextAttribute(FOREGROUND_RED);
10181       case Colour::Green:
10182         return setTextAttribute(FOREGROUND_GREEN);
10183       case Colour::Blue:
10184         return setTextAttribute(FOREGROUND_BLUE);
10185       case Colour::Cyan:
10186         return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN);
10187       case Colour::Yellow:
10188         return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN);
10189       case Colour::Grey:
10190         return setTextAttribute(0);
10191
10192       case Colour::LightGrey:
10193         return setTextAttribute(FOREGROUND_INTENSITY);
10194       case Colour::BrightRed:
10195         return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED);
10196       case Colour::BrightGreen:
10197         return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN);
10198       case Colour::BrightWhite:
10199         return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
10200       case Colour::BrightYellow:
10201         return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
10202
10203       case Colour::Bright:
10204         CATCH_INTERNAL_ERROR("not a colour");
10205
10206       default:
10207         CATCH_ERROR("Unknown colour requested");
10208     }
10209   }
10210
10211 private:
10212   void setTextAttribute(WORD _textAttribute)
10213   {
10214     SetConsoleTextAttribute(stdoutHandle, _textAttribute | originalBackgroundAttributes);
10215   }
10216   HANDLE stdoutHandle;
10217   WORD originalForegroundAttributes;
10218   WORD originalBackgroundAttributes;
10219 };
10220
10221 IColourImpl* platformColourInstance()
10222 {
10223   static Win32ColourImpl s_instance;
10224
10225   IConfigPtr config             = getCurrentContext().getConfig();
10226   UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto;
10227   if (colourMode == UseColour::Auto)
10228     colourMode = UseColour::Yes;
10229   return colourMode == UseColour::Yes ? &s_instance : NoColourImpl::instance();
10230 }
10231
10232 } // namespace
10233 } // end namespace Catch
10234
10235 #elif defined(CATCH_CONFIG_COLOUR_ANSI) //////////////////////////////////////
10236
10237 #include <unistd.h>
10238
10239 namespace Catch {
10240 namespace {
10241
10242 // use POSIX/ ANSI console terminal codes
10243 // Thanks to Adam Strzelecki for original contribution
10244 // (http://github.com/nanoant)
10245 // https://github.com/philsquared/Catch/pull/131
10246 class PosixColourImpl : public IColourImpl {
10247 public:
10248   void use(Colour::Code _colourCode) override
10249   {
10250     switch (_colourCode) {
10251       case Colour::None:
10252       case Colour::White:
10253         return setColour("[0m");
10254       case Colour::Red:
10255         return setColour("[0;31m");
10256       case Colour::Green:
10257         return setColour("[0;32m");
10258       case Colour::Blue:
10259         return setColour("[0;34m");
10260       case Colour::Cyan:
10261         return setColour("[0;36m");
10262       case Colour::Yellow:
10263         return setColour("[0;33m");
10264       case Colour::Grey:
10265         return setColour("[1;30m");
10266
10267       case Colour::LightGrey:
10268         return setColour("[0;37m");
10269       case Colour::BrightRed:
10270         return setColour("[1;31m");
10271       case Colour::BrightGreen:
10272         return setColour("[1;32m");
10273       case Colour::BrightWhite:
10274         return setColour("[1;37m");
10275       case Colour::BrightYellow:
10276         return setColour("[1;33m");
10277
10278       case Colour::Bright:
10279         CATCH_INTERNAL_ERROR("not a colour");
10280       default:
10281         CATCH_INTERNAL_ERROR("Unknown colour requested");
10282     }
10283   }
10284   static IColourImpl* instance()
10285   {
10286     static PosixColourImpl s_instance;
10287     return &s_instance;
10288   }
10289
10290 private:
10291   void setColour(const char* _escapeCode) { getCurrentContext().getConfig()->stream() << '\033' << _escapeCode; }
10292 };
10293
10294 bool useColourOnPlatform()
10295 {
10296   return
10297 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10298       !isDebuggerActive() &&
10299 #endif
10300 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
10301       isatty(STDOUT_FILENO)
10302 #else
10303       false
10304 #endif
10305           ;
10306 }
10307 IColourImpl* platformColourInstance()
10308 {
10309   ErrnoGuard guard;
10310   IConfigPtr config             = getCurrentContext().getConfig();
10311   UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto;
10312   if (colourMode == UseColour::Auto)
10313     colourMode = useColourOnPlatform() ? UseColour::Yes : UseColour::No;
10314   return colourMode == UseColour::Yes ? PosixColourImpl::instance() : NoColourImpl::instance();
10315 }
10316
10317 } // namespace
10318 } // end namespace Catch
10319
10320 #else // not Windows or ANSI ///////////////////////////////////////////////
10321
10322 namespace Catch {
10323
10324 static IColourImpl* platformColourInstance()
10325 {
10326   return NoColourImpl::instance();
10327 }
10328
10329 } // end namespace Catch
10330
10331 #endif // Windows/ ANSI/ None
10332
10333 namespace Catch {
10334
10335 Colour::Colour(Code _colourCode)
10336 {
10337   use(_colourCode);
10338 }
10339 Colour::Colour(Colour&& other) noexcept
10340 {
10341   m_moved       = other.m_moved;
10342   other.m_moved = true;
10343 }
10344 Colour& Colour::operator=(Colour&& other) noexcept
10345 {
10346   m_moved       = other.m_moved;
10347   other.m_moved = true;
10348   return *this;
10349 }
10350
10351 Colour::~Colour()
10352 {
10353   if (!m_moved)
10354     use(None);
10355 }
10356
10357 void Colour::use(Code _colourCode)
10358 {
10359   static IColourImpl* impl = platformColourInstance();
10360   // Strictly speaking, this cannot possibly happen.
10361   // However, under some conditions it does happen (see #1626),
10362   // and this change is small enough that we can let practicality
10363   // triumph over purity in this case.
10364   if (impl != nullptr) {
10365     impl->use(_colourCode);
10366   }
10367 }
10368
10369 std::ostream& operator<<(std::ostream& os, Colour const&)
10370 {
10371   return os;
10372 }
10373
10374 } // end namespace Catch
10375
10376 #if defined(__clang__)
10377 #pragma clang diagnostic pop
10378 #endif
10379
10380 // end catch_console_colour.cpp
10381 // start catch_context.cpp
10382
10383 namespace Catch {
10384
10385 class Context : public IMutableContext, NonCopyable {
10386
10387 public: // IContext
10388   IResultCapture* getResultCapture() override { return m_resultCapture; }
10389   IRunner* getRunner() override { return m_runner; }
10390
10391   IConfigPtr const& getConfig() const override { return m_config; }
10392
10393   ~Context() override;
10394
10395 public: // IMutableContext
10396   void setResultCapture(IResultCapture* resultCapture) override { m_resultCapture = resultCapture; }
10397   void setRunner(IRunner* runner) override { m_runner = runner; }
10398   void setConfig(IConfigPtr const& config) override { m_config = config; }
10399
10400   friend IMutableContext& getCurrentMutableContext();
10401
10402 private:
10403   IConfigPtr m_config;
10404   IRunner* m_runner               = nullptr;
10405   IResultCapture* m_resultCapture = nullptr;
10406 };
10407
10408 IMutableContext* IMutableContext::currentContext = nullptr;
10409
10410 void IMutableContext::createContext()
10411 {
10412   currentContext = new Context();
10413 }
10414
10415 void cleanUpContext()
10416 {
10417   delete IMutableContext::currentContext;
10418   IMutableContext::currentContext = nullptr;
10419 }
10420 IContext::~IContext()               = default;
10421 IMutableContext::~IMutableContext() = default;
10422 Context::~Context()                 = default;
10423
10424 SimplePcg32& rng()
10425 {
10426   static SimplePcg32 s_rng;
10427   return s_rng;
10428 }
10429
10430 } // namespace Catch
10431 // end catch_context.cpp
10432 // start catch_debug_console.cpp
10433
10434 // start catch_debug_console.h
10435
10436 #include <string>
10437
10438 namespace Catch {
10439 void writeToDebugConsole(std::string const& text);
10440 }
10441
10442 // end catch_debug_console.h
10443 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
10444 #include <android/log.h>
10445
10446 namespace Catch {
10447 void writeToDebugConsole(std::string const& text)
10448 {
10449   __android_log_write(ANDROID_LOG_DEBUG, "Catch", text.c_str());
10450 }
10451 } // namespace Catch
10452
10453 #elif defined(CATCH_PLATFORM_WINDOWS)
10454
10455 namespace Catch {
10456 void writeToDebugConsole(std::string const& text)
10457 {
10458   ::OutputDebugStringA(text.c_str());
10459 }
10460 } // namespace Catch
10461
10462 #else
10463
10464 namespace Catch {
10465 void writeToDebugConsole(std::string const& text)
10466 {
10467   // !TBD: Need a version for Mac/ XCode and other IDEs
10468   Catch::cout() << text;
10469 }
10470 } // namespace Catch
10471
10472 #endif // Platform
10473 // end catch_debug_console.cpp
10474 // start catch_debugger.cpp
10475
10476 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10477
10478 #include <cassert>
10479 #include <cstddef>
10480 #include <ostream>
10481 #include <sys/types.h>
10482 #include <unistd.h>
10483
10484 #ifdef __apple_build_version__
10485 // These headers will only compile with AppleClang (XCode)
10486 // For other compilers (Clang, GCC, ... ) we need to exclude them
10487 #include <sys/sysctl.h>
10488 #endif
10489
10490 namespace Catch {
10491 #ifdef __apple_build_version__
10492 // The following function is taken directly from the following technical note:
10493 // https://developer.apple.com/library/archive/qa/qa1361/_index.html
10494
10495 // Returns true if the current process is being debugged (either
10496 // running under the debugger or has a debugger attached post facto).
10497 bool isDebuggerActive()
10498 {
10499   int mib[4];
10500   struct kinfo_proc info;
10501   std::size_t size;
10502
10503   // Initialize the flags so that, if sysctl fails for some bizarre
10504   // reason, we get a predictable result.
10505
10506   info.kp_proc.p_flag = 0;
10507
10508   // Initialize mib, which tells sysctl the info we want, in this case
10509   // we're looking for information about a specific process ID.
10510
10511   mib[0] = CTL_KERN;
10512   mib[1] = KERN_PROC;
10513   mib[2] = KERN_PROC_PID;
10514   mib[3] = getpid();
10515
10516   // Call sysctl.
10517
10518   size = sizeof(info);
10519   if (sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0) {
10520     Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
10521     return false;
10522   }
10523
10524   // We're being debugged if the P_TRACED flag is set.
10525
10526   return ((info.kp_proc.p_flag & P_TRACED) != 0);
10527 }
10528 #else
10529 bool isDebuggerActive()
10530 {
10531   // We need to find another way to determine this for non-appleclang compilers on macOS
10532   return false;
10533 }
10534 #endif
10535 } // namespace Catch
10536
10537 #elif defined(CATCH_PLATFORM_LINUX)
10538 #include <fstream>
10539 #include <string>
10540
10541 namespace Catch {
10542 // The standard POSIX way of detecting a debugger is to attempt to
10543 // ptrace() the process, but this needs to be done from a child and not
10544 // this process itself to still allow attaching to this process later
10545 // if wanted, so is rather heavy. Under Linux we have the PID of the
10546 // "debugger" (which doesn't need to be gdb, of course, it could also
10547 // be strace, for example) in /proc/$PID/status, so just get it from
10548 // there instead.
10549 bool isDebuggerActive()
10550 {
10551   // Libstdc++ has a bug, where std::ifstream sets errno to 0
10552   // This way our users can properly assert over errno values
10553   ErrnoGuard guard;
10554   std::ifstream in("/proc/self/status");
10555   for (std::string line; std::getline(in, line);) {
10556     static const int PREFIX_LEN = 11;
10557     if (line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
10558       // We're traced if the PID is not 0 and no other PID starts
10559       // with 0 digit, so it's enough to check for just a single
10560       // character.
10561       return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
10562     }
10563   }
10564
10565   return false;
10566 }
10567 } // namespace Catch
10568 #elif defined(_MSC_VER)
10569 extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10570 namespace Catch {
10571 bool isDebuggerActive()
10572 {
10573   return IsDebuggerPresent() != 0;
10574 }
10575 } // namespace Catch
10576 #elif defined(__MINGW32__)
10577 extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10578 namespace Catch {
10579 bool isDebuggerActive()
10580 {
10581   return IsDebuggerPresent() != 0;
10582 }
10583 } // namespace Catch
10584 #else
10585 namespace Catch {
10586 bool isDebuggerActive()
10587 {
10588   return false;
10589 }
10590 } // namespace Catch
10591 #endif // Platform
10592 // end catch_debugger.cpp
10593 // start catch_decomposer.cpp
10594
10595 namespace Catch {
10596
10597 ITransientExpression::~ITransientExpression() = default;
10598
10599 void formatReconstructedExpression(std::ostream& os, std::string const& lhs, StringRef op, std::string const& rhs)
10600 {
10601   if (lhs.size() + rhs.size() < 40 && lhs.find('\n') == std::string::npos && rhs.find('\n') == std::string::npos)
10602     os << lhs << " " << op << " " << rhs;
10603   else
10604     os << lhs << "\n" << op << "\n" << rhs;
10605 }
10606 } // namespace Catch
10607 // end catch_decomposer.cpp
10608 // start catch_enforce.cpp
10609
10610 #include <stdexcept>
10611
10612 namespace Catch {
10613 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
10614 [[noreturn]] void throw_exception(std::exception const& e)
10615 {
10616   Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
10617                 << "The message was: " << e.what() << '\n';
10618   std::terminate();
10619 }
10620 #endif
10621
10622 [[noreturn]] void throw_logic_error(std::string const& msg)
10623 {
10624   throw_exception(std::logic_error(msg));
10625 }
10626
10627 [[noreturn]] void throw_domain_error(std::string const& msg)
10628 {
10629   throw_exception(std::domain_error(msg));
10630 }
10631
10632 [[noreturn]] void throw_runtime_error(std::string const& msg)
10633 {
10634   throw_exception(std::runtime_error(msg));
10635 }
10636
10637 } // namespace Catch
10638 // end catch_enforce.cpp
10639 // start catch_enum_values_registry.cpp
10640 // start catch_enum_values_registry.h
10641
10642 #include <memory>
10643 #include <vector>
10644
10645 namespace Catch {
10646
10647 namespace Detail {
10648
10649 std::unique_ptr<EnumInfo> makeEnumInfo(StringRef enumName, StringRef allValueNames, std::vector<int> const& values);
10650
10651 class EnumValuesRegistry : public IMutableEnumValuesRegistry {
10652
10653   std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
10654
10655   EnumInfo const& registerEnum(StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
10656 };
10657
10658 std::vector<StringRef> parseEnums(StringRef enums);
10659
10660 } // namespace Detail
10661
10662 } // namespace Catch
10663
10664 // end catch_enum_values_registry.h
10665
10666 #include <cassert>
10667 #include <map>
10668
10669 namespace Catch {
10670
10671 IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
10672
10673 namespace Detail {
10674
10675 namespace {
10676 // Extracts the actual name part of an enum instance
10677 // In other words, it returns the Blue part of Bikeshed::Colour::Blue
10678 StringRef extractInstanceName(StringRef enumInstance)
10679 {
10680   // Find last occurrence of ":"
10681   size_t name_start = enumInstance.size();
10682   while (name_start > 0 && enumInstance[name_start - 1] != ':') {
10683     --name_start;
10684   }
10685   return enumInstance.substr(name_start, enumInstance.size() - name_start);
10686 }
10687 } // namespace
10688
10689 std::vector<StringRef> parseEnums(StringRef enums)
10690 {
10691   auto enumValues = splitStringRef(enums, ',');
10692   std::vector<StringRef> parsed;
10693   parsed.reserve(enumValues.size());
10694   for (auto const& enumValue : enumValues) {
10695     parsed.push_back(trim(extractInstanceName(enumValue)));
10696   }
10697   return parsed;
10698 }
10699
10700 EnumInfo::~EnumInfo() {}
10701
10702 StringRef EnumInfo::lookup(int value) const
10703 {
10704   for (auto const& valueToName : m_values) {
10705     if (valueToName.first == value)
10706       return valueToName.second;
10707   }
10708   return "{** unexpected enum value **}"_sr;
10709 }
10710
10711 std::unique_ptr<EnumInfo> makeEnumInfo(StringRef enumName, StringRef allValueNames, std::vector<int> const& values)
10712 {
10713   std::unique_ptr<EnumInfo> enumInfo(new EnumInfo);
10714   enumInfo->m_name = enumName;
10715   enumInfo->m_values.reserve(values.size());
10716
10717   const auto valueNames = Catch::Detail::parseEnums(allValueNames);
10718   assert(valueNames.size() == values.size());
10719   std::size_t i = 0;
10720   for (auto value : values)
10721     enumInfo->m_values.emplace_back(value, valueNames[i++]);
10722
10723   return enumInfo;
10724 }
10725
10726 EnumInfo const& EnumValuesRegistry::registerEnum(StringRef enumName, StringRef allValueNames,
10727                                                  std::vector<int> const& values)
10728 {
10729   m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
10730   return *m_enumInfos.back();
10731 }
10732
10733 } // namespace Detail
10734 } // namespace Catch
10735
10736 // end catch_enum_values_registry.cpp
10737 // start catch_errno_guard.cpp
10738
10739 #include <cerrno>
10740
10741 namespace Catch {
10742 ErrnoGuard::ErrnoGuard() : m_oldErrno(errno) {}
10743 ErrnoGuard::~ErrnoGuard()
10744 {
10745   errno = m_oldErrno;
10746 }
10747 } // namespace Catch
10748 // end catch_errno_guard.cpp
10749 // start catch_exception_translator_registry.cpp
10750
10751 // start catch_exception_translator_registry.h
10752
10753 #include <memory>
10754 #include <string>
10755 #include <vector>
10756
10757 namespace Catch {
10758
10759 class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
10760 public:
10761   ~ExceptionTranslatorRegistry();
10762   virtual void registerTranslator(const IExceptionTranslator* translator);
10763   std::string translateActiveException() const override;
10764   std::string tryTranslators() const;
10765
10766 private:
10767   std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
10768 };
10769 } // namespace Catch
10770
10771 // end catch_exception_translator_registry.h
10772 #ifdef __OBJC__
10773 #import "Foundation/Foundation.h"
10774 #endif
10775
10776 namespace Catch {
10777
10778 ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {}
10779
10780 void ExceptionTranslatorRegistry::registerTranslator(const IExceptionTranslator* translator)
10781 {
10782   m_translators.push_back(std::unique_ptr<const IExceptionTranslator>(translator));
10783 }
10784
10785 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10786 std::string ExceptionTranslatorRegistry::translateActiveException() const
10787 {
10788   try {
10789 #ifdef __OBJC__
10790     // In Objective-C try objective-c exceptions first
10791     @try {
10792       return tryTranslators();
10793     } @catch (NSException* exception) {
10794       return Catch::Detail::stringify([exception description]);
10795     }
10796 #else
10797     // Compiling a mixed mode project with MSVC means that CLR
10798     // exceptions will be caught in (...) as well. However, these
10799     // do not fill-in std::current_exception and thus lead to crash
10800     // when attempting rethrow.
10801     // /EHa switch also causes structured exceptions to be caught
10802     // here, but they fill-in current_exception properly, so
10803     // at worst the output should be a little weird, instead of
10804     // causing a crash.
10805     if (std::current_exception() == nullptr) {
10806       return "Non C++ exception. Possibly a CLR exception.";
10807     }
10808     return tryTranslators();
10809 #endif
10810   } catch (TestFailureException&) {
10811     std::rethrow_exception(std::current_exception());
10812   } catch (std::exception& ex) {
10813     return ex.what();
10814   } catch (std::string& msg) {
10815     return msg;
10816   } catch (const char* msg) {
10817     return msg;
10818   } catch (...) {
10819     return "Unknown exception";
10820   }
10821 }
10822
10823 std::string ExceptionTranslatorRegistry::tryTranslators() const
10824 {
10825   if (m_translators.empty()) {
10826     std::rethrow_exception(std::current_exception());
10827   } else {
10828     return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
10829   }
10830 }
10831
10832 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
10833 std::string ExceptionTranslatorRegistry::translateActiveException() const
10834 {
10835   CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10836 }
10837
10838 std::string ExceptionTranslatorRegistry::tryTranslators() const
10839 {
10840   CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10841 }
10842 #endif
10843
10844 } // namespace Catch
10845 // end catch_exception_translator_registry.cpp
10846 // start catch_fatal_condition.cpp
10847
10848 #include <algorithm>
10849
10850 #if !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
10851
10852 namespace Catch {
10853
10854 // If neither SEH nor signal handling is required, the handler impls
10855 // do not have to do anything, and can be empty.
10856 FatalConditionHandler::engage_platform() {}
10857 FatalConditionHandler::disengage_platform() {}
10858 FatalConditionHandler::FatalConditionHandler()  = default;
10859 FatalConditionHandler::~FatalConditionHandler() = default;
10860
10861 } // end namespace Catch
10862
10863 #endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
10864
10865 #if defined(CATCH_CONFIG_WINDOWS_SEH) && defined(CATCH_CONFIG_POSIX_SIGNALS)
10866 #error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
10867 #endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
10868
10869 #if defined(CATCH_CONFIG_WINDOWS_SEH) || defined(CATCH_CONFIG_POSIX_SIGNALS)
10870
10871 namespace {
10872 //! Signals fatal error message to the run context
10873 void reportFatal(char const* const message)
10874 {
10875   Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition(message);
10876 }
10877
10878 //! Minimal size Catch2 needs for its own fatal error handling.
10879 //! Picked anecdotally, so it might not be sufficient on all
10880 //! platforms, and for all configurations.
10881 constexpr std::size_t minStackSizeForErrors = 32 * 1024;
10882 } // end unnamed namespace
10883
10884 #endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
10885
10886 #if defined(CATCH_CONFIG_WINDOWS_SEH)
10887
10888 namespace Catch {
10889
10890 struct SignalDefs {
10891   DWORD id;
10892   const char* name;
10893 };
10894
10895 // There is no 1-1 mapping between signals and windows exceptions.
10896 // Windows can easily distinguish between SO and SigSegV,
10897 // but SigInt, SigTerm, etc are handled differently.
10898 static SignalDefs signalDefs[] = {
10899     {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal"},
10900     {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
10901     {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal"},
10902     {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
10903 };
10904
10905 static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo)
10906 {
10907   for (auto const& def : signalDefs) {
10908     if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
10909       reportFatal(def.name);
10910     }
10911   }
10912   // If its not an exception we care about, pass it along.
10913   // This stops us from eating debugger breaks etc.
10914   return EXCEPTION_CONTINUE_SEARCH;
10915 }
10916
10917 // Since we do not support multiple instantiations, we put these
10918 // into global variables and rely on cleaning them up in outlined
10919 // constructors/destructors
10920 static PVOID exceptionHandlerHandle = nullptr;
10921
10922 // For MSVC, we reserve part of the stack memory for handling
10923 // memory overflow structured exception.
10924 FatalConditionHandler::FatalConditionHandler()
10925 {
10926   ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);
10927   if (!SetThreadStackGuarantee(&guaranteeSize)) {
10928     // We do not want to fully error out, because needing
10929     // the stack reserve should be rare enough anyway.
10930     Catch::cerr() << "Failed to reserve piece of stack."
10931                   << " Stack overflows will not be reported successfully.";
10932   }
10933 }
10934
10935 // We do not attempt to unset the stack guarantee, because
10936 // Windows does not support lowering the stack size guarantee.
10937 FatalConditionHandler::~FatalConditionHandler() = default;
10938
10939 void FatalConditionHandler::engage_platform()
10940 {
10941   // Register as first handler in current chain
10942   exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
10943   if (!exceptionHandlerHandle) {
10944     CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
10945   }
10946 }
10947
10948 void FatalConditionHandler::disengage_platform()
10949 {
10950   if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
10951     CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
10952   }
10953   exceptionHandlerHandle = nullptr;
10954 }
10955
10956 } // end namespace Catch
10957
10958 #endif // CATCH_CONFIG_WINDOWS_SEH
10959
10960 #if defined(CATCH_CONFIG_POSIX_SIGNALS)
10961
10962 #include <signal.h>
10963
10964 namespace Catch {
10965
10966 struct SignalDefs {
10967   int id;
10968   const char* name;
10969 };
10970
10971 static SignalDefs signalDefs[] = {
10972     {SIGINT, "SIGINT - Terminal interrupt signal"},    {SIGILL, "SIGILL - Illegal instruction signal"},
10973     {SIGFPE, "SIGFPE - Floating point error signal"},  {SIGSEGV, "SIGSEGV - Segmentation violation signal"},
10974     {SIGTERM, "SIGTERM - Termination request signal"}, {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
10975
10976 // Older GCCs trigger -Wmissing-field-initializers for T foo = {}
10977 // which is zero initialization, but not explicit. We want to avoid
10978 // that.
10979 #if defined(__GNUC__)
10980 #pragma GCC diagnostic push
10981 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
10982 #endif
10983
10984 static char* altStackMem        = nullptr;
10985 static std::size_t altStackSize = 0;
10986 static stack_t oldSigStack{};
10987 static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
10988
10989 static void restorePreviousSignalHandlers()
10990 {
10991   // We set signal handlers back to the previous ones. Hopefully
10992   // nobody overwrote them in the meantime, and doesn't expect
10993   // their signal handlers to live past ours given that they
10994   // installed them after ours..
10995   for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
10996     sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
10997   }
10998   // Return the old stack
10999   sigaltstack(&oldSigStack, nullptr);
11000 }
11001
11002 static void handleSignal(int sig)
11003 {
11004   char const* name = "<unknown signal>";
11005   for (auto const& def : signalDefs) {
11006     if (sig == def.id) {
11007       name = def.name;
11008       break;
11009     }
11010   }
11011   // We need to restore previous signal handlers and let them do
11012   // their thing, so that the users can have the debugger break
11013   // when a signal is raised, and so on.
11014   restorePreviousSignalHandlers();
11015   reportFatal(name);
11016   raise(sig);
11017 }
11018
11019 FatalConditionHandler::FatalConditionHandler()
11020 {
11021   assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
11022   if (altStackSize == 0) {
11023     altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);
11024   }
11025   altStackMem = new char[altStackSize]();
11026 }
11027
11028 FatalConditionHandler::~FatalConditionHandler()
11029 {
11030   delete[] altStackMem;
11031   // We signal that another instance can be constructed by zeroing
11032   // out the pointer.
11033   altStackMem = nullptr;
11034 }
11035
11036 void FatalConditionHandler::engage_platform()
11037 {
11038   stack_t sigStack;
11039   sigStack.ss_sp    = altStackMem;
11040   sigStack.ss_size  = altStackSize;
11041   sigStack.ss_flags = 0;
11042   sigaltstack(&sigStack, &oldSigStack);
11043   struct sigaction sa = {};
11044
11045   sa.sa_handler = handleSignal;
11046   sa.sa_flags   = SA_ONSTACK;
11047   for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
11048     sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
11049   }
11050 }
11051
11052 #if defined(__GNUC__)
11053 #pragma GCC diagnostic pop
11054 #endif
11055
11056 void FatalConditionHandler::disengage_platform()
11057 {
11058   restorePreviousSignalHandlers();
11059 }
11060
11061 } // end namespace Catch
11062
11063 #endif // CATCH_CONFIG_POSIX_SIGNALS
11064 // end catch_fatal_condition.cpp
11065 // start catch_generators.cpp
11066
11067 #include <limits>
11068 #include <set>
11069
11070 namespace Catch {
11071
11072 IGeneratorTracker::~IGeneratorTracker() {}
11073
11074 const char* GeneratorException::what() const noexcept
11075 {
11076   return m_msg;
11077 }
11078
11079 namespace Generators {
11080
11081 GeneratorUntypedBase::~GeneratorUntypedBase() {}
11082
11083 auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo) -> IGeneratorTracker&
11084 {
11085   return getResultCapture().acquireGeneratorTracker(generatorName, lineInfo);
11086 }
11087
11088 } // namespace Generators
11089 } // namespace Catch
11090 // end catch_generators.cpp
11091 // start catch_interfaces_capture.cpp
11092
11093 namespace Catch {
11094 IResultCapture::~IResultCapture() = default;
11095 }
11096 // end catch_interfaces_capture.cpp
11097 // start catch_interfaces_config.cpp
11098
11099 namespace Catch {
11100 IConfig::~IConfig() = default;
11101 }
11102 // end catch_interfaces_config.cpp
11103 // start catch_interfaces_exception.cpp
11104
11105 namespace Catch {
11106 IExceptionTranslator::~IExceptionTranslator()                 = default;
11107 IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
11108 } // namespace Catch
11109 // end catch_interfaces_exception.cpp
11110 // start catch_interfaces_registry_hub.cpp
11111
11112 namespace Catch {
11113 IRegistryHub::~IRegistryHub()               = default;
11114 IMutableRegistryHub::~IMutableRegistryHub() = default;
11115 } // namespace Catch
11116 // end catch_interfaces_registry_hub.cpp
11117 // start catch_interfaces_reporter.cpp
11118
11119 // start catch_reporter_listening.h
11120
11121 namespace Catch {
11122
11123 class ListeningReporter : public IStreamingReporter {
11124   using Reporters = std::vector<IStreamingReporterPtr>;
11125   Reporters m_listeners;
11126   IStreamingReporterPtr m_reporter = nullptr;
11127   ReporterPreferences m_preferences;
11128
11129 public:
11130   ListeningReporter();
11131
11132   void addListener(IStreamingReporterPtr&& listener);
11133   void addReporter(IStreamingReporterPtr&& reporter);
11134
11135 public: // IStreamingReporter
11136   ReporterPreferences getPreferences() const override;
11137
11138   void noMatchingTestCases(std::string const& spec) override;
11139
11140   void reportInvalidArguments(std::string const& arg) override;
11141
11142   static std::set<Verbosity> getSupportedVerbosities();
11143
11144 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
11145   void benchmarkPreparing(std::string const& name) override;
11146   void benchmarkStarting(BenchmarkInfo const& benchmarkInfo) override;
11147   void benchmarkEnded(BenchmarkStats<> const& benchmarkStats) override;
11148   void benchmarkFailed(std::string const&) override;
11149 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
11150
11151   void testRunStarting(TestRunInfo const& testRunInfo) override;
11152   void testGroupStarting(GroupInfo const& groupInfo) override;
11153   void testCaseStarting(TestCaseInfo const& testInfo) override;
11154   void sectionStarting(SectionInfo const& sectionInfo) override;
11155   void assertionStarting(AssertionInfo const& assertionInfo) override;
11156
11157   // The return value indicates if the messages buffer should be cleared:
11158   bool assertionEnded(AssertionStats const& assertionStats) override;
11159   void sectionEnded(SectionStats const& sectionStats) override;
11160   void testCaseEnded(TestCaseStats const& testCaseStats) override;
11161   void testGroupEnded(TestGroupStats const& testGroupStats) override;
11162   void testRunEnded(TestRunStats const& testRunStats) override;
11163
11164   void skipTest(TestCaseInfo const& testInfo) override;
11165   bool isMulti() const override;
11166 };
11167
11168 } // end namespace Catch
11169
11170 // end catch_reporter_listening.h
11171 namespace Catch {
11172
11173 ReporterConfig::ReporterConfig(IConfigPtr const& _fullConfig)
11174     : m_stream(&_fullConfig->stream()), m_fullConfig(_fullConfig)
11175 {
11176 }
11177
11178 ReporterConfig::ReporterConfig(IConfigPtr const& _fullConfig, std::ostream& _stream)
11179     : m_stream(&_stream), m_fullConfig(_fullConfig)
11180 {
11181 }
11182
11183 std::ostream& ReporterConfig::stream() const
11184 {
11185   return *m_stream;
11186 }
11187 IConfigPtr ReporterConfig::fullConfig() const
11188 {
11189   return m_fullConfig;
11190 }
11191
11192 TestRunInfo::TestRunInfo(std::string const& _name) : name(_name) {}
11193
11194 GroupInfo::GroupInfo(std::string const& _name, std::size_t _groupIndex, std::size_t _groupsCount)
11195     : name(_name), groupIndex(_groupIndex), groupsCounts(_groupsCount)
11196 {
11197 }
11198
11199 AssertionStats::AssertionStats(AssertionResult const& _assertionResult, std::vector<MessageInfo> const& _infoMessages,
11200                                Totals const& _totals)
11201     : assertionResult(_assertionResult), infoMessages(_infoMessages), totals(_totals)
11202 {
11203   assertionResult.m_resultData.lazyExpression.m_transientExpression =
11204       _assertionResult.m_resultData.lazyExpression.m_transientExpression;
11205
11206   if (assertionResult.hasMessage()) {
11207     // Copy message into messages list.
11208     // !TBD This should have been done earlier, somewhere
11209     MessageBuilder builder(assertionResult.getTestMacroName(), assertionResult.getSourceInfo(),
11210                            assertionResult.getResultType());
11211     builder << assertionResult.getMessage();
11212     builder.m_info.message = builder.m_stream.str();
11213
11214     infoMessages.push_back(builder.m_info);
11215   }
11216 }
11217
11218 AssertionStats::~AssertionStats() = default;
11219
11220 SectionStats::SectionStats(SectionInfo const& _sectionInfo, Counts const& _assertions, double _durationInSeconds,
11221                            bool _missingAssertions)
11222     : sectionInfo(_sectionInfo)
11223     , assertions(_assertions)
11224     , durationInSeconds(_durationInSeconds)
11225     , missingAssertions(_missingAssertions)
11226 {
11227 }
11228
11229 SectionStats::~SectionStats() = default;
11230
11231 TestCaseStats::TestCaseStats(TestCaseInfo const& _testInfo, Totals const& _totals, std::string const& _stdOut,
11232                              std::string const& _stdErr, bool _aborting)
11233     : testInfo(_testInfo), totals(_totals), stdOut(_stdOut), stdErr(_stdErr), aborting(_aborting)
11234 {
11235 }
11236
11237 TestCaseStats::~TestCaseStats() = default;
11238
11239 TestGroupStats::TestGroupStats(GroupInfo const& _groupInfo, Totals const& _totals, bool _aborting)
11240     : groupInfo(_groupInfo), totals(_totals), aborting(_aborting)
11241 {
11242 }
11243
11244 TestGroupStats::TestGroupStats(GroupInfo const& _groupInfo) : groupInfo(_groupInfo), aborting(false) {}
11245
11246 TestGroupStats::~TestGroupStats() = default;
11247
11248 TestRunStats::TestRunStats(TestRunInfo const& _runInfo, Totals const& _totals, bool _aborting)
11249     : runInfo(_runInfo), totals(_totals), aborting(_aborting)
11250 {
11251 }
11252
11253 TestRunStats::~TestRunStats() = default;
11254
11255 void IStreamingReporter::fatalErrorEncountered(StringRef) {}
11256 bool IStreamingReporter::isMulti() const
11257 {
11258   return false;
11259 }
11260
11261 IReporterFactory::~IReporterFactory()   = default;
11262 IReporterRegistry::~IReporterRegistry() = default;
11263
11264 } // end namespace Catch
11265 // end catch_interfaces_reporter.cpp
11266 // start catch_interfaces_runner.cpp
11267
11268 namespace Catch {
11269 IRunner::~IRunner() = default;
11270 }
11271 // end catch_interfaces_runner.cpp
11272 // start catch_interfaces_testcase.cpp
11273
11274 namespace Catch {
11275 ITestInvoker::~ITestInvoker()           = default;
11276 ITestCaseRegistry::~ITestCaseRegistry() = default;
11277 } // namespace Catch
11278 // end catch_interfaces_testcase.cpp
11279 // start catch_leak_detector.cpp
11280
11281 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
11282 #include <crtdbg.h>
11283
11284 namespace Catch {
11285
11286 LeakDetector::LeakDetector()
11287 {
11288   int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
11289   flag |= _CRTDBG_LEAK_CHECK_DF;
11290   flag |= _CRTDBG_ALLOC_MEM_DF;
11291   _CrtSetDbgFlag(flag);
11292   _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
11293   _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
11294   // Change this to leaking allocation's number to break there
11295   _CrtSetBreakAlloc(-1);
11296 }
11297 } // namespace Catch
11298
11299 #else
11300
11301 Catch::LeakDetector::LeakDetector() {}
11302
11303 #endif
11304
11305 Catch::LeakDetector::~LeakDetector()
11306 {
11307   Catch::cleanUp();
11308 }
11309 // end catch_leak_detector.cpp
11310 // start catch_list.cpp
11311
11312 // start catch_list.h
11313
11314 #include <set>
11315
11316 namespace Catch {
11317
11318 std::size_t listTests(Config const& config);
11319
11320 std::size_t listTestsNamesOnly(Config const& config);
11321
11322 struct TagInfo {
11323   void add(std::string const& spelling);
11324   std::string all() const;
11325
11326   std::set<std::string> spellings;
11327   std::size_t count = 0;
11328 };
11329
11330 std::size_t listTags(Config const& config);
11331
11332 std::size_t listReporters();
11333
11334 Option<std::size_t> list(std::shared_ptr<Config> const& config);
11335
11336 } // end namespace Catch
11337
11338 // end catch_list.h
11339 // start catch_text.h
11340
11341 namespace Catch {
11342 using namespace clara::TextFlow;
11343 }
11344
11345 // end catch_text.h
11346 #include <algorithm>
11347 #include <iomanip>
11348 #include <limits>
11349
11350 namespace Catch {
11351
11352 std::size_t listTests(Config const& config)
11353 {
11354   TestSpec const& testSpec = config.testSpec();
11355   if (config.hasTestFilters())
11356     Catch::cout() << "Matching test cases:\n";
11357   else {
11358     Catch::cout() << "All available test cases:\n";
11359   }
11360
11361   auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
11362   for (auto const& testCaseInfo : matchedTestCases) {
11363     Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None;
11364     Colour colourGuard(colour);
11365
11366     Catch::cout() << Column(testCaseInfo.name).initialIndent(2).indent(4) << "\n";
11367     if (config.verbosity() >= Verbosity::High) {
11368       Catch::cout() << Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl;
11369       std::string description = testCaseInfo.description;
11370       if (description.empty())
11371         description = "(NO DESCRIPTION)";
11372       Catch::cout() << Column(description).indent(4) << std::endl;
11373     }
11374     if (!testCaseInfo.tags.empty())
11375       Catch::cout() << Column(testCaseInfo.tagsAsString()).indent(6) << "\n";
11376   }
11377
11378   if (!config.hasTestFilters())
11379     Catch::cout() << pluralise(matchedTestCases.size(), "test case") << '\n' << std::endl;
11380   else
11381     Catch::cout() << pluralise(matchedTestCases.size(), "matching test case") << '\n' << std::endl;
11382   return matchedTestCases.size();
11383 }
11384
11385 std::size_t listTestsNamesOnly(Config const& config)
11386 {
11387   TestSpec const& testSpec               = config.testSpec();
11388   std::size_t matchedTests               = 0;
11389   std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
11390   for (auto const& testCaseInfo : matchedTestCases) {
11391     matchedTests++;
11392     if (startsWith(testCaseInfo.name, '#'))
11393       Catch::cout() << '"' << testCaseInfo.name << '"';
11394     else
11395       Catch::cout() << testCaseInfo.name;
11396     if (config.verbosity() >= Verbosity::High)
11397       Catch::cout() << "\t@" << testCaseInfo.lineInfo;
11398     Catch::cout() << std::endl;
11399   }
11400   return matchedTests;
11401 }
11402
11403 void TagInfo::add(std::string const& spelling)
11404 {
11405   ++count;
11406   spellings.insert(spelling);
11407 }
11408
11409 std::string TagInfo::all() const
11410 {
11411   size_t size = 0;
11412   for (auto const& spelling : spellings) {
11413     // Add 2 for the brackes
11414     size += spelling.size() + 2;
11415   }
11416
11417   std::string out;
11418   out.reserve(size);
11419   for (auto const& spelling : spellings) {
11420     out += '[';
11421     out += spelling;
11422     out += ']';
11423   }
11424   return out;
11425 }
11426
11427 std::size_t listTags(Config const& config)
11428 {
11429   TestSpec const& testSpec = config.testSpec();
11430   if (config.hasTestFilters())
11431     Catch::cout() << "Tags for matching test cases:\n";
11432   else {
11433     Catch::cout() << "All available tags:\n";
11434   }
11435
11436   std::map<std::string, TagInfo> tagCounts;
11437
11438   std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
11439   for (auto const& testCase : matchedTestCases) {
11440     for (auto const& tagName : testCase.getTestCaseInfo().tags) {
11441       std::string lcaseTagName = toLower(tagName);
11442       auto countIt             = tagCounts.find(lcaseTagName);
11443       if (countIt == tagCounts.end())
11444         countIt = tagCounts.insert(std::make_pair(lcaseTagName, TagInfo())).first;
11445       countIt->second.add(tagName);
11446     }
11447   }
11448
11449   for (auto const& tagCount : tagCounts) {
11450     ReusableStringStream rss;
11451     rss << "  " << std::setw(2) << tagCount.second.count << "  ";
11452     auto str = rss.str();
11453     auto wrapper =
11454         Column(tagCount.second.all()).initialIndent(0).indent(str.size()).width(CATCH_CONFIG_CONSOLE_WIDTH - 10);
11455     Catch::cout() << str << wrapper << '\n';
11456   }
11457   Catch::cout() << pluralise(tagCounts.size(), "tag") << '\n' << std::endl;
11458   return tagCounts.size();
11459 }
11460
11461 std::size_t listReporters()
11462 {
11463   Catch::cout() << "Available reporters:\n";
11464   IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
11465   std::size_t maxNameLen                         = 0;
11466   for (auto const& factoryKvp : factories)
11467     maxNameLen = (std::max)(maxNameLen, factoryKvp.first.size());
11468
11469   for (auto const& factoryKvp : factories) {
11470     Catch::cout() << Column(factoryKvp.first + ":").indent(2).width(5 + maxNameLen) +
11471                          Column(factoryKvp.second->getDescription())
11472                              .initialIndent(0)
11473                              .indent(2)
11474                              .width(CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8)
11475                   << "\n";
11476   }
11477   Catch::cout() << std::endl;
11478   return factories.size();
11479 }
11480
11481 Option<std::size_t> list(std::shared_ptr<Config> const& config)
11482 {
11483   Option<std::size_t> listedCount;
11484   getCurrentMutableContext().setConfig(config);
11485   if (config->listTests())
11486     listedCount = listedCount.valueOr(0) + listTests(*config);
11487   if (config->listTestNamesOnly())
11488     listedCount = listedCount.valueOr(0) + listTestsNamesOnly(*config);
11489   if (config->listTags())
11490     listedCount = listedCount.valueOr(0) + listTags(*config);
11491   if (config->listReporters())
11492     listedCount = listedCount.valueOr(0) + listReporters();
11493   return listedCount;
11494 }
11495
11496 } // end namespace Catch
11497 // end catch_list.cpp
11498 // start catch_matchers.cpp
11499
11500 namespace Catch {
11501 namespace Matchers {
11502 namespace Impl {
11503
11504 std::string MatcherUntypedBase::toString() const
11505 {
11506   if (m_cachedToString.empty())
11507     m_cachedToString = describe();
11508   return m_cachedToString;
11509 }
11510
11511 MatcherUntypedBase::~MatcherUntypedBase() = default;
11512
11513 } // namespace Impl
11514 } // namespace Matchers
11515
11516 using namespace Matchers;
11517 using Matchers::Impl::MatcherBase;
11518
11519 } // namespace Catch
11520 // end catch_matchers.cpp
11521 // start catch_matchers_exception.cpp
11522
11523 namespace Catch {
11524 namespace Matchers {
11525 namespace Exception {
11526
11527 bool ExceptionMessageMatcher::match(std::exception const& ex) const
11528 {
11529   return ex.what() == m_message;
11530 }
11531
11532 std::string ExceptionMessageMatcher::describe() const
11533 {
11534   return "exception message matches \"" + m_message + "\"";
11535 }
11536
11537 } // namespace Exception
11538 Exception::ExceptionMessageMatcher Message(std::string const& message)
11539 {
11540   return Exception::ExceptionMessageMatcher(message);
11541 }
11542
11543 // namespace Exception
11544 } // namespace Matchers
11545 } // namespace Catch
11546 // end catch_matchers_exception.cpp
11547 // start catch_matchers_floating.cpp
11548
11549 // start catch_polyfills.hpp
11550
11551 namespace Catch {
11552 bool isnan(float f);
11553 bool isnan(double d);
11554 } // namespace Catch
11555
11556 // end catch_polyfills.hpp
11557 // start catch_to_string.hpp
11558
11559 #include <string>
11560
11561 namespace Catch {
11562 template <typename T> std::string to_string(T const& t)
11563 {
11564 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11565   return std::to_string(t);
11566 #else
11567   ReusableStringStream rss;
11568   rss << t;
11569   return rss.str();
11570 #endif
11571 }
11572 } // end namespace Catch
11573
11574 // end catch_to_string.hpp
11575 #include <algorithm>
11576 #include <cmath>
11577 #include <cstdint>
11578 #include <cstdlib>
11579 #include <cstring>
11580 #include <iomanip>
11581 #include <limits>
11582 #include <sstream>
11583 #include <type_traits>
11584
11585 namespace Catch {
11586 namespace {
11587
11588 int32_t convert(float f)
11589 {
11590   static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
11591   int32_t i;
11592   std::memcpy(&i, &f, sizeof(f));
11593   return i;
11594 }
11595
11596 int64_t convert(double d)
11597 {
11598   static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
11599   int64_t i;
11600   std::memcpy(&i, &d, sizeof(d));
11601   return i;
11602 }
11603
11604 template <typename FP> bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff)
11605 {
11606   // Comparison with NaN should always be false.
11607   // This way we can rule it out before getting into the ugly details
11608   if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
11609     return false;
11610   }
11611
11612   auto lc = convert(lhs);
11613   auto rc = convert(rhs);
11614
11615   if ((lc < 0) != (rc < 0)) {
11616     // Potentially we can have +0 and -0
11617     return lhs == rhs;
11618   }
11619
11620   // static cast as a workaround for IBM XLC
11621   auto ulpDiff = std::abs(static_cast<FP>(lc - rc));
11622   return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
11623 }
11624
11625 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11626
11627 float nextafter(float x, float y)
11628 {
11629   return ::nextafterf(x, y);
11630 }
11631
11632 double nextafter(double x, double y)
11633 {
11634   return ::nextafter(x, y);
11635 }
11636
11637 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
11638
11639 template <typename FP> FP step(FP start, FP direction, uint64_t steps)
11640 {
11641   for (uint64_t i = 0; i < steps; ++i) {
11642 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11643     start = Catch::nextafter(start, direction);
11644 #else
11645     start = std::nextafter(start, direction);
11646 #endif
11647   }
11648   return start;
11649 }
11650
11651 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11652 // But without the subtraction to allow for INFINITY in comparison
11653 bool marginComparison(double lhs, double rhs, double margin)
11654 {
11655   return (lhs + margin >= rhs) && (rhs + margin >= lhs);
11656 }
11657
11658 template <typename FloatingPoint> void write(std::ostream& out, FloatingPoint num)
11659 {
11660   out << std::scientific << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1) << num;
11661 }
11662
11663 } // end anonymous namespace
11664
11665 namespace Matchers {
11666 namespace Floating {
11667
11668 enum class FloatingPointKind : uint8_t { Float, Double };
11669
11670 WithinAbsMatcher::WithinAbsMatcher(double target, double margin) : m_target{target}, m_margin{margin}
11671 {
11672   CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.' << " Margin has to be non-negative.");
11673 }
11674
11675 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11676 // But without the subtraction to allow for INFINITY in comparison
11677 bool WithinAbsMatcher::match(double const& matchee) const
11678 {
11679   return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
11680 }
11681
11682 std::string WithinAbsMatcher::describe() const
11683 {
11684   return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
11685 }
11686
11687 WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
11688     : m_target{target}, m_ulps{ulps}, m_type{baseType}
11689 {
11690   CATCH_ENFORCE(m_type == FloatingPointKind::Double || m_ulps < (std::numeric_limits<uint32_t>::max)(),
11691                 "Provided ULP is impossibly large for a float comparison.");
11692 }
11693
11694 #if defined(__clang__)
11695 #pragma clang diagnostic push
11696 // Clang <3.5 reports on the default branch in the switch below
11697 #pragma clang diagnostic ignored "-Wunreachable-code"
11698 #endif
11699
11700 bool WithinUlpsMatcher::match(double const& matchee) const
11701 {
11702   switch (m_type) {
11703     case FloatingPointKind::Float:
11704       return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
11705     case FloatingPointKind::Double:
11706       return almostEqualUlps<double>(matchee, m_target, m_ulps);
11707     default:
11708       CATCH_INTERNAL_ERROR("Unknown FloatingPointKind value");
11709   }
11710 }
11711
11712 #if defined(__clang__)
11713 #pragma clang diagnostic pop
11714 #endif
11715
11716 std::string WithinUlpsMatcher::describe() const
11717 {
11718   std::stringstream ret;
11719
11720   ret << "is within " << m_ulps << " ULPs of ";
11721
11722   if (m_type == FloatingPointKind::Float) {
11723     write(ret, static_cast<float>(m_target));
11724     ret << 'f';
11725   } else {
11726     write(ret, m_target);
11727   }
11728
11729   ret << " ([";
11730   if (m_type == FloatingPointKind::Double) {
11731     write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
11732     ret << ", ";
11733     write(ret, step(m_target, static_cast<double>(INFINITY), m_ulps));
11734   } else {
11735     // We have to cast INFINITY to float because of MinGW, see #1782
11736     write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
11737     ret << ", ";
11738     write(ret, step(static_cast<float>(m_target), static_cast<float>(INFINITY), m_ulps));
11739   }
11740   ret << "])";
11741
11742   return ret.str();
11743 }
11744
11745 WithinRelMatcher::WithinRelMatcher(double target, double epsilon) : m_target(target), m_epsilon(epsilon)
11746 {
11747   CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
11748   CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
11749 }
11750
11751 bool WithinRelMatcher::match(double const& matchee) const
11752 {
11753   const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
11754   return marginComparison(matchee, m_target, std::isinf(relMargin) ? 0 : relMargin);
11755 }
11756
11757 std::string WithinRelMatcher::describe() const
11758 {
11759   Catch::ReusableStringStream sstr;
11760   sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
11761   return sstr.str();
11762 }
11763
11764 } // namespace Floating
11765
11766 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff)
11767 {
11768   return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
11769 }
11770
11771 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff)
11772 {
11773   return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
11774 }
11775
11776 Floating::WithinAbsMatcher WithinAbs(double target, double margin)
11777 {
11778   return Floating::WithinAbsMatcher(target, margin);
11779 }
11780
11781 Floating::WithinRelMatcher WithinRel(double target, double eps)
11782 {
11783   return Floating::WithinRelMatcher(target, eps);
11784 }
11785
11786 Floating::WithinRelMatcher WithinRel(double target)
11787 {
11788   return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
11789 }
11790
11791 Floating::WithinRelMatcher WithinRel(float target, float eps)
11792 {
11793   return Floating::WithinRelMatcher(target, eps);
11794 }
11795
11796 Floating::WithinRelMatcher WithinRel(float target)
11797 {
11798   return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
11799 }
11800
11801 } // namespace Matchers
11802 } // namespace Catch
11803 // end catch_matchers_floating.cpp
11804 // start catch_matchers_generic.cpp
11805
11806 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc)
11807 {
11808   if (desc.empty()) {
11809     return "matches undescribed predicate";
11810   } else {
11811     return "matches predicate: \"" + desc + '"';
11812   }
11813 }
11814 // end catch_matchers_generic.cpp
11815 // start catch_matchers_string.cpp
11816
11817 #include <regex>
11818
11819 namespace Catch {
11820 namespace Matchers {
11821
11822 namespace StdString {
11823
11824 CasedString::CasedString(std::string const& str, CaseSensitive::Choice caseSensitivity)
11825     : m_caseSensitivity(caseSensitivity), m_str(adjustString(str))
11826 {
11827 }
11828 std::string CasedString::adjustString(std::string const& str) const
11829 {
11830   return m_caseSensitivity == CaseSensitive::No ? toLower(str) : str;
11831 }
11832 std::string CasedString::caseSensitivitySuffix() const
11833 {
11834   return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" : std::string();
11835 }
11836
11837 StringMatcherBase::StringMatcherBase(std::string const& operation, CasedString const& comparator)
11838     : m_comparator(comparator), m_operation(operation)
11839 {
11840 }
11841
11842 std::string StringMatcherBase::describe() const
11843 {
11844   std::string description;
11845   description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + m_comparator.caseSensitivitySuffix().size());
11846   description += m_operation;
11847   description += ": \"";
11848   description += m_comparator.m_str;
11849   description += "\"";
11850   description += m_comparator.caseSensitivitySuffix();
11851   return description;
11852 }
11853
11854 EqualsMatcher::EqualsMatcher(CasedString const& comparator) : StringMatcherBase("equals", comparator) {}
11855
11856 bool EqualsMatcher::match(std::string const& source) const
11857 {
11858   return m_comparator.adjustString(source) == m_comparator.m_str;
11859 }
11860
11861 ContainsMatcher::ContainsMatcher(CasedString const& comparator) : StringMatcherBase("contains", comparator) {}
11862
11863 bool ContainsMatcher::match(std::string const& source) const
11864 {
11865   return contains(m_comparator.adjustString(source), m_comparator.m_str);
11866 }
11867
11868 StartsWithMatcher::StartsWithMatcher(CasedString const& comparator) : StringMatcherBase("starts with", comparator) {}
11869
11870 bool StartsWithMatcher::match(std::string const& source) const
11871 {
11872   return startsWith(m_comparator.adjustString(source), m_comparator.m_str);
11873 }
11874
11875 EndsWithMatcher::EndsWithMatcher(CasedString const& comparator) : StringMatcherBase("ends with", comparator) {}
11876
11877 bool EndsWithMatcher::match(std::string const& source) const
11878 {
11879   return endsWith(m_comparator.adjustString(source), m_comparator.m_str);
11880 }
11881
11882 RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity)
11883     : m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity)
11884 {
11885 }
11886
11887 bool RegexMatcher::match(std::string const& matchee) const
11888 {
11889   auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
11890   if (m_caseSensitivity == CaseSensitive::Choice::No) {
11891     flags |= std::regex::icase;
11892   }
11893   auto reg = std::regex(m_regex, flags);
11894   return std::regex_match(matchee, reg);
11895 }
11896
11897 std::string RegexMatcher::describe() const
11898 {
11899   return "matches " + ::Catch::Detail::stringify(m_regex) +
11900          ((m_caseSensitivity == CaseSensitive::Choice::Yes) ? " case sensitively" : " case insensitively");
11901 }
11902
11903 } // namespace StdString
11904
11905 StdString::EqualsMatcher Equals(std::string const& str, CaseSensitive::Choice caseSensitivity)
11906 {
11907   return StdString::EqualsMatcher(StdString::CasedString(str, caseSensitivity));
11908 }
11909 StdString::ContainsMatcher Contains(std::string const& str, CaseSensitive::Choice caseSensitivity)
11910 {
11911   return StdString::ContainsMatcher(StdString::CasedString(str, caseSensitivity));
11912 }
11913 StdString::EndsWithMatcher EndsWith(std::string const& str, CaseSensitive::Choice caseSensitivity)
11914 {
11915   return StdString::EndsWithMatcher(StdString::CasedString(str, caseSensitivity));
11916 }
11917 StdString::StartsWithMatcher StartsWith(std::string const& str, CaseSensitive::Choice caseSensitivity)
11918 {
11919   return StdString::StartsWithMatcher(StdString::CasedString(str, caseSensitivity));
11920 }
11921
11922 StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity)
11923 {
11924   return StdString::RegexMatcher(regex, caseSensitivity);
11925 }
11926
11927 } // namespace Matchers
11928 } // namespace Catch
11929 // end catch_matchers_string.cpp
11930 // start catch_message.cpp
11931
11932 // start catch_uncaught_exceptions.h
11933
11934 namespace Catch {
11935 bool uncaught_exceptions();
11936 } // end namespace Catch
11937
11938 // end catch_uncaught_exceptions.h
11939 #include <cassert>
11940 #include <stack>
11941
11942 namespace Catch {
11943
11944 MessageInfo::MessageInfo(StringRef const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type)
11945     : macroName(_macroName), lineInfo(_lineInfo), type(_type), sequence(++globalCount)
11946 {
11947 }
11948
11949 bool MessageInfo::operator==(MessageInfo const& other) const
11950 {
11951   return sequence == other.sequence;
11952 }
11953
11954 bool MessageInfo::operator<(MessageInfo const& other) const
11955 {
11956   return sequence < other.sequence;
11957 }
11958
11959 // This may need protecting if threading support is added
11960 unsigned int MessageInfo::globalCount = 0;
11961
11962 ////////////////////////////////////////////////////////////////////////////
11963
11964 Catch::MessageBuilder::MessageBuilder(StringRef const& macroName, SourceLineInfo const& lineInfo,
11965                                       ResultWas::OfType type)
11966     : m_info(macroName, lineInfo, type)
11967 {
11968 }
11969
11970 ////////////////////////////////////////////////////////////////////////////
11971
11972 ScopedMessage::ScopedMessage(MessageBuilder const& builder) : m_info(builder.m_info), m_moved()
11973 {
11974   m_info.message = builder.m_stream.str();
11975   getResultCapture().pushScopedMessage(m_info);
11976 }
11977
11978 ScopedMessage::ScopedMessage(ScopedMessage&& old) : m_info(old.m_info), m_moved()
11979 {
11980   old.m_moved = true;
11981 }
11982
11983 ScopedMessage::~ScopedMessage()
11984 {
11985   if (!uncaught_exceptions() && !m_moved) {
11986     getResultCapture().popScopedMessage(m_info);
11987   }
11988 }
11989
11990 Capturer::Capturer(StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names)
11991 {
11992   auto trimmed = [&](size_t start, size_t end) {
11993     while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
11994       ++start;
11995     }
11996     while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
11997       --end;
11998     }
11999     return names.substr(start, end - start + 1);
12000   };
12001   auto skipq = [&](size_t start, char quote) {
12002     for (auto i = start + 1; i < names.size(); ++i) {
12003       if (names[i] == quote)
12004         return i;
12005       if (names[i] == '\\')
12006         ++i;
12007     }
12008     CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
12009   };
12010
12011   size_t start = 0;
12012   std::stack<char> openings;
12013   for (size_t pos = 0; pos < names.size(); ++pos) {
12014     char c = names[pos];
12015     switch (c) {
12016       case '[':
12017       case '{':
12018       case '(':
12019         // It is basically impossible to disambiguate between
12020         // comparison and start of template args in this context
12021         //            case '<':
12022         openings.push(c);
12023         break;
12024       case ']':
12025       case '}':
12026       case ')':
12027         //           case '>':
12028         openings.pop();
12029         break;
12030       case '"':
12031       case '\'':
12032         pos = skipq(pos, c);
12033         break;
12034       case ',':
12035         if (start != pos && openings.empty()) {
12036           m_messages.emplace_back(macroName, lineInfo, resultType);
12037           m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
12038           m_messages.back().message += " := ";
12039           start = pos;
12040         }
12041     }
12042   }
12043   assert(openings.empty() && "Mismatched openings");
12044   m_messages.emplace_back(macroName, lineInfo, resultType);
12045   m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
12046   m_messages.back().message += " := ";
12047 }
12048 Capturer::~Capturer()
12049 {
12050   if (!uncaught_exceptions()) {
12051     assert(m_captured == m_messages.size());
12052     for (size_t i = 0; i < m_captured; ++i)
12053       m_resultCapture.popScopedMessage(m_messages[i]);
12054   }
12055 }
12056
12057 void Capturer::captureValue(size_t index, std::string const& value)
12058 {
12059   assert(index < m_messages.size());
12060   m_messages[index].message += value;
12061   m_resultCapture.pushScopedMessage(m_messages[index]);
12062   m_captured++;
12063 }
12064
12065 } // end namespace Catch
12066 // end catch_message.cpp
12067 // start catch_output_redirect.cpp
12068
12069 // start catch_output_redirect.h
12070 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
12071 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
12072
12073 #include <cstdio>
12074 #include <iosfwd>
12075 #include <string>
12076
12077 namespace Catch {
12078
12079 class RedirectedStream {
12080   std::ostream& m_originalStream;
12081   std::ostream& m_redirectionStream;
12082   std::streambuf* m_prevBuf;
12083
12084 public:
12085   RedirectedStream(std::ostream& originalStream, std::ostream& redirectionStream);
12086   ~RedirectedStream();
12087 };
12088
12089 class RedirectedStdOut {
12090   ReusableStringStream m_rss;
12091   RedirectedStream m_cout;
12092
12093 public:
12094   RedirectedStdOut();
12095   auto str() const -> std::string;
12096 };
12097
12098 // StdErr has two constituent streams in C++, std::cerr and std::clog
12099 // This means that we need to redirect 2 streams into 1 to keep proper
12100 // order of writes
12101 class RedirectedStdErr {
12102   ReusableStringStream m_rss;
12103   RedirectedStream m_cerr;
12104   RedirectedStream m_clog;
12105
12106 public:
12107   RedirectedStdErr();
12108   auto str() const -> std::string;
12109 };
12110
12111 class RedirectedStreams {
12112 public:
12113   RedirectedStreams(RedirectedStreams const&)            = delete;
12114   RedirectedStreams& operator=(RedirectedStreams const&) = delete;
12115   RedirectedStreams(RedirectedStreams&&)                 = delete;
12116   RedirectedStreams& operator=(RedirectedStreams&&)      = delete;
12117
12118   RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
12119   ~RedirectedStreams();
12120
12121 private:
12122   std::string& m_redirectedCout;
12123   std::string& m_redirectedCerr;
12124   RedirectedStdOut m_redirectedStdOut;
12125   RedirectedStdErr m_redirectedStdErr;
12126 };
12127
12128 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12129
12130 // Windows's implementation of std::tmpfile is terrible (it tries
12131 // to create a file inside system folder, thus requiring elevated
12132 // privileges for the binary), so we have to use tmpnam(_s) and
12133 // create the file ourselves there.
12134 class TempFile {
12135 public:
12136   TempFile(TempFile const&)            = delete;
12137   TempFile& operator=(TempFile const&) = delete;
12138   TempFile(TempFile&&)                 = delete;
12139   TempFile& operator=(TempFile&&)      = delete;
12140
12141   TempFile();
12142   ~TempFile();
12143
12144   std::FILE* getFile();
12145   std::string getContents();
12146
12147 private:
12148   std::FILE* m_file = nullptr;
12149 #if defined(_MSC_VER)
12150   char m_buffer[L_tmpnam] = {0};
12151 #endif
12152 };
12153
12154 class OutputRedirect {
12155 public:
12156   OutputRedirect(OutputRedirect const&)            = delete;
12157   OutputRedirect& operator=(OutputRedirect const&) = delete;
12158   OutputRedirect(OutputRedirect&&)                 = delete;
12159   OutputRedirect& operator=(OutputRedirect&&)      = delete;
12160
12161   OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
12162   ~OutputRedirect();
12163
12164 private:
12165   int m_originalStdout = -1;
12166   int m_originalStderr = -1;
12167   TempFile m_stdoutFile;
12168   TempFile m_stderrFile;
12169   std::string& m_stdoutDest;
12170   std::string& m_stderrDest;
12171 };
12172
12173 #endif
12174
12175 } // end namespace Catch
12176
12177 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
12178 // end catch_output_redirect.h
12179 #include <cstdio>
12180 #include <cstring>
12181 #include <fstream>
12182 #include <sstream>
12183 #include <stdexcept>
12184
12185 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12186 #if defined(_MSC_VER)
12187 #include <io.h> //_dup and _dup2
12188 #define dup _dup
12189 #define dup2 _dup2
12190 #define fileno _fileno
12191 #else
12192 #include <unistd.h> // dup and dup2
12193 #endif
12194 #endif
12195
12196 namespace Catch {
12197
12198 RedirectedStream::RedirectedStream(std::ostream& originalStream, std::ostream& redirectionStream)
12199     : m_originalStream(originalStream), m_redirectionStream(redirectionStream), m_prevBuf(m_originalStream.rdbuf())
12200 {
12201   m_originalStream.rdbuf(m_redirectionStream.rdbuf());
12202 }
12203
12204 RedirectedStream::~RedirectedStream()
12205 {
12206   m_originalStream.rdbuf(m_prevBuf);
12207 }
12208
12209 RedirectedStdOut::RedirectedStdOut() : m_cout(Catch::cout(), m_rss.get()) {}
12210 auto RedirectedStdOut::str() const -> std::string
12211 {
12212   return m_rss.str();
12213 }
12214
12215 RedirectedStdErr::RedirectedStdErr() : m_cerr(Catch::cerr(), m_rss.get()), m_clog(Catch::clog(), m_rss.get()) {}
12216 auto RedirectedStdErr::str() const -> std::string
12217 {
12218   return m_rss.str();
12219 }
12220
12221 RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
12222     : m_redirectedCout(redirectedCout), m_redirectedCerr(redirectedCerr)
12223 {
12224 }
12225
12226 RedirectedStreams::~RedirectedStreams()
12227 {
12228   m_redirectedCout += m_redirectedStdOut.str();
12229   m_redirectedCerr += m_redirectedStdErr.str();
12230 }
12231
12232 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12233
12234 #if defined(_MSC_VER)
12235 TempFile::TempFile()
12236 {
12237   if (tmpnam_s(m_buffer)) {
12238     CATCH_RUNTIME_ERROR("Could not get a temp filename");
12239   }
12240   if (fopen_s(&m_file, m_buffer, "w+")) {
12241     char buffer[100];
12242     if (strerror_s(buffer, errno)) {
12243       CATCH_RUNTIME_ERROR("Could not translate errno to a string");
12244     }
12245     CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
12246   }
12247 }
12248 #else
12249 TempFile::TempFile()
12250 {
12251   m_file = std::tmpfile();
12252   if (!m_file) {
12253     CATCH_RUNTIME_ERROR("Could not create a temp file.");
12254   }
12255 }
12256
12257 #endif
12258
12259 TempFile::~TempFile()
12260 {
12261   // TBD: What to do about errors here?
12262   std::fclose(m_file);
12263   // We manually create the file on Windows only, on Linux
12264   // it will be autodeleted
12265 #if defined(_MSC_VER)
12266   std::remove(m_buffer);
12267 #endif
12268 }
12269
12270 FILE* TempFile::getFile()
12271 {
12272   return m_file;
12273 }
12274
12275 std::string TempFile::getContents()
12276 {
12277   std::stringstream sstr;
12278   char buffer[100] = {};
12279   std::rewind(m_file);
12280   while (std::fgets(buffer, sizeof(buffer), m_file)) {
12281     sstr << buffer;
12282   }
12283   return sstr.str();
12284 }
12285
12286 OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest)
12287     : m_originalStdout(dup(1)), m_originalStderr(dup(2)), m_stdoutDest(stdout_dest), m_stderrDest(stderr_dest)
12288 {
12289   dup2(fileno(m_stdoutFile.getFile()), 1);
12290   dup2(fileno(m_stderrFile.getFile()), 2);
12291 }
12292
12293 OutputRedirect::~OutputRedirect()
12294 {
12295   Catch::cout() << std::flush;
12296   fflush(stdout);
12297   // Since we support overriding these streams, we flush cerr
12298   // even though std::cerr is unbuffered
12299   Catch::cerr() << std::flush;
12300   Catch::clog() << std::flush;
12301   fflush(stderr);
12302
12303   dup2(m_originalStdout, 1);
12304   dup2(m_originalStderr, 2);
12305
12306   m_stdoutDest += m_stdoutFile.getContents();
12307   m_stderrDest += m_stderrFile.getContents();
12308 }
12309
12310 #endif // CATCH_CONFIG_NEW_CAPTURE
12311
12312 } // namespace Catch
12313
12314 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12315 #if defined(_MSC_VER)
12316 #undef dup
12317 #undef dup2
12318 #undef fileno
12319 #endif
12320 #endif
12321 // end catch_output_redirect.cpp
12322 // start catch_polyfills.cpp
12323
12324 #include <cmath>
12325
12326 namespace Catch {
12327
12328 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
12329 bool isnan(float f)
12330 {
12331   return std::isnan(f);
12332 }
12333 bool isnan(double d)
12334 {
12335   return std::isnan(d);
12336 }
12337 #else
12338 // For now we only use this for embarcadero
12339 bool isnan(float f)
12340 {
12341   return std::_isnan(f);
12342 }
12343 bool isnan(double d)
12344 {
12345   return std::_isnan(d);
12346 }
12347 #endif
12348
12349 } // end namespace Catch
12350 // end catch_polyfills.cpp
12351 // start catch_random_number_generator.cpp
12352
12353 namespace Catch {
12354
12355 namespace {
12356
12357 #if defined(_MSC_VER)
12358 #pragma warning(push)
12359 #pragma warning(disable : 4146) // we negate uint32 during the rotate
12360 #endif
12361 // Safe rotr implementation thanks to John Regehr
12362 uint32_t rotate_right(uint32_t val, uint32_t count)
12363 {
12364   const uint32_t mask = 31;
12365   count &= mask;
12366   return (val >> count) | (val << (-count & mask));
12367 }
12368
12369 #if defined(_MSC_VER)
12370 #pragma warning(pop)
12371 #endif
12372
12373 } // namespace
12374
12375 SimplePcg32::SimplePcg32(result_type seed_)
12376 {
12377   seed(seed_);
12378 }
12379
12380 void SimplePcg32::seed(result_type seed_)
12381 {
12382   m_state = 0;
12383   (*this)();
12384   m_state += seed_;
12385   (*this)();
12386 }
12387
12388 void SimplePcg32::discard(uint64_t skip)
12389 {
12390   // We could implement this to run in O(log n) steps, but this
12391   // should suffice for our use case.
12392   for (uint64_t s = 0; s < skip; ++s) {
12393     static_cast<void>((*this)());
12394   }
12395 }
12396
12397 SimplePcg32::result_type SimplePcg32::operator()()
12398 {
12399   // prepare the output value
12400   const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
12401   const auto output         = rotate_right(xorshifted, m_state >> 59u);
12402
12403   // advance state
12404   m_state = m_state * 6364136223846793005ULL + s_inc;
12405
12406   return output;
12407 }
12408
12409 bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs)
12410 {
12411   return lhs.m_state == rhs.m_state;
12412 }
12413
12414 bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs)
12415 {
12416   return lhs.m_state != rhs.m_state;
12417 }
12418 } // namespace Catch
12419 // end catch_random_number_generator.cpp
12420 // start catch_registry_hub.cpp
12421
12422 // start catch_test_case_registry_impl.h
12423
12424 #include <algorithm>
12425 #include <ios>
12426 #include <set>
12427 #include <vector>
12428
12429 namespace Catch {
12430
12431 class TestCase;
12432 struct IConfig;
12433
12434 std::vector<TestCase> sortTests(IConfig const& config, std::vector<TestCase> const& unsortedTestCases);
12435
12436 bool isThrowSafe(TestCase const& testCase, IConfig const& config);
12437 bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
12438
12439 void enforceNoDuplicateTestCases(std::vector<TestCase> const& functions);
12440
12441 std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec,
12442                                   IConfig const& config);
12443 std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
12444
12445 class TestRegistry : public ITestCaseRegistry {
12446 public:
12447   virtual ~TestRegistry() = default;
12448
12449   virtual void registerTest(TestCase const& testCase);
12450
12451   std::vector<TestCase> const& getAllTests() const override;
12452   std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const override;
12453
12454 private:
12455   std::vector<TestCase> m_functions;
12456   mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
12457   mutable std::vector<TestCase> m_sortedFunctions;
12458   std::size_t m_unnamedCount = 0;
12459   std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
12460 };
12461
12462 ///////////////////////////////////////////////////////////////////////////
12463
12464 class TestInvokerAsFunction : public ITestInvoker {
12465   void (*m_testAsFunction)();
12466
12467 public:
12468   TestInvokerAsFunction(void (*testAsFunction)()) noexcept;
12469
12470   void invoke() const override;
12471 };
12472
12473 std::string extractClassName(StringRef const& classOrQualifiedMethodName);
12474
12475 ///////////////////////////////////////////////////////////////////////////
12476
12477 } // end namespace Catch
12478
12479 // end catch_test_case_registry_impl.h
12480 // start catch_reporter_registry.h
12481
12482 #include <map>
12483
12484 namespace Catch {
12485
12486 class ReporterRegistry : public IReporterRegistry {
12487
12488 public:
12489   ~ReporterRegistry() override;
12490
12491   IStreamingReporterPtr create(std::string const& name, IConfigPtr const& config) const override;
12492
12493   void registerReporter(std::string const& name, IReporterFactoryPtr const& factory);
12494   void registerListener(IReporterFactoryPtr const& factory);
12495
12496   FactoryMap const& getFactories() const override;
12497   Listeners const& getListeners() const override;
12498
12499 private:
12500   FactoryMap m_factories;
12501   Listeners m_listeners;
12502 };
12503 } // namespace Catch
12504
12505 // end catch_reporter_registry.h
12506 // start catch_tag_alias_registry.h
12507
12508 // start catch_tag_alias.h
12509
12510 #include <string>
12511
12512 namespace Catch {
12513
12514 struct TagAlias {
12515   TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
12516
12517   std::string tag;
12518   SourceLineInfo lineInfo;
12519 };
12520
12521 } // end namespace Catch
12522
12523 // end catch_tag_alias.h
12524 #include <map>
12525
12526 namespace Catch {
12527
12528 class TagAliasRegistry : public ITagAliasRegistry {
12529 public:
12530   ~TagAliasRegistry() override;
12531   TagAlias const* find(std::string const& alias) const override;
12532   std::string expandAliases(std::string const& unexpandedTestSpec) const override;
12533   void add(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo);
12534
12535 private:
12536   std::map<std::string, TagAlias> m_registry;
12537 };
12538
12539 } // end namespace Catch
12540
12541 // end catch_tag_alias_registry.h
12542 // start catch_startup_exception_registry.h
12543
12544 #include <exception>
12545 #include <vector>
12546
12547 namespace Catch {
12548
12549 class StartupExceptionRegistry {
12550 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12551 public:
12552   void add(std::exception_ptr const& exception) noexcept;
12553   std::vector<std::exception_ptr> const& getExceptions() const noexcept;
12554
12555 private:
12556   std::vector<std::exception_ptr> m_exceptions;
12557 #endif
12558 };
12559
12560 } // end namespace Catch
12561
12562 // end catch_startup_exception_registry.h
12563 // start catch_singletons.hpp
12564
12565 namespace Catch {
12566
12567 struct ISingleton {
12568   virtual ~ISingleton();
12569 };
12570
12571 void addSingleton(ISingleton* singleton);
12572 void cleanupSingletons();
12573
12574 template <typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
12575 class Singleton : SingletonImplT, public ISingleton {
12576
12577   static auto getInternal() -> Singleton*
12578   {
12579     static Singleton* s_instance = nullptr;
12580     if (!s_instance) {
12581       s_instance = new Singleton;
12582       addSingleton(s_instance);
12583     }
12584     return s_instance;
12585   }
12586
12587 public:
12588   static auto get() -> InterfaceT const& { return *getInternal(); }
12589   static auto getMutable() -> MutableInterfaceT& { return *getInternal(); }
12590 };
12591
12592 } // namespace Catch
12593
12594 // end catch_singletons.hpp
12595 namespace Catch {
12596
12597 namespace {
12598
12599 class RegistryHub : public IRegistryHub, public IMutableRegistryHub, private NonCopyable {
12600
12601 public: // IRegistryHub
12602   RegistryHub() = default;
12603   IReporterRegistry const& getReporterRegistry() const override { return m_reporterRegistry; }
12604   ITestCaseRegistry const& getTestCaseRegistry() const override { return m_testCaseRegistry; }
12605   IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override
12606   {
12607     return m_exceptionTranslatorRegistry;
12608   }
12609   ITagAliasRegistry const& getTagAliasRegistry() const override { return m_tagAliasRegistry; }
12610   StartupExceptionRegistry const& getStartupExceptionRegistry() const override { return m_exceptionRegistry; }
12611
12612 public: // IMutableRegistryHub
12613   void registerReporter(std::string const& name, IReporterFactoryPtr const& factory) override
12614   {
12615     m_reporterRegistry.registerReporter(name, factory);
12616   }
12617   void registerListener(IReporterFactoryPtr const& factory) override { m_reporterRegistry.registerListener(factory); }
12618   void registerTest(TestCase const& testInfo) override { m_testCaseRegistry.registerTest(testInfo); }
12619   void registerTranslator(const IExceptionTranslator* translator) override
12620   {
12621     m_exceptionTranslatorRegistry.registerTranslator(translator);
12622   }
12623   void registerTagAlias(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) override
12624   {
12625     m_tagAliasRegistry.add(alias, tag, lineInfo);
12626   }
12627   void registerStartupException() noexcept override
12628   {
12629 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12630     m_exceptionRegistry.add(std::current_exception());
12631 #else
12632     CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
12633 #endif
12634   }
12635   IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override
12636   {
12637     return m_enumValuesRegistry;
12638   }
12639
12640 private:
12641   TestRegistry m_testCaseRegistry;
12642   ReporterRegistry m_reporterRegistry;
12643   ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
12644   TagAliasRegistry m_tagAliasRegistry;
12645   StartupExceptionRegistry m_exceptionRegistry;
12646   Detail::EnumValuesRegistry m_enumValuesRegistry;
12647 };
12648 } // namespace
12649
12650 using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
12651
12652 IRegistryHub const& getRegistryHub()
12653 {
12654   return RegistryHubSingleton::get();
12655 }
12656 IMutableRegistryHub& getMutableRegistryHub()
12657 {
12658   return RegistryHubSingleton::getMutable();
12659 }
12660 void cleanUp()
12661 {
12662   cleanupSingletons();
12663   cleanUpContext();
12664 }
12665 std::string translateActiveException()
12666 {
12667   return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
12668 }
12669
12670 } // end namespace Catch
12671 // end catch_registry_hub.cpp
12672 // start catch_reporter_registry.cpp
12673
12674 namespace Catch {
12675
12676 ReporterRegistry::~ReporterRegistry() = default;
12677
12678 IStreamingReporterPtr ReporterRegistry::create(std::string const& name, IConfigPtr const& config) const
12679 {
12680   auto it = m_factories.find(name);
12681   if (it == m_factories.end())
12682     return nullptr;
12683   return it->second->create(ReporterConfig(config));
12684 }
12685
12686 void ReporterRegistry::registerReporter(std::string const& name, IReporterFactoryPtr const& factory)
12687 {
12688   m_factories.emplace(name, factory);
12689 }
12690 void ReporterRegistry::registerListener(IReporterFactoryPtr const& factory)
12691 {
12692   m_listeners.push_back(factory);
12693 }
12694
12695 IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const
12696 {
12697   return m_factories;
12698 }
12699 IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const
12700 {
12701   return m_listeners;
12702 }
12703
12704 } // namespace Catch
12705 // end catch_reporter_registry.cpp
12706 // start catch_result_type.cpp
12707
12708 namespace Catch {
12709
12710 bool isOk(ResultWas::OfType resultType)
12711 {
12712   return (resultType & ResultWas::FailureBit) == 0;
12713 }
12714 bool isJustInfo(int flags)
12715 {
12716   return flags == ResultWas::Info;
12717 }
12718
12719 ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
12720 {
12721   return static_cast<ResultDisposition::Flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
12722 }
12723
12724 bool shouldContinueOnFailure(int flags)
12725 {
12726   return (flags & ResultDisposition::ContinueOnFailure) != 0;
12727 }
12728 bool shouldSuppressFailure(int flags)
12729 {
12730   return (flags & ResultDisposition::SuppressFail) != 0;
12731 }
12732
12733 } // end namespace Catch
12734 // end catch_result_type.cpp
12735 // start catch_run_context.cpp
12736
12737 #include <algorithm>
12738 #include <cassert>
12739 #include <sstream>
12740
12741 namespace Catch {
12742
12743 namespace Generators {
12744 struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
12745   GeneratorBasePtr m_generator;
12746
12747   GeneratorTracker(TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
12748       : TrackerBase(nameAndLocation, ctx, parent)
12749   {
12750   }
12751   ~GeneratorTracker();
12752
12753   static GeneratorTracker& acquire(TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation)
12754   {
12755     std::shared_ptr<GeneratorTracker> tracker;
12756
12757     ITracker& currentTracker = ctx.currentTracker();
12758     // Under specific circumstances, the generator we want
12759     // to acquire is also the current tracker. If this is
12760     // the case, we have to avoid looking through current
12761     // tracker's children, and instead return the current
12762     // tracker.
12763     // A case where this check is important is e.g.
12764     //     for (int i = 0; i < 5; ++i) {
12765     //         int n = GENERATE(1, 2);
12766     //     }
12767     //
12768     // without it, the code above creates 5 nested generators.
12769     if (currentTracker.nameAndLocation() == nameAndLocation) {
12770       auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
12771       assert(thisTracker);
12772       assert(thisTracker->isGeneratorTracker());
12773       tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
12774     } else if (TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
12775       assert(childTracker);
12776       assert(childTracker->isGeneratorTracker());
12777       tracker = std::static_pointer_cast<GeneratorTracker>(childTracker);
12778     } else {
12779       tracker = std::make_shared<GeneratorTracker>(nameAndLocation, ctx, &currentTracker);
12780       currentTracker.addChild(tracker);
12781     }
12782
12783     if (!tracker->isComplete()) {
12784       tracker->open();
12785     }
12786
12787     return *tracker;
12788   }
12789
12790   // TrackerBase interface
12791   bool isGeneratorTracker() const override { return true; }
12792   auto hasGenerator() const -> bool override { return !!m_generator; }
12793   void close() override
12794   {
12795     TrackerBase::close();
12796     // If a generator has a child (it is followed by a section)
12797     // and none of its children have started, then we must wait
12798     // until later to start consuming its values.
12799     // This catches cases where `GENERATE` is placed between two
12800     // `SECTION`s.
12801     // **The check for m_children.empty cannot be removed**.
12802     // doing so would break `GENERATE` _not_ followed by `SECTION`s.
12803     const bool should_wait_for_child = [&]() {
12804       // No children -> nobody to wait for
12805       if (m_children.empty()) {
12806         return false;
12807       }
12808       // If at least one child started executing, don't wait
12809       if (std::find_if(m_children.begin(), m_children.end(), [](TestCaseTracking::ITrackerPtr tracker) {
12810             return tracker->hasStarted();
12811           }) != m_children.end()) {
12812         return false;
12813       }
12814
12815       // No children have started. We need to check if they _can_
12816       // start, and thus we should wait for them, or they cannot
12817       // start (due to filters), and we shouldn't wait for them
12818       auto* parent = m_parent;
12819       // This is safe: there is always at least one section
12820       // tracker in a test case tracking tree
12821       while (!parent->isSectionTracker()) {
12822         parent = &(parent->parent());
12823       }
12824       assert(parent && "Missing root (test case) level section");
12825
12826       auto const& parentSection = static_cast<SectionTracker&>(*parent);
12827       auto const& filters       = parentSection.getFilters();
12828       // No filters -> no restrictions on running sections
12829       if (filters.empty()) {
12830         return true;
12831       }
12832
12833       for (auto const& child : m_children) {
12834         if (child->isSectionTracker() &&
12835             std::find(filters.begin(), filters.end(), static_cast<SectionTracker&>(*child).trimmedName()) !=
12836                 filters.end()) {
12837           return true;
12838         }
12839       }
12840       return false;
12841     }();
12842
12843     // This check is a bit tricky, because m_generator->next()
12844     // has a side-effect, where it consumes generator's current
12845     // value, but we do not want to invoke the side-effect if
12846     // this generator is still waiting for any child to start.
12847     if (should_wait_for_child || (m_runState == CompletedSuccessfully && m_generator->next())) {
12848       m_children.clear();
12849       m_runState = Executing;
12850     }
12851   }
12852
12853   // IGeneratorTracker interface
12854   auto getGenerator() const -> GeneratorBasePtr const& override { return m_generator; }
12855   void setGenerator(GeneratorBasePtr&& generator) override { m_generator = std::move(generator); }
12856 };
12857 GeneratorTracker::~GeneratorTracker() {}
12858 } // namespace Generators
12859
12860 RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
12861     : m_runInfo(_config->name())
12862     , m_context(getCurrentMutableContext())
12863     , m_config(_config)
12864     , m_reporter(std::move(reporter))
12865     , m_lastAssertionInfo{StringRef(), SourceLineInfo("", 0), StringRef(), ResultDisposition::Normal}
12866     , m_includeSuccessfulResults(m_config->includeSuccessfulResults() ||
12867                                  m_reporter->getPreferences().shouldReportAllAssertions)
12868 {
12869   m_context.setRunner(this);
12870   m_context.setConfig(m_config);
12871   m_context.setResultCapture(this);
12872   m_reporter->testRunStarting(m_runInfo);
12873 }
12874
12875 RunContext::~RunContext()
12876 {
12877   m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
12878 }
12879
12880 void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount)
12881 {
12882   m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
12883 }
12884
12885 void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex,
12886                                 std::size_t groupsCount)
12887 {
12888   m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
12889 }
12890
12891 Totals RunContext::runTest(TestCase const& testCase)
12892 {
12893   Totals prevTotals = m_totals;
12894
12895   std::string redirectedCout;
12896   std::string redirectedCerr;
12897
12898   auto const& testInfo = testCase.getTestCaseInfo();
12899
12900   m_reporter->testCaseStarting(testInfo);
12901
12902   m_activeTestCase = &testCase;
12903
12904   ITracker& rootTracker = m_trackerContext.startRun();
12905   assert(rootTracker.isSectionTracker());
12906   static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
12907   do {
12908     m_trackerContext.startCycle();
12909     m_testCaseTracker =
12910         &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
12911     runCurrentTest(redirectedCout, redirectedCerr);
12912   } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
12913
12914   Totals deltaTotals = m_totals.delta(prevTotals);
12915   if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
12916     deltaTotals.assertions.failed++;
12917     deltaTotals.testCases.passed--;
12918     deltaTotals.testCases.failed++;
12919   }
12920   m_totals.testCases += deltaTotals.testCases;
12921   m_reporter->testCaseEnded(TestCaseStats(testInfo, deltaTotals, redirectedCout, redirectedCerr, aborting()));
12922
12923   m_activeTestCase  = nullptr;
12924   m_testCaseTracker = nullptr;
12925
12926   return deltaTotals;
12927 }
12928
12929 IConfigPtr RunContext::config() const
12930 {
12931   return m_config;
12932 }
12933
12934 IStreamingReporter& RunContext::reporter() const
12935 {
12936   return *m_reporter;
12937 }
12938
12939 void RunContext::assertionEnded(AssertionResult const& result)
12940 {
12941   if (result.getResultType() == ResultWas::Ok) {
12942     m_totals.assertions.passed++;
12943     m_lastAssertionPassed = true;
12944   } else if (!result.isOk()) {
12945     m_lastAssertionPassed = false;
12946     if (m_activeTestCase->getTestCaseInfo().okToFail())
12947       m_totals.assertions.failedButOk++;
12948     else
12949       m_totals.assertions.failed++;
12950   } else {
12951     m_lastAssertionPassed = true;
12952   }
12953
12954   // We have no use for the return value (whether messages should be cleared), because messages were made scoped
12955   // and should be let to clear themselves out.
12956   static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
12957
12958   if (result.getResultType() != ResultWas::Warning)
12959     m_messageScopes.clear();
12960
12961   // Reset working state
12962   resetAssertionInfo();
12963   m_lastResult = result;
12964 }
12965 void RunContext::resetAssertionInfo()
12966 {
12967   m_lastAssertionInfo.macroName          = StringRef();
12968   m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
12969 }
12970
12971 bool RunContext::sectionStarted(SectionInfo const& sectionInfo, Counts& assertions)
12972 {
12973   ITracker& sectionTracker = SectionTracker::acquire(
12974       m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
12975   if (!sectionTracker.isOpen())
12976     return false;
12977   m_activeSections.push_back(&sectionTracker);
12978
12979   m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
12980
12981   m_reporter->sectionStarting(sectionInfo);
12982
12983   assertions = m_totals.assertions;
12984
12985   return true;
12986 }
12987 auto RunContext::acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const& lineInfo) -> IGeneratorTracker&
12988 {
12989   using namespace Generators;
12990   GeneratorTracker& tracker = GeneratorTracker::acquire(
12991       m_trackerContext, TestCaseTracking::NameAndLocation(static_cast<std::string>(generatorName), lineInfo));
12992   m_lastAssertionInfo.lineInfo = lineInfo;
12993   return tracker;
12994 }
12995
12996 bool RunContext::testForMissingAssertions(Counts& assertions)
12997 {
12998   if (assertions.total() != 0)
12999     return false;
13000   if (!m_config->warnAboutMissingAssertions())
13001     return false;
13002   if (m_trackerContext.currentTracker().hasChildren())
13003     return false;
13004   m_totals.assertions.failed++;
13005   assertions.failed++;
13006   return true;
13007 }
13008
13009 void RunContext::sectionEnded(SectionEndInfo const& endInfo)
13010 {
13011   Counts assertions      = m_totals.assertions - endInfo.prevAssertions;
13012   bool missingAssertions = testForMissingAssertions(assertions);
13013
13014   if (!m_activeSections.empty()) {
13015     m_activeSections.back()->close();
13016     m_activeSections.pop_back();
13017   }
13018
13019   m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
13020   m_messages.clear();
13021   m_messageScopes.clear();
13022 }
13023
13024 void RunContext::sectionEndedEarly(SectionEndInfo const& endInfo)
13025 {
13026   if (m_unfinishedSections.empty())
13027     m_activeSections.back()->fail();
13028   else
13029     m_activeSections.back()->close();
13030   m_activeSections.pop_back();
13031
13032   m_unfinishedSections.push_back(endInfo);
13033 }
13034
13035 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
13036 void RunContext::benchmarkPreparing(std::string const& name)
13037 {
13038   m_reporter->benchmarkPreparing(name);
13039 }
13040 void RunContext::benchmarkStarting(BenchmarkInfo const& info)
13041 {
13042   m_reporter->benchmarkStarting(info);
13043 }
13044 void RunContext::benchmarkEnded(BenchmarkStats<> const& stats)
13045 {
13046   m_reporter->benchmarkEnded(stats);
13047 }
13048 void RunContext::benchmarkFailed(std::string const& error)
13049 {
13050   m_reporter->benchmarkFailed(error);
13051 }
13052 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
13053
13054 void RunContext::pushScopedMessage(MessageInfo const& message)
13055 {
13056   m_messages.push_back(message);
13057 }
13058
13059 void RunContext::popScopedMessage(MessageInfo const& message)
13060 {
13061   m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
13062 }
13063
13064 void RunContext::emplaceUnscopedMessage(MessageBuilder const& builder)
13065 {
13066   m_messageScopes.emplace_back(builder);
13067 }
13068
13069 std::string RunContext::getCurrentTestName() const
13070 {
13071   return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name : std::string();
13072 }
13073
13074 const AssertionResult* RunContext::getLastResult() const
13075 {
13076   return &(*m_lastResult);
13077 }
13078
13079 void RunContext::exceptionEarlyReported()
13080 {
13081   m_shouldReportUnexpected = false;
13082 }
13083
13084 void RunContext::handleFatalErrorCondition(StringRef message)
13085 {
13086   // First notify reporter that bad things happened
13087   m_reporter->fatalErrorEncountered(message);
13088
13089   // Don't rebuild the result -- the stringification itself can cause more fatal errors
13090   // Instead, fake a result data.
13091   AssertionResultData tempResult(ResultWas::FatalErrorCondition, {false});
13092   tempResult.message = static_cast<std::string>(message);
13093   AssertionResult result(m_lastAssertionInfo, tempResult);
13094
13095   assertionEnded(result);
13096
13097   handleUnfinishedSections();
13098
13099   // Recreate section for test case (as we will lose the one that was in scope)
13100   auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
13101   SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
13102
13103   Counts assertions;
13104   assertions.failed = 1;
13105   SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
13106   m_reporter->sectionEnded(testCaseSectionStats);
13107
13108   auto const& testInfo = m_activeTestCase->getTestCaseInfo();
13109
13110   Totals deltaTotals;
13111   deltaTotals.testCases.failed  = 1;
13112   deltaTotals.assertions.failed = 1;
13113   m_reporter->testCaseEnded(TestCaseStats(testInfo, deltaTotals, std::string(), std::string(), false));
13114   m_totals.testCases.failed++;
13115   testGroupEnded(std::string(), m_totals, 1, 1);
13116   m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
13117 }
13118
13119 bool RunContext::lastAssertionPassed()
13120 {
13121   return m_lastAssertionPassed;
13122 }
13123
13124 void RunContext::assertionPassed()
13125 {
13126   m_lastAssertionPassed = true;
13127   ++m_totals.assertions.passed;
13128   resetAssertionInfo();
13129   m_messageScopes.clear();
13130 }
13131
13132 bool RunContext::aborting() const
13133 {
13134   return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
13135 }
13136
13137 void RunContext::runCurrentTest(std::string& redirectedCout, std::string& redirectedCerr)
13138 {
13139   auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
13140   SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
13141   m_reporter->sectionStarting(testCaseSection);
13142   Counts prevAssertions    = m_totals.assertions;
13143   double duration          = 0;
13144   m_shouldReportUnexpected = true;
13145   m_lastAssertionInfo      = {"TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal};
13146
13147   seedRng(*m_config);
13148
13149   Timer timer;
13150   CATCH_TRY
13151   {
13152     if (m_reporter->getPreferences().shouldRedirectStdOut) {
13153 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
13154       RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
13155
13156       timer.start();
13157       invokeActiveTestCase();
13158 #else
13159       OutputRedirect r(redirectedCout, redirectedCerr);
13160       timer.start();
13161       invokeActiveTestCase();
13162 #endif
13163     } else {
13164       timer.start();
13165       invokeActiveTestCase();
13166     }
13167     duration = timer.getElapsedSeconds();
13168   }
13169   CATCH_CATCH_ANON(TestFailureException&)
13170   {
13171     // This just means the test was aborted due to failure
13172   }
13173   CATCH_CATCH_ALL
13174   {
13175     // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
13176     // are reported without translation at the point of origin.
13177     if (m_shouldReportUnexpected) {
13178       AssertionReaction dummyReaction;
13179       handleUnexpectedInflightException(m_lastAssertionInfo, translateActiveException(), dummyReaction);
13180     }
13181   }
13182   Counts assertions      = m_totals.assertions - prevAssertions;
13183   bool missingAssertions = testForMissingAssertions(assertions);
13184
13185   m_testCaseTracker->close();
13186   handleUnfinishedSections();
13187   m_messages.clear();
13188   m_messageScopes.clear();
13189
13190   SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
13191   m_reporter->sectionEnded(testCaseSectionStats);
13192 }
13193
13194 void RunContext::invokeActiveTestCase()
13195 {
13196   FatalConditionHandlerGuard _(&m_fatalConditionhandler);
13197   m_activeTestCase->invoke();
13198 }
13199
13200 void RunContext::handleUnfinishedSections()
13201 {
13202   // If sections ended prematurely due to an exception we stored their
13203   // infos here so we can tear them down outside the unwind process.
13204   for (auto it = m_unfinishedSections.rbegin(), itEnd = m_unfinishedSections.rend(); it != itEnd; ++it)
13205     sectionEnded(*it);
13206   m_unfinishedSections.clear();
13207 }
13208
13209 void RunContext::handleExpr(AssertionInfo const& info, ITransientExpression const& expr, AssertionReaction& reaction)
13210 {
13211   m_reporter->assertionStarting(info);
13212
13213   bool negated = isFalseTest(info.resultDisposition);
13214   bool result  = expr.getResult() != negated;
13215
13216   if (result) {
13217     if (!m_includeSuccessfulResults) {
13218       assertionPassed();
13219     } else {
13220       reportExpr(info, ResultWas::Ok, &expr, negated);
13221     }
13222   } else {
13223     reportExpr(info, ResultWas::ExpressionFailed, &expr, negated);
13224     populateReaction(reaction);
13225   }
13226 }
13227 void RunContext::reportExpr(AssertionInfo const& info, ResultWas::OfType resultType, ITransientExpression const* expr,
13228                             bool negated)
13229 {
13230
13231   m_lastAssertionInfo = info;
13232   AssertionResultData data(resultType, LazyExpression(negated));
13233
13234   AssertionResult assertionResult{info, data};
13235   assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
13236
13237   assertionEnded(assertionResult);
13238 }
13239
13240 void RunContext::handleMessage(AssertionInfo const& info, ResultWas::OfType resultType, StringRef const& message,
13241                                AssertionReaction& reaction)
13242 {
13243   m_reporter->assertionStarting(info);
13244
13245   m_lastAssertionInfo = info;
13246
13247   AssertionResultData data(resultType, LazyExpression(false));
13248   data.message = static_cast<std::string>(message);
13249   AssertionResult assertionResult{m_lastAssertionInfo, data};
13250   assertionEnded(assertionResult);
13251   if (!assertionResult.isOk())
13252     populateReaction(reaction);
13253 }
13254 void RunContext::handleUnexpectedExceptionNotThrown(AssertionInfo const& info, AssertionReaction& reaction)
13255 {
13256   handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
13257 }
13258
13259 void RunContext::handleUnexpectedInflightException(AssertionInfo const& info, std::string const& message,
13260                                                    AssertionReaction& reaction)
13261 {
13262   m_lastAssertionInfo = info;
13263
13264   AssertionResultData data(ResultWas::ThrewException, LazyExpression(false));
13265   data.message = message;
13266   AssertionResult assertionResult{info, data};
13267   assertionEnded(assertionResult);
13268   populateReaction(reaction);
13269 }
13270
13271 void RunContext::populateReaction(AssertionReaction& reaction)
13272 {
13273   reaction.shouldDebugBreak = m_config->shouldDebugBreak();
13274   reaction.shouldThrow      = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
13275 }
13276
13277 void RunContext::handleIncomplete(AssertionInfo const& info)
13278 {
13279   m_lastAssertionInfo = info;
13280
13281   AssertionResultData data(ResultWas::ThrewException, LazyExpression(false));
13282   data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
13283   AssertionResult assertionResult{info, data};
13284   assertionEnded(assertionResult);
13285 }
13286 void RunContext::handleNonExpr(AssertionInfo const& info, ResultWas::OfType resultType, AssertionReaction& reaction)
13287 {
13288   m_lastAssertionInfo = info;
13289
13290   AssertionResultData data(resultType, LazyExpression(false));
13291   AssertionResult assertionResult{info, data};
13292   assertionEnded(assertionResult);
13293
13294   if (!assertionResult.isOk())
13295     populateReaction(reaction);
13296 }
13297
13298 IResultCapture& getResultCapture()
13299 {
13300   if (auto* capture = getCurrentContext().getResultCapture())
13301     return *capture;
13302   else
13303     CATCH_INTERNAL_ERROR("No result capture instance");
13304 }
13305
13306 void seedRng(IConfig const& config)
13307 {
13308   if (config.rngSeed() != 0) {
13309     std::srand(config.rngSeed());
13310     rng().seed(config.rngSeed());
13311   }
13312 }
13313
13314 unsigned int rngSeed()
13315 {
13316   return getCurrentContext().getConfig()->rngSeed();
13317 }
13318
13319 } // namespace Catch
13320 // end catch_run_context.cpp
13321 // start catch_section.cpp
13322
13323 namespace Catch {
13324
13325 Section::Section(SectionInfo const& info)
13326     : m_info(info), m_sectionIncluded(getResultCapture().sectionStarted(m_info, m_assertions))
13327 {
13328   m_timer.start();
13329 }
13330
13331 Section::~Section()
13332 {
13333   if (m_sectionIncluded) {
13334     SectionEndInfo endInfo{m_info, m_assertions, m_timer.getElapsedSeconds()};
13335     if (uncaught_exceptions())
13336       getResultCapture().sectionEndedEarly(endInfo);
13337     else
13338       getResultCapture().sectionEnded(endInfo);
13339   }
13340 }
13341
13342 // This indicates whether the section should be executed or not
13343 Section::operator bool() const
13344 {
13345   return m_sectionIncluded;
13346 }
13347
13348 } // end namespace Catch
13349 // end catch_section.cpp
13350 // start catch_section_info.cpp
13351
13352 namespace Catch {
13353
13354 SectionInfo::SectionInfo(SourceLineInfo const& _lineInfo, std::string const& _name) : name(_name), lineInfo(_lineInfo)
13355 {
13356 }
13357
13358 } // end namespace Catch
13359 // end catch_section_info.cpp
13360 // start catch_session.cpp
13361
13362 // start catch_session.h
13363
13364 #include <memory>
13365
13366 namespace Catch {
13367
13368 class Session : NonCopyable {
13369 public:
13370   Session();
13371   ~Session() override;
13372
13373   void showHelp() const;
13374   void libIdentify();
13375
13376   int applyCommandLine(int argc, char const* const* argv);
13377 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13378   int applyCommandLine(int argc, wchar_t const* const* argv);
13379 #endif
13380
13381   void useConfigData(ConfigData const& configData);
13382
13383   template <typename CharT> int run(int argc, CharT const* const argv[])
13384   {
13385     if (m_startupExceptions)
13386       return 1;
13387     int returnCode = applyCommandLine(argc, argv);
13388     if (returnCode == 0)
13389       returnCode = run();
13390     return returnCode;
13391   }
13392
13393   int run();
13394
13395   clara::Parser const& cli() const;
13396   void cli(clara::Parser const& newParser);
13397   ConfigData& configData();
13398   Config& config();
13399
13400 private:
13401   int runInternal();
13402
13403   clara::Parser m_cli;
13404   ConfigData m_configData;
13405   std::shared_ptr<Config> m_config;
13406   bool m_startupExceptions = false;
13407 };
13408
13409 } // end namespace Catch
13410
13411 // end catch_session.h
13412 // start catch_version.h
13413
13414 #include <iosfwd>
13415
13416 namespace Catch {
13417
13418 // Versioning information
13419 struct Version {
13420   Version(Version const&)            = delete;
13421   Version& operator=(Version const&) = delete;
13422   Version(unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber,
13423           char const* const _branchName, unsigned int _buildNumber);
13424
13425   unsigned int const majorVersion;
13426   unsigned int const minorVersion;
13427   unsigned int const patchNumber;
13428
13429   // buildNumber is only used if branchName is not null
13430   char const* const branchName;
13431   unsigned int const buildNumber;
13432
13433   friend std::ostream& operator<<(std::ostream& os, Version const& version);
13434 };
13435
13436 Version const& libraryVersion();
13437 } // namespace Catch
13438
13439 // end catch_version.h
13440 #include <cstdlib>
13441 #include <iomanip>
13442 #include <iterator>
13443 #include <set>
13444
13445 namespace Catch {
13446
13447 namespace {
13448 const int MaxExitCode = 255;
13449
13450 IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config)
13451 {
13452   auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
13453   CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
13454
13455   return reporter;
13456 }
13457
13458 IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config)
13459 {
13460   if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
13461     return createReporter(config->getReporterName(), config);
13462   }
13463
13464   // On older platforms, returning std::unique_ptr<ListeningReporter>
13465   // when the return type is std::unique_ptr<IStreamingReporter>
13466   // doesn't compile without a std::move call. However, this causes
13467   // a warning on newer platforms. Thus, we have to work around
13468   // it a bit and downcast the pointer manually.
13469   auto ret              = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
13470   auto& multi           = static_cast<ListeningReporter&>(*ret);
13471   auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
13472   for (auto const& listener : listeners) {
13473     multi.addListener(listener->create(Catch::ReporterConfig(config)));
13474   }
13475   multi.addReporter(createReporter(config->getReporterName(), config));
13476   return ret;
13477 }
13478
13479 class TestGroup {
13480 public:
13481   explicit TestGroup(std::shared_ptr<Config> const& config) : m_config{config}, m_context{config, makeReporter(config)}
13482   {
13483     auto const& allTestCases = getAllTestCasesSorted(*m_config);
13484     m_matches                = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
13485     auto const& invalidArgs  = m_config->testSpec().getInvalidArgs();
13486
13487     if (m_matches.empty() && invalidArgs.empty()) {
13488       for (auto const& test : allTestCases)
13489         if (!test.isHidden())
13490           m_tests.emplace(&test);
13491     } else {
13492       for (auto const& match : m_matches)
13493         m_tests.insert(match.tests.begin(), match.tests.end());
13494     }
13495   }
13496
13497   Totals execute()
13498   {
13499     auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13500     Totals totals;
13501     m_context.testGroupStarting(m_config->name(), 1, 1);
13502     for (auto const& testCase : m_tests) {
13503       if (!m_context.aborting())
13504         totals += m_context.runTest(*testCase);
13505       else
13506         m_context.reporter().skipTest(*testCase);
13507     }
13508
13509     for (auto const& match : m_matches) {
13510       if (match.tests.empty()) {
13511         m_context.reporter().noMatchingTestCases(match.name);
13512         totals.error = -1;
13513       }
13514     }
13515
13516     if (!invalidArgs.empty()) {
13517       for (auto const& invalidArg : invalidArgs)
13518         m_context.reporter().reportInvalidArguments(invalidArg);
13519     }
13520
13521     m_context.testGroupEnded(m_config->name(), totals, 1, 1);
13522     return totals;
13523   }
13524
13525 private:
13526   using Tests = std::set<TestCase const*>;
13527
13528   std::shared_ptr<Config> m_config;
13529   RunContext m_context;
13530   Tests m_tests;
13531   TestSpec::Matches m_matches;
13532 };
13533
13534 void applyFilenamesAsTags(Catch::IConfig const& config)
13535 {
13536   auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
13537   for (auto& testCase : tests) {
13538     auto tags = testCase.tags;
13539
13540     std::string filename = testCase.lineInfo.file;
13541     auto lastSlash       = filename.find_last_of("\\/");
13542     if (lastSlash != std::string::npos) {
13543       filename.erase(0, lastSlash);
13544       filename[0] = '#';
13545     }
13546
13547     auto lastDot = filename.find_last_of('.');
13548     if (lastDot != std::string::npos) {
13549       filename.erase(lastDot);
13550     }
13551
13552     tags.push_back(std::move(filename));
13553     setTags(testCase, tags);
13554   }
13555 }
13556
13557 } // namespace
13558
13559 Session::Session()
13560 {
13561   static bool alreadyInstantiated = false;
13562   if (alreadyInstantiated) {
13563     CATCH_TRY
13564     {
13565       CATCH_INTERNAL_ERROR("Only one instance of Catch::Session can ever be used");
13566     }
13567     CATCH_CATCH_ALL
13568     {
13569       getMutableRegistryHub().registerStartupException();
13570     }
13571   }
13572
13573   // There cannot be exceptions at startup in no-exception mode.
13574 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13575   const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
13576   if (!exceptions.empty()) {
13577     config();
13578     getCurrentMutableContext().setConfig(m_config);
13579
13580     m_startupExceptions = true;
13581     Colour colourGuard(Colour::Red);
13582     Catch::cerr() << "Errors occurred during startup!" << '\n';
13583     // iterate over all exceptions and notify user
13584     for (const auto& ex_ptr : exceptions) {
13585       try {
13586         std::rethrow_exception(ex_ptr);
13587       } catch (std::exception const& ex) {
13588         Catch::cerr() << Column(ex.what()).indent(2) << '\n';
13589       }
13590     }
13591   }
13592 #endif
13593
13594   alreadyInstantiated = true;
13595   m_cli               = makeCommandLineParser(m_configData);
13596 }
13597 Session::~Session()
13598 {
13599   Catch::cleanUp();
13600 }
13601
13602 void Session::showHelp() const
13603 {
13604   Catch::cout() << "\nCatch v" << libraryVersion() << "\n"
13605                 << m_cli << std::endl
13606                 << "For more detailed usage please see the project docs\n"
13607                 << std::endl;
13608 }
13609 void Session::libIdentify()
13610 {
13611   Catch::cout() << std::left << std::setw(16) << "description: "
13612                 << "A Catch2 test executable\n"
13613                 << std::left << std::setw(16) << "category: "
13614                 << "testframework\n"
13615                 << std::left << std::setw(16) << "framework: "
13616                 << "Catch Test\n"
13617                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
13618 }
13619
13620 int Session::applyCommandLine(int argc, char const* const* argv)
13621 {
13622   if (m_startupExceptions)
13623     return 1;
13624
13625   auto result = m_cli.parse(clara::Args(argc, argv));
13626   if (!result) {
13627     config();
13628     getCurrentMutableContext().setConfig(m_config);
13629     Catch::cerr() << Colour(Colour::Red) << "\nError(s) in input:\n"
13630                   << Column(result.errorMessage()).indent(2) << "\n\n";
13631     Catch::cerr() << "Run with -? for usage\n" << std::endl;
13632     return MaxExitCode;
13633   }
13634
13635   if (m_configData.showHelp)
13636     showHelp();
13637   if (m_configData.libIdentify)
13638     libIdentify();
13639   m_config.reset();
13640   return 0;
13641 }
13642
13643 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13644 int Session::applyCommandLine(int argc, wchar_t const* const* argv)
13645 {
13646
13647   char** utf8Argv = new char*[argc];
13648
13649   for (int i = 0; i < argc; ++i) {
13650     int bufSize = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr);
13651
13652     utf8Argv[i] = new char[bufSize];
13653
13654     WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr);
13655   }
13656
13657   int returnCode = applyCommandLine(argc, utf8Argv);
13658
13659   for (int i = 0; i < argc; ++i)
13660     delete[] utf8Argv[i];
13661
13662   delete[] utf8Argv;
13663
13664   return returnCode;
13665 }
13666 #endif
13667
13668 void Session::useConfigData(ConfigData const& configData)
13669 {
13670   m_configData = configData;
13671   m_config.reset();
13672 }
13673
13674 int Session::run()
13675 {
13676   if ((m_configData.waitForKeypress & WaitForKeypress::BeforeStart) != 0) {
13677     Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
13678     static_cast<void>(std::getchar());
13679   }
13680   int exitCode = runInternal();
13681   if ((m_configData.waitForKeypress & WaitForKeypress::BeforeExit) != 0) {
13682     Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
13683     static_cast<void>(std::getchar());
13684   }
13685   return exitCode;
13686 }
13687
13688 clara::Parser const& Session::cli() const
13689 {
13690   return m_cli;
13691 }
13692 void Session::cli(clara::Parser const& newParser)
13693 {
13694   m_cli = newParser;
13695 }
13696 ConfigData& Session::configData()
13697 {
13698   return m_configData;
13699 }
13700 Config& Session::config()
13701 {
13702   if (!m_config)
13703     m_config = std::make_shared<Config>(m_configData);
13704   return *m_config;
13705 }
13706
13707 int Session::runInternal()
13708 {
13709   if (m_startupExceptions)
13710     return 1;
13711
13712   if (m_configData.showHelp || m_configData.libIdentify) {
13713     return 0;
13714   }
13715
13716   CATCH_TRY
13717   {
13718     config(); // Force config to be constructed
13719
13720     seedRng(*m_config);
13721
13722     if (m_configData.filenamesAsTags)
13723       applyFilenamesAsTags(*m_config);
13724
13725     // Handle list request
13726     if (Option<std::size_t> listed = list(m_config))
13727       return static_cast<int>(*listed);
13728
13729     TestGroup tests{m_config};
13730     auto const totals = tests.execute();
13731
13732     if (m_config->warnAboutNoTests() && totals.error == -1)
13733       return 2;
13734
13735     // Note that on unices only the lower 8 bits are usually used, clamping
13736     // the return value to 255 prevents false negative when some multiple
13737     // of 256 tests has failed
13738     return (std::min)(MaxExitCode, (std::max)(totals.error, static_cast<int>(totals.assertions.failed)));
13739   }
13740 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13741   catch (std::exception& ex)
13742   {
13743     Catch::cerr() << ex.what() << std::endl;
13744     return MaxExitCode;
13745   }
13746 #endif
13747 }
13748
13749 } // end namespace Catch
13750 // end catch_session.cpp
13751 // start catch_singletons.cpp
13752
13753 #include <vector>
13754
13755 namespace Catch {
13756
13757 namespace {
13758 static auto getSingletons() -> std::vector<ISingleton*>*&
13759 {
13760   static std::vector<ISingleton*>* g_singletons = nullptr;
13761   if (!g_singletons)
13762     g_singletons = new std::vector<ISingleton*>();
13763   return g_singletons;
13764 }
13765 } // namespace
13766
13767 ISingleton::~ISingleton() {}
13768
13769 void addSingleton(ISingleton* singleton)
13770 {
13771   getSingletons()->push_back(singleton);
13772 }
13773 void cleanupSingletons()
13774 {
13775   auto& singletons = getSingletons();
13776   for (auto singleton : *singletons)
13777     delete singleton;
13778   delete singletons;
13779   singletons = nullptr;
13780 }
13781
13782 } // namespace Catch
13783 // end catch_singletons.cpp
13784 // start catch_startup_exception_registry.cpp
13785
13786 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13787 namespace Catch {
13788 void StartupExceptionRegistry::add(std::exception_ptr const& exception) noexcept
13789 {
13790   CATCH_TRY
13791   {
13792     m_exceptions.push_back(exception);
13793   }
13794   CATCH_CATCH_ALL
13795   {
13796     // If we run out of memory during start-up there's really not a lot more we can do about it
13797     std::terminate();
13798   }
13799 }
13800
13801 std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept
13802 {
13803   return m_exceptions;
13804 }
13805
13806 } // end namespace Catch
13807 #endif
13808 // end catch_startup_exception_registry.cpp
13809 // start catch_stream.cpp
13810
13811 #include <cstdio>
13812 #include <fstream>
13813 #include <iostream>
13814 #include <memory>
13815 #include <sstream>
13816 #include <vector>
13817
13818 namespace Catch {
13819
13820 Catch::IStream::~IStream() = default;
13821
13822 namespace Detail {
13823 namespace {
13824 template <typename WriterF, std::size_t bufferSize = 256> class StreamBufImpl : public std::streambuf {
13825   char data[bufferSize];
13826   WriterF m_writer;
13827
13828 public:
13829   StreamBufImpl() { setp(data, data + sizeof(data)); }
13830
13831   ~StreamBufImpl() noexcept { StreamBufImpl::sync(); }
13832
13833 private:
13834   int overflow(int c) override
13835   {
13836     sync();
13837
13838     if (c != EOF) {
13839       if (pbase() == epptr())
13840         m_writer(std::string(1, static_cast<char>(c)));
13841       else
13842         sputc(static_cast<char>(c));
13843     }
13844     return 0;
13845   }
13846
13847   int sync() override
13848   {
13849     if (pbase() != pptr()) {
13850       m_writer(std::string(pbase(), static_cast<std::string::size_type>(pptr() - pbase())));
13851       setp(pbase(), epptr());
13852     }
13853     return 0;
13854   }
13855 };
13856
13857 ///////////////////////////////////////////////////////////////////////////
13858
13859 struct OutputDebugWriter {
13860
13861   void operator()(std::string const& str) { writeToDebugConsole(str); }
13862 };
13863
13864 ///////////////////////////////////////////////////////////////////////////
13865
13866 class FileStream : public IStream {
13867   mutable std::ofstream m_ofs;
13868
13869 public:
13870   FileStream(StringRef filename)
13871   {
13872     m_ofs.open(filename.c_str());
13873     CATCH_ENFORCE(!m_ofs.fail(), "Unable to open file: '" << filename << "'");
13874   }
13875   ~FileStream() override = default;
13876
13877 public: // IStream
13878   std::ostream& stream() const override { return m_ofs; }
13879 };
13880
13881 ///////////////////////////////////////////////////////////////////////////
13882
13883 class CoutStream : public IStream {
13884   mutable std::ostream m_os;
13885
13886 public:
13887   // Store the streambuf from cout up-front because
13888   // cout may get redirected when running tests
13889   CoutStream() : m_os(Catch::cout().rdbuf()) {}
13890   ~CoutStream() override = default;
13891
13892 public: // IStream
13893   std::ostream& stream() const override { return m_os; }
13894 };
13895
13896 ///////////////////////////////////////////////////////////////////////////
13897
13898 class DebugOutStream : public IStream {
13899   std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
13900   mutable std::ostream m_os;
13901
13902 public:
13903   DebugOutStream() : m_streamBuf(new StreamBufImpl<OutputDebugWriter>()), m_os(m_streamBuf.get()) {}
13904
13905   ~DebugOutStream() override = default;
13906
13907 public: // IStream
13908   std::ostream& stream() const override { return m_os; }
13909 };
13910
13911 } // namespace
13912 } // namespace Detail
13913
13914 ///////////////////////////////////////////////////////////////////////////
13915
13916 auto makeStream(StringRef const& filename) -> IStream const*
13917 {
13918   if (filename.empty())
13919     return new Detail::CoutStream();
13920   else if (filename[0] == '%') {
13921     if (filename == "%debug")
13922       return new Detail::DebugOutStream();
13923     else
13924       CATCH_ERROR("Unrecognised stream: '" << filename << "'");
13925   } else
13926     return new Detail::FileStream(filename);
13927 }
13928
13929 // This class encapsulates the idea of a pool of ostringstreams that can be reused.
13930 struct StringStreams {
13931   std::vector<std::unique_ptr<std::ostringstream>> m_streams;
13932   std::vector<std::size_t> m_unused;
13933   std::ostringstream m_referenceStream; // Used for copy state/ flags from
13934
13935   auto add() -> std::size_t
13936   {
13937     if (m_unused.empty()) {
13938       m_streams.push_back(std::unique_ptr<std::ostringstream>(new std::ostringstream));
13939       return m_streams.size() - 1;
13940     } else {
13941       auto index = m_unused.back();
13942       m_unused.pop_back();
13943       return index;
13944     }
13945   }
13946
13947   void release(std::size_t index)
13948   {
13949     m_streams[index]->copyfmt(m_referenceStream); // Restore initial flags and other state
13950     m_unused.push_back(index);
13951   }
13952 };
13953
13954 ReusableStringStream::ReusableStringStream()
13955     : m_index(Singleton<StringStreams>::getMutable().add())
13956     , m_oss(Singleton<StringStreams>::getMutable().m_streams[m_index].get())
13957 {
13958 }
13959
13960 ReusableStringStream::~ReusableStringStream()
13961 {
13962   static_cast<std::ostringstream*>(m_oss)->str("");
13963   m_oss->clear();
13964   Singleton<StringStreams>::getMutable().release(m_index);
13965 }
13966
13967 auto ReusableStringStream::str() const -> std::string
13968 {
13969   return static_cast<std::ostringstream*>(m_oss)->str();
13970 }
13971
13972 ///////////////////////////////////////////////////////////////////////////
13973
13974 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
13975 std::ostream& cout()
13976 {
13977   return std::cout;
13978 }
13979 std::ostream& cerr()
13980 {
13981   return std::cerr;
13982 }
13983 std::ostream& clog()
13984 {
13985   return std::clog;
13986 }
13987 #endif
13988 } // namespace Catch
13989 // end catch_stream.cpp
13990 // start catch_string_manip.cpp
13991
13992 #include <algorithm>
13993 #include <cctype>
13994 #include <cstring>
13995 #include <ostream>
13996 #include <vector>
13997
13998 namespace Catch {
13999
14000 namespace {
14001 char toLowerCh(char c)
14002 {
14003   return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
14004 }
14005 } // namespace
14006
14007 bool startsWith(std::string const& s, std::string const& prefix)
14008 {
14009   return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
14010 }
14011 bool startsWith(std::string const& s, char prefix)
14012 {
14013   return !s.empty() && s[0] == prefix;
14014 }
14015 bool endsWith(std::string const& s, std::string const& suffix)
14016 {
14017   return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
14018 }
14019 bool endsWith(std::string const& s, char suffix)
14020 {
14021   return !s.empty() && s[s.size() - 1] == suffix;
14022 }
14023 bool contains(std::string const& s, std::string const& infix)
14024 {
14025   return s.find(infix) != std::string::npos;
14026 }
14027 void toLowerInPlace(std::string& s)
14028 {
14029   std::transform(s.begin(), s.end(), s.begin(), toLowerCh);
14030 }
14031 std::string toLower(std::string const& s)
14032 {
14033   std::string lc = s;
14034   toLowerInPlace(lc);
14035   return lc;
14036 }
14037 std::string trim(std::string const& str)
14038 {
14039   static char const* whitespaceChars = "\n\r\t ";
14040   std::string::size_type start       = str.find_first_not_of(whitespaceChars);
14041   std::string::size_type end         = str.find_last_not_of(whitespaceChars);
14042
14043   return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
14044 }
14045
14046 StringRef trim(StringRef ref)
14047 {
14048   const auto is_ws  = [](char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; };
14049   size_t real_begin = 0;
14050   while (real_begin < ref.size() && is_ws(ref[real_begin])) {
14051     ++real_begin;
14052   }
14053   size_t real_end = ref.size();
14054   while (real_end > real_begin && is_ws(ref[real_end - 1])) {
14055     --real_end;
14056   }
14057
14058   return ref.substr(real_begin, real_end - real_begin);
14059 }
14060
14061 bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis)
14062 {
14063   bool replaced = false;
14064   std::size_t i = str.find(replaceThis);
14065   while (i != std::string::npos) {
14066     replaced = true;
14067     str      = str.substr(0, i) + withThis + str.substr(i + replaceThis.size());
14068     if (i < str.size() - withThis.size())
14069       i = str.find(replaceThis, i + withThis.size());
14070     else
14071       i = std::string::npos;
14072   }
14073   return replaced;
14074 }
14075
14076 std::vector<StringRef> splitStringRef(StringRef str, char delimiter)
14077 {
14078   std::vector<StringRef> subStrings;
14079   std::size_t start = 0;
14080   for (std::size_t pos = 0; pos < str.size(); ++pos) {
14081     if (str[pos] == delimiter) {
14082       if (pos - start > 1)
14083         subStrings.push_back(str.substr(start, pos - start));
14084       start = pos + 1;
14085     }
14086   }
14087   if (start < str.size())
14088     subStrings.push_back(str.substr(start, str.size() - start));
14089   return subStrings;
14090 }
14091
14092 pluralise::pluralise(std::size_t count, std::string const& label) : m_count(count), m_label(label) {}
14093
14094 std::ostream& operator<<(std::ostream& os, pluralise const& pluraliser)
14095 {
14096   os << pluraliser.m_count << ' ' << pluraliser.m_label;
14097   if (pluraliser.m_count != 1)
14098     os << 's';
14099   return os;
14100 }
14101
14102 } // namespace Catch
14103 // end catch_string_manip.cpp
14104 // start catch_stringref.cpp
14105
14106 #include <algorithm>
14107 #include <cstdint>
14108 #include <cstring>
14109 #include <ostream>
14110
14111 namespace Catch {
14112 StringRef::StringRef(char const* rawChars) noexcept
14113     : StringRef(rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars)))
14114 {
14115 }
14116
14117 auto StringRef::c_str() const -> char const*
14118 {
14119   CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
14120   return m_start;
14121 }
14122 auto StringRef::data() const noexcept -> char const*
14123 {
14124   return m_start;
14125 }
14126
14127 auto StringRef::substr(size_type start, size_type size) const noexcept -> StringRef
14128 {
14129   if (start < m_size) {
14130     return StringRef(m_start + start, (std::min)(m_size - start, size));
14131   } else {
14132     return StringRef();
14133   }
14134 }
14135 auto StringRef::operator==(StringRef const& other) const noexcept -> bool
14136 {
14137   return m_size == other.m_size && (std::memcmp(m_start, other.m_start, m_size) == 0);
14138 }
14139
14140 auto operator<<(std::ostream& os, StringRef const& str) -> std::ostream&
14141 {
14142   return os.write(str.data(), str.size());
14143 }
14144
14145 auto operator+=(std::string& lhs, StringRef const& rhs) -> std::string&
14146 {
14147   lhs.append(rhs.data(), rhs.size());
14148   return lhs;
14149 }
14150
14151 } // namespace Catch
14152 // end catch_stringref.cpp
14153 // start catch_tag_alias.cpp
14154
14155 namespace Catch {
14156 TagAlias::TagAlias(std::string const& _tag, SourceLineInfo _lineInfo) : tag(_tag), lineInfo(_lineInfo) {}
14157 } // namespace Catch
14158 // end catch_tag_alias.cpp
14159 // start catch_tag_alias_autoregistrar.cpp
14160
14161 namespace Catch {
14162
14163 RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo)
14164 {
14165   CATCH_TRY
14166   {
14167     getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
14168   }
14169   CATCH_CATCH_ALL
14170   {
14171     // Do not throw when constructing global objects, instead register the exception to be processed later
14172     getMutableRegistryHub().registerStartupException();
14173   }
14174 }
14175
14176 } // namespace Catch
14177 // end catch_tag_alias_autoregistrar.cpp
14178 // start catch_tag_alias_registry.cpp
14179
14180 #include <sstream>
14181
14182 namespace Catch {
14183
14184 TagAliasRegistry::~TagAliasRegistry() {}
14185
14186 TagAlias const* TagAliasRegistry::find(std::string const& alias) const
14187 {
14188   auto it = m_registry.find(alias);
14189   if (it != m_registry.end())
14190     return &(it->second);
14191   else
14192     return nullptr;
14193 }
14194
14195 std::string TagAliasRegistry::expandAliases(std::string const& unexpandedTestSpec) const
14196 {
14197   std::string expandedTestSpec = unexpandedTestSpec;
14198   for (auto const& registryKvp : m_registry) {
14199     std::size_t pos = expandedTestSpec.find(registryKvp.first);
14200     if (pos != std::string::npos) {
14201       expandedTestSpec = expandedTestSpec.substr(0, pos) + registryKvp.second.tag +
14202                          expandedTestSpec.substr(pos + registryKvp.first.size());
14203     }
14204   }
14205   return expandedTestSpec;
14206 }
14207
14208 void TagAliasRegistry::add(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo)
14209 {
14210   CATCH_ENFORCE(startsWith(alias, "[@") && endsWith(alias, ']'), "error: tag alias, '"
14211                                                                      << alias << "' is not of the form [@alias name].\n"
14212                                                                      << lineInfo);
14213
14214   CATCH_ENFORCE(m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
14215                 "error: tag alias, '" << alias << "' already registered.\n"
14216                                       << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
14217                                       << "\tRedefined at: " << lineInfo);
14218 }
14219
14220 ITagAliasRegistry::~ITagAliasRegistry() {}
14221
14222 ITagAliasRegistry const& ITagAliasRegistry::get()
14223 {
14224   return getRegistryHub().getTagAliasRegistry();
14225 }
14226
14227 } // end namespace Catch
14228 // end catch_tag_alias_registry.cpp
14229 // start catch_test_case_info.cpp
14230
14231 #include <algorithm>
14232 #include <cctype>
14233 #include <exception>
14234 #include <sstream>
14235
14236 namespace Catch {
14237
14238 namespace {
14239 TestCaseInfo::SpecialProperties parseSpecialTag(std::string const& tag)
14240 {
14241   if (startsWith(tag, '.') || tag == "!hide")
14242     return TestCaseInfo::IsHidden;
14243   else if (tag == "!throws")
14244     return TestCaseInfo::Throws;
14245   else if (tag == "!shouldfail")
14246     return TestCaseInfo::ShouldFail;
14247   else if (tag == "!mayfail")
14248     return TestCaseInfo::MayFail;
14249   else if (tag == "!nonportable")
14250     return TestCaseInfo::NonPortable;
14251   else if (tag == "!benchmark")
14252     return static_cast<TestCaseInfo::SpecialProperties>(TestCaseInfo::Benchmark | TestCaseInfo::IsHidden);
14253   else
14254     return TestCaseInfo::None;
14255 }
14256 bool isReservedTag(std::string const& tag)
14257 {
14258   return parseSpecialTag(tag) == TestCaseInfo::None && tag.size() > 0 &&
14259          !std::isalnum(static_cast<unsigned char>(tag[0]));
14260 }
14261 void enforceNotReservedTag(std::string const& tag, SourceLineInfo const& _lineInfo)
14262 {
14263   CATCH_ENFORCE(!isReservedTag(tag), "Tag name: ["
14264                                          << tag << "] is not allowed.\n"
14265                                          << "Tag names starting with non alphanumeric characters are reserved\n"
14266                                          << _lineInfo);
14267 }
14268 } // namespace
14269
14270 TestCase makeTestCase(ITestInvoker* _testCase, std::string const& _className, NameAndTags const& nameAndTags,
14271                       SourceLineInfo const& _lineInfo)
14272 {
14273   bool isHidden = false;
14274
14275   // Parse out tags
14276   std::vector<std::string> tags;
14277   std::string desc, tag;
14278   bool inTag = false;
14279   for (char c : nameAndTags.tags) {
14280     if (!inTag) {
14281       if (c == '[')
14282         inTag = true;
14283       else
14284         desc += c;
14285     } else {
14286       if (c == ']') {
14287         TestCaseInfo::SpecialProperties prop = parseSpecialTag(tag);
14288         if ((prop & TestCaseInfo::IsHidden) != 0)
14289           isHidden = true;
14290         else if (prop == TestCaseInfo::None)
14291           enforceNotReservedTag(tag, _lineInfo);
14292
14293         // Merged hide tags like `[.approvals]` should be added as
14294         // `[.][approvals]`. The `[.]` is added at later point, so
14295         // we only strip the prefix
14296         if (startsWith(tag, '.') && tag.size() > 1) {
14297           tag.erase(0, 1);
14298         }
14299         tags.push_back(tag);
14300         tag.clear();
14301         inTag = false;
14302       } else
14303         tag += c;
14304     }
14305   }
14306   if (isHidden) {
14307     // Add all "hidden" tags to make them behave identically
14308     tags.insert(tags.end(), {".", "!hide"});
14309   }
14310
14311   TestCaseInfo info(static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo);
14312   return TestCase(_testCase, std::move(info));
14313 }
14314
14315 void setTags(TestCaseInfo& testCaseInfo, std::vector<std::string> tags)
14316 {
14317   std::sort(begin(tags), end(tags));
14318   tags.erase(std::unique(begin(tags), end(tags)), end(tags));
14319   testCaseInfo.lcaseTags.clear();
14320
14321   for (auto const& tag : tags) {
14322     std::string lcaseTag = toLower(tag);
14323     testCaseInfo.properties =
14324         static_cast<TestCaseInfo::SpecialProperties>(testCaseInfo.properties | parseSpecialTag(lcaseTag));
14325     testCaseInfo.lcaseTags.push_back(lcaseTag);
14326   }
14327   testCaseInfo.tags = std::move(tags);
14328 }
14329
14330 TestCaseInfo::TestCaseInfo(std::string const& _name, std::string const& _className, std::string const& _description,
14331                            std::vector<std::string> const& _tags, SourceLineInfo const& _lineInfo)
14332     : name(_name), className(_className), description(_description), lineInfo(_lineInfo), properties(None)
14333 {
14334   setTags(*this, _tags);
14335 }
14336
14337 bool TestCaseInfo::isHidden() const
14338 {
14339   return (properties & IsHidden) != 0;
14340 }
14341 bool TestCaseInfo::throws() const
14342 {
14343   return (properties & Throws) != 0;
14344 }
14345 bool TestCaseInfo::okToFail() const
14346 {
14347   return (properties & (ShouldFail | MayFail)) != 0;
14348 }
14349 bool TestCaseInfo::expectedToFail() const
14350 {
14351   return (properties & (ShouldFail)) != 0;
14352 }
14353
14354 std::string TestCaseInfo::tagsAsString() const
14355 {
14356   std::string ret;
14357   // '[' and ']' per tag
14358   std::size_t full_size = 2 * tags.size();
14359   for (const auto& tag : tags) {
14360     full_size += tag.size();
14361   }
14362   ret.reserve(full_size);
14363   for (const auto& tag : tags) {
14364     ret.push_back('[');
14365     ret.append(tag);
14366     ret.push_back(']');
14367   }
14368
14369   return ret;
14370 }
14371
14372 TestCase::TestCase(ITestInvoker* testCase, TestCaseInfo&& info) : TestCaseInfo(std::move(info)), test(testCase) {}
14373
14374 TestCase TestCase::withName(std::string const& _newName) const
14375 {
14376   TestCase other(*this);
14377   other.name = _newName;
14378   return other;
14379 }
14380
14381 void TestCase::invoke() const
14382 {
14383   test->invoke();
14384 }
14385
14386 bool TestCase::operator==(TestCase const& other) const
14387 {
14388   return test.get() == other.test.get() && name == other.name && className == other.className;
14389 }
14390
14391 bool TestCase::operator<(TestCase const& other) const
14392 {
14393   return name < other.name;
14394 }
14395
14396 TestCaseInfo const& TestCase::getTestCaseInfo() const
14397 {
14398   return *this;
14399 }
14400
14401 } // end namespace Catch
14402 // end catch_test_case_info.cpp
14403 // start catch_test_case_registry_impl.cpp
14404
14405 #include <algorithm>
14406 #include <sstream>
14407
14408 namespace Catch {
14409
14410 namespace {
14411 struct TestHasher {
14412   using hash_t = uint64_t;
14413
14414   explicit TestHasher(hash_t hashSuffix) : m_hashSuffix{hashSuffix} {}
14415
14416   uint32_t operator()(TestCase const& t) const
14417   {
14418     // FNV-1a hash with multiplication fold.
14419     const hash_t prime = 1099511628211u;
14420     hash_t hash        = 14695981039346656037u;
14421     for (const char c : t.name) {
14422       hash ^= c;
14423       hash *= prime;
14424     }
14425     hash ^= m_hashSuffix;
14426     hash *= prime;
14427     const uint32_t low{static_cast<uint32_t>(hash)};
14428     const uint32_t high{static_cast<uint32_t>(hash >> 32)};
14429     return low * high;
14430   }
14431
14432 private:
14433   hash_t m_hashSuffix;
14434 };
14435 } // end unnamed namespace
14436
14437 std::vector<TestCase> sortTests(IConfig const& config, std::vector<TestCase> const& unsortedTestCases)
14438 {
14439   switch (config.runOrder()) {
14440     case RunTests::InDeclarationOrder:
14441       // already in declaration order
14442       break;
14443
14444     case RunTests::InLexicographicalOrder: {
14445       std::vector<TestCase> sorted = unsortedTestCases;
14446       std::sort(sorted.begin(), sorted.end());
14447       return sorted;
14448     }
14449
14450     case RunTests::InRandomOrder: {
14451       seedRng(config);
14452       TestHasher h{config.rngSeed()};
14453
14454       using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
14455       std::vector<hashedTest> indexed_tests;
14456       indexed_tests.reserve(unsortedTestCases.size());
14457
14458       for (auto const& testCase : unsortedTestCases) {
14459         indexed_tests.emplace_back(h(testCase), &testCase);
14460       }
14461
14462       std::sort(indexed_tests.begin(), indexed_tests.end(), [](hashedTest const& lhs, hashedTest const& rhs) {
14463         if (lhs.first == rhs.first) {
14464           return lhs.second->name < rhs.second->name;
14465         }
14466         return lhs.first < rhs.first;
14467       });
14468
14469       std::vector<TestCase> sorted;
14470       sorted.reserve(indexed_tests.size());
14471
14472       for (auto const& hashed : indexed_tests) {
14473         sorted.emplace_back(*hashed.second);
14474       }
14475
14476       return sorted;
14477     }
14478   }
14479   return unsortedTestCases;
14480 }
14481
14482 bool isThrowSafe(TestCase const& testCase, IConfig const& config)
14483 {
14484   return !testCase.throws() || config.allowThrows();
14485 }
14486
14487 bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config)
14488 {
14489   return testSpec.matches(testCase) && isThrowSafe(testCase, config);
14490 }
14491
14492 void enforceNoDuplicateTestCases(std::vector<TestCase> const& functions)
14493 {
14494   std::set<TestCase> seenFunctions;
14495   for (auto const& function : functions) {
14496     auto prev = seenFunctions.insert(function);
14497     CATCH_ENFORCE(prev.second, "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
14498                                                       << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo
14499                                                       << "\n"
14500                                                       << "\tRedefined at " << function.getTestCaseInfo().lineInfo);
14501   }
14502 }
14503
14504 std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec,
14505                                   IConfig const& config)
14506 {
14507   std::vector<TestCase> filtered;
14508   filtered.reserve(testCases.size());
14509   for (auto const& testCase : testCases) {
14510     if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
14511         (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
14512       filtered.push_back(testCase);
14513     }
14514   }
14515   return filtered;
14516 }
14517 std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config)
14518 {
14519   return getRegistryHub().getTestCaseRegistry().getAllTestsSorted(config);
14520 }
14521
14522 void TestRegistry::registerTest(TestCase const& testCase)
14523 {
14524   std::string name = testCase.getTestCaseInfo().name;
14525   if (name.empty()) {
14526     ReusableStringStream rss;
14527     rss << "Anonymous test case " << ++m_unnamedCount;
14528     return registerTest(testCase.withName(rss.str()));
14529   }
14530   m_functions.push_back(testCase);
14531 }
14532
14533 std::vector<TestCase> const& TestRegistry::getAllTests() const
14534 {
14535   return m_functions;
14536 }
14537 std::vector<TestCase> const& TestRegistry::getAllTestsSorted(IConfig const& config) const
14538 {
14539   if (m_sortedFunctions.empty())
14540     enforceNoDuplicateTestCases(m_functions);
14541
14542   if (m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty()) {
14543     m_sortedFunctions  = sortTests(config, m_functions);
14544     m_currentSortOrder = config.runOrder();
14545   }
14546   return m_sortedFunctions;
14547 }
14548
14549 ///////////////////////////////////////////////////////////////////////////
14550 TestInvokerAsFunction::TestInvokerAsFunction(void (*testAsFunction)()) noexcept : m_testAsFunction(testAsFunction) {}
14551
14552 void TestInvokerAsFunction::invoke() const
14553 {
14554   m_testAsFunction();
14555 }
14556
14557 std::string extractClassName(StringRef const& classOrQualifiedMethodName)
14558 {
14559   std::string className(classOrQualifiedMethodName);
14560   if (startsWith(className, '&')) {
14561     std::size_t lastColons        = className.rfind("::");
14562     std::size_t penultimateColons = className.rfind("::", lastColons - 1);
14563     if (penultimateColons == std::string::npos)
14564       penultimateColons = 1;
14565     className = className.substr(penultimateColons, lastColons - penultimateColons);
14566   }
14567   return className;
14568 }
14569
14570 } // end namespace Catch
14571 // end catch_test_case_registry_impl.cpp
14572 // start catch_test_case_tracker.cpp
14573
14574 #include <algorithm>
14575 #include <cassert>
14576 #include <memory>
14577 #include <sstream>
14578 #include <stdexcept>
14579
14580 #if defined(__clang__)
14581 #pragma clang diagnostic push
14582 #pragma clang diagnostic ignored "-Wexit-time-destructors"
14583 #endif
14584
14585 namespace Catch {
14586 namespace TestCaseTracking {
14587
14588 NameAndLocation::NameAndLocation(std::string const& _name, SourceLineInfo const& _location)
14589     : name(_name), location(_location)
14590 {
14591 }
14592
14593 ITracker::~ITracker() = default;
14594
14595 ITracker& TrackerContext::startRun()
14596 {
14597   m_rootTracker = std::make_shared<SectionTracker>(NameAndLocation("{root}", CATCH_INTERNAL_LINEINFO), *this, nullptr);
14598   m_currentTracker = nullptr;
14599   m_runState       = Executing;
14600   return *m_rootTracker;
14601 }
14602
14603 void TrackerContext::endRun()
14604 {
14605   m_rootTracker.reset();
14606   m_currentTracker = nullptr;
14607   m_runState       = NotStarted;
14608 }
14609
14610 void TrackerContext::startCycle()
14611 {
14612   m_currentTracker = m_rootTracker.get();
14613   m_runState       = Executing;
14614 }
14615 void TrackerContext::completeCycle()
14616 {
14617   m_runState = CompletedCycle;
14618 }
14619
14620 bool TrackerContext::completedCycle() const
14621 {
14622   return m_runState == CompletedCycle;
14623 }
14624 ITracker& TrackerContext::currentTracker()
14625 {
14626   return *m_currentTracker;
14627 }
14628 void TrackerContext::setCurrentTracker(ITracker* tracker)
14629 {
14630   m_currentTracker = tracker;
14631 }
14632
14633 TrackerBase::TrackerBase(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
14634     : ITracker(nameAndLocation), m_ctx(ctx), m_parent(parent)
14635 {
14636 }
14637
14638 bool TrackerBase::isComplete() const
14639 {
14640   return m_runState == CompletedSuccessfully || m_runState == Failed;
14641 }
14642 bool TrackerBase::isSuccessfullyCompleted() const
14643 {
14644   return m_runState == CompletedSuccessfully;
14645 }
14646 bool TrackerBase::isOpen() const
14647 {
14648   return m_runState != NotStarted && !isComplete();
14649 }
14650 bool TrackerBase::hasChildren() const
14651 {
14652   return !m_children.empty();
14653 }
14654
14655 void TrackerBase::addChild(ITrackerPtr const& child)
14656 {
14657   m_children.push_back(child);
14658 }
14659
14660 ITrackerPtr TrackerBase::findChild(NameAndLocation const& nameAndLocation)
14661 {
14662   auto it = std::find_if(m_children.begin(), m_children.end(), [&nameAndLocation](ITrackerPtr const& tracker) {
14663     return tracker->nameAndLocation().location == nameAndLocation.location &&
14664            tracker->nameAndLocation().name == nameAndLocation.name;
14665   });
14666   return (it != m_children.end()) ? *it : nullptr;
14667 }
14668 ITracker& TrackerBase::parent()
14669 {
14670   assert(m_parent); // Should always be non-null except for root
14671   return *m_parent;
14672 }
14673
14674 void TrackerBase::openChild()
14675 {
14676   if (m_runState != ExecutingChildren) {
14677     m_runState = ExecutingChildren;
14678     if (m_parent)
14679       m_parent->openChild();
14680   }
14681 }
14682
14683 bool TrackerBase::isSectionTracker() const
14684 {
14685   return false;
14686 }
14687 bool TrackerBase::isGeneratorTracker() const
14688 {
14689   return false;
14690 }
14691
14692 void TrackerBase::open()
14693 {
14694   m_runState = Executing;
14695   moveToThis();
14696   if (m_parent)
14697     m_parent->openChild();
14698 }
14699
14700 void TrackerBase::close()
14701 {
14702
14703   // Close any still open children (e.g. generators)
14704   while (&m_ctx.currentTracker() != this)
14705     m_ctx.currentTracker().close();
14706
14707   switch (m_runState) {
14708     case NeedsAnotherRun:
14709       break;
14710
14711     case Executing:
14712       m_runState = CompletedSuccessfully;
14713       break;
14714     case ExecutingChildren:
14715       if (std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t) { return t->isComplete(); }))
14716         m_runState = CompletedSuccessfully;
14717       break;
14718
14719     case NotStarted:
14720     case CompletedSuccessfully:
14721     case Failed:
14722       CATCH_INTERNAL_ERROR("Illogical state: " << m_runState);
14723
14724     default:
14725       CATCH_INTERNAL_ERROR("Unknown state: " << m_runState);
14726   }
14727   moveToParent();
14728   m_ctx.completeCycle();
14729 }
14730 void TrackerBase::fail()
14731 {
14732   m_runState = Failed;
14733   if (m_parent)
14734     m_parent->markAsNeedingAnotherRun();
14735   moveToParent();
14736   m_ctx.completeCycle();
14737 }
14738 void TrackerBase::markAsNeedingAnotherRun()
14739 {
14740   m_runState = NeedsAnotherRun;
14741 }
14742
14743 void TrackerBase::moveToParent()
14744 {
14745   assert(m_parent);
14746   m_ctx.setCurrentTracker(m_parent);
14747 }
14748 void TrackerBase::moveToThis()
14749 {
14750   m_ctx.setCurrentTracker(this);
14751 }
14752
14753 SectionTracker::SectionTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
14754     : TrackerBase(nameAndLocation, ctx, parent), m_trimmed_name(trim(nameAndLocation.name))
14755 {
14756   if (parent) {
14757     while (!parent->isSectionTracker())
14758       parent = &parent->parent();
14759
14760     SectionTracker& parentSection = static_cast<SectionTracker&>(*parent);
14761     addNextFilters(parentSection.m_filters);
14762   }
14763 }
14764
14765 bool SectionTracker::isComplete() const
14766 {
14767   bool complete = true;
14768
14769   if (m_filters.empty() || m_filters[0] == "" ||
14770       std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
14771     complete = TrackerBase::isComplete();
14772   }
14773   return complete;
14774 }
14775
14776 bool SectionTracker::isSectionTracker() const
14777 {
14778   return true;
14779 }
14780
14781 SectionTracker& SectionTracker::acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation)
14782 {
14783   std::shared_ptr<SectionTracker> section;
14784
14785   ITracker& currentTracker = ctx.currentTracker();
14786   if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
14787     assert(childTracker);
14788     assert(childTracker->isSectionTracker());
14789     section = std::static_pointer_cast<SectionTracker>(childTracker);
14790   } else {
14791     section = std::make_shared<SectionTracker>(nameAndLocation, ctx, &currentTracker);
14792     currentTracker.addChild(section);
14793   }
14794   if (!ctx.completedCycle())
14795     section->tryOpen();
14796   return *section;
14797 }
14798
14799 void SectionTracker::tryOpen()
14800 {
14801   if (!isComplete())
14802     open();
14803 }
14804
14805 void SectionTracker::addInitialFilters(std::vector<std::string> const& filters)
14806 {
14807   if (!filters.empty()) {
14808     m_filters.reserve(m_filters.size() + filters.size() + 2);
14809     m_filters.emplace_back(""); // Root - should never be consulted
14810     m_filters.emplace_back(""); // Test Case - not a section filter
14811     m_filters.insert(m_filters.end(), filters.begin(), filters.end());
14812   }
14813 }
14814 void SectionTracker::addNextFilters(std::vector<std::string> const& filters)
14815 {
14816   if (filters.size() > 1)
14817     m_filters.insert(m_filters.end(), filters.begin() + 1, filters.end());
14818 }
14819
14820 std::vector<std::string> const& SectionTracker::getFilters() const
14821 {
14822   return m_filters;
14823 }
14824
14825 std::string const& SectionTracker::trimmedName() const
14826 {
14827   return m_trimmed_name;
14828 }
14829
14830 } // namespace TestCaseTracking
14831
14832 using TestCaseTracking::ITracker;
14833 using TestCaseTracking::SectionTracker;
14834 using TestCaseTracking::TrackerContext;
14835
14836 } // namespace Catch
14837
14838 #if defined(__clang__)
14839 #pragma clang diagnostic pop
14840 #endif
14841 // end catch_test_case_tracker.cpp
14842 // start catch_test_registry.cpp
14843
14844 namespace Catch {
14845
14846 auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker*
14847 {
14848   return new (std::nothrow) TestInvokerAsFunction(testAsFunction);
14849 }
14850
14851 NameAndTags::NameAndTags(StringRef const& name_, StringRef const& tags_) noexcept : name(name_), tags(tags_) {}
14852
14853 AutoReg::AutoReg(ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod,
14854                  NameAndTags const& nameAndTags) noexcept
14855 {
14856   CATCH_TRY
14857   {
14858     getMutableRegistryHub().registerTest(makeTestCase(invoker, extractClassName(classOrMethod), nameAndTags, lineInfo));
14859   }
14860   CATCH_CATCH_ALL
14861   {
14862     // Do not throw when constructing global objects, instead register the exception to be processed later
14863     getMutableRegistryHub().registerStartupException();
14864   }
14865 }
14866
14867 AutoReg::~AutoReg() = default;
14868 } // namespace Catch
14869 // end catch_test_registry.cpp
14870 // start catch_test_spec.cpp
14871
14872 #include <algorithm>
14873 #include <memory>
14874 #include <string>
14875 #include <vector>
14876
14877 namespace Catch {
14878
14879 TestSpec::Pattern::Pattern(std::string const& name) : m_name(name) {}
14880
14881 TestSpec::Pattern::~Pattern() = default;
14882
14883 std::string const& TestSpec::Pattern::name() const
14884 {
14885   return m_name;
14886 }
14887
14888 TestSpec::NamePattern::NamePattern(std::string const& name, std::string const& filterString)
14889     : Pattern(filterString), m_wildcardPattern(toLower(name), CaseSensitive::No)
14890 {
14891 }
14892
14893 bool TestSpec::NamePattern::matches(TestCaseInfo const& testCase) const
14894 {
14895   return m_wildcardPattern.matches(testCase.name);
14896 }
14897
14898 TestSpec::TagPattern::TagPattern(std::string const& tag, std::string const& filterString)
14899     : Pattern(filterString), m_tag(toLower(tag))
14900 {
14901 }
14902
14903 bool TestSpec::TagPattern::matches(TestCaseInfo const& testCase) const
14904 {
14905   return std::find(begin(testCase.lcaseTags), end(testCase.lcaseTags), m_tag) != end(testCase.lcaseTags);
14906 }
14907
14908 TestSpec::ExcludedPattern::ExcludedPattern(PatternPtr const& underlyingPattern)
14909     : Pattern(underlyingPattern->name()), m_underlyingPattern(underlyingPattern)
14910 {
14911 }
14912
14913 bool TestSpec::ExcludedPattern::matches(TestCaseInfo const& testCase) const
14914 {
14915   return !m_underlyingPattern->matches(testCase);
14916 }
14917
14918 bool TestSpec::Filter::matches(TestCaseInfo const& testCase) const
14919 {
14920   return std::all_of(m_patterns.begin(), m_patterns.end(), [&](PatternPtr const& p) { return p->matches(testCase); });
14921 }
14922
14923 std::string TestSpec::Filter::name() const
14924 {
14925   std::string name;
14926   for (auto const& p : m_patterns)
14927     name += p->name();
14928   return name;
14929 }
14930
14931 bool TestSpec::hasFilters() const
14932 {
14933   return !m_filters.empty();
14934 }
14935
14936 bool TestSpec::matches(TestCaseInfo const& testCase) const
14937 {
14938   return std::any_of(m_filters.begin(), m_filters.end(), [&](Filter const& f) { return f.matches(testCase); });
14939 }
14940
14941 TestSpec::Matches TestSpec::matchesByFilter(std::vector<TestCase> const& testCases, IConfig const& config) const
14942 {
14943   Matches matches(m_filters.size());
14944   std::transform(m_filters.begin(), m_filters.end(), matches.begin(), [&](Filter const& filter) {
14945     std::vector<TestCase const*> currentMatches;
14946     for (auto const& test : testCases)
14947       if (isThrowSafe(test, config) && filter.matches(test))
14948         currentMatches.emplace_back(&test);
14949     return FilterMatch{filter.name(), currentMatches};
14950   });
14951   return matches;
14952 }
14953
14954 const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const
14955 {
14956   return (m_invalidArgs);
14957 }
14958
14959 } // namespace Catch
14960 // end catch_test_spec.cpp
14961 // start catch_test_spec_parser.cpp
14962
14963 namespace Catch {
14964
14965 TestSpecParser::TestSpecParser(ITagAliasRegistry const& tagAliases) : m_tagAliases(&tagAliases) {}
14966
14967 TestSpecParser& TestSpecParser::parse(std::string const& arg)
14968 {
14969   m_mode      = None;
14970   m_exclusion = false;
14971   m_arg       = m_tagAliases->expandAliases(arg);
14972   m_escapeChars.clear();
14973   m_substring.reserve(m_arg.size());
14974   m_patternName.reserve(m_arg.size());
14975   m_realPatternPos = 0;
14976
14977   for (m_pos = 0; m_pos < m_arg.size(); ++m_pos)
14978     // if visitChar fails
14979     if (!visitChar(m_arg[m_pos])) {
14980       m_testSpec.m_invalidArgs.push_back(arg);
14981       break;
14982     }
14983   endMode();
14984   return *this;
14985 }
14986 TestSpec TestSpecParser::testSpec()
14987 {
14988   addFilter();
14989   return m_testSpec;
14990 }
14991 bool TestSpecParser::visitChar(char c)
14992 {
14993   if ((m_mode != EscapedName) && (c == '\\')) {
14994     escape();
14995     addCharToPattern(c);
14996     return true;
14997   } else if ((m_mode != EscapedName) && (c == ',')) {
14998     return separate();
14999   }
15000
15001   switch (m_mode) {
15002     case None:
15003       if (processNoneChar(c))
15004         return true;
15005       break;
15006     case Name:
15007       processNameChar(c);
15008       break;
15009     case EscapedName:
15010       endMode();
15011       addCharToPattern(c);
15012       return true;
15013     default:
15014     case Tag:
15015     case QuotedName:
15016       if (processOtherChar(c))
15017         return true;
15018       break;
15019   }
15020
15021   m_substring += c;
15022   if (!isControlChar(c)) {
15023     m_patternName += c;
15024     m_realPatternPos++;
15025   }
15026   return true;
15027 }
15028 // Two of the processing methods return true to signal the caller to return
15029 // without adding the given character to the current pattern strings
15030 bool TestSpecParser::processNoneChar(char c)
15031 {
15032   switch (c) {
15033     case ' ':
15034       return true;
15035     case '~':
15036       m_exclusion = true;
15037       return false;
15038     case '[':
15039       startNewMode(Tag);
15040       return false;
15041     case '"':
15042       startNewMode(QuotedName);
15043       return false;
15044     default:
15045       startNewMode(Name);
15046       return false;
15047   }
15048 }
15049 void TestSpecParser::processNameChar(char c)
15050 {
15051   if (c == '[') {
15052     if (m_substring == "exclude:")
15053       m_exclusion = true;
15054     else
15055       endMode();
15056     startNewMode(Tag);
15057   }
15058 }
15059 bool TestSpecParser::processOtherChar(char c)
15060 {
15061   if (!isControlChar(c))
15062     return false;
15063   m_substring += c;
15064   endMode();
15065   return true;
15066 }
15067 void TestSpecParser::startNewMode(Mode mode)
15068 {
15069   m_mode = mode;
15070 }
15071 void TestSpecParser::endMode()
15072 {
15073   switch (m_mode) {
15074     case Name:
15075     case QuotedName:
15076       return addNamePattern();
15077     case Tag:
15078       return addTagPattern();
15079     case EscapedName:
15080       revertBackToLastMode();
15081       return;
15082     case None:
15083     default:
15084       return startNewMode(None);
15085   }
15086 }
15087 void TestSpecParser::escape()
15088 {
15089   saveLastMode();
15090   m_mode = EscapedName;
15091   m_escapeChars.push_back(m_realPatternPos);
15092 }
15093 bool TestSpecParser::isControlChar(char c) const
15094 {
15095   switch (m_mode) {
15096     default:
15097       return false;
15098     case None:
15099       return c == '~';
15100     case Name:
15101       return c == '[';
15102     case EscapedName:
15103       return true;
15104     case QuotedName:
15105       return c == '"';
15106     case Tag:
15107       return c == '[' || c == ']';
15108   }
15109 }
15110
15111 void TestSpecParser::addFilter()
15112 {
15113   if (!m_currentFilter.m_patterns.empty()) {
15114     m_testSpec.m_filters.push_back(m_currentFilter);
15115     m_currentFilter = TestSpec::Filter();
15116   }
15117 }
15118
15119 void TestSpecParser::saveLastMode()
15120 {
15121   lastMode = m_mode;
15122 }
15123
15124 void TestSpecParser::revertBackToLastMode()
15125 {
15126   m_mode = lastMode;
15127 }
15128
15129 bool TestSpecParser::separate()
15130 {
15131   if ((m_mode == QuotedName) || (m_mode == Tag)) {
15132     // invalid argument, signal failure to previous scope.
15133     m_mode = None;
15134     m_pos  = m_arg.size();
15135     m_substring.clear();
15136     m_patternName.clear();
15137     m_realPatternPos = 0;
15138     return false;
15139   }
15140   endMode();
15141   addFilter();
15142   return true; // success
15143 }
15144
15145 std::string TestSpecParser::preprocessPattern()
15146 {
15147   std::string token = m_patternName;
15148   for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
15149     token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
15150   m_escapeChars.clear();
15151   if (startsWith(token, "exclude:")) {
15152     m_exclusion = true;
15153     token       = token.substr(8);
15154   }
15155
15156   m_patternName.clear();
15157   m_realPatternPos = 0;
15158
15159   return token;
15160 }
15161
15162 void TestSpecParser::addNamePattern()
15163 {
15164   auto token = preprocessPattern();
15165
15166   if (!token.empty()) {
15167     TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
15168     if (m_exclusion)
15169       pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
15170     m_currentFilter.m_patterns.push_back(pattern);
15171   }
15172   m_substring.clear();
15173   m_exclusion = false;
15174   m_mode      = None;
15175 }
15176
15177 void TestSpecParser::addTagPattern()
15178 {
15179   auto token = preprocessPattern();
15180
15181   if (!token.empty()) {
15182     // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
15183     // we have to create a separate hide tag and shorten the real one
15184     if (token.size() > 1 && token[0] == '.') {
15185       token.erase(token.begin());
15186       TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
15187       if (m_exclusion) {
15188         pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
15189       }
15190       m_currentFilter.m_patterns.push_back(pattern);
15191     }
15192
15193     TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
15194
15195     if (m_exclusion) {
15196       pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
15197     }
15198     m_currentFilter.m_patterns.push_back(pattern);
15199   }
15200   m_substring.clear();
15201   m_exclusion = false;
15202   m_mode      = None;
15203 }
15204
15205 TestSpec parseTestSpec(std::string const& arg)
15206 {
15207   return TestSpecParser(ITagAliasRegistry::get()).parse(arg).testSpec();
15208 }
15209
15210 } // namespace Catch
15211 // end catch_test_spec_parser.cpp
15212 // start catch_timer.cpp
15213
15214 #include <chrono>
15215
15216 static const uint64_t nanosecondsInSecond = 1000000000;
15217
15218 namespace Catch {
15219
15220 auto getCurrentNanosecondsSinceEpoch() -> uint64_t
15221 {
15222   return std::chrono::duration_cast<std::chrono::nanoseconds>(
15223              std::chrono::high_resolution_clock::now().time_since_epoch())
15224       .count();
15225 }
15226
15227 namespace {
15228 auto estimateClockResolution() -> uint64_t
15229 {
15230   uint64_t sum                     = 0;
15231   static const uint64_t iterations = 1000000;
15232
15233   auto startTime = getCurrentNanosecondsSinceEpoch();
15234
15235   for (std::size_t i = 0; i < iterations; ++i) {
15236
15237     uint64_t ticks;
15238     uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
15239     do {
15240       ticks = getCurrentNanosecondsSinceEpoch();
15241     } while (ticks == baseTicks);
15242
15243     auto delta = ticks - baseTicks;
15244     sum += delta;
15245
15246     // If we have been calibrating for over 3 seconds -- the clock
15247     // is terrible and we should move on.
15248     // TBD: How to signal that the measured resolution is probably wrong?
15249     if (ticks > startTime + 3 * nanosecondsInSecond) {
15250       return sum / (i + 1u);
15251     }
15252   }
15253
15254   // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
15255   // - and potentially do more iterations if there's a high variance.
15256   return sum / iterations;
15257 }
15258 } // namespace
15259 auto getEstimatedClockResolution() -> uint64_t
15260 {
15261   static auto s_resolution = estimateClockResolution();
15262   return s_resolution;
15263 }
15264
15265 void Timer::start()
15266 {
15267   m_nanoseconds = getCurrentNanosecondsSinceEpoch();
15268 }
15269 auto Timer::getElapsedNanoseconds() const -> uint64_t
15270 {
15271   return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
15272 }
15273 auto Timer::getElapsedMicroseconds() const -> uint64_t
15274 {
15275   return getElapsedNanoseconds() / 1000;
15276 }
15277 auto Timer::getElapsedMilliseconds() const -> unsigned int
15278 {
15279   return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
15280 }
15281 auto Timer::getElapsedSeconds() const -> double
15282 {
15283   return getElapsedMicroseconds() / 1000000.0;
15284 }
15285
15286 } // namespace Catch
15287 // end catch_timer.cpp
15288 // start catch_tostring.cpp
15289
15290 #if defined(__clang__)
15291 #pragma clang diagnostic push
15292 #pragma clang diagnostic ignored "-Wexit-time-destructors"
15293 #pragma clang diagnostic ignored "-Wglobal-constructors"
15294 #endif
15295
15296 // Enable specific decls locally
15297 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
15298 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
15299 #endif
15300
15301 #include <cmath>
15302 #include <iomanip>
15303
15304 namespace Catch {
15305
15306 namespace Detail {
15307
15308 const std::string unprintableString = "{?}";
15309
15310 namespace {
15311 const int hexThreshold = 255;
15312
15313 struct Endianness {
15314   enum Arch { Big, Little };
15315
15316   static Arch which()
15317   {
15318     int one = 1;
15319     // If the lowest byte we read is non-zero, we can assume
15320     // that little endian format is used.
15321     auto value = *reinterpret_cast<char*>(&one);
15322     return value ? Little : Big;
15323   }
15324 };
15325 } // namespace
15326
15327 std::string rawMemoryToString(const void* object, std::size_t size)
15328 {
15329   // Reverse order for little endian architectures
15330   int i = 0, end = static_cast<int>(size), inc = 1;
15331   if (Endianness::which() == Endianness::Little) {
15332     i   = end - 1;
15333     end = inc = -1;
15334   }
15335
15336   unsigned char const* bytes = static_cast<unsigned char const*>(object);
15337   ReusableStringStream rss;
15338   rss << "0x" << std::setfill('0') << std::hex;
15339   for (; i != end; i += inc)
15340     rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
15341   return rss.str();
15342 }
15343 } // namespace Detail
15344
15345 template <typename T> std::string fpToString(T value, int precision)
15346 {
15347   if (Catch::isnan(value)) {
15348     return "nan";
15349   }
15350
15351   ReusableStringStream rss;
15352   rss << std::setprecision(precision) << std::fixed << value;
15353   std::string d = rss.str();
15354   std::size_t i = d.find_last_not_of('0');
15355   if (i != std::string::npos && i != d.size() - 1) {
15356     if (d[i] == '.')
15357       i++;
15358     d = d.substr(0, i + 1);
15359   }
15360   return d;
15361 }
15362
15363 //// ======================================================= ////
15364 //
15365 //   Out-of-line defs for full specialization of StringMaker
15366 //
15367 //// ======================================================= ////
15368
15369 std::string StringMaker<std::string>::convert(const std::string& str)
15370 {
15371   if (!getCurrentContext().getConfig()->showInvisibles()) {
15372     return '"' + str + '"';
15373   }
15374
15375   std::string s("\"");
15376   for (char c : str) {
15377     switch (c) {
15378       case '\n':
15379         s.append("\\n");
15380         break;
15381       case '\t':
15382         s.append("\\t");
15383         break;
15384       default:
15385         s.push_back(c);
15386         break;
15387     }
15388   }
15389   s.append("\"");
15390   return s;
15391 }
15392
15393 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15394 std::string StringMaker<std::string_view>::convert(std::string_view str)
15395 {
15396   return ::Catch::Detail::stringify(std::string{str});
15397 }
15398 #endif
15399
15400 std::string StringMaker<char const*>::convert(char const* str)
15401 {
15402   if (str) {
15403     return ::Catch::Detail::stringify(std::string{str});
15404   } else {
15405     return {"{null string}"};
15406   }
15407 }
15408 std::string StringMaker<char*>::convert(char* str)
15409 {
15410   if (str) {
15411     return ::Catch::Detail::stringify(std::string{str});
15412   } else {
15413     return {"{null string}"};
15414   }
15415 }
15416
15417 #ifdef CATCH_CONFIG_WCHAR
15418 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr)
15419 {
15420   std::string s;
15421   s.reserve(wstr.size());
15422   for (auto c : wstr) {
15423     s += (c <= 0xff) ? static_cast<char>(c) : '?';
15424   }
15425   return ::Catch::Detail::stringify(s);
15426 }
15427
15428 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15429 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str)
15430 {
15431   return StringMaker<std::wstring>::convert(std::wstring(str));
15432 }
15433 #endif
15434
15435 std::string StringMaker<wchar_t const*>::convert(wchar_t const* str)
15436 {
15437   if (str) {
15438     return ::Catch::Detail::stringify(std::wstring{str});
15439   } else {
15440     return {"{null string}"};
15441   }
15442 }
15443 std::string StringMaker<wchar_t*>::convert(wchar_t* str)
15444 {
15445   if (str) {
15446     return ::Catch::Detail::stringify(std::wstring{str});
15447   } else {
15448     return {"{null string}"};
15449   }
15450 }
15451 #endif
15452
15453 #if defined(CATCH_CONFIG_CPP17_BYTE)
15454 #include <cstddef>
15455 std::string StringMaker<std::byte>::convert(std::byte value)
15456 {
15457   return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
15458 }
15459 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
15460
15461 std::string StringMaker<int>::convert(int value)
15462 {
15463   return ::Catch::Detail::stringify(static_cast<long long>(value));
15464 }
15465 std::string StringMaker<long>::convert(long value)
15466 {
15467   return ::Catch::Detail::stringify(static_cast<long long>(value));
15468 }
15469 std::string StringMaker<long long>::convert(long long value)
15470 {
15471   ReusableStringStream rss;
15472   rss << value;
15473   if (value > Detail::hexThreshold) {
15474     rss << " (0x" << std::hex << value << ')';
15475   }
15476   return rss.str();
15477 }
15478
15479 std::string StringMaker<unsigned int>::convert(unsigned int value)
15480 {
15481   return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15482 }
15483 std::string StringMaker<unsigned long>::convert(unsigned long value)
15484 {
15485   return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15486 }
15487 std::string StringMaker<unsigned long long>::convert(unsigned long long value)
15488 {
15489   ReusableStringStream rss;
15490   rss << value;
15491   if (value > Detail::hexThreshold) {
15492     rss << " (0x" << std::hex << value << ')';
15493   }
15494   return rss.str();
15495 }
15496
15497 std::string StringMaker<bool>::convert(bool b)
15498 {
15499   return b ? "true" : "false";
15500 }
15501
15502 std::string StringMaker<signed char>::convert(signed char value)
15503 {
15504   if (value == '\r') {
15505     return "'\\r'";
15506   } else if (value == '\f') {
15507     return "'\\f'";
15508   } else if (value == '\n') {
15509     return "'\\n'";
15510   } else if (value == '\t') {
15511     return "'\\t'";
15512   } else if ('\0' <= value && value < ' ') {
15513     return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
15514   } else {
15515     char chstr[] = "' '";
15516     chstr[1]     = value;
15517     return chstr;
15518   }
15519 }
15520 std::string StringMaker<char>::convert(char c)
15521 {
15522   return ::Catch::Detail::stringify(static_cast<signed char>(c));
15523 }
15524 std::string StringMaker<unsigned char>::convert(unsigned char c)
15525 {
15526   return ::Catch::Detail::stringify(static_cast<char>(c));
15527 }
15528
15529 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t)
15530 {
15531   return "nullptr";
15532 }
15533
15534 int StringMaker<float>::precision = 5;
15535
15536 std::string StringMaker<float>::convert(float value)
15537 {
15538   return fpToString(value, precision) + 'f';
15539 }
15540
15541 int StringMaker<double>::precision = 10;
15542
15543 std::string StringMaker<double>::convert(double value)
15544 {
15545   return fpToString(value, precision);
15546 }
15547
15548 std::string ratio_string<std::atto>::symbol()
15549 {
15550   return "a";
15551 }
15552 std::string ratio_string<std::femto>::symbol()
15553 {
15554   return "f";
15555 }
15556 std::string ratio_string<std::pico>::symbol()
15557 {
15558   return "p";
15559 }
15560 std::string ratio_string<std::nano>::symbol()
15561 {
15562   return "n";
15563 }
15564 std::string ratio_string<std::micro>::symbol()
15565 {
15566   return "u";
15567 }
15568 std::string ratio_string<std::milli>::symbol()
15569 {
15570   return "m";
15571 }
15572
15573 } // end namespace Catch
15574
15575 #if defined(__clang__)
15576 #pragma clang diagnostic pop
15577 #endif
15578
15579 // end catch_tostring.cpp
15580 // start catch_totals.cpp
15581
15582 namespace Catch {
15583
15584 Counts Counts::operator-(Counts const& other) const
15585 {
15586   Counts diff;
15587   diff.passed      = passed - other.passed;
15588   diff.failed      = failed - other.failed;
15589   diff.failedButOk = failedButOk - other.failedButOk;
15590   return diff;
15591 }
15592
15593 Counts& Counts::operator+=(Counts const& other)
15594 {
15595   passed += other.passed;
15596   failed += other.failed;
15597   failedButOk += other.failedButOk;
15598   return *this;
15599 }
15600
15601 std::size_t Counts::total() const
15602 {
15603   return passed + failed + failedButOk;
15604 }
15605 bool Counts::allPassed() const
15606 {
15607   return failed == 0 && failedButOk == 0;
15608 }
15609 bool Counts::allOk() const
15610 {
15611   return failed == 0;
15612 }
15613
15614 Totals Totals::operator-(Totals const& other) const
15615 {
15616   Totals diff;
15617   diff.assertions = assertions - other.assertions;
15618   diff.testCases  = testCases - other.testCases;
15619   return diff;
15620 }
15621
15622 Totals& Totals::operator+=(Totals const& other)
15623 {
15624   assertions += other.assertions;
15625   testCases += other.testCases;
15626   return *this;
15627 }
15628
15629 Totals Totals::delta(Totals const& prevTotals) const
15630 {
15631   Totals diff = *this - prevTotals;
15632   if (diff.assertions.failed > 0)
15633     ++diff.testCases.failed;
15634   else if (diff.assertions.failedButOk > 0)
15635     ++diff.testCases.failedButOk;
15636   else
15637     ++diff.testCases.passed;
15638   return diff;
15639 }
15640
15641 } // namespace Catch
15642 // end catch_totals.cpp
15643 // start catch_uncaught_exceptions.cpp
15644
15645 // start catch_config_uncaught_exceptions.hpp
15646
15647 //              Copyright Catch2 Authors
15648 // Distributed under the Boost Software License, Version 1.0.
15649 //   (See accompanying file LICENSE_1_0.txt or copy at
15650 //        https://www.boost.org/LICENSE_1_0.txt)
15651
15652 // SPDX-License-Identifier: BSL-1.0
15653
15654 #ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15655 #define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15656
15657 #if defined(_MSC_VER)
15658 #if _MSC_VER >= 1900 // Visual Studio 2015 or newer
15659 #define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15660 #endif
15661 #endif
15662
15663 #include <exception>
15664
15665 #if defined(__cpp_lib_uncaught_exceptions) && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15666
15667 #define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15668 #endif // __cpp_lib_uncaught_exceptions
15669
15670 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && \
15671     !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15672
15673 #define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15674 #endif
15675
15676 #endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15677 // end catch_config_uncaught_exceptions.hpp
15678 #include <exception>
15679
15680 namespace Catch {
15681 bool uncaught_exceptions()
15682 {
15683 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
15684   return false;
15685 #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15686   return std::uncaught_exceptions() > 0;
15687 #else
15688   return std::uncaught_exception();
15689 #endif
15690 }
15691 } // end namespace Catch
15692 // end catch_uncaught_exceptions.cpp
15693 // start catch_version.cpp
15694
15695 #include <ostream>
15696
15697 namespace Catch {
15698
15699 Version::Version(unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber,
15700                  char const* const _branchName, unsigned int _buildNumber)
15701     : majorVersion(_majorVersion)
15702     , minorVersion(_minorVersion)
15703     , patchNumber(_patchNumber)
15704     , branchName(_branchName)
15705     , buildNumber(_buildNumber)
15706 {
15707 }
15708
15709 std::ostream& operator<<(std::ostream& os, Version const& version)
15710 {
15711   os << version.majorVersion << '.' << version.minorVersion << '.' << version.patchNumber;
15712   // branchName is never null -> 0th char is \0 if it is empty
15713   if (version.branchName[0]) {
15714     os << '-' << version.branchName << '.' << version.buildNumber;
15715   }
15716   return os;
15717 }
15718
15719 Version const& libraryVersion()
15720 {
15721   static Version version(2, 13, 5, "", 0);
15722   return version;
15723 }
15724
15725 } // namespace Catch
15726 // end catch_version.cpp
15727 // start catch_wildcard_pattern.cpp
15728
15729 namespace Catch {
15730
15731 WildcardPattern::WildcardPattern(std::string const& pattern, CaseSensitive::Choice caseSensitivity)
15732     : m_caseSensitivity(caseSensitivity), m_pattern(normaliseString(pattern))
15733 {
15734   if (startsWith(m_pattern, '*')) {
15735     m_pattern  = m_pattern.substr(1);
15736     m_wildcard = WildcardAtStart;
15737   }
15738   if (endsWith(m_pattern, '*')) {
15739     m_pattern  = m_pattern.substr(0, m_pattern.size() - 1);
15740     m_wildcard = static_cast<WildcardPosition>(m_wildcard | WildcardAtEnd);
15741   }
15742 }
15743
15744 bool WildcardPattern::matches(std::string const& str) const
15745 {
15746   switch (m_wildcard) {
15747     case NoWildcard:
15748       return m_pattern == normaliseString(str);
15749     case WildcardAtStart:
15750       return endsWith(normaliseString(str), m_pattern);
15751     case WildcardAtEnd:
15752       return startsWith(normaliseString(str), m_pattern);
15753     case WildcardAtBothEnds:
15754       return contains(normaliseString(str), m_pattern);
15755     default:
15756       CATCH_INTERNAL_ERROR("Unknown enum");
15757   }
15758 }
15759
15760 std::string WildcardPattern::normaliseString(std::string const& str) const
15761 {
15762   return trim(m_caseSensitivity == CaseSensitive::No ? toLower(str) : str);
15763 }
15764 } // namespace Catch
15765 // end catch_wildcard_pattern.cpp
15766 // start catch_xmlwriter.cpp
15767
15768 #include <iomanip>
15769 #include <type_traits>
15770
15771 namespace Catch {
15772
15773 namespace {
15774
15775 size_t trailingBytes(unsigned char c)
15776 {
15777   if ((c & 0xE0) == 0xC0) {
15778     return 2;
15779   }
15780   if ((c & 0xF0) == 0xE0) {
15781     return 3;
15782   }
15783   if ((c & 0xF8) == 0xF0) {
15784     return 4;
15785   }
15786   CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15787 }
15788
15789 uint32_t headerValue(unsigned char c)
15790 {
15791   if ((c & 0xE0) == 0xC0) {
15792     return c & 0x1F;
15793   }
15794   if ((c & 0xF0) == 0xE0) {
15795     return c & 0x0F;
15796   }
15797   if ((c & 0xF8) == 0xF0) {
15798     return c & 0x07;
15799   }
15800   CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15801 }
15802
15803 void hexEscapeChar(std::ostream& os, unsigned char c)
15804 {
15805   std::ios_base::fmtflags f(os.flags());
15806   os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(c);
15807   os.flags(f);
15808 }
15809
15810 bool shouldNewline(XmlFormatting fmt)
15811 {
15812   return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
15813 }
15814
15815 bool shouldIndent(XmlFormatting fmt)
15816 {
15817   return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
15818 }
15819
15820 } // anonymous namespace
15821
15822 XmlFormatting operator|(XmlFormatting lhs, XmlFormatting rhs)
15823 {
15824   return static_cast<XmlFormatting>(static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
15825                                     static_cast<std::underlying_type<XmlFormatting>::type>(rhs));
15826 }
15827
15828 XmlFormatting operator&(XmlFormatting lhs, XmlFormatting rhs)
15829 {
15830   return static_cast<XmlFormatting>(static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
15831                                     static_cast<std::underlying_type<XmlFormatting>::type>(rhs));
15832 }
15833
15834 XmlEncode::XmlEncode(std::string const& str, ForWhat forWhat) : m_str(str), m_forWhat(forWhat) {}
15835
15836 void XmlEncode::encodeTo(std::ostream& os) const
15837 {
15838   // Apostrophe escaping not necessary if we always use " to write attributes
15839   // (see: http://www.w3.org/TR/xml/#syntax)
15840
15841   for (std::size_t idx = 0; idx < m_str.size(); ++idx) {
15842     unsigned char c = m_str[idx];
15843     switch (c) {
15844       case '<':
15845         os << "&lt;";
15846         break;
15847       case '&':
15848         os << "&amp;";
15849         break;
15850
15851       case '>':
15852         // See: http://www.w3.org/TR/xml/#syntax
15853         if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
15854           os << "&gt;";
15855         else
15856           os << c;
15857         break;
15858
15859       case '\"':
15860         if (m_forWhat == ForAttributes)
15861           os << "&quot;";
15862         else
15863           os << c;
15864         break;
15865
15866       default:
15867         // Check for control characters and invalid utf-8
15868
15869         // Escape control characters in standard ascii
15870         // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
15871         if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
15872           hexEscapeChar(os, c);
15873           break;
15874         }
15875
15876         // Plain ASCII: Write it to stream
15877         if (c < 0x7F) {
15878           os << c;
15879           break;
15880         }
15881
15882         // UTF-8 territory
15883         // Check if the encoding is valid and if it is not, hex escape bytes.
15884         // Important: We do not check the exact decoded values for validity, only the encoding format
15885         // First check that this bytes is a valid lead byte:
15886         // This means that it is not encoded as 1111 1XXX
15887         // Or as 10XX XXXX
15888         if (c < 0xC0 || c >= 0xF8) {
15889           hexEscapeChar(os, c);
15890           break;
15891         }
15892
15893         auto encBytes = trailingBytes(c);
15894         // Are there enough bytes left to avoid accessing out-of-bounds memory?
15895         if (idx + encBytes - 1 >= m_str.size()) {
15896           hexEscapeChar(os, c);
15897           break;
15898         }
15899         // The header is valid, check data
15900         // The next encBytes bytes must together be a valid utf-8
15901         // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
15902         bool valid     = true;
15903         uint32_t value = headerValue(c);
15904         for (std::size_t n = 1; n < encBytes; ++n) {
15905           unsigned char nc = m_str[idx + n];
15906           valid &= ((nc & 0xC0) == 0x80);
15907           value = (value << 6) | (nc & 0x3F);
15908         }
15909
15910         if (
15911             // Wrong bit pattern of following bytes
15912             (!valid) ||
15913             // Overlong encodings
15914             (value < 0x80) || (0x80 <= value && value < 0x800 && encBytes > 2) ||
15915             (0x800 < value && value < 0x10000 && encBytes > 3) ||
15916             // Encoded value out of range
15917             (value >= 0x110000)) {
15918           hexEscapeChar(os, c);
15919           break;
15920         }
15921
15922         // If we got here, this is in fact a valid(ish) utf-8 sequence
15923         for (std::size_t n = 0; n < encBytes; ++n) {
15924           os << m_str[idx + n];
15925         }
15926         idx += encBytes - 1;
15927         break;
15928     }
15929   }
15930 }
15931
15932 std::ostream& operator<<(std::ostream& os, XmlEncode const& xmlEncode)
15933 {
15934   xmlEncode.encodeTo(os);
15935   return os;
15936 }
15937
15938 XmlWriter::ScopedElement::ScopedElement(XmlWriter* writer, XmlFormatting fmt) : m_writer(writer), m_fmt(fmt) {}
15939
15940 XmlWriter::ScopedElement::ScopedElement(ScopedElement&& other) noexcept : m_writer(other.m_writer), m_fmt(other.m_fmt)
15941 {
15942   other.m_writer = nullptr;
15943   other.m_fmt    = XmlFormatting::None;
15944 }
15945 XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=(ScopedElement&& other) noexcept
15946 {
15947   if (m_writer) {
15948     m_writer->endElement();
15949   }
15950   m_writer       = other.m_writer;
15951   other.m_writer = nullptr;
15952   m_fmt          = other.m_fmt;
15953   other.m_fmt    = XmlFormatting::None;
15954   return *this;
15955 }
15956
15957 XmlWriter::ScopedElement::~ScopedElement()
15958 {
15959   if (m_writer) {
15960     m_writer->endElement(m_fmt);
15961   }
15962 }
15963
15964 XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText(std::string const& text, XmlFormatting fmt)
15965 {
15966   m_writer->writeText(text, fmt);
15967   return *this;
15968 }
15969
15970 XmlWriter::XmlWriter(std::ostream& os) : m_os(os)
15971 {
15972   writeDeclaration();
15973 }
15974
15975 XmlWriter::~XmlWriter()
15976 {
15977   while (!m_tags.empty()) {
15978     endElement();
15979   }
15980   newlineIfNecessary();
15981 }
15982
15983 XmlWriter& XmlWriter::startElement(std::string const& name, XmlFormatting fmt)
15984 {
15985   ensureTagClosed();
15986   newlineIfNecessary();
15987   if (shouldIndent(fmt)) {
15988     m_os << m_indent;
15989     m_indent += "  ";
15990   }
15991   m_os << '<' << name;
15992   m_tags.push_back(name);
15993   m_tagIsOpen = true;
15994   applyFormatting(fmt);
15995   return *this;
15996 }
15997
15998 XmlWriter::ScopedElement XmlWriter::scopedElement(std::string const& name, XmlFormatting fmt)
15999 {
16000   ScopedElement scoped(this, fmt);
16001   startElement(name, fmt);
16002   return scoped;
16003 }
16004
16005 XmlWriter& XmlWriter::endElement(XmlFormatting fmt)
16006 {
16007   m_indent = m_indent.substr(0, m_indent.size() - 2);
16008
16009   if (m_tagIsOpen) {
16010     m_os << "/>";
16011     m_tagIsOpen = false;
16012   } else {
16013     newlineIfNecessary();
16014     if (shouldIndent(fmt)) {
16015       m_os << m_indent;
16016     }
16017     m_os << "</" << m_tags.back() << ">";
16018   }
16019   m_os << std::flush;
16020   applyFormatting(fmt);
16021   m_tags.pop_back();
16022   return *this;
16023 }
16024
16025 XmlWriter& XmlWriter::writeAttribute(std::string const& name, std::string const& attribute)
16026 {
16027   if (!name.empty() && !attribute.empty())
16028     m_os << ' ' << name << "=\"" << XmlEncode(attribute, XmlEncode::ForAttributes) << '"';
16029   return *this;
16030 }
16031
16032 XmlWriter& XmlWriter::writeAttribute(std::string const& name, bool attribute)
16033 {
16034   m_os << ' ' << name << "=\"" << (attribute ? "true" : "false") << '"';
16035   return *this;
16036 }
16037
16038 XmlWriter& XmlWriter::writeText(std::string const& text, XmlFormatting fmt)
16039 {
16040   if (!text.empty()) {
16041     bool tagWasOpen = m_tagIsOpen;
16042     ensureTagClosed();
16043     if (tagWasOpen && shouldIndent(fmt)) {
16044       m_os << m_indent;
16045     }
16046     m_os << XmlEncode(text);
16047     applyFormatting(fmt);
16048   }
16049   return *this;
16050 }
16051
16052 XmlWriter& XmlWriter::writeComment(std::string const& text, XmlFormatting fmt)
16053 {
16054   ensureTagClosed();
16055   if (shouldIndent(fmt)) {
16056     m_os << m_indent;
16057   }
16058   m_os << "<!--" << text << "-->";
16059   applyFormatting(fmt);
16060   return *this;
16061 }
16062
16063 void XmlWriter::writeStylesheetRef(std::string const& url)
16064 {
16065   m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
16066 }
16067
16068 XmlWriter& XmlWriter::writeBlankLine()
16069 {
16070   ensureTagClosed();
16071   m_os << '\n';
16072   return *this;
16073 }
16074
16075 void XmlWriter::ensureTagClosed()
16076 {
16077   if (m_tagIsOpen) {
16078     m_os << '>' << std::flush;
16079     newlineIfNecessary();
16080     m_tagIsOpen = false;
16081   }
16082 }
16083
16084 void XmlWriter::applyFormatting(XmlFormatting fmt)
16085 {
16086   m_needsNewline = shouldNewline(fmt);
16087 }
16088
16089 void XmlWriter::writeDeclaration()
16090 {
16091   m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
16092 }
16093
16094 void XmlWriter::newlineIfNecessary()
16095 {
16096   if (m_needsNewline) {
16097     m_os << std::endl;
16098     m_needsNewline = false;
16099   }
16100 }
16101 } // namespace Catch
16102 // end catch_xmlwriter.cpp
16103 // start catch_reporter_bases.cpp
16104
16105 #include <cassert>
16106 #include <cfloat>
16107 #include <cstdio>
16108 #include <cstring>
16109 #include <memory>
16110
16111 namespace Catch {
16112 void prepareExpandedExpression(AssertionResult& result)
16113 {
16114   result.getExpandedExpression();
16115 }
16116
16117 // Because formatting using c++ streams is stateful, drop down to C is required
16118 // Alternatively we could use stringstream, but its performance is... not good.
16119 std::string getFormattedDuration(double duration)
16120 {
16121   // Max exponent + 1 is required to represent the whole part
16122   // + 1 for decimal point
16123   // + 3 for the 3 decimal places
16124   // + 1 for null terminator
16125   const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
16126   char buffer[maxDoubleSize];
16127
16128   // Save previous errno, to prevent sprintf from overwriting it
16129   ErrnoGuard guard;
16130 #ifdef _MSC_VER
16131   sprintf_s(buffer, "%.3f", duration);
16132 #else
16133   std::sprintf(buffer, "%.3f", duration);
16134 #endif
16135   return std::string(buffer);
16136 }
16137
16138 bool shouldShowDuration(IConfig const& config, double duration)
16139 {
16140   if (config.showDurations() == ShowDurations::Always) {
16141     return true;
16142   }
16143   if (config.showDurations() == ShowDurations::Never) {
16144     return false;
16145   }
16146   const double min = config.minDuration();
16147   return min >= 0 && duration >= min;
16148 }
16149
16150 std::string serializeFilters(std::vector<std::string> const& container)
16151 {
16152   ReusableStringStream oss;
16153   bool first = true;
16154   for (auto&& filter : container) {
16155     if (!first)
16156       oss << ' ';
16157     else
16158       first = false;
16159
16160     oss << filter;
16161   }
16162   return oss.str();
16163 }
16164
16165 TestEventListenerBase::TestEventListenerBase(ReporterConfig const& _config) : StreamingReporterBase(_config) {}
16166
16167 std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities()
16168 {
16169   return {Verbosity::Quiet, Verbosity::Normal, Verbosity::High};
16170 }
16171
16172 void TestEventListenerBase::assertionStarting(AssertionInfo const&) {}
16173
16174 bool TestEventListenerBase::assertionEnded(AssertionStats const&)
16175 {
16176   return false;
16177 }
16178
16179 } // end namespace Catch
16180 // end catch_reporter_bases.cpp
16181 // start catch_reporter_compact.cpp
16182
16183 namespace {
16184
16185 #ifdef CATCH_PLATFORM_MAC
16186 const char* failedString()
16187 {
16188   return "FAILED";
16189 }
16190 const char* passedString()
16191 {
16192   return "PASSED";
16193 }
16194 #else
16195 const char* failedString()
16196 {
16197   return "failed";
16198 }
16199 const char* passedString()
16200 {
16201   return "passed";
16202 }
16203 #endif
16204
16205 // Colour::LightGrey
16206 Catch::Colour::Code dimColour()
16207 {
16208   return Catch::Colour::FileName;
16209 }
16210
16211 std::string bothOrAll(std::size_t count)
16212 {
16213   return count == 1 ? std::string() : count == 2 ? "both " : "all ";
16214 }
16215
16216 } // namespace
16217
16218 namespace Catch {
16219 namespace {
16220 // Colour, message variants:
16221 // - white: No tests ran.
16222 // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
16223 // - white: Passed [both/all] N test cases (no assertions).
16224 // -   red: Failed N tests cases, failed M assertions.
16225 // - green: Passed [both/all] N tests cases with M assertions.
16226 void printTotals(std::ostream& out, const Totals& totals)
16227 {
16228   if (totals.testCases.total() == 0) {
16229     out << "No tests ran.";
16230   } else if (totals.testCases.failed == totals.testCases.total()) {
16231     Colour colour(Colour::ResultError);
16232     const std::string qualify_assertions_failed =
16233         totals.assertions.failed == totals.assertions.total() ? bothOrAll(totals.assertions.failed) : std::string();
16234     out << "Failed " << bothOrAll(totals.testCases.failed) << pluralise(totals.testCases.failed, "test case")
16235         << ", "
16236            "failed "
16237         << qualify_assertions_failed << pluralise(totals.assertions.failed, "assertion") << '.';
16238   } else if (totals.assertions.total() == 0) {
16239     out << "Passed " << bothOrAll(totals.testCases.total()) << pluralise(totals.testCases.total(), "test case")
16240         << " (no assertions).";
16241   } else if (totals.assertions.failed) {
16242     Colour colour(Colour::ResultError);
16243     out << "Failed " << pluralise(totals.testCases.failed, "test case")
16244         << ", "
16245            "failed "
16246         << pluralise(totals.assertions.failed, "assertion") << '.';
16247   } else {
16248     Colour colour(Colour::ResultSuccess);
16249     out << "Passed " << bothOrAll(totals.testCases.passed) << pluralise(totals.testCases.passed, "test case")
16250         << " with " << pluralise(totals.assertions.passed, "assertion") << '.';
16251   }
16252 }
16253
16254 // Implementation of CompactReporter formatting
16255 class AssertionPrinter {
16256 public:
16257   AssertionPrinter& operator=(AssertionPrinter const&) = delete;
16258   AssertionPrinter(AssertionPrinter const&)            = delete;
16259   AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
16260       : stream(_stream)
16261       , result(_stats.assertionResult)
16262       , messages(_stats.infoMessages)
16263       , itMessage(_stats.infoMessages.begin())
16264       , printInfoMessages(_printInfoMessages)
16265   {
16266   }
16267
16268   void print()
16269   {
16270     printSourceInfo();
16271
16272     itMessage = messages.begin();
16273
16274     switch (result.getResultType()) {
16275       case ResultWas::Ok:
16276         printResultType(Colour::ResultSuccess, passedString());
16277         printOriginalExpression();
16278         printReconstructedExpression();
16279         if (!result.hasExpression())
16280           printRemainingMessages(Colour::None);
16281         else
16282           printRemainingMessages();
16283         break;
16284       case ResultWas::ExpressionFailed:
16285         if (result.isOk())
16286           printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
16287         else
16288           printResultType(Colour::Error, failedString());
16289         printOriginalExpression();
16290         printReconstructedExpression();
16291         printRemainingMessages();
16292         break;
16293       case ResultWas::ThrewException:
16294         printResultType(Colour::Error, failedString());
16295         printIssue("unexpected exception with message:");
16296         printMessage();
16297         printExpressionWas();
16298         printRemainingMessages();
16299         break;
16300       case ResultWas::FatalErrorCondition:
16301         printResultType(Colour::Error, failedString());
16302         printIssue("fatal error condition with message:");
16303         printMessage();
16304         printExpressionWas();
16305         printRemainingMessages();
16306         break;
16307       case ResultWas::DidntThrowException:
16308         printResultType(Colour::Error, failedString());
16309         printIssue("expected exception, got none");
16310         printExpressionWas();
16311         printRemainingMessages();
16312         break;
16313       case ResultWas::Info:
16314         printResultType(Colour::None, "info");
16315         printMessage();
16316         printRemainingMessages();
16317         break;
16318       case ResultWas::Warning:
16319         printResultType(Colour::None, "warning");
16320         printMessage();
16321         printRemainingMessages();
16322         break;
16323       case ResultWas::ExplicitFailure:
16324         printResultType(Colour::Error, failedString());
16325         printIssue("explicitly");
16326         printRemainingMessages(Colour::None);
16327         break;
16328         // These cases are here to prevent compiler warnings
16329       case ResultWas::Unknown:
16330       case ResultWas::FailureBit:
16331       case ResultWas::Exception:
16332         printResultType(Colour::Error, "** internal error **");
16333         break;
16334     }
16335   }
16336
16337 private:
16338   void printSourceInfo() const
16339   {
16340     Colour colourGuard(Colour::FileName);
16341     stream << result.getSourceInfo() << ':';
16342   }
16343
16344   void printResultType(Colour::Code colour, std::string const& passOrFail) const
16345   {
16346     if (!passOrFail.empty()) {
16347       {
16348         Colour colourGuard(colour);
16349         stream << ' ' << passOrFail;
16350       }
16351       stream << ':';
16352     }
16353   }
16354
16355   void printIssue(std::string const& issue) const { stream << ' ' << issue; }
16356
16357   void printExpressionWas()
16358   {
16359     if (result.hasExpression()) {
16360       stream << ';';
16361       {
16362         Colour colour(dimColour());
16363         stream << " expression was:";
16364       }
16365       printOriginalExpression();
16366     }
16367   }
16368
16369   void printOriginalExpression() const
16370   {
16371     if (result.hasExpression()) {
16372       stream << ' ' << result.getExpression();
16373     }
16374   }
16375
16376   void printReconstructedExpression() const
16377   {
16378     if (result.hasExpandedExpression()) {
16379       {
16380         Colour colour(dimColour());
16381         stream << " for: ";
16382       }
16383       stream << result.getExpandedExpression();
16384     }
16385   }
16386
16387   void printMessage()
16388   {
16389     if (itMessage != messages.end()) {
16390       stream << " '" << itMessage->message << '\'';
16391       ++itMessage;
16392     }
16393   }
16394
16395   void printRemainingMessages(Colour::Code colour = dimColour())
16396   {
16397     if (itMessage == messages.end())
16398       return;
16399
16400     const auto itEnd = messages.cend();
16401     const auto N     = static_cast<std::size_t>(std::distance(itMessage, itEnd));
16402
16403     {
16404       Colour colourGuard(colour);
16405       stream << " with " << pluralise(N, "message") << ':';
16406     }
16407
16408     while (itMessage != itEnd) {
16409       // If this assertion is a warning ignore any INFO messages
16410       if (printInfoMessages || itMessage->type != ResultWas::Info) {
16411         printMessage();
16412         if (itMessage != itEnd) {
16413           Colour colourGuard(dimColour());
16414           stream << " and";
16415         }
16416         continue;
16417       }
16418       ++itMessage;
16419     }
16420   }
16421
16422 private:
16423   std::ostream& stream;
16424   AssertionResult const& result;
16425   std::vector<MessageInfo> messages;
16426   std::vector<MessageInfo>::const_iterator itMessage;
16427   bool printInfoMessages;
16428 };
16429
16430 } // namespace
16431
16432 std::string CompactReporter::getDescription()
16433 {
16434   return "Reports test results on a single line, suitable for IDEs";
16435 }
16436
16437 void CompactReporter::noMatchingTestCases(std::string const& spec)
16438 {
16439   stream << "No test cases matched '" << spec << '\'' << std::endl;
16440 }
16441
16442 void CompactReporter::assertionStarting(AssertionInfo const&) {}
16443
16444 bool CompactReporter::assertionEnded(AssertionStats const& _assertionStats)
16445 {
16446   AssertionResult const& result = _assertionStats.assertionResult;
16447
16448   bool printInfoMessages = true;
16449
16450   // Drop out if result was successful and we're not printing those
16451   if (!m_config->includeSuccessfulResults() && result.isOk()) {
16452     if (result.getResultType() != ResultWas::Warning)
16453       return false;
16454     printInfoMessages = false;
16455   }
16456
16457   AssertionPrinter printer(stream, _assertionStats, printInfoMessages);
16458   printer.print();
16459
16460   stream << std::endl;
16461   return true;
16462 }
16463
16464 void CompactReporter::sectionEnded(SectionStats const& _sectionStats)
16465 {
16466   double dur = _sectionStats.durationInSeconds;
16467   if (shouldShowDuration(*m_config, dur)) {
16468     stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16469   }
16470 }
16471
16472 void CompactReporter::testRunEnded(TestRunStats const& _testRunStats)
16473 {
16474   printTotals(stream, _testRunStats.totals);
16475   stream << '\n' << std::endl;
16476   StreamingReporterBase::testRunEnded(_testRunStats);
16477 }
16478
16479 CompactReporter::~CompactReporter() {}
16480
16481 CATCH_REGISTER_REPORTER("compact", CompactReporter)
16482
16483 } // end namespace Catch
16484 // end catch_reporter_compact.cpp
16485 // start catch_reporter_console.cpp
16486
16487 #include <cfloat>
16488 #include <cstdio>
16489
16490 #if defined(_MSC_VER)
16491 #pragma warning(push)
16492 #pragma warning(disable : 4061) // Not all labels are EXPLICITLY handled in switch
16493                                 // Note that 4062 (not all labels are handled and default is missing) is enabled
16494 #endif
16495
16496 #if defined(__clang__)
16497 #pragma clang diagnostic push
16498 // For simplicity, benchmarking-only helpers are always enabled
16499 #pragma clang diagnostic ignored "-Wunused-function"
16500 #endif
16501
16502 namespace Catch {
16503
16504 namespace {
16505
16506 // Formatter impl for ConsoleReporter
16507 class ConsoleAssertionPrinter {
16508 public:
16509   ConsoleAssertionPrinter& operator=(ConsoleAssertionPrinter const&) = delete;
16510   ConsoleAssertionPrinter(ConsoleAssertionPrinter const&)            = delete;
16511   ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
16512       : stream(_stream)
16513       , stats(_stats)
16514       , result(_stats.assertionResult)
16515       , colour(Colour::None)
16516       , message(result.getMessage())
16517       , messages(_stats.infoMessages)
16518       , printInfoMessages(_printInfoMessages)
16519   {
16520     switch (result.getResultType()) {
16521       case ResultWas::Ok:
16522         colour     = Colour::Success;
16523         passOrFail = "PASSED";
16524         // if( result.hasMessage() )
16525         if (_stats.infoMessages.size() == 1)
16526           messageLabel = "with message";
16527         if (_stats.infoMessages.size() > 1)
16528           messageLabel = "with messages";
16529         break;
16530       case ResultWas::ExpressionFailed:
16531         if (result.isOk()) {
16532           colour     = Colour::Success;
16533           passOrFail = "FAILED - but was ok";
16534         } else {
16535           colour     = Colour::Error;
16536           passOrFail = "FAILED";
16537         }
16538         if (_stats.infoMessages.size() == 1)
16539           messageLabel = "with message";
16540         if (_stats.infoMessages.size() > 1)
16541           messageLabel = "with messages";
16542         break;
16543       case ResultWas::ThrewException:
16544         colour       = Colour::Error;
16545         passOrFail   = "FAILED";
16546         messageLabel = "due to unexpected exception with ";
16547         if (_stats.infoMessages.size() == 1)
16548           messageLabel += "message";
16549         if (_stats.infoMessages.size() > 1)
16550           messageLabel += "messages";
16551         break;
16552       case ResultWas::FatalErrorCondition:
16553         colour       = Colour::Error;
16554         passOrFail   = "FAILED";
16555         messageLabel = "due to a fatal error condition";
16556         break;
16557       case ResultWas::DidntThrowException:
16558         colour       = Colour::Error;
16559         passOrFail   = "FAILED";
16560         messageLabel = "because no exception was thrown where one was expected";
16561         break;
16562       case ResultWas::Info:
16563         messageLabel = "info";
16564         break;
16565       case ResultWas::Warning:
16566         messageLabel = "warning";
16567         break;
16568       case ResultWas::ExplicitFailure:
16569         passOrFail = "FAILED";
16570         colour     = Colour::Error;
16571         if (_stats.infoMessages.size() == 1)
16572           messageLabel = "explicitly with message";
16573         if (_stats.infoMessages.size() > 1)
16574           messageLabel = "explicitly with messages";
16575         break;
16576         // These cases are here to prevent compiler warnings
16577       case ResultWas::Unknown:
16578       case ResultWas::FailureBit:
16579       case ResultWas::Exception:
16580         passOrFail = "** internal error **";
16581         colour     = Colour::Error;
16582         break;
16583     }
16584   }
16585
16586   void print() const
16587   {
16588     printSourceInfo();
16589     if (stats.totals.assertions.total() > 0) {
16590       printResultType();
16591       printOriginalExpression();
16592       printReconstructedExpression();
16593     } else {
16594       stream << '\n';
16595     }
16596     printMessage();
16597   }
16598
16599 private:
16600   void printResultType() const
16601   {
16602     if (!passOrFail.empty()) {
16603       Colour colourGuard(colour);
16604       stream << passOrFail << ":\n";
16605     }
16606   }
16607   void printOriginalExpression() const
16608   {
16609     if (result.hasExpression()) {
16610       Colour colourGuard(Colour::OriginalExpression);
16611       stream << "  ";
16612       stream << result.getExpressionInMacro();
16613       stream << '\n';
16614     }
16615   }
16616   void printReconstructedExpression() const
16617   {
16618     if (result.hasExpandedExpression()) {
16619       stream << "with expansion:\n";
16620       Colour colourGuard(Colour::ReconstructedExpression);
16621       stream << Column(result.getExpandedExpression()).indent(2) << '\n';
16622     }
16623   }
16624   void printMessage() const
16625   {
16626     if (!messageLabel.empty())
16627       stream << messageLabel << ':' << '\n';
16628     for (auto const& msg : messages) {
16629       // If this assertion is a warning ignore any INFO messages
16630       if (printInfoMessages || msg.type != ResultWas::Info)
16631         stream << Column(msg.message).indent(2) << '\n';
16632     }
16633   }
16634   void printSourceInfo() const
16635   {
16636     Colour colourGuard(Colour::FileName);
16637     stream << result.getSourceInfo() << ": ";
16638   }
16639
16640   std::ostream& stream;
16641   AssertionStats const& stats;
16642   AssertionResult const& result;
16643   Colour::Code colour;
16644   std::string passOrFail;
16645   std::string messageLabel;
16646   std::string message;
16647   std::vector<MessageInfo> messages;
16648   bool printInfoMessages;
16649 };
16650
16651 std::size_t makeRatio(std::size_t number, std::size_t total)
16652 {
16653   std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
16654   return (ratio == 0 && number > 0) ? 1 : ratio;
16655 }
16656
16657 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k)
16658 {
16659   if (i > j && i > k)
16660     return i;
16661   else if (j > k)
16662     return j;
16663   else
16664     return k;
16665 }
16666
16667 struct ColumnInfo {
16668   enum Justification { Left, Right };
16669   std::string name;
16670   int width;
16671   Justification justification;
16672 };
16673 struct ColumnBreak {};
16674 struct RowBreak {};
16675
16676 class Duration {
16677   enum class Unit { Auto, Nanoseconds, Microseconds, Milliseconds, Seconds, Minutes };
16678   static const uint64_t s_nanosecondsInAMicrosecond = 1000;
16679   static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
16680   static const uint64_t s_nanosecondsInASecond      = 1000 * s_nanosecondsInAMillisecond;
16681   static const uint64_t s_nanosecondsInAMinute      = 60 * s_nanosecondsInASecond;
16682
16683   double m_inNanoseconds;
16684   Unit m_units;
16685
16686 public:
16687   explicit Duration(double inNanoseconds, Unit units = Unit::Auto) : m_inNanoseconds(inNanoseconds), m_units(units)
16688   {
16689     if (m_units == Unit::Auto) {
16690       if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
16691         m_units = Unit::Nanoseconds;
16692       else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
16693         m_units = Unit::Microseconds;
16694       else if (m_inNanoseconds < s_nanosecondsInASecond)
16695         m_units = Unit::Milliseconds;
16696       else if (m_inNanoseconds < s_nanosecondsInAMinute)
16697         m_units = Unit::Seconds;
16698       else
16699         m_units = Unit::Minutes;
16700     }
16701   }
16702
16703   auto value() const -> double
16704   {
16705     switch (m_units) {
16706       case Unit::Microseconds:
16707         return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
16708       case Unit::Milliseconds:
16709         return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
16710       case Unit::Seconds:
16711         return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
16712       case Unit::Minutes:
16713         return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
16714       default:
16715         return m_inNanoseconds;
16716     }
16717   }
16718   auto unitsAsString() const -> std::string
16719   {
16720     switch (m_units) {
16721       case Unit::Nanoseconds:
16722         return "ns";
16723       case Unit::Microseconds:
16724         return "us";
16725       case Unit::Milliseconds:
16726         return "ms";
16727       case Unit::Seconds:
16728         return "s";
16729       case Unit::Minutes:
16730         return "m";
16731       default:
16732         return "** internal error **";
16733     }
16734   }
16735   friend auto operator<<(std::ostream& os, Duration const& duration) -> std::ostream&
16736   {
16737     return os << duration.value() << ' ' << duration.unitsAsString();
16738   }
16739 };
16740 } // namespace
16741
16742 class TablePrinter {
16743   std::ostream& m_os;
16744   std::vector<ColumnInfo> m_columnInfos;
16745   std::ostringstream m_oss;
16746   int m_currentColumn = -1;
16747   bool m_isOpen       = false;
16748
16749 public:
16750   TablePrinter(std::ostream& os, std::vector<ColumnInfo> columnInfos) : m_os(os), m_columnInfos(std::move(columnInfos))
16751   {
16752   }
16753
16754   auto columnInfos() const -> std::vector<ColumnInfo> const& { return m_columnInfos; }
16755
16756   void open()
16757   {
16758     if (!m_isOpen) {
16759       m_isOpen = true;
16760       *this << RowBreak();
16761
16762       Columns headerCols;
16763       Spacer spacer(2);
16764       for (auto const& info : m_columnInfos) {
16765         headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
16766         headerCols += spacer;
16767       }
16768       m_os << headerCols << '\n';
16769
16770       m_os << Catch::getLineOfChars<'-'>() << '\n';
16771     }
16772   }
16773   void close()
16774   {
16775     if (m_isOpen) {
16776       *this << RowBreak();
16777       m_os << std::endl;
16778       m_isOpen = false;
16779     }
16780   }
16781
16782   template <typename T> friend TablePrinter& operator<<(TablePrinter& tp, T const& value)
16783   {
16784     tp.m_oss << value;
16785     return tp;
16786   }
16787
16788   friend TablePrinter& operator<<(TablePrinter& tp, ColumnBreak)
16789   {
16790     auto colStr        = tp.m_oss.str();
16791     const auto strSize = colStr.size();
16792     tp.m_oss.str("");
16793     tp.open();
16794     if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
16795       tp.m_currentColumn = -1;
16796       tp.m_os << '\n';
16797     }
16798     tp.m_currentColumn++;
16799
16800     auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
16801     auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
16802                        ? std::string(colInfo.width - (strSize + 1), ' ')
16803                        : std::string();
16804     if (colInfo.justification == ColumnInfo::Left)
16805       tp.m_os << colStr << padding << ' ';
16806     else
16807       tp.m_os << padding << colStr << ' ';
16808     return tp;
16809   }
16810
16811   friend TablePrinter& operator<<(TablePrinter& tp, RowBreak)
16812   {
16813     if (tp.m_currentColumn > 0) {
16814       tp.m_os << '\n';
16815       tp.m_currentColumn = -1;
16816     }
16817     return tp;
16818   }
16819 };
16820
16821 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
16822     : StreamingReporterBase(config)
16823     , m_tablePrinter(new TablePrinter(config.stream(), [&config]() -> std::vector<ColumnInfo> {
16824       if (config.fullConfig()->benchmarkNoAnalysis()) {
16825         return {{"benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left},
16826                 {"     samples", 14, ColumnInfo::Right},
16827                 {"  iterations", 14, ColumnInfo::Right},
16828                 {"        mean", 14, ColumnInfo::Right}};
16829       } else {
16830         return {{"benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left},
16831                 {"samples      mean       std dev", 14, ColumnInfo::Right},
16832                 {"iterations   low mean   low std dev", 14, ColumnInfo::Right},
16833                 {"estimated    high mean  high std dev", 14, ColumnInfo::Right}};
16834       }
16835     }()))
16836 {
16837 }
16838 ConsoleReporter::~ConsoleReporter() = default;
16839
16840 std::string ConsoleReporter::getDescription()
16841 {
16842   return "Reports test results as plain lines of text";
16843 }
16844
16845 void ConsoleReporter::noMatchingTestCases(std::string const& spec)
16846 {
16847   stream << "No test cases matched '" << spec << '\'' << std::endl;
16848 }
16849
16850 void ConsoleReporter::reportInvalidArguments(std::string const& arg)
16851 {
16852   stream << "Invalid Filter: " << arg << std::endl;
16853 }
16854
16855 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
16856
16857 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats)
16858 {
16859   AssertionResult const& result = _assertionStats.assertionResult;
16860
16861   bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16862
16863   // Drop out if result was successful but we're not printing them.
16864   if (!includeResults && result.getResultType() != ResultWas::Warning)
16865     return false;
16866
16867   lazyPrint();
16868
16869   ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
16870   printer.print();
16871   stream << std::endl;
16872   return true;
16873 }
16874
16875 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo)
16876 {
16877   m_tablePrinter->close();
16878   m_headerPrinted = false;
16879   StreamingReporterBase::sectionStarting(_sectionInfo);
16880 }
16881 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats)
16882 {
16883   m_tablePrinter->close();
16884   if (_sectionStats.missingAssertions) {
16885     lazyPrint();
16886     Colour colour(Colour::ResultError);
16887     if (m_sectionStack.size() > 1)
16888       stream << "\nNo assertions in section";
16889     else
16890       stream << "\nNo assertions in test case";
16891     stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
16892   }
16893   double dur = _sectionStats.durationInSeconds;
16894   if (shouldShowDuration(*m_config, dur)) {
16895     stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16896   }
16897   if (m_headerPrinted) {
16898     m_headerPrinted = false;
16899   }
16900   StreamingReporterBase::sectionEnded(_sectionStats);
16901 }
16902
16903 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16904 void ConsoleReporter::benchmarkPreparing(std::string const& name)
16905 {
16906   lazyPrintWithoutClosingBenchmarkTable();
16907
16908   auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
16909
16910   bool firstLine = true;
16911   for (auto line : nameCol) {
16912     if (!firstLine)
16913       (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
16914     else
16915       firstLine = false;
16916
16917     (*m_tablePrinter) << line << ColumnBreak();
16918   }
16919 }
16920
16921 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info)
16922 {
16923   (*m_tablePrinter) << info.samples << ColumnBreak() << info.iterations << ColumnBreak();
16924   if (!m_config->benchmarkNoAnalysis())
16925     (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
16926 }
16927 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats)
16928 {
16929   if (m_config->benchmarkNoAnalysis()) {
16930     (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
16931   } else {
16932     (*m_tablePrinter) << ColumnBreak() << Duration(stats.mean.point.count()) << ColumnBreak()
16933                       << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
16934                       << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
16935                       << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
16936                       << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
16937                       << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak()
16938                       << ColumnBreak() << ColumnBreak() << ColumnBreak();
16939   }
16940 }
16941
16942 void ConsoleReporter::benchmarkFailed(std::string const& error)
16943 {
16944   Colour colour(Colour::Red);
16945   (*m_tablePrinter) << "Benchmark failed (" << error << ')' << ColumnBreak() << RowBreak();
16946 }
16947 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16948
16949 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats)
16950 {
16951   m_tablePrinter->close();
16952   StreamingReporterBase::testCaseEnded(_testCaseStats);
16953   m_headerPrinted = false;
16954 }
16955 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats)
16956 {
16957   if (currentGroupInfo.used) {
16958     printSummaryDivider();
16959     stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
16960     printTotals(_testGroupStats.totals);
16961     stream << '\n' << std::endl;
16962   }
16963   StreamingReporterBase::testGroupEnded(_testGroupStats);
16964 }
16965 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats)
16966 {
16967   printTotalsDivider(_testRunStats.totals);
16968   printTotals(_testRunStats.totals);
16969   stream << std::endl;
16970   StreamingReporterBase::testRunEnded(_testRunStats);
16971 }
16972 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo)
16973 {
16974   StreamingReporterBase::testRunStarting(_testInfo);
16975   printTestFilters();
16976 }
16977
16978 void ConsoleReporter::lazyPrint()
16979 {
16980
16981   m_tablePrinter->close();
16982   lazyPrintWithoutClosingBenchmarkTable();
16983 }
16984
16985 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable()
16986 {
16987
16988   if (!currentTestRunInfo.used)
16989     lazyPrintRunInfo();
16990   if (!currentGroupInfo.used)
16991     lazyPrintGroupInfo();
16992
16993   if (!m_headerPrinted) {
16994     printTestCaseAndSectionHeader();
16995     m_headerPrinted = true;
16996   }
16997 }
16998 void ConsoleReporter::lazyPrintRunInfo()
16999 {
17000   stream << '\n' << getLineOfChars<'~'>() << '\n';
17001   Colour colour(Colour::SecondaryText);
17002   stream << currentTestRunInfo->name << " is a Catch v" << libraryVersion() << " host application.\n"
17003          << "Run with -? for options\n\n";
17004
17005   if (m_config->rngSeed() != 0)
17006     stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
17007
17008   currentTestRunInfo.used = true;
17009 }
17010 void ConsoleReporter::lazyPrintGroupInfo()
17011 {
17012   if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
17013     printClosedHeader("Group: " + currentGroupInfo->name);
17014     currentGroupInfo.used = true;
17015   }
17016 }
17017 void ConsoleReporter::printTestCaseAndSectionHeader()
17018 {
17019   assert(!m_sectionStack.empty());
17020   printOpenHeader(currentTestCaseInfo->name);
17021
17022   if (m_sectionStack.size() > 1) {
17023     Colour colourGuard(Colour::Headers);
17024
17025     auto it   = m_sectionStack.begin() + 1, // Skip first section (test case)
17026         itEnd = m_sectionStack.end();
17027     for (; it != itEnd; ++it)
17028       printHeaderString(it->name, 2);
17029   }
17030
17031   SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
17032
17033   stream << getLineOfChars<'-'>() << '\n';
17034   Colour colourGuard(Colour::FileName);
17035   stream << lineInfo << '\n';
17036   stream << getLineOfChars<'.'>() << '\n' << std::endl;
17037 }
17038
17039 void ConsoleReporter::printClosedHeader(std::string const& _name)
17040 {
17041   printOpenHeader(_name);
17042   stream << getLineOfChars<'.'>() << '\n';
17043 }
17044 void ConsoleReporter::printOpenHeader(std::string const& _name)
17045 {
17046   stream << getLineOfChars<'-'>() << '\n';
17047   {
17048     Colour colourGuard(Colour::Headers);
17049     printHeaderString(_name);
17050   }
17051 }
17052
17053 // if string has a : in first line will set indent to follow it on
17054 // subsequent lines
17055 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent)
17056 {
17057   std::size_t i = _string.find(": ");
17058   if (i != std::string::npos)
17059     i += 2;
17060   else
17061     i = 0;
17062   stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
17063 }
17064
17065 struct SummaryColumn {
17066
17067   SummaryColumn(std::string _label, Colour::Code _colour) : label(std::move(_label)), colour(_colour) {}
17068   SummaryColumn addRow(std::size_t count)
17069   {
17070     ReusableStringStream rss;
17071     rss << count;
17072     std::string row = rss.str();
17073     for (auto& oldRow : rows) {
17074       while (oldRow.size() < row.size())
17075         oldRow = ' ' + oldRow;
17076       while (oldRow.size() > row.size())
17077         row = ' ' + row;
17078     }
17079     rows.push_back(row);
17080     return *this;
17081   }
17082
17083   std::string label;
17084   Colour::Code colour;
17085   std::vector<std::string> rows;
17086 };
17087
17088 void ConsoleReporter::printTotals(Totals const& totals)
17089 {
17090   if (totals.testCases.total() == 0) {
17091     stream << Colour(Colour::Warning) << "No tests ran\n";
17092   } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
17093     stream << Colour(Colour::ResultSuccess) << "All tests passed";
17094     stream << " (" << pluralise(totals.assertions.passed, "assertion") << " in "
17095            << pluralise(totals.testCases.passed, "test case") << ')' << '\n';
17096   } else {
17097
17098     std::vector<SummaryColumn> columns;
17099     columns.push_back(
17100         SummaryColumn("", Colour::None).addRow(totals.testCases.total()).addRow(totals.assertions.total()));
17101     columns.push_back(
17102         SummaryColumn("passed", Colour::Success).addRow(totals.testCases.passed).addRow(totals.assertions.passed));
17103     columns.push_back(
17104         SummaryColumn("failed", Colour::ResultError).addRow(totals.testCases.failed).addRow(totals.assertions.failed));
17105     columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
17106                           .addRow(totals.testCases.failedButOk)
17107                           .addRow(totals.assertions.failedButOk));
17108
17109     printSummaryRow("test cases", columns, 0);
17110     printSummaryRow("assertions", columns, 1);
17111   }
17112 }
17113 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row)
17114 {
17115   for (auto col : cols) {
17116     std::string value = col.rows[row];
17117     if (col.label.empty()) {
17118       stream << label << ": ";
17119       if (value != "0")
17120         stream << value;
17121       else
17122         stream << Colour(Colour::Warning) << "- none -";
17123     } else if (value != "0") {
17124       stream << Colour(Colour::LightGrey) << " | ";
17125       stream << Colour(col.colour) << value << ' ' << col.label;
17126     }
17127   }
17128   stream << '\n';
17129 }
17130
17131 void ConsoleReporter::printTotalsDivider(Totals const& totals)
17132 {
17133   if (totals.testCases.total() > 0) {
17134     std::size_t failedRatio      = makeRatio(totals.testCases.failed, totals.testCases.total());
17135     std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
17136     std::size_t passedRatio      = makeRatio(totals.testCases.passed, totals.testCases.total());
17137     while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
17138       findMax(failedRatio, failedButOkRatio, passedRatio)++;
17139     while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
17140       findMax(failedRatio, failedButOkRatio, passedRatio)--;
17141
17142     stream << Colour(Colour::Error) << std::string(failedRatio, '=');
17143     stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
17144     if (totals.testCases.allPassed())
17145       stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
17146     else
17147       stream << Colour(Colour::Success) << std::string(passedRatio, '=');
17148   } else {
17149     stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
17150   }
17151   stream << '\n';
17152 }
17153 void ConsoleReporter::printSummaryDivider()
17154 {
17155   stream << getLineOfChars<'-'>() << '\n';
17156 }
17157
17158 void ConsoleReporter::printTestFilters()
17159 {
17160   if (m_config->testSpec().hasFilters()) {
17161     Colour guard(Colour::BrightYellow);
17162     stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
17163   }
17164 }
17165
17166 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
17167
17168 } // end namespace Catch
17169
17170 #if defined(_MSC_VER)
17171 #pragma warning(pop)
17172 #endif
17173
17174 #if defined(__clang__)
17175 #pragma clang diagnostic pop
17176 #endif
17177 // end catch_reporter_console.cpp
17178 // start catch_reporter_junit.cpp
17179
17180 #include <algorithm>
17181 #include <cassert>
17182 #include <ctime>
17183 #include <sstream>
17184
17185 namespace Catch {
17186
17187 namespace {
17188 std::string getCurrentTimestamp()
17189 {
17190   // Beware, this is not reentrant because of backward compatibility issues
17191   // Also, UTC only, again because of backward compatibility (%z is C++11)
17192   time_t rawtime;
17193   std::time(&rawtime);
17194   auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
17195
17196 #ifdef _MSC_VER
17197   std::tm timeInfo = {};
17198   gmtime_s(&timeInfo, &rawtime);
17199 #else
17200   std::tm* timeInfo;
17201   timeInfo = std::gmtime(&rawtime);
17202 #endif
17203
17204   char timeStamp[timeStampSize];
17205   const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
17206
17207 #ifdef _MSC_VER
17208   std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
17209 #else
17210   std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
17211 #endif
17212   return std::string(timeStamp);
17213 }
17214
17215 std::string fileNameTag(const std::vector<std::string>& tags)
17216 {
17217   auto it = std::find_if(begin(tags), end(tags), [](std::string const& tag) { return tag.front() == '#'; });
17218   if (it != tags.end())
17219     return it->substr(1);
17220   return std::string();
17221 }
17222 } // anonymous namespace
17223
17224 JunitReporter::JunitReporter(ReporterConfig const& _config) : CumulativeReporterBase(_config), xml(_config.stream())
17225 {
17226   m_reporterPrefs.shouldRedirectStdOut      = true;
17227   m_reporterPrefs.shouldReportAllAssertions = true;
17228 }
17229
17230 JunitReporter::~JunitReporter() {}
17231
17232 std::string JunitReporter::getDescription()
17233 {
17234   return "Reports test results in an XML format that looks like Ant's junitreport target";
17235 }
17236
17237 void JunitReporter::noMatchingTestCases(std::string const& /*spec*/) {}
17238
17239 void JunitReporter::testRunStarting(TestRunInfo const& runInfo)
17240 {
17241   CumulativeReporterBase::testRunStarting(runInfo);
17242   xml.startElement("testsuites");
17243 }
17244
17245 void JunitReporter::testGroupStarting(GroupInfo const& groupInfo)
17246 {
17247   suiteTimer.start();
17248   stdOutForSuite.clear();
17249   stdErrForSuite.clear();
17250   unexpectedExceptions = 0;
17251   CumulativeReporterBase::testGroupStarting(groupInfo);
17252 }
17253
17254 void JunitReporter::testCaseStarting(TestCaseInfo const& testCaseInfo)
17255 {
17256   m_okToFail = testCaseInfo.okToFail();
17257 }
17258
17259 bool JunitReporter::assertionEnded(AssertionStats const& assertionStats)
17260 {
17261   if (assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail)
17262     unexpectedExceptions++;
17263   return CumulativeReporterBase::assertionEnded(assertionStats);
17264 }
17265
17266 void JunitReporter::testCaseEnded(TestCaseStats const& testCaseStats)
17267 {
17268   stdOutForSuite += testCaseStats.stdOut;
17269   stdErrForSuite += testCaseStats.stdErr;
17270   CumulativeReporterBase::testCaseEnded(testCaseStats);
17271 }
17272
17273 void JunitReporter::testGroupEnded(TestGroupStats const& testGroupStats)
17274 {
17275   double suiteTime = suiteTimer.getElapsedSeconds();
17276   CumulativeReporterBase::testGroupEnded(testGroupStats);
17277   writeGroup(*m_testGroups.back(), suiteTime);
17278 }
17279
17280 void JunitReporter::testRunEndedCumulative()
17281 {
17282   xml.endElement();
17283 }
17284
17285 void JunitReporter::writeGroup(TestGroupNode const& groupNode, double suiteTime)
17286 {
17287   XmlWriter::ScopedElement e = xml.scopedElement("testsuite");
17288
17289   TestGroupStats const& stats = groupNode.value;
17290   xml.writeAttribute("name", stats.groupInfo.name);
17291   xml.writeAttribute("errors", unexpectedExceptions);
17292   xml.writeAttribute("failures", stats.totals.assertions.failed - unexpectedExceptions);
17293   xml.writeAttribute("tests", stats.totals.assertions.total());
17294   xml.writeAttribute("hostname", "tbd"); // !TBD
17295   if (m_config->showDurations() == ShowDurations::Never)
17296     xml.writeAttribute("time", "");
17297   else
17298     xml.writeAttribute("time", suiteTime);
17299   xml.writeAttribute("timestamp", getCurrentTimestamp());
17300
17301   // Write properties if there are any
17302   if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
17303     auto properties = xml.scopedElement("properties");
17304     if (m_config->hasTestFilters()) {
17305       xml.scopedElement("property")
17306           .writeAttribute("name", "filters")
17307           .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
17308     }
17309     if (m_config->rngSeed() != 0) {
17310       xml.scopedElement("property").writeAttribute("name", "random-seed").writeAttribute("value", m_config->rngSeed());
17311     }
17312   }
17313
17314   // Write test cases
17315   for (auto const& child : groupNode.children)
17316     writeTestCase(*child);
17317
17318   xml.scopedElement("system-out").writeText(trim(stdOutForSuite), XmlFormatting::Newline);
17319   xml.scopedElement("system-err").writeText(trim(stdErrForSuite), XmlFormatting::Newline);
17320 }
17321
17322 void JunitReporter::writeTestCase(TestCaseNode const& testCaseNode)
17323 {
17324   TestCaseStats const& stats = testCaseNode.value;
17325
17326   // All test cases have exactly one section - which represents the
17327   // test case itself. That section may have 0-n nested sections
17328   assert(testCaseNode.children.size() == 1);
17329   SectionNode const& rootSection = *testCaseNode.children.front();
17330
17331   std::string className = stats.testInfo.className;
17332
17333   if (className.empty()) {
17334     className = fileNameTag(stats.testInfo.tags);
17335     if (className.empty())
17336       className = "global";
17337   }
17338
17339   if (!m_config->name().empty())
17340     className = m_config->name() + "." + className;
17341
17342   writeSection(className, "", rootSection);
17343 }
17344
17345 void JunitReporter::writeSection(std::string const& className, std::string const& rootName,
17346                                  SectionNode const& sectionNode)
17347 {
17348   std::string name = trim(sectionNode.stats.sectionInfo.name);
17349   if (!rootName.empty())
17350     name = rootName + '/' + name;
17351
17352   if (!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) {
17353     XmlWriter::ScopedElement e = xml.scopedElement("testcase");
17354     if (className.empty()) {
17355       xml.writeAttribute("classname", name);
17356       xml.writeAttribute("name", "root");
17357     } else {
17358       xml.writeAttribute("classname", className);
17359       xml.writeAttribute("name", name);
17360     }
17361     xml.writeAttribute("time", ::Catch::Detail::stringify(sectionNode.stats.durationInSeconds));
17362     // This is not ideal, but it should be enough to mimic gtest's
17363     // junit output.
17364     // Ideally the JUnit reporter would also handle `skipTest`
17365     // events and write those out appropriately.
17366     xml.writeAttribute("status", "run");
17367
17368     writeAssertions(sectionNode);
17369
17370     if (!sectionNode.stdOut.empty())
17371       xml.scopedElement("system-out").writeText(trim(sectionNode.stdOut), XmlFormatting::Newline);
17372     if (!sectionNode.stdErr.empty())
17373       xml.scopedElement("system-err").writeText(trim(sectionNode.stdErr), XmlFormatting::Newline);
17374   }
17375   for (auto const& childNode : sectionNode.childSections)
17376     if (className.empty())
17377       writeSection(name, "", *childNode);
17378     else
17379       writeSection(className, name, *childNode);
17380 }
17381
17382 void JunitReporter::writeAssertions(SectionNode const& sectionNode)
17383 {
17384   for (auto const& assertion : sectionNode.assertions)
17385     writeAssertion(assertion);
17386 }
17387
17388 void JunitReporter::writeAssertion(AssertionStats const& stats)
17389 {
17390   AssertionResult const& result = stats.assertionResult;
17391   if (!result.isOk()) {
17392     std::string elementName;
17393     switch (result.getResultType()) {
17394       case ResultWas::ThrewException:
17395       case ResultWas::FatalErrorCondition:
17396         elementName = "error";
17397         break;
17398       case ResultWas::ExplicitFailure:
17399       case ResultWas::ExpressionFailed:
17400       case ResultWas::DidntThrowException:
17401         elementName = "failure";
17402         break;
17403
17404       // We should never see these here:
17405       case ResultWas::Info:
17406       case ResultWas::Warning:
17407       case ResultWas::Ok:
17408       case ResultWas::Unknown:
17409       case ResultWas::FailureBit:
17410       case ResultWas::Exception:
17411         elementName = "internalError";
17412         break;
17413     }
17414
17415     XmlWriter::ScopedElement e = xml.scopedElement(elementName);
17416
17417     xml.writeAttribute("message", result.getExpression());
17418     xml.writeAttribute("type", result.getTestMacroName());
17419
17420     ReusableStringStream rss;
17421     if (stats.totals.assertions.total() > 0) {
17422       rss << "FAILED"
17423           << ":\n";
17424       if (result.hasExpression()) {
17425         rss << "  ";
17426         rss << result.getExpressionInMacro();
17427         rss << '\n';
17428       }
17429       if (result.hasExpandedExpression()) {
17430         rss << "with expansion:\n";
17431         rss << Column(result.getExpandedExpression()).indent(2) << '\n';
17432       }
17433     } else {
17434       rss << '\n';
17435     }
17436
17437     if (!result.getMessage().empty())
17438       rss << result.getMessage() << '\n';
17439     for (auto const& msg : stats.infoMessages)
17440       if (msg.type == ResultWas::Info)
17441         rss << msg.message << '\n';
17442
17443     rss << "at " << result.getSourceInfo();
17444     xml.writeText(rss.str(), XmlFormatting::Newline);
17445   }
17446 }
17447
17448 CATCH_REGISTER_REPORTER("junit", JunitReporter)
17449
17450 } // end namespace Catch
17451 // end catch_reporter_junit.cpp
17452 // start catch_reporter_listening.cpp
17453
17454 #include <cassert>
17455
17456 namespace Catch {
17457
17458 ListeningReporter::ListeningReporter()
17459 {
17460   // We will assume that listeners will always want all assertions
17461   m_preferences.shouldReportAllAssertions = true;
17462 }
17463
17464 void ListeningReporter::addListener(IStreamingReporterPtr&& listener)
17465 {
17466   m_listeners.push_back(std::move(listener));
17467 }
17468
17469 void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter)
17470 {
17471   assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
17472   m_reporter                         = std::move(reporter);
17473   m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
17474 }
17475
17476 ReporterPreferences ListeningReporter::getPreferences() const
17477 {
17478   return m_preferences;
17479 }
17480
17481 std::set<Verbosity> ListeningReporter::getSupportedVerbosities()
17482 {
17483   return std::set<Verbosity>{};
17484 }
17485
17486 void ListeningReporter::noMatchingTestCases(std::string const& spec)
17487 {
17488   for (auto const& listener : m_listeners) {
17489     listener->noMatchingTestCases(spec);
17490   }
17491   m_reporter->noMatchingTestCases(spec);
17492 }
17493
17494 void ListeningReporter::reportInvalidArguments(std::string const& arg)
17495 {
17496   for (auto const& listener : m_listeners) {
17497     listener->reportInvalidArguments(arg);
17498   }
17499   m_reporter->reportInvalidArguments(arg);
17500 }
17501
17502 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17503 void ListeningReporter::benchmarkPreparing(std::string const& name)
17504 {
17505   for (auto const& listener : m_listeners) {
17506     listener->benchmarkPreparing(name);
17507   }
17508   m_reporter->benchmarkPreparing(name);
17509 }
17510 void ListeningReporter::benchmarkStarting(BenchmarkInfo const& benchmarkInfo)
17511 {
17512   for (auto const& listener : m_listeners) {
17513     listener->benchmarkStarting(benchmarkInfo);
17514   }
17515   m_reporter->benchmarkStarting(benchmarkInfo);
17516 }
17517 void ListeningReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats)
17518 {
17519   for (auto const& listener : m_listeners) {
17520     listener->benchmarkEnded(benchmarkStats);
17521   }
17522   m_reporter->benchmarkEnded(benchmarkStats);
17523 }
17524
17525 void ListeningReporter::benchmarkFailed(std::string const& error)
17526 {
17527   for (auto const& listener : m_listeners) {
17528     listener->benchmarkFailed(error);
17529   }
17530   m_reporter->benchmarkFailed(error);
17531 }
17532 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17533
17534 void ListeningReporter::testRunStarting(TestRunInfo const& testRunInfo)
17535 {
17536   for (auto const& listener : m_listeners) {
17537     listener->testRunStarting(testRunInfo);
17538   }
17539   m_reporter->testRunStarting(testRunInfo);
17540 }
17541
17542 void ListeningReporter::testGroupStarting(GroupInfo const& groupInfo)
17543 {
17544   for (auto const& listener : m_listeners) {
17545     listener->testGroupStarting(groupInfo);
17546   }
17547   m_reporter->testGroupStarting(groupInfo);
17548 }
17549
17550 void ListeningReporter::testCaseStarting(TestCaseInfo const& testInfo)
17551 {
17552   for (auto const& listener : m_listeners) {
17553     listener->testCaseStarting(testInfo);
17554   }
17555   m_reporter->testCaseStarting(testInfo);
17556 }
17557
17558 void ListeningReporter::sectionStarting(SectionInfo const& sectionInfo)
17559 {
17560   for (auto const& listener : m_listeners) {
17561     listener->sectionStarting(sectionInfo);
17562   }
17563   m_reporter->sectionStarting(sectionInfo);
17564 }
17565
17566 void ListeningReporter::assertionStarting(AssertionInfo const& assertionInfo)
17567 {
17568   for (auto const& listener : m_listeners) {
17569     listener->assertionStarting(assertionInfo);
17570   }
17571   m_reporter->assertionStarting(assertionInfo);
17572 }
17573
17574 // The return value indicates if the messages buffer should be cleared:
17575 bool ListeningReporter::assertionEnded(AssertionStats const& assertionStats)
17576 {
17577   for (auto const& listener : m_listeners) {
17578     static_cast<void>(listener->assertionEnded(assertionStats));
17579   }
17580   return m_reporter->assertionEnded(assertionStats);
17581 }
17582
17583 void ListeningReporter::sectionEnded(SectionStats const& sectionStats)
17584 {
17585   for (auto const& listener : m_listeners) {
17586     listener->sectionEnded(sectionStats);
17587   }
17588   m_reporter->sectionEnded(sectionStats);
17589 }
17590
17591 void ListeningReporter::testCaseEnded(TestCaseStats const& testCaseStats)
17592 {
17593   for (auto const& listener : m_listeners) {
17594     listener->testCaseEnded(testCaseStats);
17595   }
17596   m_reporter->testCaseEnded(testCaseStats);
17597 }
17598
17599 void ListeningReporter::testGroupEnded(TestGroupStats const& testGroupStats)
17600 {
17601   for (auto const& listener : m_listeners) {
17602     listener->testGroupEnded(testGroupStats);
17603   }
17604   m_reporter->testGroupEnded(testGroupStats);
17605 }
17606
17607 void ListeningReporter::testRunEnded(TestRunStats const& testRunStats)
17608 {
17609   for (auto const& listener : m_listeners) {
17610     listener->testRunEnded(testRunStats);
17611   }
17612   m_reporter->testRunEnded(testRunStats);
17613 }
17614
17615 void ListeningReporter::skipTest(TestCaseInfo const& testInfo)
17616 {
17617   for (auto const& listener : m_listeners) {
17618     listener->skipTest(testInfo);
17619   }
17620   m_reporter->skipTest(testInfo);
17621 }
17622
17623 bool ListeningReporter::isMulti() const
17624 {
17625   return true;
17626 }
17627
17628 } // end namespace Catch
17629 // end catch_reporter_listening.cpp
17630 // start catch_reporter_xml.cpp
17631
17632 #if defined(_MSC_VER)
17633 #pragma warning(push)
17634 #pragma warning(disable : 4061) // Not all labels are EXPLICITLY handled in switch
17635                                 // Note that 4062 (not all labels are handled
17636                                 // and default is missing) is enabled
17637 #endif
17638
17639 namespace Catch {
17640 XmlReporter::XmlReporter(ReporterConfig const& _config) : StreamingReporterBase(_config), m_xml(_config.stream())
17641 {
17642   m_reporterPrefs.shouldRedirectStdOut      = true;
17643   m_reporterPrefs.shouldReportAllAssertions = true;
17644 }
17645
17646 XmlReporter::~XmlReporter() = default;
17647
17648 std::string XmlReporter::getDescription()
17649 {
17650   return "Reports test results as an XML document";
17651 }
17652
17653 std::string XmlReporter::getStylesheetRef() const
17654 {
17655   return std::string();
17656 }
17657
17658 void XmlReporter::writeSourceInfo(SourceLineInfo const& sourceInfo)
17659 {
17660   m_xml.writeAttribute("filename", sourceInfo.file).writeAttribute("line", sourceInfo.line);
17661 }
17662
17663 void XmlReporter::noMatchingTestCases(std::string const& s)
17664 {
17665   StreamingReporterBase::noMatchingTestCases(s);
17666 }
17667
17668 void XmlReporter::testRunStarting(TestRunInfo const& testInfo)
17669 {
17670   StreamingReporterBase::testRunStarting(testInfo);
17671   std::string stylesheetRef = getStylesheetRef();
17672   if (!stylesheetRef.empty())
17673     m_xml.writeStylesheetRef(stylesheetRef);
17674   m_xml.startElement("Catch");
17675   if (!m_config->name().empty())
17676     m_xml.writeAttribute("name", m_config->name());
17677   if (m_config->testSpec().hasFilters())
17678     m_xml.writeAttribute("filters", serializeFilters(m_config->getTestsOrTags()));
17679   if (m_config->rngSeed() != 0)
17680     m_xml.scopedElement("Randomness").writeAttribute("seed", m_config->rngSeed());
17681 }
17682
17683 void XmlReporter::testGroupStarting(GroupInfo const& groupInfo)
17684 {
17685   StreamingReporterBase::testGroupStarting(groupInfo);
17686   m_xml.startElement("Group").writeAttribute("name", groupInfo.name);
17687 }
17688
17689 void XmlReporter::testCaseStarting(TestCaseInfo const& testInfo)
17690 {
17691   StreamingReporterBase::testCaseStarting(testInfo);
17692   m_xml.startElement("TestCase")
17693       .writeAttribute("name", trim(testInfo.name))
17694       .writeAttribute("description", testInfo.description)
17695       .writeAttribute("tags", testInfo.tagsAsString());
17696
17697   writeSourceInfo(testInfo.lineInfo);
17698
17699   if (m_config->showDurations() == ShowDurations::Always)
17700     m_testCaseTimer.start();
17701   m_xml.ensureTagClosed();
17702 }
17703
17704 void XmlReporter::sectionStarting(SectionInfo const& sectionInfo)
17705 {
17706   StreamingReporterBase::sectionStarting(sectionInfo);
17707   if (m_sectionDepth++ > 0) {
17708     m_xml.startElement("Section").writeAttribute("name", trim(sectionInfo.name));
17709     writeSourceInfo(sectionInfo.lineInfo);
17710     m_xml.ensureTagClosed();
17711   }
17712 }
17713
17714 void XmlReporter::assertionStarting(AssertionInfo const&) {}
17715
17716 bool XmlReporter::assertionEnded(AssertionStats const& assertionStats)
17717 {
17718
17719   AssertionResult const& result = assertionStats.assertionResult;
17720
17721   bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
17722
17723   if (includeResults || result.getResultType() == ResultWas::Warning) {
17724     // Print any info messages in <Info> tags.
17725     for (auto const& msg : assertionStats.infoMessages) {
17726       if (msg.type == ResultWas::Info && includeResults) {
17727         m_xml.scopedElement("Info").writeText(msg.message);
17728       } else if (msg.type == ResultWas::Warning) {
17729         m_xml.scopedElement("Warning").writeText(msg.message);
17730       }
17731     }
17732   }
17733
17734   // Drop out if result was successful but we're not printing them.
17735   if (!includeResults && result.getResultType() != ResultWas::Warning)
17736     return true;
17737
17738   // Print the expression if there is one.
17739   if (result.hasExpression()) {
17740     m_xml.startElement("Expression")
17741         .writeAttribute("success", result.succeeded())
17742         .writeAttribute("type", result.getTestMacroName());
17743
17744     writeSourceInfo(result.getSourceInfo());
17745
17746     m_xml.scopedElement("Original").writeText(result.getExpression());
17747     m_xml.scopedElement("Expanded").writeText(result.getExpandedExpression());
17748   }
17749
17750   // And... Print a result applicable to each result type.
17751   switch (result.getResultType()) {
17752     case ResultWas::ThrewException:
17753       m_xml.startElement("Exception");
17754       writeSourceInfo(result.getSourceInfo());
17755       m_xml.writeText(result.getMessage());
17756       m_xml.endElement();
17757       break;
17758     case ResultWas::FatalErrorCondition:
17759       m_xml.startElement("FatalErrorCondition");
17760       writeSourceInfo(result.getSourceInfo());
17761       m_xml.writeText(result.getMessage());
17762       m_xml.endElement();
17763       break;
17764     case ResultWas::Info:
17765       m_xml.scopedElement("Info").writeText(result.getMessage());
17766       break;
17767     case ResultWas::Warning:
17768       // Warning will already have been written
17769       break;
17770     case ResultWas::ExplicitFailure:
17771       m_xml.startElement("Failure");
17772       writeSourceInfo(result.getSourceInfo());
17773       m_xml.writeText(result.getMessage());
17774       m_xml.endElement();
17775       break;
17776     default:
17777       break;
17778   }
17779
17780   if (result.hasExpression())
17781     m_xml.endElement();
17782
17783   return true;
17784 }
17785
17786 void XmlReporter::sectionEnded(SectionStats const& sectionStats)
17787 {
17788   StreamingReporterBase::sectionEnded(sectionStats);
17789   if (--m_sectionDepth > 0) {
17790     XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResults");
17791     e.writeAttribute("successes", sectionStats.assertions.passed);
17792     e.writeAttribute("failures", sectionStats.assertions.failed);
17793     e.writeAttribute("expectedFailures", sectionStats.assertions.failedButOk);
17794
17795     if (m_config->showDurations() == ShowDurations::Always)
17796       e.writeAttribute("durationInSeconds", sectionStats.durationInSeconds);
17797
17798     m_xml.endElement();
17799   }
17800 }
17801
17802 void XmlReporter::testCaseEnded(TestCaseStats const& testCaseStats)
17803 {
17804   StreamingReporterBase::testCaseEnded(testCaseStats);
17805   XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResult");
17806   e.writeAttribute("success", testCaseStats.totals.assertions.allOk());
17807
17808   if (m_config->showDurations() == ShowDurations::Always)
17809     e.writeAttribute("durationInSeconds", m_testCaseTimer.getElapsedSeconds());
17810
17811   if (!testCaseStats.stdOut.empty())
17812     m_xml.scopedElement("StdOut").writeText(trim(testCaseStats.stdOut), XmlFormatting::Newline);
17813   if (!testCaseStats.stdErr.empty())
17814     m_xml.scopedElement("StdErr").writeText(trim(testCaseStats.stdErr), XmlFormatting::Newline);
17815
17816   m_xml.endElement();
17817 }
17818
17819 void XmlReporter::testGroupEnded(TestGroupStats const& testGroupStats)
17820 {
17821   StreamingReporterBase::testGroupEnded(testGroupStats);
17822   // TODO: Check testGroupStats.aborting and act accordingly.
17823   m_xml.scopedElement("OverallResults")
17824       .writeAttribute("successes", testGroupStats.totals.assertions.passed)
17825       .writeAttribute("failures", testGroupStats.totals.assertions.failed)
17826       .writeAttribute("expectedFailures", testGroupStats.totals.assertions.failedButOk);
17827   m_xml.scopedElement("OverallResultsCases")
17828       .writeAttribute("successes", testGroupStats.totals.testCases.passed)
17829       .writeAttribute("failures", testGroupStats.totals.testCases.failed)
17830       .writeAttribute("expectedFailures", testGroupStats.totals.testCases.failedButOk);
17831   m_xml.endElement();
17832 }
17833
17834 void XmlReporter::testRunEnded(TestRunStats const& testRunStats)
17835 {
17836   StreamingReporterBase::testRunEnded(testRunStats);
17837   m_xml.scopedElement("OverallResults")
17838       .writeAttribute("successes", testRunStats.totals.assertions.passed)
17839       .writeAttribute("failures", testRunStats.totals.assertions.failed)
17840       .writeAttribute("expectedFailures", testRunStats.totals.assertions.failedButOk);
17841   m_xml.scopedElement("OverallResultsCases")
17842       .writeAttribute("successes", testRunStats.totals.testCases.passed)
17843       .writeAttribute("failures", testRunStats.totals.testCases.failed)
17844       .writeAttribute("expectedFailures", testRunStats.totals.testCases.failedButOk);
17845   m_xml.endElement();
17846 }
17847
17848 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17849 void XmlReporter::benchmarkPreparing(std::string const& name)
17850 {
17851   m_xml.startElement("BenchmarkResults").writeAttribute("name", name);
17852 }
17853
17854 void XmlReporter::benchmarkStarting(BenchmarkInfo const& info)
17855 {
17856   m_xml.writeAttribute("samples", info.samples)
17857       .writeAttribute("resamples", info.resamples)
17858       .writeAttribute("iterations", info.iterations)
17859       .writeAttribute("clockResolution", info.clockResolution)
17860       .writeAttribute("estimatedDuration", info.estimatedDuration)
17861       .writeComment("All values in nano seconds");
17862 }
17863
17864 void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats)
17865 {
17866   m_xml.startElement("mean")
17867       .writeAttribute("value", benchmarkStats.mean.point.count())
17868       .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
17869       .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
17870       .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
17871   m_xml.endElement();
17872   m_xml.startElement("standardDeviation")
17873       .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
17874       .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
17875       .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
17876       .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
17877   m_xml.endElement();
17878   m_xml.startElement("outliers")
17879       .writeAttribute("variance", benchmarkStats.outlierVariance)
17880       .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
17881       .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
17882       .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
17883       .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
17884   m_xml.endElement();
17885   m_xml.endElement();
17886 }
17887
17888 void XmlReporter::benchmarkFailed(std::string const& error)
17889 {
17890   m_xml.scopedElement("failed").writeAttribute("message", error);
17891   m_xml.endElement();
17892 }
17893 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17894
17895 CATCH_REGISTER_REPORTER("xml", XmlReporter)
17896
17897 } // end namespace Catch
17898
17899 #if defined(_MSC_VER)
17900 #pragma warning(pop)
17901 #endif
17902 // end catch_reporter_xml.cpp
17903
17904 namespace Catch {
17905 LeakDetector leakDetector;
17906 }
17907
17908 #ifdef __clang__
17909 #pragma clang diagnostic pop
17910 #endif
17911
17912 // end catch_impl.hpp
17913 #endif
17914
17915 #ifdef CATCH_CONFIG_MAIN
17916 // start catch_default_main.hpp
17917
17918 #ifndef __OBJC__
17919
17920 #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
17921 // Standard C/C++ Win32 Unicode wmain entry point
17922 extern "C" int wmain(int argc, wchar_t* argv[], wchar_t*[])
17923 {
17924 #else
17925 // Standard C/C++ main entry point
17926 int main(int argc, char* argv[])
17927 {
17928 #endif
17929
17930   return Catch::Session().run(argc, argv);
17931 }
17932
17933 #else // __OBJC__
17934
17935 // Objective-C entry point
17936 int main(int argc, char* const argv[])
17937 {
17938 #if !CATCH_ARC_ENABLED
17939   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
17940 #endif
17941
17942   Catch::registerTestMethods();
17943   int result = Catch::Session().run(argc, (char**)argv);
17944
17945 #if !CATCH_ARC_ENABLED
17946   [pool drain];
17947 #endif
17948
17949   return result;
17950 }
17951
17952 #endif // __OBJC__
17953
17954 // end catch_default_main.hpp
17955 #endif
17956
17957 #if !defined(CATCH_CONFIG_IMPL_ONLY)
17958
17959 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
17960 #undef CLARA_CONFIG_MAIN
17961 #endif
17962
17963 #if !defined(CATCH_CONFIG_DISABLE)
17964 //////
17965 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17966 #ifdef CATCH_CONFIG_PREFIX_ALL
17967
17968 #define CATCH_REQUIRE(...) INTERNAL_CATCH_TEST("CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__)
17969 #define CATCH_REQUIRE_FALSE(...)                                                                                       \
17970   INTERNAL_CATCH_TEST("CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest,   \
17971                       __VA_ARGS__)
17972
17973 #define CATCH_REQUIRE_THROWS(...)                                                                                      \
17974   INTERNAL_CATCH_THROWS("CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__)
17975 #define CATCH_REQUIRE_THROWS_AS(expr, exceptionType)                                                                   \
17976   INTERNAL_CATCH_THROWS_AS("CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr)
17977 #define CATCH_REQUIRE_THROWS_WITH(expr, matcher)                                                                       \
17978   INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr)
17979 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17980 #define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher)                                                     \
17981   INTERNAL_CATCH_THROWS_MATCHES("CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal,       \
17982                                 matcher, expr)
17983 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17984 #define CATCH_REQUIRE_NOTHROW(...)                                                                                     \
17985   INTERNAL_CATCH_NO_THROW("CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__)
17986
17987 #define CATCH_CHECK(...) INTERNAL_CATCH_TEST("CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17988 #define CATCH_CHECK_FALSE(...)                                                                                         \
17989   INTERNAL_CATCH_TEST("CATCH_CHECK_FALSE",                                                                             \
17990                       Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
17991 #define CATCH_CHECKED_IF(...)                                                                                          \
17992   INTERNAL_CATCH_IF("CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17993 #define CATCH_CHECKED_ELSE(...)                                                                                        \
17994   INTERNAL_CATCH_ELSE("CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17995 #define CATCH_CHECK_NOFAIL(...)                                                                                        \
17996   INTERNAL_CATCH_TEST("CATCH_CHECK_NOFAIL",                                                                            \
17997                       Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail,            \
17998                       __VA_ARGS__)
17999
18000 #define CATCH_CHECK_THROWS(...)                                                                                        \
18001   INTERNAL_CATCH_THROWS("CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18002 #define CATCH_CHECK_THROWS_AS(expr, exceptionType)                                                                     \
18003   INTERNAL_CATCH_THROWS_AS("CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr)
18004 #define CATCH_CHECK_THROWS_WITH(expr, matcher)                                                                         \
18005   INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher,   \
18006                                     expr)
18007 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18008 #define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher)                                                       \
18009   INTERNAL_CATCH_THROWS_MATCHES("CATCH_CHECK_THROWS_MATCHES", exceptionType,                                           \
18010                                 Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
18011 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18012 #define CATCH_CHECK_NOTHROW(...)                                                                                       \
18013   INTERNAL_CATCH_NO_THROW("CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18014
18015 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18016 #define CATCH_CHECK_THAT(arg, matcher)                                                                                 \
18017   INTERNAL_CHECK_THAT("CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg)
18018
18019 #define CATCH_REQUIRE_THAT(arg, matcher)                                                                               \
18020   INTERNAL_CHECK_THAT("CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg)
18021 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18022
18023 #define CATCH_INFO(msg) INTERNAL_CATCH_INFO("CATCH_INFO", msg)
18024 #define CATCH_UNSCOPED_INFO(msg) INTERNAL_CATCH_UNSCOPED_INFO("CATCH_UNSCOPED_INFO", msg)
18025 #define CATCH_WARN(msg)                                                                                                \
18026   INTERNAL_CATCH_MSG("CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg)
18027 #define CATCH_CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__)
18028
18029 #define CATCH_TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__)
18030 #define CATCH_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__)
18031 #define CATCH_METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__)
18032 #define CATCH_REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__)
18033 #define CATCH_SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__)
18034 #define CATCH_DYNAMIC_SECTION(...) INTERNAL_CATCH_DYNAMIC_SECTION(__VA_ARGS__)
18035 #define CATCH_FAIL(...)                                                                                                \
18036   INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__)
18037 #define CATCH_FAIL_CHECK(...)                                                                                          \
18038   INTERNAL_CATCH_MSG("CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure,                                            \
18039                      Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18040 #define CATCH_SUCCEED(...)                                                                                             \
18041   INTERNAL_CATCH_MSG("CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18042
18043 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
18044
18045 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
18046 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
18047 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
18048 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18049 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                            \
18050   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
18051 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
18052 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
18053 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...)                                                        \
18054   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__)
18055 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...)                                                    \
18056   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
18057 #else
18058 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__))
18059 #define CATCH_TEMPLATE_TEST_CASE_SIG(...)                                                                              \
18060   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__))
18061 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...)                                                                \
18062   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__))
18063 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                            \
18064   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
18065 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...)                                                                          \
18066   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__))
18067 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...)                                                                      \
18068   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__))
18069 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...)                                                        \
18070   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__))
18071 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...)                                                    \
18072   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
18073 #endif
18074
18075 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
18076 #define CATCH_STATIC_REQUIRE(...)                                                                                      \
18077   static_assert(__VA_ARGS__, #__VA_ARGS__);                                                                            \
18078   CATCH_SUCCEED(#__VA_ARGS__)
18079 #define CATCH_STATIC_REQUIRE_FALSE(...)                                                                                \
18080   static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")");                                                                \
18081   CATCH_SUCCEED(#__VA_ARGS__)
18082 #else
18083 #define CATCH_STATIC_REQUIRE(...) CATCH_REQUIRE(__VA_ARGS__)
18084 #define CATCH_STATIC_REQUIRE_FALSE(...) CATCH_REQUIRE_FALSE(__VA_ARGS__)
18085 #endif
18086
18087 // "BDD-style" convenience wrappers
18088 #define CATCH_SCENARIO(...) CATCH_TEST_CASE("Scenario: " __VA_ARGS__)
18089 #define CATCH_SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
18090 #define CATCH_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("    Given: " << desc)
18091 #define CATCH_AND_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("And given: " << desc)
18092 #define CATCH_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("     When: " << desc)
18093 #define CATCH_AND_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And when: " << desc)
18094 #define CATCH_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("     Then: " << desc)
18095 #define CATCH_AND_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("      And: " << desc)
18096
18097 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
18098 #define CATCH_BENCHMARK(...)                                                                                           \
18099   INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____),                                 \
18100                            INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__, , ), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__, , ))
18101 #define CATCH_BENCHMARK_ADVANCED(name)                                                                                 \
18102   INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
18103 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
18104
18105 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
18106 #else
18107
18108 #define REQUIRE(...) INTERNAL_CATCH_TEST("REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__)
18109 #define REQUIRE_FALSE(...)                                                                                             \
18110   INTERNAL_CATCH_TEST("REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest,         \
18111                       __VA_ARGS__)
18112
18113 #define REQUIRE_THROWS(...) INTERNAL_CATCH_THROWS("REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__)
18114 #define REQUIRE_THROWS_AS(expr, exceptionType)                                                                         \
18115   INTERNAL_CATCH_THROWS_AS("REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr)
18116 #define REQUIRE_THROWS_WITH(expr, matcher)                                                                             \
18117   INTERNAL_CATCH_THROWS_STR_MATCHES("REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr)
18118 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18119 #define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher)                                                           \
18120   INTERNAL_CATCH_THROWS_MATCHES("REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher,    \
18121                                 expr)
18122 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18123 #define REQUIRE_NOTHROW(...) INTERNAL_CATCH_NO_THROW("REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__)
18124
18125 #define CHECK(...) INTERNAL_CATCH_TEST("CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18126 #define CHECK_FALSE(...)                                                                                               \
18127   INTERNAL_CATCH_TEST("CHECK_FALSE",                                                                                   \
18128                       Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
18129 #define CHECKED_IF(...) INTERNAL_CATCH_IF("CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18130 #define CHECKED_ELSE(...) INTERNAL_CATCH_ELSE("CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18131 #define CHECK_NOFAIL(...)                                                                                              \
18132   INTERNAL_CATCH_TEST("CHECK_NOFAIL",                                                                                  \
18133                       Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail,            \
18134                       __VA_ARGS__)
18135
18136 #define CHECK_THROWS(...)                                                                                              \
18137   INTERNAL_CATCH_THROWS("CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18138 #define CHECK_THROWS_AS(expr, exceptionType)                                                                           \
18139   INTERNAL_CATCH_THROWS_AS("CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr)
18140 #define CHECK_THROWS_WITH(expr, matcher)                                                                               \
18141   INTERNAL_CATCH_THROWS_STR_MATCHES("CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
18142 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18143 #define CHECK_THROWS_MATCHES(expr, exceptionType, matcher)                                                             \
18144   INTERNAL_CATCH_THROWS_MATCHES("CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure,    \
18145                                 matcher, expr)
18146 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18147 #define CHECK_NOTHROW(...)                                                                                             \
18148   INTERNAL_CATCH_NO_THROW("CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18149
18150 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18151 #define CHECK_THAT(arg, matcher)                                                                                       \
18152   INTERNAL_CHECK_THAT("CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg)
18153
18154 #define REQUIRE_THAT(arg, matcher) INTERNAL_CHECK_THAT("REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg)
18155 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18156
18157 #define INFO(msg) INTERNAL_CATCH_INFO("INFO", msg)
18158 #define UNSCOPED_INFO(msg) INTERNAL_CATCH_UNSCOPED_INFO("UNSCOPED_INFO", msg)
18159 #define WARN(msg)                                                                                                      \
18160   INTERNAL_CATCH_MSG("WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg)
18161 #define CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__)
18162
18163 #define TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__)
18164 #define TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__)
18165 #define METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__)
18166 #define REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__)
18167 #define SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__)
18168 #define DYNAMIC_SECTION(...) INTERNAL_CATCH_DYNAMIC_SECTION(__VA_ARGS__)
18169 #define FAIL(...)                                                                                                      \
18170   INTERNAL_CATCH_MSG("FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__)
18171 #define FAIL_CHECK(...)                                                                                                \
18172   INTERNAL_CATCH_MSG("FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure,     \
18173                      __VA_ARGS__)
18174 #define SUCCEED(...)                                                                                                   \
18175   INTERNAL_CATCH_MSG("SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
18176 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
18177
18178 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
18179 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
18180 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
18181 #define TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18182 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                                  \
18183   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
18184 #define TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
18185 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
18186 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...)                                                              \
18187   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__)
18188 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...)                                                          \
18189   INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
18190 #define TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
18191 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...)                                                                 \
18192   INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__)
18193 #else
18194 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__))
18195 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__))
18196 #define TEMPLATE_TEST_CASE_METHOD(className, ...)                                                                      \
18197   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__))
18198 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                                  \
18199   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
18200 #define TEMPLATE_PRODUCT_TEST_CASE(...)                                                                                \
18201   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__))
18202 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...)                                                                            \
18203   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__))
18204 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...)                                                              \
18205   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__))
18206 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...)                                                          \
18207   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
18208 #define TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__))
18209 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...)                                                                 \
18210   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__))
18211 #endif
18212
18213 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
18214 #define STATIC_REQUIRE(...)                                                                                            \
18215   static_assert(__VA_ARGS__, #__VA_ARGS__);                                                                            \
18216   SUCCEED(#__VA_ARGS__)
18217 #define STATIC_REQUIRE_FALSE(...)                                                                                      \
18218   static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")");                                                                \
18219   SUCCEED("!(" #__VA_ARGS__ ")")
18220 #else
18221 #define STATIC_REQUIRE(...) REQUIRE(__VA_ARGS__)
18222 #define STATIC_REQUIRE_FALSE(...) REQUIRE_FALSE(__VA_ARGS__)
18223 #endif
18224
18225 #endif
18226
18227 #define CATCH_TRANSLATE_EXCEPTION(signature) INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature)
18228
18229 // "BDD-style" convenience wrappers
18230 #define SCENARIO(...) TEST_CASE("Scenario: " __VA_ARGS__)
18231 #define SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
18232
18233 #define GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("    Given: " << desc)
18234 #define AND_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("And given: " << desc)
18235 #define WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("     When: " << desc)
18236 #define AND_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And when: " << desc)
18237 #define THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("     Then: " << desc)
18238 #define AND_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("      And: " << desc)
18239
18240 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
18241 #define BENCHMARK(...)                                                                                                 \
18242   INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____),                                 \
18243                            INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__, , ), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__, , ))
18244 #define BENCHMARK_ADVANCED(name)                                                                                       \
18245   INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
18246 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
18247
18248 using Catch::Detail::Approx;
18249
18250 #else // CATCH_CONFIG_DISABLE
18251
18252 //////
18253 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
18254 #ifdef CATCH_CONFIG_PREFIX_ALL
18255
18256 #define CATCH_REQUIRE(...) (void)(0)
18257 #define CATCH_REQUIRE_FALSE(...) (void)(0)
18258
18259 #define CATCH_REQUIRE_THROWS(...) (void)(0)
18260 #define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) (void)(0)
18261 #define CATCH_REQUIRE_THROWS_WITH(expr, matcher) (void)(0)
18262 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18263 #define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
18264 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18265 #define CATCH_REQUIRE_NOTHROW(...) (void)(0)
18266
18267 #define CATCH_CHECK(...) (void)(0)
18268 #define CATCH_CHECK_FALSE(...) (void)(0)
18269 #define CATCH_CHECKED_IF(...) if (__VA_ARGS__)
18270 #define CATCH_CHECKED_ELSE(...) if (!(__VA_ARGS__))
18271 #define CATCH_CHECK_NOFAIL(...) (void)(0)
18272
18273 #define CATCH_CHECK_THROWS(...) (void)(0)
18274 #define CATCH_CHECK_THROWS_AS(expr, exceptionType) (void)(0)
18275 #define CATCH_CHECK_THROWS_WITH(expr, matcher) (void)(0)
18276 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18277 #define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
18278 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18279 #define CATCH_CHECK_NOTHROW(...) (void)(0)
18280
18281 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18282 #define CATCH_CHECK_THAT(arg, matcher) (void)(0)
18283
18284 #define CATCH_REQUIRE_THAT(arg, matcher) (void)(0)
18285 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18286
18287 #define CATCH_INFO(msg) (void)(0)
18288 #define CATCH_UNSCOPED_INFO(msg) (void)(0)
18289 #define CATCH_WARN(msg) (void)(0)
18290 #define CATCH_CAPTURE(msg) (void)(0)
18291
18292 #define CATCH_TEST_CASE(...)                                                                                           \
18293   INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18294 #define CATCH_TEST_CASE_METHOD(className, ...)                                                                         \
18295   INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18296 #define CATCH_METHOD_AS_TEST_CASE(method, ...)
18297 #define CATCH_REGISTER_TEST_CASE(Function, ...) (void)(0)
18298 #define CATCH_SECTION(...)
18299 #define CATCH_DYNAMIC_SECTION(...)
18300 #define CATCH_FAIL(...) (void)(0)
18301 #define CATCH_FAIL_CHECK(...) (void)(0)
18302 #define CATCH_SUCCEED(...) (void)(0)
18303
18304 #define CATCH_ANON_TEST_CASE()                                                                                         \
18305   INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18306
18307 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
18308 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
18309 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
18310 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...)                                                                \
18311   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
18312 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                            \
18313   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__)
18314 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
18315 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
18316 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18317 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...)                                                    \
18318   CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18319 #else
18320 #define CATCH_TEMPLATE_TEST_CASE(...)                                                                                  \
18321   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__))
18322 #define CATCH_TEMPLATE_TEST_CASE_SIG(...)                                                                              \
18323   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__))
18324 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...)                                                                \
18325   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__))
18326 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                            \
18327   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__))
18328 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
18329 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
18330 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18331 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...)                                                    \
18332   CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18333 #endif
18334
18335 // "BDD-style" convenience wrappers
18336 #define CATCH_SCENARIO(...)                                                                                            \
18337   INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18338 #define CATCH_SCENARIO_METHOD(className, ...)                                                                          \
18339   INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), className)
18340 #define CATCH_GIVEN(desc)
18341 #define CATCH_AND_GIVEN(desc)
18342 #define CATCH_WHEN(desc)
18343 #define CATCH_AND_WHEN(desc)
18344 #define CATCH_THEN(desc)
18345 #define CATCH_AND_THEN(desc)
18346
18347 #define CATCH_STATIC_REQUIRE(...) (void)(0)
18348 #define CATCH_STATIC_REQUIRE_FALSE(...) (void)(0)
18349
18350 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
18351 #else
18352
18353 #define REQUIRE(...) (void)(0)
18354 #define REQUIRE_FALSE(...) (void)(0)
18355
18356 #define REQUIRE_THROWS(...) (void)(0)
18357 #define REQUIRE_THROWS_AS(expr, exceptionType) (void)(0)
18358 #define REQUIRE_THROWS_WITH(expr, matcher) (void)(0)
18359 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18360 #define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
18361 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18362 #define REQUIRE_NOTHROW(...) (void)(0)
18363
18364 #define CHECK(...) (void)(0)
18365 #define CHECK_FALSE(...) (void)(0)
18366 #define CHECKED_IF(...) if (__VA_ARGS__)
18367 #define CHECKED_ELSE(...) if (!(__VA_ARGS__))
18368 #define CHECK_NOFAIL(...) (void)(0)
18369
18370 #define CHECK_THROWS(...) (void)(0)
18371 #define CHECK_THROWS_AS(expr, exceptionType) (void)(0)
18372 #define CHECK_THROWS_WITH(expr, matcher) (void)(0)
18373 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18374 #define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
18375 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18376 #define CHECK_NOTHROW(...) (void)(0)
18377
18378 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
18379 #define CHECK_THAT(arg, matcher) (void)(0)
18380
18381 #define REQUIRE_THAT(arg, matcher) (void)(0)
18382 #endif // CATCH_CONFIG_DISABLE_MATCHERS
18383
18384 #define INFO(msg) (void)(0)
18385 #define UNSCOPED_INFO(msg) (void)(0)
18386 #define WARN(msg) (void)(0)
18387 #define CAPTURE(msg) (void)(0)
18388
18389 #define TEST_CASE(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18390 #define TEST_CASE_METHOD(className, ...)                                                                               \
18391   INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18392 #define METHOD_AS_TEST_CASE(method, ...)
18393 #define REGISTER_TEST_CASE(Function, ...) (void)(0)
18394 #define SECTION(...)
18395 #define DYNAMIC_SECTION(...)
18396 #define FAIL(...) (void)(0)
18397 #define FAIL_CHECK(...) (void)(0)
18398 #define SUCCEED(...) (void)(0)
18399 #define ANON_TEST_CASE()                                                                                               \
18400   INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18401
18402 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
18403 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
18404 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
18405 #define TEMPLATE_TEST_CASE_METHOD(className, ...)                                                                      \
18406   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
18407 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                                  \
18408   INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__)
18409 #define TEMPLATE_PRODUCT_TEST_CASE(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18410 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18411 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18412 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18413 #else
18414 #define TEMPLATE_TEST_CASE(...)                                                                                        \
18415   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__))
18416 #define TEMPLATE_TEST_CASE_SIG(...)                                                                                    \
18417   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__))
18418 #define TEMPLATE_TEST_CASE_METHOD(className, ...)                                                                      \
18419   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__))
18420 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...)                                                                  \
18421   INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__))
18422 #define TEMPLATE_PRODUCT_TEST_CASE(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18423 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18424 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18425 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18426 #endif
18427
18428 #define STATIC_REQUIRE(...) (void)(0)
18429 #define STATIC_REQUIRE_FALSE(...) (void)(0)
18430
18431 #endif
18432
18433 #define CATCH_TRANSLATE_EXCEPTION(signature)                                                                           \
18434   INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature)
18435
18436 // "BDD-style" convenience wrappers
18437 #define SCENARIO(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18438 #define SCENARIO_METHOD(className, ...)                                                                                \
18439   INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), className)
18440
18441 #define GIVEN(desc)
18442 #define AND_GIVEN(desc)
18443 #define WHEN(desc)
18444 #define AND_WHEN(desc)
18445 #define THEN(desc)
18446 #define AND_THEN(desc)
18447
18448 using Catch::Detail::Approx;
18449
18450 #endif
18451
18452 #endif // ! CATCH_CONFIG_IMPL_ONLY
18453
18454 // start catch_reenable_warnings.h
18455
18456 #ifdef __clang__
18457 #ifdef __ICC // icpc defines the __clang__ macro
18458 #pragma warning(pop)
18459 #else
18460 #pragma clang diagnostic pop
18461 #endif
18462 #elif defined __GNUC__
18463 #pragma GCC diagnostic pop
18464 #endif
18465
18466 // end catch_reenable_warnings.h
18467 // end catch.hpp
18468 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED