[Adaptation Layer] Added rive-tizen adaptation layer class.
[platform/core/uifw/rive-tizen.git] / submodule / skia / recorder / test / include / catch.hpp
1 /*
2  *  Catch v2.12.3
3  *  Generated: 2020-06-29 20:47:52.374964
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2020 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
16 #define CATCH_VERSION_MAJOR 2
17 #define CATCH_VERSION_MINOR 12
18 #define CATCH_VERSION_PATCH 3
19
20 #ifdef __clang__
21 #    pragma clang system_header
22 #elif defined __GNUC__
23 #    pragma GCC system_header
24 #endif
25
26 // start catch_suppress_warnings.h
27
28 #ifdef __clang__
29 #   ifdef __ICC // icpc defines the __clang__ macro
30 #       pragma warning(push)
31 #       pragma warning(disable: 161 1682)
32 #   else // __ICC
33 #       pragma clang diagnostic push
34 #       pragma clang diagnostic ignored "-Wpadded"
35 #       pragma clang diagnostic ignored "-Wswitch-enum"
36 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
37 #    endif
38 #elif defined __GNUC__
39      // Because REQUIREs trigger GCC's -Wparentheses, and because still
40      // supported version of g++ have only buggy support for _Pragmas,
41      // Wparentheses have to be suppressed globally.
42 #    pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
43
44 #    pragma GCC diagnostic push
45 #    pragma GCC diagnostic ignored "-Wunused-variable"
46 #    pragma GCC diagnostic ignored "-Wpadded"
47 #endif
48 // end catch_suppress_warnings.h
49 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
50 #  define CATCH_IMPL
51 #  define CATCH_CONFIG_ALL_PARTS
52 #endif
53
54 // In the impl file, we want to have access to all parts of the headers
55 // Can also be used to sanely support PCHs
56 #if defined(CATCH_CONFIG_ALL_PARTS)
57 #  define CATCH_CONFIG_EXTERNAL_INTERFACES
58 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
59 #    undef CATCH_CONFIG_DISABLE_MATCHERS
60 #  endif
61 #  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
62 #    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
63 #  endif
64 #endif
65
66 #if !defined(CATCH_CONFIG_IMPL_ONLY)
67 // start catch_platform.h
68
69 #ifdef __APPLE__
70 # include <TargetConditionals.h>
71 # if TARGET_OS_OSX == 1
72 #  define CATCH_PLATFORM_MAC
73 # elif TARGET_OS_IPHONE == 1
74 #  define CATCH_PLATFORM_IPHONE
75 # endif
76
77 #elif defined(linux) || defined(__linux) || defined(__linux__)
78 #  define CATCH_PLATFORM_LINUX
79
80 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
81 #  define CATCH_PLATFORM_WINDOWS
82 #endif
83
84 // end catch_platform.h
85
86 #ifdef CATCH_IMPL
87 #  ifndef CLARA_CONFIG_MAIN
88 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
89 #    define CLARA_CONFIG_MAIN
90 #  endif
91 #endif
92
93 // start catch_user_interfaces.h
94
95 namespace Catch {
96     unsigned int rngSeed();
97 }
98
99 // end catch_user_interfaces.h
100 // start catch_tag_alias_autoregistrar.h
101
102 // start catch_common.h
103
104 // start catch_compiler_capabilities.h
105
106 // Detect a number of compiler features - by compiler
107 // The following features are defined:
108 //
109 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
110 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
111 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
112 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
113 // ****************
114 // Note to maintainers: if new toggles are added please document them
115 // in configuration.md, too
116 // ****************
117
118 // In general each macro has a _NO_<feature name> form
119 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
120 // Many features, at point of detection, define an _INTERNAL_ macro, so they
121 // can be combined, en-mass, with the _NO_ forms later.
122
123 #ifdef __cplusplus
124
125 #  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
126 #    define CATCH_CPP14_OR_GREATER
127 #  endif
128
129 #  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
130 #    define CATCH_CPP17_OR_GREATER
131 #  endif
132
133 #endif
134
135 #if defined(__cpp_lib_uncaught_exceptions)
136 #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
137 #endif
138
139 // We have to avoid both ICC and Clang, because they try to mask themselves
140 // as gcc, and we want only GCC in this block
141 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
142 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
143 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "GCC diagnostic pop" )
144
145 #    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
146
147 #endif
148
149 #if defined(__clang__)
150
151 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
152 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
153
154 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
155 // which results in calls to destructors being emitted for each temporary,
156 // without a matching initialization. In practice, this can result in something
157 // like `std::string::~string` being called on an uninitialized value.
158 //
159 // For example, this code will likely segfault under IBM XL:
160 // ```
161 // REQUIRE(std::string("12") + "34" == "1234")
162 // ```
163 //
164 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
165 #  if !defined(__ibmxl__)
166 #    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
167 #  endif
168
169 #    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
170          _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
171          _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
172
173 #    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
174          _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
175
176 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
177          _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
178
179 #    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
180          _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
181
182 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
183          _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
184
185 #endif // __clang__
186
187 ////////////////////////////////////////////////////////////////////////////////
188 // Assume that non-Windows platforms support posix signals by default
189 #if !defined(CATCH_PLATFORM_WINDOWS)
190     #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
191 #endif
192
193 ////////////////////////////////////////////////////////////////////////////////
194 // We know some environments not to support full POSIX signals
195 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
196     #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
197 #endif
198
199 #ifdef __OS400__
200 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
201 #       define CATCH_CONFIG_COLOUR_NONE
202 #endif
203
204 ////////////////////////////////////////////////////////////////////////////////
205 // Android somehow still does not support std::to_string
206 #if defined(__ANDROID__)
207 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
208 #    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
209 #endif
210
211 ////////////////////////////////////////////////////////////////////////////////
212 // Not all Windows environments support SEH properly
213 #if defined(__MINGW32__)
214 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
215 #endif
216
217 ////////////////////////////////////////////////////////////////////////////////
218 // PS4
219 #if defined(__ORBIS__)
220 #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
221 #endif
222
223 ////////////////////////////////////////////////////////////////////////////////
224 // Cygwin
225 #ifdef __CYGWIN__
226
227 // Required for some versions of Cygwin to declare gettimeofday
228 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
229 #   define _BSD_SOURCE
230 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
231 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
232 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
233            && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
234
235 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
236
237 # endif
238 #endif // __CYGWIN__
239
240 ////////////////////////////////////////////////////////////////////////////////
241 // Visual C++
242 #if defined(_MSC_VER)
243
244 #  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
245 #  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
246
247 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
248 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
249 #  endif
250
251 // Universal Windows platform does not support SEH
252 // Or console colours (or console at all...)
253 #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
254 #    define CATCH_CONFIG_COLOUR_NONE
255 #  else
256 #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
257 #  endif
258
259 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
260 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
261 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
262 #  if !defined(__clang__) // Handle Clang masquerading for msvc
263 #    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
264 #      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
265 #    endif // MSVC_TRADITIONAL
266 #  endif // __clang__
267
268 #endif // _MSC_VER
269
270 #if defined(_REENTRANT) || defined(_MSC_VER)
271 // Enable async processing, as -pthread is specified or no additional linking is required
272 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
273 #endif // _MSC_VER
274
275 ////////////////////////////////////////////////////////////////////////////////
276 // Check if we are compiled with -fno-exceptions or equivalent
277 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
278 #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
279 #endif
280
281 ////////////////////////////////////////////////////////////////////////////////
282 // DJGPP
283 #ifdef __DJGPP__
284 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
285 #endif // __DJGPP__
286
287 ////////////////////////////////////////////////////////////////////////////////
288 // Embarcadero C++Build
289 #if defined(__BORLANDC__)
290     #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
291 #endif
292
293 ////////////////////////////////////////////////////////////////////////////////
294
295 // Use of __COUNTER__ is suppressed during code analysis in
296 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
297 // handled by it.
298 // Otherwise all supported compilers support COUNTER macro,
299 // but user still might want to turn it off
300 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
301     #define CATCH_INTERNAL_CONFIG_COUNTER
302 #endif
303
304 ////////////////////////////////////////////////////////////////////////////////
305
306 // RTX is a special version of Windows that is real time.
307 // This means that it is detected as Windows, but does not provide
308 // the same set of capabilities as real Windows does.
309 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
310     #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
311     #define CATCH_INTERNAL_CONFIG_NO_ASYNC
312     #define CATCH_CONFIG_COLOUR_NONE
313 #endif
314
315 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
316 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
317 #endif
318
319 // Various stdlib support checks that require __has_include
320 #if defined(__has_include)
321   // Check if string_view is available and usable
322   #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
323   #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
324   #endif
325
326   // Check if optional is available and usable
327   #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
328   #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
329   #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
330
331   // Check if byte is available and usable
332   #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
333   #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
334   #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
335
336   // Check if variant is available and usable
337   #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
338   #    if defined(__clang__) && (__clang_major__ < 8)
339          // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
340          // fix should be in clang 8, workaround in libstdc++ 8.2
341   #      include <ciso646>
342   #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
343   #        define CATCH_CONFIG_NO_CPP17_VARIANT
344   #      else
345   #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
346   #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
347   #    else
348   #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
349   #    endif // defined(__clang__) && (__clang_major__ < 8)
350   #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
351 #endif // defined(__has_include)
352
353 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
354 #   define CATCH_CONFIG_COUNTER
355 #endif
356 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
357 #   define CATCH_CONFIG_WINDOWS_SEH
358 #endif
359 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
360 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
361 #   define CATCH_CONFIG_POSIX_SIGNALS
362 #endif
363 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
364 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
365 #   define CATCH_CONFIG_WCHAR
366 #endif
367
368 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
369 #    define CATCH_CONFIG_CPP11_TO_STRING
370 #endif
371
372 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
373 #  define CATCH_CONFIG_CPP17_OPTIONAL
374 #endif
375
376 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
377 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
378 #endif
379
380 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
381 #  define CATCH_CONFIG_CPP17_STRING_VIEW
382 #endif
383
384 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
385 #  define CATCH_CONFIG_CPP17_VARIANT
386 #endif
387
388 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
389 #  define CATCH_CONFIG_CPP17_BYTE
390 #endif
391
392 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
393 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
394 #endif
395
396 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
397 #  define CATCH_CONFIG_NEW_CAPTURE
398 #endif
399
400 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
401 #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
402 #endif
403
404 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
405 #  define CATCH_CONFIG_POLYFILL_ISNAN
406 #endif
407
408 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
409 #  define CATCH_CONFIG_USE_ASYNC
410 #endif
411
412 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !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) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
417 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
418 #endif
419
420 // Even if we do not think the compiler has that warning, we still have
421 // to provide a macro that can be used by the code.
422 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
423 #   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
424 #endif
425 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
426 #   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
427 #endif
428 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
429 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
430 #endif
431 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
432 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
433 #endif
434 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
435 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
436 #endif
437 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
438 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
439 #endif
440
441 // The goal of this macro is to avoid evaluation of the arguments, but
442 // still have the compiler warn on problems inside...
443 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
444 #   define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
445 #endif
446
447 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
448 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
449 #elif defined(__clang__) && (__clang_major__ < 5)
450 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
451 #endif
452
453 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
454 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
455 #endif
456
457 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
458 #define CATCH_TRY if ((true))
459 #define CATCH_CATCH_ALL if ((false))
460 #define CATCH_CATCH_ANON(type) if ((false))
461 #else
462 #define CATCH_TRY try
463 #define CATCH_CATCH_ALL catch (...)
464 #define CATCH_CATCH_ANON(type) catch (type)
465 #endif
466
467 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
468 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
469 #endif
470
471 // end catch_compiler_capabilities.h
472 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
473 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
474 #ifdef CATCH_CONFIG_COUNTER
475 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
476 #else
477 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
478 #endif
479
480 #include <iosfwd>
481 #include <string>
482 #include <cstdint>
483
484 // We need a dummy global operator<< so we can bring it into Catch namespace later
485 struct Catch_global_namespace_dummy {};
486 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
487
488 namespace Catch {
489
490     struct CaseSensitive { enum Choice {
491         Yes,
492         No
493     }; };
494
495     class NonCopyable {
496         NonCopyable( NonCopyable const& )              = delete;
497         NonCopyable( NonCopyable && )                  = delete;
498         NonCopyable& operator = ( NonCopyable const& ) = delete;
499         NonCopyable& operator = ( NonCopyable && )     = delete;
500
501     protected:
502         NonCopyable();
503         virtual ~NonCopyable();
504     };
505
506     struct SourceLineInfo {
507
508         SourceLineInfo() = delete;
509         SourceLineInfo( char const* _file, std::size_t _line ) noexcept
510         :   file( _file ),
511             line( _line )
512         {}
513
514         SourceLineInfo( SourceLineInfo const& other )            = default;
515         SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
516         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
517         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
518
519         bool empty() const noexcept { return file[0] == '\0'; }
520         bool operator == ( SourceLineInfo const& other ) const noexcept;
521         bool operator < ( SourceLineInfo const& other ) const noexcept;
522
523         char const* file;
524         std::size_t line;
525     };
526
527     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
528
529     // Bring in operator<< from global namespace into Catch namespace
530     // This is necessary because the overload of operator<< above makes
531     // lookup stop at namespace Catch
532     using ::operator<<;
533
534     // Use this in variadic streaming macros to allow
535     //    >> +StreamEndStop
536     // as well as
537     //    >> stuff +StreamEndStop
538     struct StreamEndStop {
539         std::string operator+() const;
540     };
541     template<typename T>
542     T const& operator + ( T const& value, StreamEndStop ) {
543         return value;
544     }
545 }
546
547 #define CATCH_INTERNAL_LINEINFO \
548     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
549
550 // end catch_common.h
551 namespace Catch {
552
553     struct RegistrarForTagAliases {
554         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
555     };
556
557 } // end namespace Catch
558
559 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
560     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
561     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
562     namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
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, IConfig const& config );
593     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
594
595 }
596
597 // end catch_interfaces_testcase.h
598 // start catch_stringref.h
599
600 #include <cstddef>
601 #include <string>
602 #include <iosfwd>
603 #include <cassert>
604
605 namespace Catch {
606
607     /// A non-owning string class (similar to the forthcoming std::string_view)
608     /// Note that, because a StringRef may be a substring of another string,
609     /// it may not be null terminated.
610     class StringRef {
611     public:
612         using size_type = std::size_t;
613         using const_iterator = const char*;
614
615     private:
616         static constexpr char const* const s_empty = "";
617
618         char const* m_start = s_empty;
619         size_type m_size = 0;
620
621     public: // construction
622         constexpr StringRef() noexcept = default;
623
624         StringRef( char const* rawChars ) noexcept;
625
626         constexpr StringRef( char const* rawChars, size_type size ) noexcept
627         :   m_start( rawChars ),
628             m_size( size )
629         {}
630
631         StringRef( std::string const& stdString ) noexcept
632         :   m_start( stdString.c_str() ),
633             m_size( stdString.size() )
634         {}
635
636         explicit operator std::string() const {
637             return std::string(m_start, m_size);
638         }
639
640     public: // operators
641         auto operator == ( StringRef const& other ) const noexcept -> bool;
642         auto operator != (StringRef const& other) const noexcept -> bool {
643             return !(*this == other);
644         }
645
646         auto operator[] ( size_type index ) const noexcept -> char {
647             assert(index < m_size);
648             return m_start[index];
649         }
650
651     public: // named queries
652         constexpr auto empty() const noexcept -> bool {
653             return m_size == 0;
654         }
655         constexpr auto size() const noexcept -> size_type {
656             return m_size;
657         }
658
659         // Returns the current start pointer. If the StringRef is not
660         // null-terminated, throws std::domain_exception
661         auto c_str() const -> char const*;
662
663     public: // substrings and searches
664         // Returns a substring of [start, start + length).
665         // If start + length > size(), then the substring is [start, size()).
666         // If start > size(), then the substring is empty.
667         auto substr( size_type start, size_type length ) const noexcept -> StringRef;
668
669         // Returns the current start pointer. May not be null-terminated.
670         auto data() const noexcept -> char const*;
671
672         constexpr auto isNullTerminated() const noexcept -> bool {
673             return m_start[m_size] == '\0';
674         }
675
676     public: // iterators
677         constexpr const_iterator begin() const { return m_start; }
678         constexpr const_iterator end() const { return m_start + m_size; }
679     };
680
681     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
682     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
683
684     constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
685         return StringRef( rawChars, size );
686     }
687 } // namespace Catch
688
689 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
690     return Catch::StringRef( rawChars, size );
691 }
692
693 // end catch_stringref.h
694 // start catch_preprocessor.hpp
695
696
697 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
698 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
699 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
700 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
701 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
702 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
703
704 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
705 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
706 // MSVC needs more evaluations
707 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
708 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
709 #else
710 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
711 #endif
712
713 #define CATCH_REC_END(...)
714 #define CATCH_REC_OUT
715
716 #define CATCH_EMPTY()
717 #define CATCH_DEFER(id) id CATCH_EMPTY()
718
719 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
720 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
721 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
722 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
723 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
724 #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
725
726 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
727 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
728 #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
729
730 #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
731 #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
732 #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
733
734 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
735 // and passes userdata as the first parameter to each invocation,
736 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
737 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
738
739 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
740
741 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
742 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
743 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
744 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
745 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
746 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
747 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
748 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
749 #else
750 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
751 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
752 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
753 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
754 #endif
755
756 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
757 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
758
759 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
760
761 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
762 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
763 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
764 #else
765 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
766 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
767 #endif
768
769 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
770     CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
771
772 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
773 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
774 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
775 #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
776 #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
777 #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
778 #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
779 #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
780 #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
781 #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
782 #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
783
784 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
785
786 #define INTERNAL_CATCH_TYPE_GEN\
787     template<typename...> struct TypeList {};\
788     template<typename...Ts>\
789     constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
790     template<template<typename...> class...> struct TemplateTypeList{};\
791     template<template<typename...> class...Cs>\
792     constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
793     template<typename...>\
794     struct append;\
795     template<typename...>\
796     struct rewrap;\
797     template<template<typename...> class, typename...>\
798     struct create;\
799     template<template<typename...> class, typename>\
800     struct convert;\
801     \
802     template<typename T> \
803     struct append<T> { using type = T; };\
804     template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
805     struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
806     template< template<typename...> class L1, typename...E1, typename...Rest>\
807     struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
808     \
809     template< template<typename...> class Container, template<typename...> class List, typename...elems>\
810     struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
811     template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
812     struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
813     \
814     template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
815     struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
816     template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
817     struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
818
819 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
820     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
821     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
822     constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
823     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
824     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
825     constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
826     \
827     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
828     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
829     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
830     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
831     template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
832     struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
833
834 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
835 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
836     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
837     static void TestName()
838 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
839     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
840     static void TestName()
841
842 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
843 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
844     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
845     static void TestName()
846 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
847     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
848     static void TestName()
849
850 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
851     template<typename Type>\
852     void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
853     {\
854         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
855     }
856
857 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
858     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
859     void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
860     {\
861         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
862     }
863
864 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
865     template<typename Type>\
866     void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
867     {\
868         Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
869     }
870
871 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
872     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
873     void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
874     {\
875         Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
876     }
877
878 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
879 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
880     template<typename TestType> \
881     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
882         void test();\
883     }
884
885 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
886     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
887     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
888         void test();\
889     }
890
891 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
892 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
893     template<typename TestType> \
894     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
895 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
896     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
897     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
898
899 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
900 #define INTERNAL_CATCH_NTTP_0
901 #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
902 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
903 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
904 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
905 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
906 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
907 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
908 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
909 #else
910 #define INTERNAL_CATCH_NTTP_0(signature)
911 #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
912 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
913 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
914 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
915 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
916 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
917 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
918 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
919 #endif
920
921 // end catch_preprocessor.hpp
922 // start catch_meta.hpp
923
924
925 #include <type_traits>
926
927 namespace Catch {
928     template<typename T>
929     struct always_false : std::false_type {};
930
931     template <typename> struct true_given : std::true_type {};
932     struct is_callable_tester {
933         template <typename Fun, typename... Args>
934         true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
935         template <typename...>
936         std::false_type static test(...);
937     };
938
939     template <typename T>
940     struct is_callable;
941
942     template <typename Fun, typename... Args>
943     struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
944
945 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
946     // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
947     // replaced with std::invoke_result here.
948     template <typename Func, typename... U>
949     using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
950 #else
951     // Keep ::type here because we still support C++11
952     template <typename Func, typename... U>
953     using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
954 #endif
955
956 } // namespace Catch
957
958 namespace mpl_{
959     struct na;
960 }
961
962 // end catch_meta.hpp
963 namespace Catch {
964
965 template<typename C>
966 class TestInvokerAsMethod : public ITestInvoker {
967     void (C::*m_testAsMethod)();
968 public:
969     TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
970
971     void invoke() const override {
972         C obj;
973         (obj.*m_testAsMethod)();
974     }
975 };
976
977 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
978
979 template<typename C>
980 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
981     return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
982 }
983
984 struct NameAndTags {
985     NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
986     StringRef name;
987     StringRef tags;
988 };
989
990 struct AutoReg : NonCopyable {
991     AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
992     ~AutoReg();
993 };
994
995 } // end namespace Catch
996
997 #if defined(CATCH_CONFIG_DISABLE)
998     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
999         static void TestName()
1000     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
1001         namespace{                        \
1002             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1003                 void test();              \
1004             };                            \
1005         }                                 \
1006         void TestName::test()
1007     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
1008         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1009     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
1010         namespace{                                                                                  \
1011             namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
1012             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1013         }                                                                                           \
1014         }                                                                                           \
1015         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1016
1017     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1018         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1019             INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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 TestType, __VA_ARGS__ )
1020     #else
1021         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1022             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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 TestType, __VA_ARGS__ ) )
1023     #endif
1024
1025     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1026         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1027             INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__ )
1028     #else
1029         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1030             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__ ) )
1031     #endif
1032
1033     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1034         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1035             INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( 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____ ), 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, __VA_ARGS__ )
1036     #else
1037         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1038             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( 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____ ), 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, __VA_ARGS__ ) )
1039     #endif
1040
1041     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1042         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1043             INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( 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____ ), 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, __VA_ARGS__ )
1044     #else
1045         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1046             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( 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____ ), 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, __VA_ARGS__ ) )
1047     #endif
1048 #endif
1049
1050     ///////////////////////////////////////////////////////////////////////////////
1051     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
1052         static void TestName(); \
1053         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1054         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1055         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1056         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1057         static void TestName()
1058     #define INTERNAL_CATCH_TESTCASE( ... ) \
1059         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
1060
1061     ///////////////////////////////////////////////////////////////////////////////
1062     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
1063         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1064         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1065         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1066         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1067
1068     ///////////////////////////////////////////////////////////////////////////////
1069     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
1070         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1071         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1072         namespace{ \
1073             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1074                 void test(); \
1075             }; \
1076             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1077         } \
1078         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1079         void TestName::test()
1080     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
1081         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
1082
1083     ///////////////////////////////////////////////////////////////////////////////
1084     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
1085         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1086         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1087         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1088         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1089
1090     ///////////////////////////////////////////////////////////////////////////////
1091     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
1092         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1093         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1094         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1095         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1096         INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1097         namespace {\
1098         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1099             INTERNAL_CATCH_TYPE_GEN\
1100             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1101             INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1102             template<typename...Types> \
1103             struct TestName{\
1104                 TestName(){\
1105                     int index = 0;                                    \
1106                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1107                     using expander = int[];\
1108                     (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
1109                 }\
1110             };\
1111             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1112             TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1113             return 0;\
1114         }();\
1115         }\
1116         }\
1117         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1118         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
1119
1120 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1121     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1122         INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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 TestType, __VA_ARGS__ )
1123 #else
1124     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1125         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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 TestType, __VA_ARGS__ ) )
1126 #endif
1127
1128 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1129     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1130         INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__ )
1131 #else
1132     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1133         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__ ) )
1134 #endif
1135
1136     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
1137         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
1138         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
1139         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
1140         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
1141         template<typename TestType> static void TestFuncName();       \
1142         namespace {\
1143         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
1144             INTERNAL_CATCH_TYPE_GEN                                                  \
1145             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
1146             template<typename... Types>                               \
1147             struct TestName {                                         \
1148                 void reg_tests() {                                          \
1149                     int index = 0;                                    \
1150                     using expander = int[];                           \
1151                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1152                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1153                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1154                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
1155                 }                                                     \
1156             };                                                        \
1157             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1158                 using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
1159                 TestInit t;                                           \
1160                 t.reg_tests();                                        \
1161                 return 0;                                             \
1162             }();                                                      \
1163         }                                                             \
1164         }                                                             \
1165         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
1166         template<typename TestType>                                   \
1167         static void TestFuncName()
1168
1169 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1170     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1171         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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,__VA_ARGS__)
1172 #else
1173     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1174         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__ ) )
1175 #endif
1176
1177 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1178     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1179         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__)
1180 #else
1181     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1182         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, __VA_ARGS__ ) )
1183 #endif
1184
1185     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
1186         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1187         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1188         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1189         template<typename TestType> static void TestFunc();       \
1190         namespace {\
1191         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1192         INTERNAL_CATCH_TYPE_GEN\
1193         template<typename... Types>                               \
1194         struct TestName {                                         \
1195             void reg_tests() {                                          \
1196                 int index = 0;                                    \
1197                 using expander = int[];                           \
1198                 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
1199             }                                                     \
1200         };\
1201         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1202                 using TestInit = typename convert<TestName, TmplList>::type; \
1203                 TestInit t;                                           \
1204                 t.reg_tests();                                        \
1205                 return 0;                                             \
1206             }();                                                      \
1207         }}\
1208         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
1209         template<typename TestType>                                   \
1210         static void TestFunc()
1211
1212     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
1213         INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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 )
1214
1215     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1216         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1217         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1218         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1219         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1220         namespace {\
1221         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1222             INTERNAL_CATCH_TYPE_GEN\
1223             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1224             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1225             INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1226             template<typename...Types> \
1227             struct TestNameClass{\
1228                 TestNameClass(){\
1229                     int index = 0;                                    \
1230                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1231                     using expander = int[];\
1232                     (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
1233                 }\
1234             };\
1235             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1236                 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1237                 return 0;\
1238         }();\
1239         }\
1240         }\
1241         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1242         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1243
1244 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1245     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1246         INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( 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____ ), 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, __VA_ARGS__ )
1247 #else
1248     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1249         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( 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____ ), 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, __VA_ARGS__ ) )
1250 #endif
1251
1252 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1253     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1254         INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( 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____ ), 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, __VA_ARGS__ )
1255 #else
1256     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1257         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( 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____ ), 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, __VA_ARGS__ ) )
1258 #endif
1259
1260     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
1261         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1262         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1263         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1264         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1265         template<typename TestType> \
1266             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1267                 void test();\
1268             };\
1269         namespace {\
1270         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
1271             INTERNAL_CATCH_TYPE_GEN                  \
1272             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1273             template<typename...Types>\
1274             struct TestNameClass{\
1275                 void reg_tests(){\
1276                     int index = 0;\
1277                     using expander = int[];\
1278                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1279                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1280                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1281                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
1282                 }\
1283             };\
1284             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1285                 using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
1286                 TestInit t;\
1287                 t.reg_tests();\
1288                 return 0;\
1289             }(); \
1290         }\
1291         }\
1292         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1293         template<typename TestType> \
1294         void TestName<TestType>::test()
1295
1296 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1297     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1298         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, typename T, __VA_ARGS__ )
1299 #else
1300     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1301         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, typename T,__VA_ARGS__ ) )
1302 #endif
1303
1304 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1305     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1306         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, Signature, __VA_ARGS__ )
1307 #else
1308     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1309         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, Signature,__VA_ARGS__ ) )
1310 #endif
1311
1312     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
1313         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1314         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1315         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1316         template<typename TestType> \
1317         struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1318             void test();\
1319         };\
1320         namespace {\
1321         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1322             INTERNAL_CATCH_TYPE_GEN\
1323             template<typename...Types>\
1324             struct TestNameClass{\
1325                 void reg_tests(){\
1326                     int index = 0;\
1327                     using expander = int[];\
1328                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
1329                 }\
1330             };\
1331             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1332                 using TestInit = typename convert<TestNameClass, TmplList>::type;\
1333                 TestInit t;\
1334                 t.reg_tests();\
1335                 return 0;\
1336             }(); \
1337         }}\
1338         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1339         template<typename TestType> \
1340         void TestName<TestType>::test()
1341
1342 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
1343         INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), 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, TmplList )
1344
1345 // end catch_test_registry.h
1346 // start catch_capture.hpp
1347
1348 // start catch_assertionhandler.h
1349
1350 // start catch_assertioninfo.h
1351
1352 // start catch_result_type.h
1353
1354 namespace Catch {
1355
1356     // ResultWas::OfType enum
1357     struct ResultWas { enum OfType {
1358         Unknown = -1,
1359         Ok = 0,
1360         Info = 1,
1361         Warning = 2,
1362
1363         FailureBit = 0x10,
1364
1365         ExpressionFailed = FailureBit | 1,
1366         ExplicitFailure = FailureBit | 2,
1367
1368         Exception = 0x100 | FailureBit,
1369
1370         ThrewException = Exception | 1,
1371         DidntThrowException = Exception | 2,
1372
1373         FatalErrorCondition = 0x200 | FailureBit
1374
1375     }; };
1376
1377     bool isOk( ResultWas::OfType resultType );
1378     bool isJustInfo( int flags );
1379
1380     // ResultDisposition::Flags enum
1381     struct ResultDisposition { enum Flags {
1382         Normal = 0x01,
1383
1384         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
1385         FalseTest = 0x04,           // Prefix expression with !
1386         SuppressFail = 0x08         // Failures are reported but do not fail the test
1387     }; };
1388
1389     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
1390
1391     bool shouldContinueOnFailure( int flags );
1392     inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
1393     bool shouldSuppressFailure( int flags );
1394
1395 } // end namespace Catch
1396
1397 // end catch_result_type.h
1398 namespace Catch {
1399
1400     struct AssertionInfo
1401     {
1402         StringRef macroName;
1403         SourceLineInfo lineInfo;
1404         StringRef capturedExpression;
1405         ResultDisposition::Flags resultDisposition;
1406
1407         // We want to delete this constructor but a compiler bug in 4.8 means
1408         // the struct is then treated as non-aggregate
1409         //AssertionInfo() = delete;
1410     };
1411
1412 } // end namespace Catch
1413
1414 // end catch_assertioninfo.h
1415 // start catch_decomposer.h
1416
1417 // start catch_tostring.h
1418
1419 #include <vector>
1420 #include <cstddef>
1421 #include <type_traits>
1422 #include <string>
1423 // start catch_stream.h
1424
1425 #include <iosfwd>
1426 #include <cstddef>
1427 #include <ostream>
1428
1429 namespace Catch {
1430
1431     std::ostream& cout();
1432     std::ostream& cerr();
1433     std::ostream& clog();
1434
1435     class StringRef;
1436
1437     struct IStream {
1438         virtual ~IStream();
1439         virtual std::ostream& stream() const = 0;
1440     };
1441
1442     auto makeStream( StringRef const &filename ) -> IStream const*;
1443
1444     class ReusableStringStream : NonCopyable {
1445         std::size_t m_index;
1446         std::ostream* m_oss;
1447     public:
1448         ReusableStringStream();
1449         ~ReusableStringStream();
1450
1451         auto str() const -> std::string;
1452
1453         template<typename T>
1454         auto operator << ( T const& value ) -> ReusableStringStream& {
1455             *m_oss << value;
1456             return *this;
1457         }
1458         auto get() -> std::ostream& { return *m_oss; }
1459     };
1460 }
1461
1462 // end catch_stream.h
1463 // start catch_interfaces_enum_values_registry.h
1464
1465 #include <vector>
1466
1467 namespace Catch {
1468
1469     namespace Detail {
1470         struct EnumInfo {
1471             StringRef m_name;
1472             std::vector<std::pair<int, StringRef>> m_values;
1473
1474             ~EnumInfo();
1475
1476             StringRef lookup( int value ) const;
1477         };
1478     } // namespace Detail
1479
1480     struct IMutableEnumValuesRegistry {
1481         virtual ~IMutableEnumValuesRegistry();
1482
1483         virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
1484
1485         template<typename E>
1486         Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
1487             static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1488             std::vector<int> intValues;
1489             intValues.reserve( values.size() );
1490             for( auto enumValue : values )
1491                 intValues.push_back( static_cast<int>( enumValue ) );
1492             return registerEnum( enumName, allEnums, intValues );
1493         }
1494     };
1495
1496 } // Catch
1497
1498 // end catch_interfaces_enum_values_registry.h
1499
1500 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1501 #include <string_view>
1502 #endif
1503
1504 #ifdef __OBJC__
1505 // start catch_objc_arc.hpp
1506
1507 #import <Foundation/Foundation.h>
1508
1509 #ifdef __has_feature
1510 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1511 #else
1512 #define CATCH_ARC_ENABLED 0
1513 #endif
1514
1515 void arcSafeRelease( NSObject* obj );
1516 id performOptionalSelector( id obj, SEL sel );
1517
1518 #if !CATCH_ARC_ENABLED
1519 inline void arcSafeRelease( NSObject* obj ) {
1520     [obj release];
1521 }
1522 inline id performOptionalSelector( id obj, SEL sel ) {
1523     if( [obj respondsToSelector: sel] )
1524         return [obj performSelector: sel];
1525     return nil;
1526 }
1527 #define CATCH_UNSAFE_UNRETAINED
1528 #define CATCH_ARC_STRONG
1529 #else
1530 inline void arcSafeRelease( NSObject* ){}
1531 inline id performOptionalSelector( id obj, SEL sel ) {
1532 #ifdef __clang__
1533 #pragma clang diagnostic push
1534 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1535 #endif
1536     if( [obj respondsToSelector: sel] )
1537         return [obj performSelector: sel];
1538 #ifdef __clang__
1539 #pragma clang diagnostic pop
1540 #endif
1541     return nil;
1542 }
1543 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1544 #define CATCH_ARC_STRONG __strong
1545 #endif
1546
1547 // end catch_objc_arc.hpp
1548 #endif
1549
1550 #ifdef _MSC_VER
1551 #pragma warning(push)
1552 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1553 #endif
1554
1555 namespace Catch {
1556     namespace Detail {
1557
1558         extern const std::string unprintableString;
1559
1560         std::string rawMemoryToString( const void *object, std::size_t size );
1561
1562         template<typename T>
1563         std::string rawMemoryToString( const T& object ) {
1564           return rawMemoryToString( &object, sizeof(object) );
1565         }
1566
1567         template<typename T>
1568         class IsStreamInsertable {
1569             template<typename Stream, typename U>
1570             static auto test(int)
1571                 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
1572
1573             template<typename, typename>
1574             static auto test(...)->std::false_type;
1575
1576         public:
1577             static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1578         };
1579
1580         template<typename E>
1581         std::string convertUnknownEnumToString( E e );
1582
1583         template<typename T>
1584         typename std::enable_if<
1585             !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
1586         std::string>::type convertUnstreamable( T const& ) {
1587             return Detail::unprintableString;
1588         }
1589         template<typename T>
1590         typename std::enable_if<
1591             !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
1592          std::string>::type convertUnstreamable(T const& ex) {
1593             return ex.what();
1594         }
1595
1596         template<typename T>
1597         typename std::enable_if<
1598             std::is_enum<T>::value
1599         , std::string>::type convertUnstreamable( T const& value ) {
1600             return convertUnknownEnumToString( value );
1601         }
1602
1603 #if defined(_MANAGED)
1604         //! Convert a CLR string to a utf8 std::string
1605         template<typename T>
1606         std::string clrReferenceToString( T^ ref ) {
1607             if (ref == nullptr)
1608                 return std::string("null");
1609             auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1610             cli::pin_ptr<System::Byte> p = &bytes[0];
1611             return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1612         }
1613 #endif
1614
1615     } // namespace Detail
1616
1617     // If we decide for C++14, change these to enable_if_ts
1618     template <typename T, typename = void>
1619     struct StringMaker {
1620         template <typename Fake = T>
1621         static
1622         typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1623             convert(const Fake& value) {
1624                 ReusableStringStream rss;
1625                 // NB: call using the function-like syntax to avoid ambiguity with
1626                 // user-defined templated operator<< under clang.
1627                 rss.operator<<(value);
1628                 return rss.str();
1629         }
1630
1631         template <typename Fake = T>
1632         static
1633         typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1634             convert( const Fake& value ) {
1635 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1636             return Detail::convertUnstreamable(value);
1637 #else
1638             return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1639 #endif
1640         }
1641     };
1642
1643     namespace Detail {
1644
1645         // This function dispatches all stringification requests inside of Catch.
1646         // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1647         template <typename T>
1648         std::string stringify(const T& e) {
1649             return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1650         }
1651
1652         template<typename E>
1653         std::string convertUnknownEnumToString( E e ) {
1654             return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1655         }
1656
1657 #if defined(_MANAGED)
1658         template <typename T>
1659         std::string stringify( T^ e ) {
1660             return ::Catch::StringMaker<T^>::convert(e);
1661         }
1662 #endif
1663
1664     } // namespace Detail
1665
1666     // Some predefined specializations
1667
1668     template<>
1669     struct StringMaker<std::string> {
1670         static std::string convert(const std::string& str);
1671     };
1672
1673 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1674     template<>
1675     struct StringMaker<std::string_view> {
1676         static std::string convert(std::string_view str);
1677     };
1678 #endif
1679
1680     template<>
1681     struct StringMaker<char const *> {
1682         static std::string convert(char const * str);
1683     };
1684     template<>
1685     struct StringMaker<char *> {
1686         static std::string convert(char * str);
1687     };
1688
1689 #ifdef CATCH_CONFIG_WCHAR
1690     template<>
1691     struct StringMaker<std::wstring> {
1692         static std::string convert(const std::wstring& wstr);
1693     };
1694
1695 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1696     template<>
1697     struct StringMaker<std::wstring_view> {
1698         static std::string convert(std::wstring_view str);
1699     };
1700 # endif
1701
1702     template<>
1703     struct StringMaker<wchar_t const *> {
1704         static std::string convert(wchar_t const * str);
1705     };
1706     template<>
1707     struct StringMaker<wchar_t *> {
1708         static std::string convert(wchar_t * str);
1709     };
1710 #endif
1711
1712     // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1713     //      while keeping string semantics?
1714     template<int SZ>
1715     struct StringMaker<char[SZ]> {
1716         static std::string convert(char const* str) {
1717             return ::Catch::Detail::stringify(std::string{ str });
1718         }
1719     };
1720     template<int SZ>
1721     struct StringMaker<signed char[SZ]> {
1722         static std::string convert(signed char const* str) {
1723             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1724         }
1725     };
1726     template<int SZ>
1727     struct StringMaker<unsigned char[SZ]> {
1728         static std::string convert(unsigned char const* str) {
1729             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1730         }
1731     };
1732
1733 #if defined(CATCH_CONFIG_CPP17_BYTE)
1734     template<>
1735     struct StringMaker<std::byte> {
1736         static std::string convert(std::byte value);
1737     };
1738 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
1739     template<>
1740     struct StringMaker<int> {
1741         static std::string convert(int value);
1742     };
1743     template<>
1744     struct StringMaker<long> {
1745         static std::string convert(long value);
1746     };
1747     template<>
1748     struct StringMaker<long long> {
1749         static std::string convert(long long value);
1750     };
1751     template<>
1752     struct StringMaker<unsigned int> {
1753         static std::string convert(unsigned int value);
1754     };
1755     template<>
1756     struct StringMaker<unsigned long> {
1757         static std::string convert(unsigned long value);
1758     };
1759     template<>
1760     struct StringMaker<unsigned long long> {
1761         static std::string convert(unsigned long long value);
1762     };
1763
1764     template<>
1765     struct StringMaker<bool> {
1766         static std::string convert(bool b);
1767     };
1768
1769     template<>
1770     struct StringMaker<char> {
1771         static std::string convert(char c);
1772     };
1773     template<>
1774     struct StringMaker<signed char> {
1775         static std::string convert(signed char c);
1776     };
1777     template<>
1778     struct StringMaker<unsigned char> {
1779         static std::string convert(unsigned char c);
1780     };
1781
1782     template<>
1783     struct StringMaker<std::nullptr_t> {
1784         static std::string convert(std::nullptr_t);
1785     };
1786
1787     template<>
1788     struct StringMaker<float> {
1789         static std::string convert(float value);
1790         static int precision;
1791     };
1792
1793     template<>
1794     struct StringMaker<double> {
1795         static std::string convert(double value);
1796         static int precision;
1797     };
1798
1799     template <typename T>
1800     struct StringMaker<T*> {
1801         template <typename U>
1802         static std::string convert(U* p) {
1803             if (p) {
1804                 return ::Catch::Detail::rawMemoryToString(p);
1805             } else {
1806                 return "nullptr";
1807             }
1808         }
1809     };
1810
1811     template <typename R, typename C>
1812     struct StringMaker<R C::*> {
1813         static std::string convert(R C::* p) {
1814             if (p) {
1815                 return ::Catch::Detail::rawMemoryToString(p);
1816             } else {
1817                 return "nullptr";
1818             }
1819         }
1820     };
1821
1822 #if defined(_MANAGED)
1823     template <typename T>
1824     struct StringMaker<T^> {
1825         static std::string convert( T^ ref ) {
1826             return ::Catch::Detail::clrReferenceToString(ref);
1827         }
1828     };
1829 #endif
1830
1831     namespace Detail {
1832         template<typename InputIterator>
1833         std::string rangeToString(InputIterator first, InputIterator last) {
1834             ReusableStringStream rss;
1835             rss << "{ ";
1836             if (first != last) {
1837                 rss << ::Catch::Detail::stringify(*first);
1838                 for (++first; first != last; ++first)
1839                     rss << ", " << ::Catch::Detail::stringify(*first);
1840             }
1841             rss << " }";
1842             return rss.str();
1843         }
1844     }
1845
1846 #ifdef __OBJC__
1847     template<>
1848     struct StringMaker<NSString*> {
1849         static std::string convert(NSString * nsstring) {
1850             if (!nsstring)
1851                 return "nil";
1852             return std::string("@") + [nsstring UTF8String];
1853         }
1854     };
1855     template<>
1856     struct StringMaker<NSObject*> {
1857         static std::string convert(NSObject* nsObject) {
1858             return ::Catch::Detail::stringify([nsObject description]);
1859         }
1860
1861     };
1862     namespace Detail {
1863         inline std::string stringify( NSString* nsstring ) {
1864             return StringMaker<NSString*>::convert( nsstring );
1865         }
1866
1867     } // namespace Detail
1868 #endif // __OBJC__
1869
1870 } // namespace Catch
1871
1872 //////////////////////////////////////////////////////
1873 // Separate std-lib types stringification, so it can be selectively enabled
1874 // This means that we do not bring in
1875
1876 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1877 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1878 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1879 #  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1880 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1881 #  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1882 #endif
1883
1884 // Separate std::pair specialization
1885 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1886 #include <utility>
1887 namespace Catch {
1888     template<typename T1, typename T2>
1889     struct StringMaker<std::pair<T1, T2> > {
1890         static std::string convert(const std::pair<T1, T2>& pair) {
1891             ReusableStringStream rss;
1892             rss << "{ "
1893                 << ::Catch::Detail::stringify(pair.first)
1894                 << ", "
1895                 << ::Catch::Detail::stringify(pair.second)
1896                 << " }";
1897             return rss.str();
1898         }
1899     };
1900 }
1901 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1902
1903 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
1904 #include <optional>
1905 namespace Catch {
1906     template<typename T>
1907     struct StringMaker<std::optional<T> > {
1908         static std::string convert(const std::optional<T>& optional) {
1909             ReusableStringStream rss;
1910             if (optional.has_value()) {
1911                 rss << ::Catch::Detail::stringify(*optional);
1912             } else {
1913                 rss << "{ }";
1914             }
1915             return rss.str();
1916         }
1917     };
1918 }
1919 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1920
1921 // Separate std::tuple specialization
1922 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1923 #include <tuple>
1924 namespace Catch {
1925     namespace Detail {
1926         template<
1927             typename Tuple,
1928             std::size_t N = 0,
1929             bool = (N < std::tuple_size<Tuple>::value)
1930             >
1931             struct TupleElementPrinter {
1932             static void print(const Tuple& tuple, std::ostream& os) {
1933                 os << (N ? ", " : " ")
1934                     << ::Catch::Detail::stringify(std::get<N>(tuple));
1935                 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1936             }
1937         };
1938
1939         template<
1940             typename Tuple,
1941             std::size_t N
1942         >
1943             struct TupleElementPrinter<Tuple, N, false> {
1944             static void print(const Tuple&, std::ostream&) {}
1945         };
1946
1947     }
1948
1949     template<typename ...Types>
1950     struct StringMaker<std::tuple<Types...>> {
1951         static std::string convert(const std::tuple<Types...>& tuple) {
1952             ReusableStringStream rss;
1953             rss << '{';
1954             Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1955             rss << " }";
1956             return rss.str();
1957         }
1958     };
1959 }
1960 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1961
1962 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1963 #include <variant>
1964 namespace Catch {
1965     template<>
1966     struct StringMaker<std::monostate> {
1967         static std::string convert(const std::monostate&) {
1968             return "{ }";
1969         }
1970     };
1971
1972     template<typename... Elements>
1973     struct StringMaker<std::variant<Elements...>> {
1974         static std::string convert(const std::variant<Elements...>& variant) {
1975             if (variant.valueless_by_exception()) {
1976                 return "{valueless variant}";
1977             } else {
1978                 return std::visit(
1979                     [](const auto& value) {
1980                         return ::Catch::Detail::stringify(value);
1981                     },
1982                     variant
1983                 );
1984             }
1985         }
1986     };
1987 }
1988 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1989
1990 namespace Catch {
1991     // Import begin/ end from std here
1992     using std::begin;
1993     using std::end;
1994
1995     namespace detail {
1996         template <typename...>
1997         struct void_type {
1998             using type = void;
1999         };
2000
2001         template <typename T, typename = void>
2002         struct is_range_impl : std::false_type {
2003         };
2004
2005         template <typename T>
2006         struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {
2007         };
2008     } // namespace detail
2009
2010     template <typename T>
2011     struct is_range : detail::is_range_impl<T> {
2012     };
2013
2014 #if defined(_MANAGED) // Managed types are never ranges
2015     template <typename T>
2016     struct is_range<T^> {
2017         static const bool value = false;
2018     };
2019 #endif
2020
2021     template<typename Range>
2022     std::string rangeToString( Range const& range ) {
2023         return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
2024     }
2025
2026     // Handle vector<bool> specially
2027     template<typename Allocator>
2028     std::string rangeToString( std::vector<bool, Allocator> const& v ) {
2029         ReusableStringStream rss;
2030         rss << "{ ";
2031         bool first = true;
2032         for( bool b : v ) {
2033             if( first )
2034                 first = false;
2035             else
2036                 rss << ", ";
2037             rss << ::Catch::Detail::stringify( b );
2038         }
2039         rss << " }";
2040         return rss.str();
2041     }
2042
2043     template<typename R>
2044     struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
2045         static std::string convert( R const& range ) {
2046             return rangeToString( range );
2047         }
2048     };
2049
2050     template <typename T, int SZ>
2051     struct StringMaker<T[SZ]> {
2052         static std::string convert(T const(&arr)[SZ]) {
2053             return rangeToString(arr);
2054         }
2055     };
2056
2057 } // namespace Catch
2058
2059 // Separate std::chrono::duration specialization
2060 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2061 #include <ctime>
2062 #include <ratio>
2063 #include <chrono>
2064
2065 namespace Catch {
2066
2067 template <class Ratio>
2068 struct ratio_string {
2069     static std::string symbol();
2070 };
2071
2072 template <class Ratio>
2073 std::string ratio_string<Ratio>::symbol() {
2074     Catch::ReusableStringStream rss;
2075     rss << '[' << Ratio::num << '/'
2076         << Ratio::den << ']';
2077     return rss.str();
2078 }
2079 template <>
2080 struct ratio_string<std::atto> {
2081     static std::string symbol();
2082 };
2083 template <>
2084 struct ratio_string<std::femto> {
2085     static std::string symbol();
2086 };
2087 template <>
2088 struct ratio_string<std::pico> {
2089     static std::string symbol();
2090 };
2091 template <>
2092 struct ratio_string<std::nano> {
2093     static std::string symbol();
2094 };
2095 template <>
2096 struct ratio_string<std::micro> {
2097     static std::string symbol();
2098 };
2099 template <>
2100 struct ratio_string<std::milli> {
2101     static std::string symbol();
2102 };
2103
2104     ////////////
2105     // std::chrono::duration specializations
2106     template<typename Value, typename Ratio>
2107     struct StringMaker<std::chrono::duration<Value, Ratio>> {
2108         static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
2109             ReusableStringStream rss;
2110             rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2111             return rss.str();
2112         }
2113     };
2114     template<typename Value>
2115     struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2116         static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
2117             ReusableStringStream rss;
2118             rss << duration.count() << " s";
2119             return rss.str();
2120         }
2121     };
2122     template<typename Value>
2123     struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2124         static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
2125             ReusableStringStream rss;
2126             rss << duration.count() << " m";
2127             return rss.str();
2128         }
2129     };
2130     template<typename Value>
2131     struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2132         static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
2133             ReusableStringStream rss;
2134             rss << duration.count() << " h";
2135             return rss.str();
2136         }
2137     };
2138
2139     ////////////
2140     // std::chrono::time_point specialization
2141     // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2142     template<typename Clock, typename Duration>
2143     struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2144         static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
2145             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2146         }
2147     };
2148     // std::chrono::time_point<system_clock> specialization
2149     template<typename Duration>
2150     struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
2151         static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
2152             auto converted = std::chrono::system_clock::to_time_t(time_point);
2153
2154 #ifdef _MSC_VER
2155             std::tm timeInfo = {};
2156             gmtime_s(&timeInfo, &converted);
2157 #else
2158             std::tm* timeInfo = std::gmtime(&converted);
2159 #endif
2160
2161             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2162             char timeStamp[timeStampSize];
2163             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
2164
2165 #ifdef _MSC_VER
2166             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2167 #else
2168             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2169 #endif
2170             return std::string(timeStamp);
2171         }
2172     };
2173 }
2174 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2175
2176 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
2177 namespace Catch { \
2178     template<> struct StringMaker<enumName> { \
2179         static std::string convert( enumName value ) { \
2180             static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
2181             return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
2182         } \
2183     }; \
2184 }
2185
2186 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
2187
2188 #ifdef _MSC_VER
2189 #pragma warning(pop)
2190 #endif
2191
2192 // end catch_tostring.h
2193 #include <iosfwd>
2194
2195 #ifdef _MSC_VER
2196 #pragma warning(push)
2197 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
2198 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
2199 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2200 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
2201 #pragma warning(disable:4800) // Forcing result to true or false
2202 #endif
2203
2204 namespace Catch {
2205
2206     struct ITransientExpression {
2207         auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
2208         auto getResult() const -> bool { return m_result; }
2209         virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
2210
2211         ITransientExpression( bool isBinaryExpression, bool result )
2212         :   m_isBinaryExpression( isBinaryExpression ),
2213             m_result( result )
2214         {}
2215
2216         // We don't actually need a virtual destructor, but many static analysers
2217         // complain if it's not here :-(
2218         virtual ~ITransientExpression();
2219
2220         bool m_isBinaryExpression;
2221         bool m_result;
2222
2223     };
2224
2225     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
2226
2227     template<typename LhsT, typename RhsT>
2228     class BinaryExpr  : public ITransientExpression {
2229         LhsT m_lhs;
2230         StringRef m_op;
2231         RhsT m_rhs;
2232
2233         void streamReconstructedExpression( std::ostream &os ) const override {
2234             formatReconstructedExpression
2235                     ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
2236         }
2237
2238     public:
2239         BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
2240         :   ITransientExpression{ true, comparisonResult },
2241             m_lhs( lhs ),
2242             m_op( op ),
2243             m_rhs( rhs )
2244         {}
2245
2246         template<typename T>
2247         auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2248             static_assert(always_false<T>::value,
2249             "chained comparisons are not supported inside assertions, "
2250             "wrap the expression inside parentheses, or decompose it");
2251         }
2252
2253         template<typename T>
2254         auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2255             static_assert(always_false<T>::value,
2256             "chained comparisons are not supported inside assertions, "
2257             "wrap the expression inside parentheses, or decompose it");
2258         }
2259
2260         template<typename T>
2261         auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2262             static_assert(always_false<T>::value,
2263             "chained comparisons are not supported inside assertions, "
2264             "wrap the expression inside parentheses, or decompose it");
2265         }
2266
2267         template<typename T>
2268         auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2269             static_assert(always_false<T>::value,
2270             "chained comparisons are not supported inside assertions, "
2271             "wrap the expression inside parentheses, or decompose it");
2272         }
2273
2274         template<typename T>
2275         auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2276             static_assert(always_false<T>::value,
2277             "chained comparisons are not supported inside assertions, "
2278             "wrap the expression inside parentheses, or decompose it");
2279         }
2280
2281         template<typename T>
2282         auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2283             static_assert(always_false<T>::value,
2284             "chained comparisons are not supported inside assertions, "
2285             "wrap the expression inside parentheses, or decompose it");
2286         }
2287
2288         template<typename T>
2289         auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2290             static_assert(always_false<T>::value,
2291             "chained comparisons are not supported inside assertions, "
2292             "wrap the expression inside parentheses, or decompose it");
2293         }
2294
2295         template<typename T>
2296         auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2297             static_assert(always_false<T>::value,
2298             "chained comparisons are not supported inside assertions, "
2299             "wrap the expression inside parentheses, or decompose it");
2300         }
2301     };
2302
2303     template<typename LhsT>
2304     class UnaryExpr : public ITransientExpression {
2305         LhsT m_lhs;
2306
2307         void streamReconstructedExpression( std::ostream &os ) const override {
2308             os << Catch::Detail::stringify( m_lhs );
2309         }
2310
2311     public:
2312         explicit UnaryExpr( LhsT lhs )
2313         :   ITransientExpression{ false, static_cast<bool>(lhs) },
2314             m_lhs( lhs )
2315         {}
2316     };
2317
2318     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2319     template<typename LhsT, typename RhsT>
2320     auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
2321     template<typename T>
2322     auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2323     template<typename T>
2324     auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2325     template<typename T>
2326     auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2327     template<typename T>
2328     auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2329
2330     template<typename LhsT, typename RhsT>
2331     auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
2332     template<typename T>
2333     auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2334     template<typename T>
2335     auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2336     template<typename T>
2337     auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2338     template<typename T>
2339     auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2340
2341     template<typename LhsT>
2342     class ExprLhs {
2343         LhsT m_lhs;
2344     public:
2345         explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
2346
2347         template<typename RhsT>
2348         auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2349             return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
2350         }
2351         auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2352             return { m_lhs == rhs, m_lhs, "==", rhs };
2353         }
2354
2355         template<typename RhsT>
2356         auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2357             return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
2358         }
2359         auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2360             return { m_lhs != rhs, m_lhs, "!=", rhs };
2361         }
2362
2363         template<typename RhsT>
2364         auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2365             return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
2366         }
2367         template<typename RhsT>
2368         auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2369             return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
2370         }
2371         template<typename RhsT>
2372         auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2373             return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
2374         }
2375         template<typename RhsT>
2376         auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2377             return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
2378         }
2379         template <typename RhsT>
2380         auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2381             return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
2382         }
2383         template <typename RhsT>
2384         auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2385             return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
2386         }
2387         template <typename RhsT>
2388         auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2389             return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
2390         }
2391
2392         template<typename RhsT>
2393         auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2394             static_assert(always_false<RhsT>::value,
2395             "operator&& is not supported inside assertions, "
2396             "wrap the expression inside parentheses, or decompose it");
2397         }
2398
2399         template<typename RhsT>
2400         auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2401             static_assert(always_false<RhsT>::value,
2402             "operator|| is not supported inside assertions, "
2403             "wrap the expression inside parentheses, or decompose it");
2404         }
2405
2406         auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
2407             return UnaryExpr<LhsT>{ m_lhs };
2408         }
2409     };
2410
2411     void handleExpression( ITransientExpression const& expr );
2412
2413     template<typename T>
2414     void handleExpression( ExprLhs<T> const& expr ) {
2415         handleExpression( expr.makeUnaryExpr() );
2416     }
2417
2418     struct Decomposer {
2419         template<typename T>
2420         auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
2421             return ExprLhs<T const&>{ lhs };
2422         }
2423
2424         auto operator <=( bool value ) -> ExprLhs<bool> {
2425             return ExprLhs<bool>{ value };
2426         }
2427     };
2428
2429 } // end namespace Catch
2430
2431 #ifdef _MSC_VER
2432 #pragma warning(pop)
2433 #endif
2434
2435 // end catch_decomposer.h
2436 // start catch_interfaces_capture.h
2437
2438 #include <string>
2439 #include <chrono>
2440
2441 namespace Catch {
2442
2443     class AssertionResult;
2444     struct AssertionInfo;
2445     struct SectionInfo;
2446     struct SectionEndInfo;
2447     struct MessageInfo;
2448     struct MessageBuilder;
2449     struct Counts;
2450     struct AssertionReaction;
2451     struct SourceLineInfo;
2452
2453     struct ITransientExpression;
2454     struct IGeneratorTracker;
2455
2456 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2457     struct BenchmarkInfo;
2458     template <typename Duration = std::chrono::duration<double, std::nano>>
2459     struct BenchmarkStats;
2460 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2461
2462     struct IResultCapture {
2463
2464         virtual ~IResultCapture();
2465
2466         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
2467                                         Counts& assertions ) = 0;
2468         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2469         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2470
2471         virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
2472
2473 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2474         virtual void benchmarkPreparing( std::string const& name ) = 0;
2475         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
2476         virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
2477         virtual void benchmarkFailed( std::string const& error ) = 0;
2478 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2479
2480         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2481         virtual void popScopedMessage( MessageInfo const& message ) = 0;
2482
2483         virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
2484
2485         virtual void handleFatalErrorCondition( StringRef message ) = 0;
2486
2487         virtual void handleExpr
2488                 (   AssertionInfo const& info,
2489                     ITransientExpression const& expr,
2490                     AssertionReaction& reaction ) = 0;
2491         virtual void handleMessage
2492                 (   AssertionInfo const& info,
2493                     ResultWas::OfType resultType,
2494                     StringRef const& message,
2495                     AssertionReaction& reaction ) = 0;
2496         virtual void handleUnexpectedExceptionNotThrown
2497                 (   AssertionInfo const& info,
2498                     AssertionReaction& reaction ) = 0;
2499         virtual void handleUnexpectedInflightException
2500                 (   AssertionInfo const& info,
2501                     std::string const& message,
2502                     AssertionReaction& reaction ) = 0;
2503         virtual void handleIncomplete
2504                 (   AssertionInfo const& info ) = 0;
2505         virtual void handleNonExpr
2506                 (   AssertionInfo const &info,
2507                     ResultWas::OfType resultType,
2508                     AssertionReaction &reaction ) = 0;
2509
2510         virtual bool lastAssertionPassed() = 0;
2511         virtual void assertionPassed() = 0;
2512
2513         // Deprecated, do not use:
2514         virtual std::string getCurrentTestName() const = 0;
2515         virtual const AssertionResult* getLastResult() const = 0;
2516         virtual void exceptionEarlyReported() = 0;
2517     };
2518
2519     IResultCapture& getResultCapture();
2520 }
2521
2522 // end catch_interfaces_capture.h
2523 namespace Catch {
2524
2525     struct TestFailureException{};
2526     struct AssertionResultData;
2527     struct IResultCapture;
2528     class RunContext;
2529
2530     class LazyExpression {
2531         friend class AssertionHandler;
2532         friend struct AssertionStats;
2533         friend class RunContext;
2534
2535         ITransientExpression const* m_transientExpression = nullptr;
2536         bool m_isNegated;
2537     public:
2538         LazyExpression( bool isNegated );
2539         LazyExpression( LazyExpression const& other );
2540         LazyExpression& operator = ( LazyExpression const& ) = delete;
2541
2542         explicit operator bool() const;
2543
2544         friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
2545     };
2546
2547     struct AssertionReaction {
2548         bool shouldDebugBreak = false;
2549         bool shouldThrow = false;
2550     };
2551
2552     class AssertionHandler {
2553         AssertionInfo m_assertionInfo;
2554         AssertionReaction m_reaction;
2555         bool m_completed = false;
2556         IResultCapture& m_resultCapture;
2557
2558     public:
2559         AssertionHandler
2560             (   StringRef const& macroName,
2561                 SourceLineInfo const& lineInfo,
2562                 StringRef capturedExpression,
2563                 ResultDisposition::Flags resultDisposition );
2564         ~AssertionHandler() {
2565             if ( !m_completed ) {
2566                 m_resultCapture.handleIncomplete( m_assertionInfo );
2567             }
2568         }
2569
2570         template<typename T>
2571         void handleExpr( ExprLhs<T> const& expr ) {
2572             handleExpr( expr.makeUnaryExpr() );
2573         }
2574         void handleExpr( ITransientExpression const& expr );
2575
2576         void handleMessage(ResultWas::OfType resultType, StringRef const& message);
2577
2578         void handleExceptionThrownAsExpected();
2579         void handleUnexpectedExceptionNotThrown();
2580         void handleExceptionNotThrownAsExpected();
2581         void handleThrowingCallSkipped();
2582         void handleUnexpectedInflightException();
2583
2584         void complete();
2585         void setCompleted();
2586
2587         // query
2588         auto allowThrows() const -> bool;
2589     };
2590
2591     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
2592
2593 } // namespace Catch
2594
2595 // end catch_assertionhandler.h
2596 // start catch_message.h
2597
2598 #include <string>
2599 #include <vector>
2600
2601 namespace Catch {
2602
2603     struct MessageInfo {
2604         MessageInfo(    StringRef const& _macroName,
2605                         SourceLineInfo const& _lineInfo,
2606                         ResultWas::OfType _type );
2607
2608         StringRef macroName;
2609         std::string message;
2610         SourceLineInfo lineInfo;
2611         ResultWas::OfType type;
2612         unsigned int sequence;
2613
2614         bool operator == ( MessageInfo const& other ) const;
2615         bool operator < ( MessageInfo const& other ) const;
2616     private:
2617         static unsigned int globalCount;
2618     };
2619
2620     struct MessageStream {
2621
2622         template<typename T>
2623         MessageStream& operator << ( T const& value ) {
2624             m_stream << value;
2625             return *this;
2626         }
2627
2628         ReusableStringStream m_stream;
2629     };
2630
2631     struct MessageBuilder : MessageStream {
2632         MessageBuilder( StringRef const& macroName,
2633                         SourceLineInfo const& lineInfo,
2634                         ResultWas::OfType type );
2635
2636         template<typename T>
2637         MessageBuilder& operator << ( T const& value ) {
2638             m_stream << value;
2639             return *this;
2640         }
2641
2642         MessageInfo m_info;
2643     };
2644
2645     class ScopedMessage {
2646     public:
2647         explicit ScopedMessage( MessageBuilder const& builder );
2648         ScopedMessage( ScopedMessage& duplicate ) = delete;
2649         ScopedMessage( ScopedMessage&& old );
2650         ~ScopedMessage();
2651
2652         MessageInfo m_info;
2653         bool m_moved;
2654     };
2655
2656     class Capturer {
2657         std::vector<MessageInfo> m_messages;
2658         IResultCapture& m_resultCapture = getResultCapture();
2659         size_t m_captured = 0;
2660     public:
2661         Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
2662         ~Capturer();
2663
2664         void captureValue( size_t index, std::string const& value );
2665
2666         template<typename T>
2667         void captureValues( size_t index, T const& value ) {
2668             captureValue( index, Catch::Detail::stringify( value ) );
2669         }
2670
2671         template<typename T, typename... Ts>
2672         void captureValues( size_t index, T const& value, Ts const&... values ) {
2673             captureValue( index, Catch::Detail::stringify(value) );
2674             captureValues( index+1, values... );
2675         }
2676     };
2677
2678 } // end namespace Catch
2679
2680 // end catch_message.h
2681 #if !defined(CATCH_CONFIG_DISABLE)
2682
2683 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2684   #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2685 #else
2686   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2687 #endif
2688
2689 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2690
2691 ///////////////////////////////////////////////////////////////////////////////
2692 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2693 // macros.
2694 #define INTERNAL_CATCH_TRY
2695 #define INTERNAL_CATCH_CATCH( capturer )
2696
2697 #else // CATCH_CONFIG_FAST_COMPILE
2698
2699 #define INTERNAL_CATCH_TRY try
2700 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
2701
2702 #endif
2703
2704 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
2705
2706 ///////////////////////////////////////////////////////////////////////////////
2707 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2708     do { \
2709         CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
2710         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2711         INTERNAL_CATCH_TRY { \
2712             CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2713             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2714             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
2715             CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
2716         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2717         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2718     } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
2719
2720 ///////////////////////////////////////////////////////////////////////////////
2721 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
2722     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2723     if( Catch::getResultCapture().lastAssertionPassed() )
2724
2725 ///////////////////////////////////////////////////////////////////////////////
2726 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
2727     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2728     if( !Catch::getResultCapture().lastAssertionPassed() )
2729
2730 ///////////////////////////////////////////////////////////////////////////////
2731 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2732     do { \
2733         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2734         try { \
2735             static_cast<void>(__VA_ARGS__); \
2736             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
2737         } \
2738         catch( ... ) { \
2739             catchAssertionHandler.handleUnexpectedInflightException(); \
2740         } \
2741         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2742     } while( false )
2743
2744 ///////////////////////////////////////////////////////////////////////////////
2745 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2746     do { \
2747         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
2748         if( catchAssertionHandler.allowThrows() ) \
2749             try { \
2750                 static_cast<void>(__VA_ARGS__); \
2751                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2752             } \
2753             catch( ... ) { \
2754                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
2755             } \
2756         else \
2757             catchAssertionHandler.handleThrowingCallSkipped(); \
2758         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2759     } while( false )
2760
2761 ///////////////////////////////////////////////////////////////////////////////
2762 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2763     do { \
2764         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2765         if( catchAssertionHandler.allowThrows() ) \
2766             try { \
2767                 static_cast<void>(expr); \
2768                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2769             } \
2770             catch( exceptionType const& ) { \
2771                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
2772             } \
2773             catch( ... ) { \
2774                 catchAssertionHandler.handleUnexpectedInflightException(); \
2775             } \
2776         else \
2777             catchAssertionHandler.handleThrowingCallSkipped(); \
2778         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2779     } while( false )
2780
2781 ///////////////////////////////////////////////////////////////////////////////
2782 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2783     do { \
2784         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
2785         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
2786         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2787     } while( false )
2788
2789 ///////////////////////////////////////////////////////////////////////////////
2790 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
2791     auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
2792     varName.captureValues( 0, __VA_ARGS__ )
2793
2794 ///////////////////////////////////////////////////////////////////////////////
2795 #define INTERNAL_CATCH_INFO( macroName, log ) \
2796     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
2797
2798 ///////////////////////////////////////////////////////////////////////////////
2799 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
2800     Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
2801
2802 ///////////////////////////////////////////////////////////////////////////////
2803 // Although this is matcher-based, it can be used with just a string
2804 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
2805     do { \
2806         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2807         if( catchAssertionHandler.allowThrows() ) \
2808             try { \
2809                 static_cast<void>(__VA_ARGS__); \
2810                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2811             } \
2812             catch( ... ) { \
2813                 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
2814             } \
2815         else \
2816             catchAssertionHandler.handleThrowingCallSkipped(); \
2817         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2818     } while( false )
2819
2820 #endif // CATCH_CONFIG_DISABLE
2821
2822 // end catch_capture.hpp
2823 // start catch_section.h
2824
2825 // start catch_section_info.h
2826
2827 // start catch_totals.h
2828
2829 #include <cstddef>
2830
2831 namespace Catch {
2832
2833     struct Counts {
2834         Counts operator - ( Counts const& other ) const;
2835         Counts& operator += ( Counts const& other );
2836
2837         std::size_t total() const;
2838         bool allPassed() const;
2839         bool allOk() const;
2840
2841         std::size_t passed = 0;
2842         std::size_t failed = 0;
2843         std::size_t failedButOk = 0;
2844     };
2845
2846     struct Totals {
2847
2848         Totals operator - ( Totals const& other ) const;
2849         Totals& operator += ( Totals const& other );
2850
2851         Totals delta( Totals const& prevTotals ) const;
2852
2853         int error = 0;
2854         Counts assertions;
2855         Counts testCases;
2856     };
2857 }
2858
2859 // end catch_totals.h
2860 #include <string>
2861
2862 namespace Catch {
2863
2864     struct SectionInfo {
2865         SectionInfo
2866             (   SourceLineInfo const& _lineInfo,
2867                 std::string const& _name );
2868
2869         // Deprecated
2870         SectionInfo
2871             (   SourceLineInfo const& _lineInfo,
2872                 std::string const& _name,
2873                 std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2874
2875         std::string name;
2876         std::string description; // !Deprecated: this will always be empty
2877         SourceLineInfo lineInfo;
2878     };
2879
2880     struct SectionEndInfo {
2881         SectionInfo sectionInfo;
2882         Counts prevAssertions;
2883         double durationInSeconds;
2884     };
2885
2886 } // end namespace Catch
2887
2888 // end catch_section_info.h
2889 // start catch_timer.h
2890
2891 #include <cstdint>
2892
2893 namespace Catch {
2894
2895     auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
2896     auto getEstimatedClockResolution() -> uint64_t;
2897
2898     class Timer {
2899         uint64_t m_nanoseconds = 0;
2900     public:
2901         void start();
2902         auto getElapsedNanoseconds() const -> uint64_t;
2903         auto getElapsedMicroseconds() const -> uint64_t;
2904         auto getElapsedMilliseconds() const -> unsigned int;
2905         auto getElapsedSeconds() const -> double;
2906     };
2907
2908 } // namespace Catch
2909
2910 // end catch_timer.h
2911 #include <string>
2912
2913 namespace Catch {
2914
2915     class Section : NonCopyable {
2916     public:
2917         Section( SectionInfo const& info );
2918         ~Section();
2919
2920         // This indicates whether the section should be executed or not
2921         explicit operator bool() const;
2922
2923     private:
2924         SectionInfo m_info;
2925
2926         std::string m_name;
2927         Counts m_assertions;
2928         bool m_sectionIncluded;
2929         Timer m_timer;
2930     };
2931
2932 } // end namespace Catch
2933
2934 #define INTERNAL_CATCH_SECTION( ... ) \
2935     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2936     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2937     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2938     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2939
2940 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2941     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2942     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2943     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2944     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2945
2946 // end catch_section.h
2947 // start catch_interfaces_exception.h
2948
2949 // start catch_interfaces_registry_hub.h
2950
2951 #include <string>
2952 #include <memory>
2953
2954 namespace Catch {
2955
2956     class TestCase;
2957     struct ITestCaseRegistry;
2958     struct IExceptionTranslatorRegistry;
2959     struct IExceptionTranslator;
2960     struct IReporterRegistry;
2961     struct IReporterFactory;
2962     struct ITagAliasRegistry;
2963     struct IMutableEnumValuesRegistry;
2964
2965     class StartupExceptionRegistry;
2966
2967     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2968
2969     struct IRegistryHub {
2970         virtual ~IRegistryHub();
2971
2972         virtual IReporterRegistry const& getReporterRegistry() const = 0;
2973         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2974         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2975         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2976
2977         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2978     };
2979
2980     struct IMutableRegistryHub {
2981         virtual ~IMutableRegistryHub();
2982         virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2983         virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2984         virtual void registerTest( TestCase const& testInfo ) = 0;
2985         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2986         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2987         virtual void registerStartupException() noexcept = 0;
2988         virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
2989     };
2990
2991     IRegistryHub const& getRegistryHub();
2992     IMutableRegistryHub& getMutableRegistryHub();
2993     void cleanUp();
2994     std::string translateActiveException();
2995
2996 }
2997
2998 // end catch_interfaces_registry_hub.h
2999 #if defined(CATCH_CONFIG_DISABLE)
3000     #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
3001         static std::string translatorName( signature )
3002 #endif
3003
3004 #include <exception>
3005 #include <string>
3006 #include <vector>
3007
3008 namespace Catch {
3009     using exceptionTranslateFunction = std::string(*)();
3010
3011     struct IExceptionTranslator;
3012     using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
3013
3014     struct IExceptionTranslator {
3015         virtual ~IExceptionTranslator();
3016         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
3017     };
3018
3019     struct IExceptionTranslatorRegistry {
3020         virtual ~IExceptionTranslatorRegistry();
3021
3022         virtual std::string translateActiveException() const = 0;
3023     };
3024
3025     class ExceptionTranslatorRegistrar {
3026         template<typename T>
3027         class ExceptionTranslator : public IExceptionTranslator {
3028         public:
3029
3030             ExceptionTranslator( std::string(*translateFunction)( T& ) )
3031             : m_translateFunction( translateFunction )
3032             {}
3033
3034             std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
3035 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3036                 return "";
3037 #else
3038                 try {
3039                     if( it == itEnd )
3040                         std::rethrow_exception(std::current_exception());
3041                     else
3042                         return (*it)->translate( it+1, itEnd );
3043                 }
3044                 catch( T& ex ) {
3045                     return m_translateFunction( ex );
3046                 }
3047 #endif
3048             }
3049
3050         protected:
3051             std::string(*m_translateFunction)( T& );
3052         };
3053
3054     public:
3055         template<typename T>
3056         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
3057             getMutableRegistryHub().registerTranslator
3058                 ( new ExceptionTranslator<T>( translateFunction ) );
3059         }
3060     };
3061 }
3062
3063 ///////////////////////////////////////////////////////////////////////////////
3064 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
3065     static std::string translatorName( signature ); \
3066     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3067     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
3068     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
3069     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
3070     static std::string translatorName( signature )
3071
3072 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
3073
3074 // end catch_interfaces_exception.h
3075 // start catch_approx.h
3076
3077 #include <type_traits>
3078
3079 namespace Catch {
3080 namespace Detail {
3081
3082     class Approx {
3083     private:
3084         bool equalityComparisonImpl(double other) const;
3085         // Validates the new margin (margin >= 0)
3086         // out-of-line to avoid including stdexcept in the header
3087         void setMargin(double margin);
3088         // Validates the new epsilon (0 < epsilon < 1)
3089         // out-of-line to avoid including stdexcept in the header
3090         void setEpsilon(double epsilon);
3091
3092     public:
3093         explicit Approx ( double value );
3094
3095         static Approx custom();
3096
3097         Approx operator-() const;
3098
3099         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3100         Approx operator()( T const& value ) {
3101             Approx approx( static_cast<double>(value) );
3102             approx.m_epsilon = m_epsilon;
3103             approx.m_margin = m_margin;
3104             approx.m_scale = m_scale;
3105             return approx;
3106         }
3107
3108         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3109         explicit Approx( T const& value ): Approx(static_cast<double>(value))
3110         {}
3111
3112         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3113         friend bool operator == ( const T& lhs, Approx const& rhs ) {
3114             auto lhs_v = static_cast<double>(lhs);
3115             return rhs.equalityComparisonImpl(lhs_v);
3116         }
3117
3118         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3119         friend bool operator == ( Approx const& lhs, const T& rhs ) {
3120             return operator==( rhs, lhs );
3121         }
3122
3123         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3124         friend bool operator != ( T const& lhs, Approx const& rhs ) {
3125             return !operator==( lhs, rhs );
3126         }
3127
3128         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3129         friend bool operator != ( Approx const& lhs, T const& rhs ) {
3130             return !operator==( rhs, lhs );
3131         }
3132
3133         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3134         friend bool operator <= ( T const& lhs, Approx const& rhs ) {
3135             return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3136         }
3137
3138         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3139         friend bool operator <= ( Approx const& lhs, T const& rhs ) {
3140             return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3141         }
3142
3143         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3144         friend bool operator >= ( T const& lhs, Approx const& rhs ) {
3145             return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3146         }
3147
3148         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3149         friend bool operator >= ( Approx const& lhs, T const& rhs ) {
3150             return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3151         }
3152
3153         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3154         Approx& epsilon( T const& newEpsilon ) {
3155             double epsilonAsDouble = static_cast<double>(newEpsilon);
3156             setEpsilon(epsilonAsDouble);
3157             return *this;
3158         }
3159
3160         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3161         Approx& margin( T const& newMargin ) {
3162             double marginAsDouble = static_cast<double>(newMargin);
3163             setMargin(marginAsDouble);
3164             return *this;
3165         }
3166
3167         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3168         Approx& scale( T const& newScale ) {
3169             m_scale = static_cast<double>(newScale);
3170             return *this;
3171         }
3172
3173         std::string toString() const;
3174
3175     private:
3176         double m_epsilon;
3177         double m_margin;
3178         double m_scale;
3179         double m_value;
3180     };
3181 } // end namespace Detail
3182
3183 namespace literals {
3184     Detail::Approx operator "" _a(long double val);
3185     Detail::Approx operator "" _a(unsigned long long val);
3186 } // end namespace literals
3187
3188 template<>
3189 struct StringMaker<Catch::Detail::Approx> {
3190     static std::string convert(Catch::Detail::Approx const& value);
3191 };
3192
3193 } // end namespace Catch
3194
3195 // end catch_approx.h
3196 // start catch_string_manip.h
3197
3198 #include <string>
3199 #include <iosfwd>
3200 #include <vector>
3201
3202 namespace Catch {
3203
3204     bool startsWith( std::string const& s, std::string const& prefix );
3205     bool startsWith( std::string const& s, char prefix );
3206     bool endsWith( std::string const& s, std::string const& suffix );
3207     bool endsWith( std::string const& s, char suffix );
3208     bool contains( std::string const& s, std::string const& infix );
3209     void toLowerInPlace( std::string& s );
3210     std::string toLower( std::string const& s );
3211     //! Returns a new string without whitespace at the start/end
3212     std::string trim( std::string const& str );
3213     //! Returns a substring of the original ref without whitespace. Beware lifetimes!
3214     StringRef trim(StringRef ref);
3215
3216     // !!! Be aware, returns refs into original string - make sure original string outlives them
3217     std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
3218     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
3219
3220     struct pluralise {
3221         pluralise( std::size_t count, std::string const& label );
3222
3223         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
3224
3225         std::size_t m_count;
3226         std::string m_label;
3227     };
3228 }
3229
3230 // end catch_string_manip.h
3231 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
3232 // start catch_capture_matchers.h
3233
3234 // start catch_matchers.h
3235
3236 #include <string>
3237 #include <vector>
3238
3239 namespace Catch {
3240 namespace Matchers {
3241     namespace Impl {
3242
3243         template<typename ArgT> struct MatchAllOf;
3244         template<typename ArgT> struct MatchAnyOf;
3245         template<typename ArgT> struct MatchNotOf;
3246
3247         class MatcherUntypedBase {
3248         public:
3249             MatcherUntypedBase() = default;
3250             MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
3251             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
3252             std::string toString() const;
3253
3254         protected:
3255             virtual ~MatcherUntypedBase();
3256             virtual std::string describe() const = 0;
3257             mutable std::string m_cachedToString;
3258         };
3259
3260 #ifdef __clang__
3261 #    pragma clang diagnostic push
3262 #    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
3263 #endif
3264
3265         template<typename ObjectT>
3266         struct MatcherMethod {
3267             virtual bool match( ObjectT const& arg ) const = 0;
3268         };
3269
3270 #if defined(__OBJC__)
3271         // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
3272         // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
3273         template<>
3274         struct MatcherMethod<NSString*> {
3275             virtual bool match( NSString* arg ) const = 0;
3276         };
3277 #endif
3278
3279 #ifdef __clang__
3280 #    pragma clang diagnostic pop
3281 #endif
3282
3283         template<typename T>
3284         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
3285
3286             MatchAllOf<T> operator && ( MatcherBase const& other ) const;
3287             MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
3288             MatchNotOf<T> operator ! () const;
3289         };
3290
3291         template<typename ArgT>
3292         struct MatchAllOf : MatcherBase<ArgT> {
3293             bool match( ArgT const& arg ) const override {
3294                 for( auto matcher : m_matchers ) {
3295                     if (!matcher->match(arg))
3296                         return false;
3297                 }
3298                 return true;
3299             }
3300             std::string describe() const override {
3301                 std::string description;
3302                 description.reserve( 4 + m_matchers.size()*32 );
3303                 description += "( ";
3304                 bool first = true;
3305                 for( auto matcher : m_matchers ) {
3306                     if( first )
3307                         first = false;
3308                     else
3309                         description += " and ";
3310                     description += matcher->toString();
3311                 }
3312                 description += " )";
3313                 return description;
3314             }
3315
3316             MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
3317                 auto copy(*this);
3318                 copy.m_matchers.push_back( &other );
3319                 return copy;
3320             }
3321
3322             std::vector<MatcherBase<ArgT> const*> m_matchers;
3323         };
3324         template<typename ArgT>
3325         struct MatchAnyOf : MatcherBase<ArgT> {
3326
3327             bool match( ArgT const& arg ) const override {
3328                 for( auto matcher : m_matchers ) {
3329                     if (matcher->match(arg))
3330                         return true;
3331                 }
3332                 return false;
3333             }
3334             std::string describe() const override {
3335                 std::string description;
3336                 description.reserve( 4 + m_matchers.size()*32 );
3337                 description += "( ";
3338                 bool first = true;
3339                 for( auto matcher : m_matchers ) {
3340                     if( first )
3341                         first = false;
3342                     else
3343                         description += " or ";
3344                     description += matcher->toString();
3345                 }
3346                 description += " )";
3347                 return description;
3348             }
3349
3350             MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
3351                 auto copy(*this);
3352                 copy.m_matchers.push_back( &other );
3353                 return copy;
3354             }
3355
3356             std::vector<MatcherBase<ArgT> const*> m_matchers;
3357         };
3358
3359         template<typename ArgT>
3360         struct MatchNotOf : MatcherBase<ArgT> {
3361
3362             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
3363
3364             bool match( ArgT const& arg ) const override {
3365                 return !m_underlyingMatcher.match( arg );
3366             }
3367
3368             std::string describe() const override {
3369                 return "not " + m_underlyingMatcher.toString();
3370             }
3371             MatcherBase<ArgT> const& m_underlyingMatcher;
3372         };
3373
3374         template<typename T>
3375         MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
3376             return MatchAllOf<T>() && *this && other;
3377         }
3378         template<typename T>
3379         MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
3380             return MatchAnyOf<T>() || *this || other;
3381         }
3382         template<typename T>
3383         MatchNotOf<T> MatcherBase<T>::operator ! () const {
3384             return MatchNotOf<T>( *this );
3385         }
3386
3387     } // namespace Impl
3388
3389 } // namespace Matchers
3390
3391 using namespace Matchers;
3392 using Matchers::Impl::MatcherBase;
3393
3394 } // namespace Catch
3395
3396 // end catch_matchers.h
3397 // start catch_matchers_exception.hpp
3398
3399 namespace Catch {
3400 namespace Matchers {
3401 namespace Exception {
3402
3403 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
3404     std::string m_message;
3405 public:
3406
3407     ExceptionMessageMatcher(std::string const& message):
3408         m_message(message)
3409     {}
3410
3411     bool match(std::exception const& ex) const override;
3412
3413     std::string describe() const override;
3414 };
3415
3416 } // namespace Exception
3417
3418 Exception::ExceptionMessageMatcher Message(std::string const& message);
3419
3420 } // namespace Matchers
3421 } // namespace Catch
3422
3423 // end catch_matchers_exception.hpp
3424 // start catch_matchers_floating.h
3425
3426 namespace Catch {
3427 namespace Matchers {
3428
3429     namespace Floating {
3430
3431         enum class FloatingPointKind : uint8_t;
3432
3433         struct WithinAbsMatcher : MatcherBase<double> {
3434             WithinAbsMatcher(double target, double margin);
3435             bool match(double const& matchee) const override;
3436             std::string describe() const override;
3437         private:
3438             double m_target;
3439             double m_margin;
3440         };
3441
3442         struct WithinUlpsMatcher : MatcherBase<double> {
3443             WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
3444             bool match(double const& matchee) const override;
3445             std::string describe() const override;
3446         private:
3447             double m_target;
3448             uint64_t m_ulps;
3449             FloatingPointKind m_type;
3450         };
3451
3452         // Given IEEE-754 format for floats and doubles, we can assume
3453         // that float -> double promotion is lossless. Given this, we can
3454         // assume that if we do the standard relative comparison of
3455         // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
3456         // the same result if we do this for floats, as if we do this for
3457         // doubles that were promoted from floats.
3458         struct WithinRelMatcher : MatcherBase<double> {
3459             WithinRelMatcher(double target, double epsilon);
3460             bool match(double const& matchee) const override;
3461             std::string describe() const override;
3462         private:
3463             double m_target;
3464             double m_epsilon;
3465         };
3466
3467     } // namespace Floating
3468
3469     // The following functions create the actual matcher objects.
3470     // This allows the types to be inferred
3471     Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
3472     Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
3473     Floating::WithinAbsMatcher WithinAbs(double target, double margin);
3474     Floating::WithinRelMatcher WithinRel(double target, double eps);
3475     // defaults epsilon to 100*numeric_limits<double>::epsilon()
3476     Floating::WithinRelMatcher WithinRel(double target);
3477     Floating::WithinRelMatcher WithinRel(float target, float eps);
3478     // defaults epsilon to 100*numeric_limits<float>::epsilon()
3479     Floating::WithinRelMatcher WithinRel(float target);
3480
3481 } // namespace Matchers
3482 } // namespace Catch
3483
3484 // end catch_matchers_floating.h
3485 // start catch_matchers_generic.hpp
3486
3487 #include <functional>
3488 #include <string>
3489
3490 namespace Catch {
3491 namespace Matchers {
3492 namespace Generic {
3493
3494 namespace Detail {
3495     std::string finalizeDescription(const std::string& desc);
3496 }
3497
3498 template <typename T>
3499 class PredicateMatcher : public MatcherBase<T> {
3500     std::function<bool(T const&)> m_predicate;
3501     std::string m_description;
3502 public:
3503
3504     PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
3505         :m_predicate(std::move(elem)),
3506         m_description(Detail::finalizeDescription(descr))
3507     {}
3508
3509     bool match( T const& item ) const override {
3510         return m_predicate(item);
3511     }
3512
3513     std::string describe() const override {
3514         return m_description;
3515     }
3516 };
3517
3518 } // namespace Generic
3519
3520     // The following functions create the actual matcher objects.
3521     // The user has to explicitly specify type to the function, because
3522     // inferring std::function<bool(T const&)> is hard (but possible) and
3523     // requires a lot of TMP.
3524     template<typename T>
3525     Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
3526         return Generic::PredicateMatcher<T>(predicate, description);
3527     }
3528
3529 } // namespace Matchers
3530 } // namespace Catch
3531
3532 // end catch_matchers_generic.hpp
3533 // start catch_matchers_string.h
3534
3535 #include <string>
3536
3537 namespace Catch {
3538 namespace Matchers {
3539
3540     namespace StdString {
3541
3542         struct CasedString
3543         {
3544             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
3545             std::string adjustString( std::string const& str ) const;
3546             std::string caseSensitivitySuffix() const;
3547
3548             CaseSensitive::Choice m_caseSensitivity;
3549             std::string m_str;
3550         };
3551
3552         struct StringMatcherBase : MatcherBase<std::string> {
3553             StringMatcherBase( std::string const& operation, CasedString const& comparator );
3554             std::string describe() const override;
3555
3556             CasedString m_comparator;
3557             std::string m_operation;
3558         };
3559
3560         struct EqualsMatcher : StringMatcherBase {
3561             EqualsMatcher( CasedString const& comparator );
3562             bool match( std::string const& source ) const override;
3563         };
3564         struct ContainsMatcher : StringMatcherBase {
3565             ContainsMatcher( CasedString const& comparator );
3566             bool match( std::string const& source ) const override;
3567         };
3568         struct StartsWithMatcher : StringMatcherBase {
3569             StartsWithMatcher( CasedString const& comparator );
3570             bool match( std::string const& source ) const override;
3571         };
3572         struct EndsWithMatcher : StringMatcherBase {
3573             EndsWithMatcher( CasedString const& comparator );
3574             bool match( std::string const& source ) const override;
3575         };
3576
3577         struct RegexMatcher : MatcherBase<std::string> {
3578             RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
3579             bool match( std::string const& matchee ) const override;
3580             std::string describe() const override;
3581
3582         private:
3583             std::string m_regex;
3584             CaseSensitive::Choice m_caseSensitivity;
3585         };
3586
3587     } // namespace StdString
3588
3589     // The following functions create the actual matcher objects.
3590     // This allows the types to be inferred
3591
3592     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3593     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3594     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3595     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3596     StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3597
3598 } // namespace Matchers
3599 } // namespace Catch
3600
3601 // end catch_matchers_string.h
3602 // start catch_matchers_vector.h
3603
3604 #include <algorithm>
3605
3606 namespace Catch {
3607 namespace Matchers {
3608
3609     namespace Vector {
3610         template<typename T, typename Alloc>
3611         struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
3612
3613             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3614
3615             bool match(std::vector<T, Alloc> const &v) const override {
3616                 for (auto const& el : v) {
3617                     if (el == m_comparator) {
3618                         return true;
3619                     }
3620                 }
3621                 return false;
3622             }
3623
3624             std::string describe() const override {
3625                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3626             }
3627
3628             T const& m_comparator;
3629         };
3630
3631         template<typename T, typename AllocComp, typename AllocMatch>
3632         struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3633
3634             ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
3635
3636             bool match(std::vector<T, AllocMatch> const &v) const override {
3637                 // !TBD: see note in EqualsMatcher
3638                 if (m_comparator.size() > v.size())
3639                     return false;
3640                 for (auto const& comparator : m_comparator) {
3641                     auto present = false;
3642                     for (const auto& el : v) {
3643                         if (el == comparator) {
3644                             present = true;
3645                             break;
3646                         }
3647                     }
3648                     if (!present) {
3649                         return false;
3650                     }
3651                 }
3652                 return true;
3653             }
3654             std::string describe() const override {
3655                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3656             }
3657
3658             std::vector<T, AllocComp> const& m_comparator;
3659         };
3660
3661         template<typename T, typename AllocComp, typename AllocMatch>
3662         struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3663
3664             EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
3665
3666             bool match(std::vector<T, AllocMatch> const &v) const override {
3667                 // !TBD: This currently works if all elements can be compared using !=
3668                 // - a more general approach would be via a compare template that defaults
3669                 // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
3670                 // - then just call that directly
3671                 if (m_comparator.size() != v.size())
3672                     return false;
3673                 for (std::size_t i = 0; i < v.size(); ++i)
3674                     if (m_comparator[i] != v[i])
3675                         return false;
3676                 return true;
3677             }
3678             std::string describe() const override {
3679                 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
3680             }
3681             std::vector<T, AllocComp> const& m_comparator;
3682         };
3683
3684         template<typename T, typename AllocComp, typename AllocMatch>
3685         struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3686
3687             ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
3688
3689             bool match(std::vector<T, AllocMatch> const &v) const override {
3690                 if (m_comparator.size() != v.size())
3691                     return false;
3692                 for (std::size_t i = 0; i < v.size(); ++i)
3693                     if (m_comparator[i] != approx(v[i]))
3694                         return false;
3695                 return true;
3696             }
3697             std::string describe() const override {
3698                 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
3699             }
3700             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3701             ApproxMatcher& epsilon( T const& newEpsilon ) {
3702                 approx.epsilon(newEpsilon);
3703                 return *this;
3704             }
3705             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3706             ApproxMatcher& margin( T const& newMargin ) {
3707                 approx.margin(newMargin);
3708                 return *this;
3709             }
3710             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3711             ApproxMatcher& scale( T const& newScale ) {
3712                 approx.scale(newScale);
3713                 return *this;
3714             }
3715
3716             std::vector<T, AllocComp> const& m_comparator;
3717             mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
3718         };
3719
3720         template<typename T, typename AllocComp, typename AllocMatch>
3721         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3722             UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
3723             bool match(std::vector<T, AllocMatch> const& vec) const override {
3724                 if (m_target.size() != vec.size()) {
3725                     return false;
3726                 }
3727                 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
3728             }
3729
3730             std::string describe() const override {
3731                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
3732             }
3733         private:
3734             std::vector<T, AllocComp> const& m_target;
3735         };
3736
3737     } // namespace Vector
3738
3739     // The following functions create the actual matcher objects.
3740     // This allows the types to be inferred
3741
3742     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3743     Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
3744         return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );
3745     }
3746
3747     template<typename T, typename Alloc = std::allocator<T>>
3748     Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
3749         return Vector::ContainsElementMatcher<T, Alloc>( comparator );
3750     }
3751
3752     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3753     Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
3754         return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );
3755     }
3756
3757     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3758     Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
3759         return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );
3760     }
3761
3762     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3763     Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
3764         return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );
3765     }
3766
3767 } // namespace Matchers
3768 } // namespace Catch
3769
3770 // end catch_matchers_vector.h
3771 namespace Catch {
3772
3773     template<typename ArgT, typename MatcherT>
3774     class MatchExpr : public ITransientExpression {
3775         ArgT const& m_arg;
3776         MatcherT m_matcher;
3777         StringRef m_matcherString;
3778     public:
3779         MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
3780         :   ITransientExpression{ true, matcher.match( arg ) },
3781             m_arg( arg ),
3782             m_matcher( matcher ),
3783             m_matcherString( matcherString )
3784         {}
3785
3786         void streamReconstructedExpression( std::ostream &os ) const override {
3787             auto matcherAsString = m_matcher.toString();
3788             os << Catch::Detail::stringify( m_arg ) << ' ';
3789             if( matcherAsString == Detail::unprintableString )
3790                 os << m_matcherString;
3791             else
3792                 os << matcherAsString;
3793         }
3794     };
3795
3796     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
3797
3798     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
3799
3800     template<typename ArgT, typename MatcherT>
3801     auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
3802         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
3803     }
3804
3805 } // namespace Catch
3806
3807 ///////////////////////////////////////////////////////////////////////////////
3808 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
3809     do { \
3810         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3811         INTERNAL_CATCH_TRY { \
3812             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
3813         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
3814         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3815     } while( false )
3816
3817 ///////////////////////////////////////////////////////////////////////////////
3818 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
3819     do { \
3820         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3821         if( catchAssertionHandler.allowThrows() ) \
3822             try { \
3823                 static_cast<void>(__VA_ARGS__ ); \
3824                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3825             } \
3826             catch( exceptionType const& ex ) { \
3827                 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
3828             } \
3829             catch( ... ) { \
3830                 catchAssertionHandler.handleUnexpectedInflightException(); \
3831             } \
3832         else \
3833             catchAssertionHandler.handleThrowingCallSkipped(); \
3834         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3835     } while( false )
3836
3837 // end catch_capture_matchers.h
3838 #endif
3839 // start catch_generators.hpp
3840
3841 // start catch_interfaces_generatortracker.h
3842
3843
3844 #include <memory>
3845
3846 namespace Catch {
3847
3848     namespace Generators {
3849         class GeneratorUntypedBase {
3850         public:
3851             GeneratorUntypedBase() = default;
3852             virtual ~GeneratorUntypedBase();
3853             // Attempts to move the generator to the next element
3854              //
3855              // Returns true iff the move succeeded (and a valid element
3856              // can be retrieved).
3857             virtual bool next() = 0;
3858         };
3859         using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
3860
3861     } // namespace Generators
3862
3863     struct IGeneratorTracker {
3864         virtual ~IGeneratorTracker();
3865         virtual auto hasGenerator() const -> bool = 0;
3866         virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3867         virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3868     };
3869
3870 } // namespace Catch
3871
3872 // end catch_interfaces_generatortracker.h
3873 // start catch_enforce.h
3874
3875 #include <exception>
3876
3877 namespace Catch {
3878 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3879     template <typename Ex>
3880     [[noreturn]]
3881     void throw_exception(Ex const& e) {
3882         throw e;
3883     }
3884 #else // ^^ Exceptions are enabled //  Exceptions are disabled vv
3885     [[noreturn]]
3886     void throw_exception(std::exception const& e);
3887 #endif
3888
3889     [[noreturn]]
3890     void throw_logic_error(std::string const& msg);
3891     [[noreturn]]
3892     void throw_domain_error(std::string const& msg);
3893     [[noreturn]]
3894     void throw_runtime_error(std::string const& msg);
3895
3896 } // namespace Catch;
3897
3898 #define CATCH_MAKE_MSG(...) \
3899     (Catch::ReusableStringStream() << __VA_ARGS__).str()
3900
3901 #define CATCH_INTERNAL_ERROR(...) \
3902     Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
3903
3904 #define CATCH_ERROR(...) \
3905     Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3906
3907 #define CATCH_RUNTIME_ERROR(...) \
3908     Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3909
3910 #define CATCH_ENFORCE( condition, ... ) \
3911     do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
3912
3913 // end catch_enforce.h
3914 #include <memory>
3915 #include <vector>
3916 #include <cassert>
3917
3918 #include <utility>
3919 #include <exception>
3920
3921 namespace Catch {
3922
3923 class GeneratorException : public std::exception {
3924     const char* const m_msg = "";
3925
3926 public:
3927     GeneratorException(const char* msg):
3928         m_msg(msg)
3929     {}
3930
3931     const char* what() const noexcept override final;
3932 };
3933
3934 namespace Generators {
3935
3936     // !TBD move this into its own location?
3937     namespace pf{
3938         template<typename T, typename... Args>
3939         std::unique_ptr<T> make_unique( Args&&... args ) {
3940             return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3941         }
3942     }
3943
3944     template<typename T>
3945     struct IGenerator : GeneratorUntypedBase {
3946         virtual ~IGenerator() = default;
3947
3948         // Returns the current element of the generator
3949         //
3950         // \Precondition The generator is either freshly constructed,
3951         // or the last call to `next()` returned true
3952         virtual T const& get() const = 0;
3953         using type = T;
3954     };
3955
3956     template<typename T>
3957     class SingleValueGenerator final : public IGenerator<T> {
3958         T m_value;
3959     public:
3960         SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
3961
3962         T const& get() const override {
3963             return m_value;
3964         }
3965         bool next() override {
3966             return false;
3967         }
3968     };
3969
3970     template<typename T>
3971     class FixedValuesGenerator final : public IGenerator<T> {
3972         static_assert(!std::is_same<T, bool>::value,
3973             "FixedValuesGenerator does not support bools because of std::vector<bool>"
3974             "specialization, use SingleValue Generator instead.");
3975         std::vector<T> m_values;
3976         size_t m_idx = 0;
3977     public:
3978         FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3979
3980         T const& get() const override {
3981             return m_values[m_idx];
3982         }
3983         bool next() override {
3984             ++m_idx;
3985             return m_idx < m_values.size();
3986         }
3987     };
3988
3989     template <typename T>
3990     class GeneratorWrapper final {
3991         std::unique_ptr<IGenerator<T>> m_generator;
3992     public:
3993         GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
3994             m_generator(std::move(generator))
3995         {}
3996         T const& get() const {
3997             return m_generator->get();
3998         }
3999         bool next() {
4000             return m_generator->next();
4001         }
4002     };
4003
4004     template <typename T>
4005     GeneratorWrapper<T> value(T&& value) {
4006         return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
4007     }
4008     template <typename T>
4009     GeneratorWrapper<T> values(std::initializer_list<T> values) {
4010         return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
4011     }
4012
4013     template<typename T>
4014     class Generators : public IGenerator<T> {
4015         std::vector<GeneratorWrapper<T>> m_generators;
4016         size_t m_current = 0;
4017
4018         void populate(GeneratorWrapper<T>&& generator) {
4019             m_generators.emplace_back(std::move(generator));
4020         }
4021         void populate(T&& val) {
4022             m_generators.emplace_back(value(std::forward<T>(val)));
4023         }
4024         template<typename U>
4025         void populate(U&& val) {
4026             populate(T(std::forward<U>(val)));
4027         }
4028         template<typename U, typename... Gs>
4029         void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
4030             populate(std::forward<U>(valueOrGenerator));
4031             populate(std::forward<Gs>(moreGenerators)...);
4032         }
4033
4034     public:
4035         template <typename... Gs>
4036         Generators(Gs &&... moreGenerators) {
4037             m_generators.reserve(sizeof...(Gs));
4038             populate(std::forward<Gs>(moreGenerators)...);
4039         }
4040
4041         T const& get() const override {
4042             return m_generators[m_current].get();
4043         }
4044
4045         bool next() override {
4046             if (m_current >= m_generators.size()) {
4047                 return false;
4048             }
4049             const bool current_status = m_generators[m_current].next();
4050             if (!current_status) {
4051                 ++m_current;
4052             }
4053             return m_current < m_generators.size();
4054         }
4055     };
4056
4057     template<typename... Ts>
4058     GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
4059         return values<std::tuple<Ts...>>( tuples );
4060     }
4061
4062     // Tag type to signal that a generator sequence should convert arguments to a specific type
4063     template <typename T>
4064     struct as {};
4065
4066     template<typename T, typename... Gs>
4067     auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
4068         return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
4069     }
4070     template<typename T>
4071     auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
4072         return Generators<T>(std::move(generator));
4073     }
4074     template<typename T, typename... Gs>
4075     auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
4076         return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
4077     }
4078     template<typename T, typename U, typename... Gs>
4079     auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
4080         return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
4081     }
4082
4083     auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
4084
4085     template<typename L>
4086     // Note: The type after -> is weird, because VS2015 cannot parse
4087     //       the expression used in the typedef inside, when it is in
4088     //       return type. Yeah.
4089     auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
4090         using UnderlyingType = typename decltype(generatorExpression())::type;
4091
4092         IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
4093         if (!tracker.hasGenerator()) {
4094             tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
4095         }
4096
4097         auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
4098         return generator.get();
4099     }
4100
4101 } // namespace Generators
4102 } // namespace Catch
4103
4104 #define GENERATE( ... ) \
4105     Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4106                                  CATCH_INTERNAL_LINEINFO, \
4107                                  [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4108 #define GENERATE_COPY( ... ) \
4109     Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4110                                  CATCH_INTERNAL_LINEINFO, \
4111                                  [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4112 #define GENERATE_REF( ... ) \
4113     Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4114                                  CATCH_INTERNAL_LINEINFO, \
4115                                  [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4116
4117 // end catch_generators.hpp
4118 // start catch_generators_generic.hpp
4119
4120 namespace Catch {
4121 namespace Generators {
4122
4123     template <typename T>
4124     class TakeGenerator : public IGenerator<T> {
4125         GeneratorWrapper<T> m_generator;
4126         size_t m_returned = 0;
4127         size_t m_target;
4128     public:
4129         TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
4130             m_generator(std::move(generator)),
4131             m_target(target)
4132         {
4133             assert(target != 0 && "Empty generators are not allowed");
4134         }
4135         T const& get() const override {
4136             return m_generator.get();
4137         }
4138         bool next() override {
4139             ++m_returned;
4140             if (m_returned >= m_target) {
4141                 return false;
4142             }
4143
4144             const auto success = m_generator.next();
4145             // If the underlying generator does not contain enough values
4146             // then we cut short as well
4147             if (!success) {
4148                 m_returned = m_target;
4149             }
4150             return success;
4151         }
4152     };
4153
4154     template <typename T>
4155     GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
4156         return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
4157     }
4158
4159     template <typename T, typename Predicate>
4160     class FilterGenerator : public IGenerator<T> {
4161         GeneratorWrapper<T> m_generator;
4162         Predicate m_predicate;
4163     public:
4164         template <typename P = Predicate>
4165         FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
4166             m_generator(std::move(generator)),
4167             m_predicate(std::forward<P>(pred))
4168         {
4169             if (!m_predicate(m_generator.get())) {
4170                 // It might happen that there are no values that pass the
4171                 // filter. In that case we throw an exception.
4172                 auto has_initial_value = next();
4173                 if (!has_initial_value) {
4174                     Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
4175                 }
4176             }
4177         }
4178
4179         T const& get() const override {
4180             return m_generator.get();
4181         }
4182
4183         bool next() override {
4184             bool success = m_generator.next();
4185             if (!success) {
4186                 return false;
4187             }
4188             while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
4189             return success;
4190         }
4191     };
4192
4193     template <typename T, typename Predicate>
4194     GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
4195         return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
4196     }
4197
4198     template <typename T>
4199     class RepeatGenerator : public IGenerator<T> {
4200         static_assert(!std::is_same<T, bool>::value,
4201             "RepeatGenerator currently does not support bools"
4202             "because of std::vector<bool> specialization");
4203         GeneratorWrapper<T> m_generator;
4204         mutable std::vector<T> m_returned;
4205         size_t m_target_repeats;
4206         size_t m_current_repeat = 0;
4207         size_t m_repeat_index = 0;
4208     public:
4209         RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
4210             m_generator(std::move(generator)),
4211             m_target_repeats(repeats)
4212         {
4213             assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
4214         }
4215
4216         T const& get() const override {
4217             if (m_current_repeat == 0) {
4218                 m_returned.push_back(m_generator.get());
4219                 return m_returned.back();
4220             }
4221             return m_returned[m_repeat_index];
4222         }
4223
4224         bool next() override {
4225             // There are 2 basic cases:
4226             // 1) We are still reading the generator
4227             // 2) We are reading our own cache
4228
4229             // In the first case, we need to poke the underlying generator.
4230             // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
4231             if (m_current_repeat == 0) {
4232                 const auto success = m_generator.next();
4233                 if (!success) {
4234                     ++m_current_repeat;
4235                 }
4236                 return m_current_repeat < m_target_repeats;
4237             }
4238
4239             // In the second case, we need to move indices forward and check that we haven't run up against the end
4240             ++m_repeat_index;
4241             if (m_repeat_index == m_returned.size()) {
4242                 m_repeat_index = 0;
4243                 ++m_current_repeat;
4244             }
4245             return m_current_repeat < m_target_repeats;
4246         }
4247     };
4248
4249     template <typename T>
4250     GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
4251         return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
4252     }
4253
4254     template <typename T, typename U, typename Func>
4255     class MapGenerator : public IGenerator<T> {
4256         // TBD: provide static assert for mapping function, for friendly error message
4257         GeneratorWrapper<U> m_generator;
4258         Func m_function;
4259         // To avoid returning dangling reference, we have to save the values
4260         T m_cache;
4261     public:
4262         template <typename F2 = Func>
4263         MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
4264             m_generator(std::move(generator)),
4265             m_function(std::forward<F2>(function)),
4266             m_cache(m_function(m_generator.get()))
4267         {}
4268
4269         T const& get() const override {
4270             return m_cache;
4271         }
4272         bool next() override {
4273             const auto success = m_generator.next();
4274             if (success) {
4275                 m_cache = m_function(m_generator.get());
4276             }
4277             return success;
4278         }
4279     };
4280
4281     template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
4282     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4283         return GeneratorWrapper<T>(
4284             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4285         );
4286     }
4287
4288     template <typename T, typename U, typename Func>
4289     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4290         return GeneratorWrapper<T>(
4291             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4292         );
4293     }
4294
4295     template <typename T>
4296     class ChunkGenerator final : public IGenerator<std::vector<T>> {
4297         std::vector<T> m_chunk;
4298         size_t m_chunk_size;
4299         GeneratorWrapper<T> m_generator;
4300         bool m_used_up = false;
4301     public:
4302         ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
4303             m_chunk_size(size), m_generator(std::move(generator))
4304         {
4305             m_chunk.reserve(m_chunk_size);
4306             if (m_chunk_size != 0) {
4307                 m_chunk.push_back(m_generator.get());
4308                 for (size_t i = 1; i < m_chunk_size; ++i) {
4309                     if (!m_generator.next()) {
4310                         Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
4311                     }
4312                     m_chunk.push_back(m_generator.get());
4313                 }
4314             }
4315         }
4316         std::vector<T> const& get() const override {
4317             return m_chunk;
4318         }
4319         bool next() override {
4320             m_chunk.clear();
4321             for (size_t idx = 0; idx < m_chunk_size; ++idx) {
4322                 if (!m_generator.next()) {
4323                     return false;
4324                 }
4325                 m_chunk.push_back(m_generator.get());
4326             }
4327             return true;
4328         }
4329     };
4330
4331     template <typename T>
4332     GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
4333         return GeneratorWrapper<std::vector<T>>(
4334             pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
4335         );
4336     }
4337
4338 } // namespace Generators
4339 } // namespace Catch
4340
4341 // end catch_generators_generic.hpp
4342 // start catch_generators_specific.hpp
4343
4344 // start catch_context.h
4345
4346 #include <memory>
4347
4348 namespace Catch {
4349
4350     struct IResultCapture;
4351     struct IRunner;
4352     struct IConfig;
4353     struct IMutableContext;
4354
4355     using IConfigPtr = std::shared_ptr<IConfig const>;
4356
4357     struct IContext
4358     {
4359         virtual ~IContext();
4360
4361         virtual IResultCapture* getResultCapture() = 0;
4362         virtual IRunner* getRunner() = 0;
4363         virtual IConfigPtr const& getConfig() const = 0;
4364     };
4365
4366     struct IMutableContext : IContext
4367     {
4368         virtual ~IMutableContext();
4369         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
4370         virtual void setRunner( IRunner* runner ) = 0;
4371         virtual void setConfig( IConfigPtr const& config ) = 0;
4372
4373     private:
4374         static IMutableContext *currentContext;
4375         friend IMutableContext& getCurrentMutableContext();
4376         friend void cleanUpContext();
4377         static void createContext();
4378     };
4379
4380     inline IMutableContext& getCurrentMutableContext()
4381     {
4382         if( !IMutableContext::currentContext )
4383             IMutableContext::createContext();
4384         // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
4385         return *IMutableContext::currentContext;
4386     }
4387
4388     inline IContext& getCurrentContext()
4389     {
4390         return getCurrentMutableContext();
4391     }
4392
4393     void cleanUpContext();
4394
4395     class SimplePcg32;
4396     SimplePcg32& rng();
4397 }
4398
4399 // end catch_context.h
4400 // start catch_interfaces_config.h
4401
4402 // start catch_option.hpp
4403
4404 namespace Catch {
4405
4406     // An optional type
4407     template<typename T>
4408     class Option {
4409     public:
4410         Option() : nullableValue( nullptr ) {}
4411         Option( T const& _value )
4412         : nullableValue( new( storage ) T( _value ) )
4413         {}
4414         Option( Option const& _other )
4415         : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4416         {}
4417
4418         ~Option() {
4419             reset();
4420         }
4421
4422         Option& operator= ( Option const& _other ) {
4423             if( &_other != this ) {
4424                 reset();
4425                 if( _other )
4426                     nullableValue = new( storage ) T( *_other );
4427             }
4428             return *this;
4429         }
4430         Option& operator = ( T const& _value ) {
4431             reset();
4432             nullableValue = new( storage ) T( _value );
4433             return *this;
4434         }
4435
4436         void reset() {
4437             if( nullableValue )
4438                 nullableValue->~T();
4439             nullableValue = nullptr;
4440         }
4441
4442         T& operator*() { return *nullableValue; }
4443         T const& operator*() const { return *nullableValue; }
4444         T* operator->() { return nullableValue; }
4445         const T* operator->() const { return nullableValue; }
4446
4447         T valueOr( T const& defaultValue ) const {
4448             return nullableValue ? *nullableValue : defaultValue;
4449         }
4450
4451         bool some() const { return nullableValue != nullptr; }
4452         bool none() const { return nullableValue == nullptr; }
4453
4454         bool operator !() const { return nullableValue == nullptr; }
4455         explicit operator bool() const {
4456             return some();
4457         }
4458
4459     private:
4460         T *nullableValue;
4461         alignas(alignof(T)) char storage[sizeof(T)];
4462     };
4463
4464 } // end namespace Catch
4465
4466 // end catch_option.hpp
4467 #include <chrono>
4468 #include <iosfwd>
4469 #include <string>
4470 #include <vector>
4471 #include <memory>
4472
4473 namespace Catch {
4474
4475     enum class Verbosity {
4476         Quiet = 0,
4477         Normal,
4478         High
4479     };
4480
4481     struct WarnAbout { enum What {
4482         Nothing = 0x00,
4483         NoAssertions = 0x01,
4484         NoTests = 0x02
4485     }; };
4486
4487     struct ShowDurations { enum OrNot {
4488         DefaultForReporter,
4489         Always,
4490         Never
4491     }; };
4492     struct RunTests { enum InWhatOrder {
4493         InDeclarationOrder,
4494         InLexicographicalOrder,
4495         InRandomOrder
4496     }; };
4497     struct UseColour { enum YesOrNo {
4498         Auto,
4499         Yes,
4500         No
4501     }; };
4502     struct WaitForKeypress { enum When {
4503         Never,
4504         BeforeStart = 1,
4505         BeforeExit = 2,
4506         BeforeStartAndExit = BeforeStart | BeforeExit
4507     }; };
4508
4509     class TestSpec;
4510
4511     struct IConfig : NonCopyable {
4512
4513         virtual ~IConfig();
4514
4515         virtual bool allowThrows() const = 0;
4516         virtual std::ostream& stream() const = 0;
4517         virtual std::string name() const = 0;
4518         virtual bool includeSuccessfulResults() const = 0;
4519         virtual bool shouldDebugBreak() const = 0;
4520         virtual bool warnAboutMissingAssertions() const = 0;
4521         virtual bool warnAboutNoTests() const = 0;
4522         virtual int abortAfter() const = 0;
4523         virtual bool showInvisibles() const = 0;
4524         virtual ShowDurations::OrNot showDurations() const = 0;
4525         virtual TestSpec const& testSpec() const = 0;
4526         virtual bool hasTestFilters() const = 0;
4527         virtual std::vector<std::string> const& getTestsOrTags() const = 0;
4528         virtual RunTests::InWhatOrder runOrder() const = 0;
4529         virtual unsigned int rngSeed() const = 0;
4530         virtual UseColour::YesOrNo useColour() const = 0;
4531         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4532         virtual Verbosity verbosity() const = 0;
4533
4534         virtual bool benchmarkNoAnalysis() const = 0;
4535         virtual int benchmarkSamples() const = 0;
4536         virtual double benchmarkConfidenceInterval() const = 0;
4537         virtual unsigned int benchmarkResamples() const = 0;
4538         virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
4539     };
4540
4541     using IConfigPtr = std::shared_ptr<IConfig const>;
4542 }
4543
4544 // end catch_interfaces_config.h
4545 // start catch_random_number_generator.h
4546
4547 #include <cstdint>
4548
4549 namespace Catch {
4550
4551     // This is a simple implementation of C++11 Uniform Random Number
4552     // Generator. It does not provide all operators, because Catch2
4553     // does not use it, but it should behave as expected inside stdlib's
4554     // distributions.
4555     // The implementation is based on the PCG family (http://pcg-random.org)
4556     class SimplePcg32 {
4557         using state_type = std::uint64_t;
4558     public:
4559         using result_type = std::uint32_t;
4560         static constexpr result_type (min)() {
4561             return 0;
4562         }
4563         static constexpr result_type (max)() {
4564             return static_cast<result_type>(-1);
4565         }
4566
4567         // Provide some default initial state for the default constructor
4568         SimplePcg32():SimplePcg32(0xed743cc4U) {}
4569
4570         explicit SimplePcg32(result_type seed_);
4571
4572         void seed(result_type seed_);
4573         void discard(uint64_t skip);
4574
4575         result_type operator()();
4576
4577     private:
4578         friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4579         friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4580
4581         // In theory we also need operator<< and operator>>
4582         // In practice we do not use them, so we will skip them for now
4583
4584         std::uint64_t m_state;
4585         // This part of the state determines which "stream" of the numbers
4586         // is chosen -- we take it as a constant for Catch2, so we only
4587         // need to deal with seeding the main state.
4588         // Picked by reading 8 bytes from `/dev/random` :-)
4589         static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
4590     };
4591
4592 } // end namespace Catch
4593
4594 // end catch_random_number_generator.h
4595 #include <random>
4596
4597 namespace Catch {
4598 namespace Generators {
4599
4600 template <typename Float>
4601 class RandomFloatingGenerator final : public IGenerator<Float> {
4602     Catch::SimplePcg32& m_rng;
4603     std::uniform_real_distribution<Float> m_dist;
4604     Float m_current_number;
4605 public:
4606
4607     RandomFloatingGenerator(Float a, Float b):
4608         m_rng(rng()),
4609         m_dist(a, b) {
4610         static_cast<void>(next());
4611     }
4612
4613     Float const& get() const override {
4614         return m_current_number;
4615     }
4616     bool next() override {
4617         m_current_number = m_dist(m_rng);
4618         return true;
4619     }
4620 };
4621
4622 template <typename Integer>
4623 class RandomIntegerGenerator final : public IGenerator<Integer> {
4624     Catch::SimplePcg32& m_rng;
4625     std::uniform_int_distribution<Integer> m_dist;
4626     Integer m_current_number;
4627 public:
4628
4629     RandomIntegerGenerator(Integer a, Integer b):
4630         m_rng(rng()),
4631         m_dist(a, b) {
4632         static_cast<void>(next());
4633     }
4634
4635     Integer const& get() const override {
4636         return m_current_number;
4637     }
4638     bool next() override {
4639         m_current_number = m_dist(m_rng);
4640         return true;
4641     }
4642 };
4643
4644 // TODO: Ideally this would be also constrained against the various char types,
4645 //       but I don't expect users to run into that in practice.
4646 template <typename T>
4647 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
4648 GeneratorWrapper<T>>::type
4649 random(T a, T b) {
4650     return GeneratorWrapper<T>(
4651         pf::make_unique<RandomIntegerGenerator<T>>(a, b)
4652     );
4653 }
4654
4655 template <typename T>
4656 typename std::enable_if<std::is_floating_point<T>::value,
4657 GeneratorWrapper<T>>::type
4658 random(T a, T b) {
4659     return GeneratorWrapper<T>(
4660         pf::make_unique<RandomFloatingGenerator<T>>(a, b)
4661     );
4662 }
4663
4664 template <typename T>
4665 class RangeGenerator final : public IGenerator<T> {
4666     T m_current;
4667     T m_end;
4668     T m_step;
4669     bool m_positive;
4670
4671 public:
4672     RangeGenerator(T const& start, T const& end, T const& step):
4673         m_current(start),
4674         m_end(end),
4675         m_step(step),
4676         m_positive(m_step > T(0))
4677     {
4678         assert(m_current != m_end && "Range start and end cannot be equal");
4679         assert(m_step != T(0) && "Step size cannot be zero");
4680         assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
4681     }
4682
4683     RangeGenerator(T const& start, T const& end):
4684         RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
4685     {}
4686
4687     T const& get() const override {
4688         return m_current;
4689     }
4690
4691     bool next() override {
4692         m_current += m_step;
4693         return (m_positive) ? (m_current < m_end) : (m_current > m_end);
4694     }
4695 };
4696
4697 template <typename T>
4698 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
4699     static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
4700     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
4701 }
4702
4703 template <typename T>
4704 GeneratorWrapper<T> range(T const& start, T const& end) {
4705     static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4706     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
4707 }
4708
4709 template <typename T>
4710 class IteratorGenerator final : public IGenerator<T> {
4711     static_assert(!std::is_same<T, bool>::value,
4712         "IteratorGenerator currently does not support bools"
4713         "because of std::vector<bool> specialization");
4714
4715     std::vector<T> m_elems;
4716     size_t m_current = 0;
4717 public:
4718     template <typename InputIterator, typename InputSentinel>
4719     IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
4720         if (m_elems.empty()) {
4721             Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
4722         }
4723     }
4724
4725     T const& get() const override {
4726         return m_elems[m_current];
4727     }
4728
4729     bool next() override {
4730         ++m_current;
4731         return m_current != m_elems.size();
4732     }
4733 };
4734
4735 template <typename InputIterator,
4736           typename InputSentinel,
4737           typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
4738 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
4739     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
4740 }
4741
4742 template <typename Container,
4743           typename ResultType = typename Container::value_type>
4744 GeneratorWrapper<ResultType> from_range(Container const& cnt) {
4745     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
4746 }
4747
4748 } // namespace Generators
4749 } // namespace Catch
4750
4751 // end catch_generators_specific.hpp
4752
4753 // These files are included here so the single_include script doesn't put them
4754 // in the conditionally compiled sections
4755 // start catch_test_case_info.h
4756
4757 #include <string>
4758 #include <vector>
4759 #include <memory>
4760
4761 #ifdef __clang__
4762 #pragma clang diagnostic push
4763 #pragma clang diagnostic ignored "-Wpadded"
4764 #endif
4765
4766 namespace Catch {
4767
4768     struct ITestInvoker;
4769
4770     struct TestCaseInfo {
4771         enum SpecialProperties{
4772             None = 0,
4773             IsHidden = 1 << 1,
4774             ShouldFail = 1 << 2,
4775             MayFail = 1 << 3,
4776             Throws = 1 << 4,
4777             NonPortable = 1 << 5,
4778             Benchmark = 1 << 6
4779         };
4780
4781         TestCaseInfo(   std::string const& _name,
4782                         std::string const& _className,
4783                         std::string const& _description,
4784                         std::vector<std::string> const& _tags,
4785                         SourceLineInfo const& _lineInfo );
4786
4787         friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
4788
4789         bool isHidden() const;
4790         bool throws() const;
4791         bool okToFail() const;
4792         bool expectedToFail() const;
4793
4794         std::string tagsAsString() const;
4795
4796         std::string name;
4797         std::string className;
4798         std::string description;
4799         std::vector<std::string> tags;
4800         std::vector<std::string> lcaseTags;
4801         SourceLineInfo lineInfo;
4802         SpecialProperties properties;
4803     };
4804
4805     class TestCase : public TestCaseInfo {
4806     public:
4807
4808         TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
4809
4810         TestCase withName( std::string const& _newName ) const;
4811
4812         void invoke() const;
4813
4814         TestCaseInfo const& getTestCaseInfo() const;
4815
4816         bool operator == ( TestCase const& other ) const;
4817         bool operator < ( TestCase const& other ) const;
4818
4819     private:
4820         std::shared_ptr<ITestInvoker> test;
4821     };
4822
4823     TestCase makeTestCase(  ITestInvoker* testCase,
4824                             std::string const& className,
4825                             NameAndTags const& nameAndTags,
4826                             SourceLineInfo const& lineInfo );
4827 }
4828
4829 #ifdef __clang__
4830 #pragma clang diagnostic pop
4831 #endif
4832
4833 // end catch_test_case_info.h
4834 // start catch_interfaces_runner.h
4835
4836 namespace Catch {
4837
4838     struct IRunner {
4839         virtual ~IRunner();
4840         virtual bool aborting() const = 0;
4841     };
4842 }
4843
4844 // end catch_interfaces_runner.h
4845
4846 #ifdef __OBJC__
4847 // start catch_objc.hpp
4848
4849 #import <objc/runtime.h>
4850
4851 #include <string>
4852
4853 // NB. Any general catch headers included here must be included
4854 // in catch.hpp first to make sure they are included by the single
4855 // header for non obj-usage
4856
4857 ///////////////////////////////////////////////////////////////////////////////
4858 // This protocol is really only here for (self) documenting purposes, since
4859 // all its methods are optional.
4860 @protocol OcFixture
4861
4862 @optional
4863
4864 -(void) setUp;
4865 -(void) tearDown;
4866
4867 @end
4868
4869 namespace Catch {
4870
4871     class OcMethod : public ITestInvoker {
4872
4873     public:
4874         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
4875
4876         virtual void invoke() const {
4877             id obj = [[m_cls alloc] init];
4878
4879             performOptionalSelector( obj, @selector(setUp)  );
4880             performOptionalSelector( obj, m_sel );
4881             performOptionalSelector( obj, @selector(tearDown)  );
4882
4883             arcSafeRelease( obj );
4884         }
4885     private:
4886         virtual ~OcMethod() {}
4887
4888         Class m_cls;
4889         SEL m_sel;
4890     };
4891
4892     namespace Detail{
4893
4894         inline std::string getAnnotation(   Class cls,
4895                                             std::string const& annotationName,
4896                                             std::string const& testCaseName ) {
4897             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
4898             SEL sel = NSSelectorFromString( selStr );
4899             arcSafeRelease( selStr );
4900             id value = performOptionalSelector( cls, sel );
4901             if( value )
4902                 return [(NSString*)value UTF8String];
4903             return "";
4904         }
4905     }
4906
4907     inline std::size_t registerTestMethods() {
4908         std::size_t noTestMethods = 0;
4909         int noClasses = objc_getClassList( nullptr, 0 );
4910
4911         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
4912         objc_getClassList( classes, noClasses );
4913
4914         for( int c = 0; c < noClasses; c++ ) {
4915             Class cls = classes[c];
4916             {
4917                 u_int count;
4918                 Method* methods = class_copyMethodList( cls, &count );
4919                 for( u_int m = 0; m < count ; m++ ) {
4920                     SEL selector = method_getName(methods[m]);
4921                     std::string methodName = sel_getName(selector);
4922                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
4923                         std::string testCaseName = methodName.substr( 15 );
4924                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
4925                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
4926                         const char* className = class_getName( cls );
4927
4928                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
4929                         noTestMethods++;
4930                     }
4931                 }
4932                 free(methods);
4933             }
4934         }
4935         return noTestMethods;
4936     }
4937
4938 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
4939
4940     namespace Matchers {
4941         namespace Impl {
4942         namespace NSStringMatchers {
4943
4944             struct StringHolder : MatcherBase<NSString*>{
4945                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
4946                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
4947                 StringHolder() {
4948                     arcSafeRelease( m_substr );
4949                 }
4950
4951                 bool match( NSString* str ) const override {
4952                     return false;
4953                 }
4954
4955                 NSString* CATCH_ARC_STRONG m_substr;
4956             };
4957
4958             struct Equals : StringHolder {
4959                 Equals( NSString* substr ) : StringHolder( substr ){}
4960
4961                 bool match( NSString* str ) const override {
4962                     return  (str != nil || m_substr == nil ) &&
4963                             [str isEqualToString:m_substr];
4964                 }
4965
4966                 std::string describe() const override {
4967                     return "equals string: " + Catch::Detail::stringify( m_substr );
4968                 }
4969             };
4970
4971             struct Contains : StringHolder {
4972                 Contains( NSString* substr ) : StringHolder( substr ){}
4973
4974                 bool match( NSString* str ) const override {
4975                     return  (str != nil || m_substr == nil ) &&
4976                             [str rangeOfString:m_substr].location != NSNotFound;
4977                 }
4978
4979                 std::string describe() const override {
4980                     return "contains string: " + Catch::Detail::stringify( m_substr );
4981                 }
4982             };
4983
4984             struct StartsWith : StringHolder {
4985                 StartsWith( NSString* substr ) : StringHolder( substr ){}
4986
4987                 bool match( NSString* str ) const override {
4988                     return  (str != nil || m_substr == nil ) &&
4989                             [str rangeOfString:m_substr].location == 0;
4990                 }
4991
4992                 std::string describe() const override {
4993                     return "starts with: " + Catch::Detail::stringify( m_substr );
4994                 }
4995             };
4996             struct EndsWith : StringHolder {
4997                 EndsWith( NSString* substr ) : StringHolder( substr ){}
4998
4999                 bool match( NSString* str ) const override {
5000                     return  (str != nil || m_substr == nil ) &&
5001                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
5002                 }
5003
5004                 std::string describe() const override {
5005                     return "ends with: " + Catch::Detail::stringify( m_substr );
5006                 }
5007             };
5008
5009         } // namespace NSStringMatchers
5010         } // namespace Impl
5011
5012         inline Impl::NSStringMatchers::Equals
5013             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
5014
5015         inline Impl::NSStringMatchers::Contains
5016             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
5017
5018         inline Impl::NSStringMatchers::StartsWith
5019             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
5020
5021         inline Impl::NSStringMatchers::EndsWith
5022             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
5023
5024     } // namespace Matchers
5025
5026     using namespace Matchers;
5027
5028 #endif // CATCH_CONFIG_DISABLE_MATCHERS
5029
5030 } // namespace Catch
5031
5032 ///////////////////////////////////////////////////////////////////////////////
5033 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
5034 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
5035 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
5036 { \
5037 return @ name; \
5038 } \
5039 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
5040 { \
5041 return @ desc; \
5042 } \
5043 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
5044
5045 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
5046
5047 // end catch_objc.hpp
5048 #endif
5049
5050 // Benchmarking needs the externally-facing parts of reporters to work
5051 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5052 // start catch_external_interfaces.h
5053
5054 // start catch_reporter_bases.hpp
5055
5056 // start catch_interfaces_reporter.h
5057
5058 // start catch_config.hpp
5059
5060 // start catch_test_spec_parser.h
5061
5062 #ifdef __clang__
5063 #pragma clang diagnostic push
5064 #pragma clang diagnostic ignored "-Wpadded"
5065 #endif
5066
5067 // start catch_test_spec.h
5068
5069 #ifdef __clang__
5070 #pragma clang diagnostic push
5071 #pragma clang diagnostic ignored "-Wpadded"
5072 #endif
5073
5074 // start catch_wildcard_pattern.h
5075
5076 namespace Catch
5077 {
5078     class WildcardPattern {
5079         enum WildcardPosition {
5080             NoWildcard = 0,
5081             WildcardAtStart = 1,
5082             WildcardAtEnd = 2,
5083             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
5084         };
5085
5086     public:
5087
5088         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
5089         virtual ~WildcardPattern() = default;
5090         virtual bool matches( std::string const& str ) const;
5091
5092     private:
5093         std::string normaliseString( std::string const& str ) const;
5094         CaseSensitive::Choice m_caseSensitivity;
5095         WildcardPosition m_wildcard = NoWildcard;
5096         std::string m_pattern;
5097     };
5098 }
5099
5100 // end catch_wildcard_pattern.h
5101 #include <string>
5102 #include <vector>
5103 #include <memory>
5104
5105 namespace Catch {
5106
5107     struct IConfig;
5108
5109     class TestSpec {
5110         class Pattern {
5111         public:
5112             explicit Pattern( std::string const& name );
5113             virtual ~Pattern();
5114             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
5115             std::string const& name() const;
5116         private:
5117             std::string const m_name;
5118         };
5119         using PatternPtr = std::shared_ptr<Pattern>;
5120
5121         class NamePattern : public Pattern {
5122         public:
5123             explicit NamePattern( std::string const& name, std::string const& filterString );
5124             bool matches( TestCaseInfo const& testCase ) const override;
5125         private:
5126             WildcardPattern m_wildcardPattern;
5127         };
5128
5129         class TagPattern : public Pattern {
5130         public:
5131             explicit TagPattern( std::string const& tag, std::string const& filterString );
5132             bool matches( TestCaseInfo const& testCase ) const override;
5133         private:
5134             std::string m_tag;
5135         };
5136
5137         class ExcludedPattern : public Pattern {
5138         public:
5139             explicit ExcludedPattern( PatternPtr const& underlyingPattern );
5140             bool matches( TestCaseInfo const& testCase ) const override;
5141         private:
5142             PatternPtr m_underlyingPattern;
5143         };
5144
5145         struct Filter {
5146             std::vector<PatternPtr> m_patterns;
5147
5148             bool matches( TestCaseInfo const& testCase ) const;
5149             std::string name() const;
5150         };
5151
5152     public:
5153         struct FilterMatch {
5154             std::string name;
5155             std::vector<TestCase const*> tests;
5156         };
5157         using Matches = std::vector<FilterMatch>;
5158         using vectorStrings = std::vector<std::string>;
5159
5160         bool hasFilters() const;
5161         bool matches( TestCaseInfo const& testCase ) const;
5162         Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
5163         const vectorStrings & getInvalidArgs() const;
5164
5165     private:
5166         std::vector<Filter> m_filters;
5167         std::vector<std::string> m_invalidArgs;
5168         friend class TestSpecParser;
5169     };
5170 }
5171
5172 #ifdef __clang__
5173 #pragma clang diagnostic pop
5174 #endif
5175
5176 // end catch_test_spec.h
5177 // start catch_interfaces_tag_alias_registry.h
5178
5179 #include <string>
5180
5181 namespace Catch {
5182
5183     struct TagAlias;
5184
5185     struct ITagAliasRegistry {
5186         virtual ~ITagAliasRegistry();
5187         // Nullptr if not present
5188         virtual TagAlias const* find( std::string const& alias ) const = 0;
5189         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
5190
5191         static ITagAliasRegistry const& get();
5192     };
5193
5194 } // end namespace Catch
5195
5196 // end catch_interfaces_tag_alias_registry.h
5197 namespace Catch {
5198
5199     class TestSpecParser {
5200         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
5201         Mode m_mode = None;
5202         Mode lastMode = None;
5203         bool m_exclusion = false;
5204         std::size_t m_pos = 0;
5205         std::size_t m_realPatternPos = 0;
5206         std::string m_arg;
5207         std::string m_substring;
5208         std::string m_patternName;
5209         std::vector<std::size_t> m_escapeChars;
5210         TestSpec::Filter m_currentFilter;
5211         TestSpec m_testSpec;
5212         ITagAliasRegistry const* m_tagAliases = nullptr;
5213
5214     public:
5215         TestSpecParser( ITagAliasRegistry const& tagAliases );
5216
5217         TestSpecParser& parse( std::string const& arg );
5218         TestSpec testSpec();
5219
5220     private:
5221         bool visitChar( char c );
5222         void startNewMode( Mode mode );
5223         bool processNoneChar( char c );
5224         void processNameChar( char c );
5225         bool processOtherChar( char c );
5226         void endMode();
5227         void escape();
5228         bool isControlChar( char c ) const;
5229         void saveLastMode();
5230         void revertBackToLastMode();
5231         void addFilter();
5232         bool separate();
5233
5234         // Handles common preprocessing of the pattern for name/tag patterns
5235         std::string preprocessPattern();
5236         // Adds the current pattern as a test name
5237         void addNamePattern();
5238         // Adds the current pattern as a tag
5239         void addTagPattern();
5240
5241         inline void addCharToPattern(char c) {
5242             m_substring += c;
5243             m_patternName += c;
5244             m_realPatternPos++;
5245         }
5246
5247     };
5248     TestSpec parseTestSpec( std::string const& arg );
5249
5250 } // namespace Catch
5251
5252 #ifdef __clang__
5253 #pragma clang diagnostic pop
5254 #endif
5255
5256 // end catch_test_spec_parser.h
5257 // Libstdc++ doesn't like incomplete classes for unique_ptr
5258
5259 #include <memory>
5260 #include <vector>
5261 #include <string>
5262
5263 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
5264 #define CATCH_CONFIG_CONSOLE_WIDTH 80
5265 #endif
5266
5267 namespace Catch {
5268
5269     struct IStream;
5270
5271     struct ConfigData {
5272         bool listTests = false;
5273         bool listTags = false;
5274         bool listReporters = false;
5275         bool listTestNamesOnly = false;
5276
5277         bool showSuccessfulTests = false;
5278         bool shouldDebugBreak = false;
5279         bool noThrow = false;
5280         bool showHelp = false;
5281         bool showInvisibles = false;
5282         bool filenamesAsTags = false;
5283         bool libIdentify = false;
5284
5285         int abortAfter = -1;
5286         unsigned int rngSeed = 0;
5287
5288         bool benchmarkNoAnalysis = false;
5289         unsigned int benchmarkSamples = 100;
5290         double benchmarkConfidenceInterval = 0.95;
5291         unsigned int benchmarkResamples = 100000;
5292         std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
5293
5294         Verbosity verbosity = Verbosity::Normal;
5295         WarnAbout::What warnings = WarnAbout::Nothing;
5296         ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
5297         RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
5298         UseColour::YesOrNo useColour = UseColour::Auto;
5299         WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
5300
5301         std::string outputFilename;
5302         std::string name;
5303         std::string processName;
5304 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
5305 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
5306 #endif
5307         std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
5308 #undef CATCH_CONFIG_DEFAULT_REPORTER
5309
5310         std::vector<std::string> testsOrTags;
5311         std::vector<std::string> sectionsToRun;
5312     };
5313
5314     class Config : public IConfig {
5315     public:
5316
5317         Config() = default;
5318         Config( ConfigData const& data );
5319         virtual ~Config() = default;
5320
5321         std::string const& getFilename() const;
5322
5323         bool listTests() const;
5324         bool listTestNamesOnly() const;
5325         bool listTags() const;
5326         bool listReporters() const;
5327
5328         std::string getProcessName() const;
5329         std::string const& getReporterName() const;
5330
5331         std::vector<std::string> const& getTestsOrTags() const override;
5332         std::vector<std::string> const& getSectionsToRun() const override;
5333
5334         TestSpec const& testSpec() const override;
5335         bool hasTestFilters() const override;
5336
5337         bool showHelp() const;
5338
5339         // IConfig interface
5340         bool allowThrows() const override;
5341         std::ostream& stream() const override;
5342         std::string name() const override;
5343         bool includeSuccessfulResults() const override;
5344         bool warnAboutMissingAssertions() const override;
5345         bool warnAboutNoTests() const override;
5346         ShowDurations::OrNot showDurations() const override;
5347         RunTests::InWhatOrder runOrder() const override;
5348         unsigned int rngSeed() const override;
5349         UseColour::YesOrNo useColour() const override;
5350         bool shouldDebugBreak() const override;
5351         int abortAfter() const override;
5352         bool showInvisibles() const override;
5353         Verbosity verbosity() const override;
5354         bool benchmarkNoAnalysis() const override;
5355         int benchmarkSamples() const override;
5356         double benchmarkConfidenceInterval() const override;
5357         unsigned int benchmarkResamples() const override;
5358         std::chrono::milliseconds benchmarkWarmupTime() const override;
5359
5360     private:
5361
5362         IStream const* openStream();
5363         ConfigData m_data;
5364
5365         std::unique_ptr<IStream const> m_stream;
5366         TestSpec m_testSpec;
5367         bool m_hasTestFilters = false;
5368     };
5369
5370 } // end namespace Catch
5371
5372 // end catch_config.hpp
5373 // start catch_assertionresult.h
5374
5375 #include <string>
5376
5377 namespace Catch {
5378
5379     struct AssertionResultData
5380     {
5381         AssertionResultData() = delete;
5382
5383         AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
5384
5385         std::string message;
5386         mutable std::string reconstructedExpression;
5387         LazyExpression lazyExpression;
5388         ResultWas::OfType resultType;
5389
5390         std::string reconstructExpression() const;
5391     };
5392
5393     class AssertionResult {
5394     public:
5395         AssertionResult() = delete;
5396         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
5397
5398         bool isOk() const;
5399         bool succeeded() const;
5400         ResultWas::OfType getResultType() const;
5401         bool hasExpression() const;
5402         bool hasMessage() const;
5403         std::string getExpression() const;
5404         std::string getExpressionInMacro() const;
5405         bool hasExpandedExpression() const;
5406         std::string getExpandedExpression() const;
5407         std::string getMessage() const;
5408         SourceLineInfo getSourceInfo() const;
5409         StringRef getTestMacroName() const;
5410
5411     //protected:
5412         AssertionInfo m_info;
5413         AssertionResultData m_resultData;
5414     };
5415
5416 } // end namespace Catch
5417
5418 // end catch_assertionresult.h
5419 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5420 // start catch_estimate.hpp
5421
5422  // Statistics estimates
5423
5424
5425 namespace Catch {
5426     namespace Benchmark {
5427         template <typename Duration>
5428         struct Estimate {
5429             Duration point;
5430             Duration lower_bound;
5431             Duration upper_bound;
5432             double confidence_interval;
5433
5434             template <typename Duration2>
5435             operator Estimate<Duration2>() const {
5436                 return { point, lower_bound, upper_bound, confidence_interval };
5437             }
5438         };
5439     } // namespace Benchmark
5440 } // namespace Catch
5441
5442 // end catch_estimate.hpp
5443 // start catch_outlier_classification.hpp
5444
5445 // Outlier information
5446
5447 namespace Catch {
5448     namespace Benchmark {
5449         struct OutlierClassification {
5450             int samples_seen = 0;
5451             int low_severe = 0;     // more than 3 times IQR below Q1
5452             int low_mild = 0;       // 1.5 to 3 times IQR below Q1
5453             int high_mild = 0;      // 1.5 to 3 times IQR above Q3
5454             int high_severe = 0;    // more than 3 times IQR above Q3
5455
5456             int total() const {
5457                 return low_severe + low_mild + high_mild + high_severe;
5458             }
5459         };
5460     } // namespace Benchmark
5461 } // namespace Catch
5462
5463 // end catch_outlier_classification.hpp
5464 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5465
5466 #include <string>
5467 #include <iosfwd>
5468 #include <map>
5469 #include <set>
5470 #include <memory>
5471 #include <algorithm>
5472
5473 namespace Catch {
5474
5475     struct ReporterConfig {
5476         explicit ReporterConfig( IConfigPtr const& _fullConfig );
5477
5478         ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
5479
5480         std::ostream& stream() const;
5481         IConfigPtr fullConfig() const;
5482
5483     private:
5484         std::ostream* m_stream;
5485         IConfigPtr m_fullConfig;
5486     };
5487
5488     struct ReporterPreferences {
5489         bool shouldRedirectStdOut = false;
5490         bool shouldReportAllAssertions = false;
5491     };
5492
5493     template<typename T>
5494     struct LazyStat : Option<T> {
5495         LazyStat& operator=( T const& _value ) {
5496             Option<T>::operator=( _value );
5497             used = false;
5498             return *this;
5499         }
5500         void reset() {
5501             Option<T>::reset();
5502             used = false;
5503         }
5504         bool used = false;
5505     };
5506
5507     struct TestRunInfo {
5508         TestRunInfo( std::string const& _name );
5509         std::string name;
5510     };
5511     struct GroupInfo {
5512         GroupInfo(  std::string const& _name,
5513                     std::size_t _groupIndex,
5514                     std::size_t _groupsCount );
5515
5516         std::string name;
5517         std::size_t groupIndex;
5518         std::size_t groupsCounts;
5519     };
5520
5521     struct AssertionStats {
5522         AssertionStats( AssertionResult const& _assertionResult,
5523                         std::vector<MessageInfo> const& _infoMessages,
5524                         Totals const& _totals );
5525
5526         AssertionStats( AssertionStats const& )              = default;
5527         AssertionStats( AssertionStats && )                  = default;
5528         AssertionStats& operator = ( AssertionStats const& ) = delete;
5529         AssertionStats& operator = ( AssertionStats && )     = delete;
5530         virtual ~AssertionStats();
5531
5532         AssertionResult assertionResult;
5533         std::vector<MessageInfo> infoMessages;
5534         Totals totals;
5535     };
5536
5537     struct SectionStats {
5538         SectionStats(   SectionInfo const& _sectionInfo,
5539                         Counts const& _assertions,
5540                         double _durationInSeconds,
5541                         bool _missingAssertions );
5542         SectionStats( SectionStats const& )              = default;
5543         SectionStats( SectionStats && )                  = default;
5544         SectionStats& operator = ( SectionStats const& ) = default;
5545         SectionStats& operator = ( SectionStats && )     = default;
5546         virtual ~SectionStats();
5547
5548         SectionInfo sectionInfo;
5549         Counts assertions;
5550         double durationInSeconds;
5551         bool missingAssertions;
5552     };
5553
5554     struct TestCaseStats {
5555         TestCaseStats(  TestCaseInfo const& _testInfo,
5556                         Totals const& _totals,
5557                         std::string const& _stdOut,
5558                         std::string const& _stdErr,
5559                         bool _aborting );
5560
5561         TestCaseStats( TestCaseStats const& )              = default;
5562         TestCaseStats( TestCaseStats && )                  = default;
5563         TestCaseStats& operator = ( TestCaseStats const& ) = default;
5564         TestCaseStats& operator = ( TestCaseStats && )     = default;
5565         virtual ~TestCaseStats();
5566
5567         TestCaseInfo testInfo;
5568         Totals totals;
5569         std::string stdOut;
5570         std::string stdErr;
5571         bool aborting;
5572     };
5573
5574     struct TestGroupStats {
5575         TestGroupStats( GroupInfo const& _groupInfo,
5576                         Totals const& _totals,
5577                         bool _aborting );
5578         TestGroupStats( GroupInfo const& _groupInfo );
5579
5580         TestGroupStats( TestGroupStats const& )              = default;
5581         TestGroupStats( TestGroupStats && )                  = default;
5582         TestGroupStats& operator = ( TestGroupStats const& ) = default;
5583         TestGroupStats& operator = ( TestGroupStats && )     = default;
5584         virtual ~TestGroupStats();
5585
5586         GroupInfo groupInfo;
5587         Totals totals;
5588         bool aborting;
5589     };
5590
5591     struct TestRunStats {
5592         TestRunStats(   TestRunInfo const& _runInfo,
5593                         Totals const& _totals,
5594                         bool _aborting );
5595
5596         TestRunStats( TestRunStats const& )              = default;
5597         TestRunStats( TestRunStats && )                  = default;
5598         TestRunStats& operator = ( TestRunStats const& ) = default;
5599         TestRunStats& operator = ( TestRunStats && )     = default;
5600         virtual ~TestRunStats();
5601
5602         TestRunInfo runInfo;
5603         Totals totals;
5604         bool aborting;
5605     };
5606
5607 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5608     struct BenchmarkInfo {
5609         std::string name;
5610         double estimatedDuration;
5611         int iterations;
5612         int samples;
5613         unsigned int resamples;
5614         double clockResolution;
5615         double clockCost;
5616     };
5617
5618     template <class Duration>
5619     struct BenchmarkStats {
5620         BenchmarkInfo info;
5621
5622         std::vector<Duration> samples;
5623         Benchmark::Estimate<Duration> mean;
5624         Benchmark::Estimate<Duration> standardDeviation;
5625         Benchmark::OutlierClassification outliers;
5626         double outlierVariance;
5627
5628         template <typename Duration2>
5629         operator BenchmarkStats<Duration2>() const {
5630             std::vector<Duration2> samples2;
5631             samples2.reserve(samples.size());
5632             std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
5633             return {
5634                 info,
5635                 std::move(samples2),
5636                 mean,
5637                 standardDeviation,
5638                 outliers,
5639                 outlierVariance,
5640             };
5641         }
5642     };
5643 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5644
5645     struct IStreamingReporter {
5646         virtual ~IStreamingReporter() = default;
5647
5648         // Implementing class must also provide the following static methods:
5649         // static std::string getDescription();
5650         // static std::set<Verbosity> getSupportedVerbosities()
5651
5652         virtual ReporterPreferences getPreferences() const = 0;
5653
5654         virtual void noMatchingTestCases( std::string const& spec ) = 0;
5655
5656         virtual void reportInvalidArguments(std::string const&) {}
5657
5658         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5659         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5660
5661         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5662         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5663
5664 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5665         virtual void benchmarkPreparing( std::string const& ) {}
5666         virtual void benchmarkStarting( BenchmarkInfo const& ) {}
5667         virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
5668         virtual void benchmarkFailed( std::string const& ) {}
5669 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5670
5671         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5672
5673         // The return value indicates if the messages buffer should be cleared:
5674         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5675
5676         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5677         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5678         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5679         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5680
5681         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5682
5683         // Default empty implementation provided
5684         virtual void fatalErrorEncountered( StringRef name );
5685
5686         virtual bool isMulti() const;
5687     };
5688     using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
5689
5690     struct IReporterFactory {
5691         virtual ~IReporterFactory();
5692         virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
5693         virtual std::string getDescription() const = 0;
5694     };
5695     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
5696
5697     struct IReporterRegistry {
5698         using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
5699         using Listeners = std::vector<IReporterFactoryPtr>;
5700
5701         virtual ~IReporterRegistry();
5702         virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
5703         virtual FactoryMap const& getFactories() const = 0;
5704         virtual Listeners const& getListeners() const = 0;
5705     };
5706
5707 } // end namespace Catch
5708
5709 // end catch_interfaces_reporter.h
5710 #include <algorithm>
5711 #include <cstring>
5712 #include <cfloat>
5713 #include <cstdio>
5714 #include <cassert>
5715 #include <memory>
5716 #include <ostream>
5717
5718 namespace Catch {
5719     void prepareExpandedExpression(AssertionResult& result);
5720
5721     // Returns double formatted as %.3f (format expected on output)
5722     std::string getFormattedDuration( double duration );
5723
5724     std::string serializeFilters( std::vector<std::string> const& container );
5725
5726     template<typename DerivedT>
5727     struct StreamingReporterBase : IStreamingReporter {
5728
5729         StreamingReporterBase( ReporterConfig const& _config )
5730         :   m_config( _config.fullConfig() ),
5731             stream( _config.stream() )
5732         {
5733             m_reporterPrefs.shouldRedirectStdOut = false;
5734             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5735                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
5736         }
5737
5738         ReporterPreferences getPreferences() const override {
5739             return m_reporterPrefs;
5740         }
5741
5742         static std::set<Verbosity> getSupportedVerbosities() {
5743             return { Verbosity::Normal };
5744         }
5745
5746         ~StreamingReporterBase() override = default;
5747
5748         void noMatchingTestCases(std::string const&) override {}
5749
5750         void reportInvalidArguments(std::string const&) override {}
5751
5752         void testRunStarting(TestRunInfo const& _testRunInfo) override {
5753             currentTestRunInfo = _testRunInfo;
5754         }
5755
5756         void testGroupStarting(GroupInfo const& _groupInfo) override {
5757             currentGroupInfo = _groupInfo;
5758         }
5759
5760         void testCaseStarting(TestCaseInfo const& _testInfo) override  {
5761             currentTestCaseInfo = _testInfo;
5762         }
5763         void sectionStarting(SectionInfo const& _sectionInfo) override {
5764             m_sectionStack.push_back(_sectionInfo);
5765         }
5766
5767         void sectionEnded(SectionStats const& /* _sectionStats */) override {
5768             m_sectionStack.pop_back();
5769         }
5770         void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
5771             currentTestCaseInfo.reset();
5772         }
5773         void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
5774             currentGroupInfo.reset();
5775         }
5776         void testRunEnded(TestRunStats const& /* _testRunStats */) override {
5777             currentTestCaseInfo.reset();
5778             currentGroupInfo.reset();
5779             currentTestRunInfo.reset();
5780         }
5781
5782         void skipTest(TestCaseInfo const&) override {
5783             // Don't do anything with this by default.
5784             // It can optionally be overridden in the derived class.
5785         }
5786
5787         IConfigPtr m_config;
5788         std::ostream& stream;
5789
5790         LazyStat<TestRunInfo> currentTestRunInfo;
5791         LazyStat<GroupInfo> currentGroupInfo;
5792         LazyStat<TestCaseInfo> currentTestCaseInfo;
5793
5794         std::vector<SectionInfo> m_sectionStack;
5795         ReporterPreferences m_reporterPrefs;
5796     };
5797
5798     template<typename DerivedT>
5799     struct CumulativeReporterBase : IStreamingReporter {
5800         template<typename T, typename ChildNodeT>
5801         struct Node {
5802             explicit Node( T const& _value ) : value( _value ) {}
5803             virtual ~Node() {}
5804
5805             using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
5806             T value;
5807             ChildNodes children;
5808         };
5809         struct SectionNode {
5810             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
5811             virtual ~SectionNode() = default;
5812
5813             bool operator == (SectionNode const& other) const {
5814                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
5815             }
5816             bool operator == (std::shared_ptr<SectionNode> const& other) const {
5817                 return operator==(*other);
5818             }
5819
5820             SectionStats stats;
5821             using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
5822             using Assertions = std::vector<AssertionStats>;
5823             ChildSections childSections;
5824             Assertions assertions;
5825             std::string stdOut;
5826             std::string stdErr;
5827         };
5828
5829         struct BySectionInfo {
5830             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
5831             BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
5832             bool operator() (std::shared_ptr<SectionNode> const& node) const {
5833                 return ((node->stats.sectionInfo.name == m_other.name) &&
5834                         (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
5835             }
5836             void operator=(BySectionInfo const&) = delete;
5837
5838         private:
5839             SectionInfo const& m_other;
5840         };
5841
5842         using TestCaseNode = Node<TestCaseStats, SectionNode>;
5843         using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
5844         using TestRunNode = Node<TestRunStats, TestGroupNode>;
5845
5846         CumulativeReporterBase( ReporterConfig const& _config )
5847         :   m_config( _config.fullConfig() ),
5848             stream( _config.stream() )
5849         {
5850             m_reporterPrefs.shouldRedirectStdOut = false;
5851             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5852                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
5853         }
5854         ~CumulativeReporterBase() override = default;
5855
5856         ReporterPreferences getPreferences() const override {
5857             return m_reporterPrefs;
5858         }
5859
5860         static std::set<Verbosity> getSupportedVerbosities() {
5861             return { Verbosity::Normal };
5862         }
5863
5864         void testRunStarting( TestRunInfo const& ) override {}
5865         void testGroupStarting( GroupInfo const& ) override {}
5866
5867         void testCaseStarting( TestCaseInfo const& ) override {}
5868
5869         void sectionStarting( SectionInfo const& sectionInfo ) override {
5870             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
5871             std::shared_ptr<SectionNode> node;
5872             if( m_sectionStack.empty() ) {
5873                 if( !m_rootSection )
5874                     m_rootSection = std::make_shared<SectionNode>( incompleteStats );
5875                 node = m_rootSection;
5876             }
5877             else {
5878                 SectionNode& parentNode = *m_sectionStack.back();
5879                 auto it =
5880                     std::find_if(   parentNode.childSections.begin(),
5881                                     parentNode.childSections.end(),
5882                                     BySectionInfo( sectionInfo ) );
5883                 if( it == parentNode.childSections.end() ) {
5884                     node = std::make_shared<SectionNode>( incompleteStats );
5885                     parentNode.childSections.push_back( node );
5886                 }
5887                 else
5888                     node = *it;
5889             }
5890             m_sectionStack.push_back( node );
5891             m_deepestSection = std::move(node);
5892         }
5893
5894         void assertionStarting(AssertionInfo const&) override {}
5895
5896         bool assertionEnded(AssertionStats const& assertionStats) override {
5897             assert(!m_sectionStack.empty());
5898             // AssertionResult holds a pointer to a temporary DecomposedExpression,
5899             // which getExpandedExpression() calls to build the expression string.
5900             // Our section stack copy of the assertionResult will likely outlive the
5901             // temporary, so it must be expanded or discarded now to avoid calling
5902             // a destroyed object later.
5903             prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
5904             SectionNode& sectionNode = *m_sectionStack.back();
5905             sectionNode.assertions.push_back(assertionStats);
5906             return true;
5907         }
5908         void sectionEnded(SectionStats const& sectionStats) override {
5909             assert(!m_sectionStack.empty());
5910             SectionNode& node = *m_sectionStack.back();
5911             node.stats = sectionStats;
5912             m_sectionStack.pop_back();
5913         }
5914         void testCaseEnded(TestCaseStats const& testCaseStats) override {
5915             auto node = std::make_shared<TestCaseNode>(testCaseStats);
5916             assert(m_sectionStack.size() == 0);
5917             node->children.push_back(m_rootSection);
5918             m_testCases.push_back(node);
5919             m_rootSection.reset();
5920
5921             assert(m_deepestSection);
5922             m_deepestSection->stdOut = testCaseStats.stdOut;
5923             m_deepestSection->stdErr = testCaseStats.stdErr;
5924         }
5925         void testGroupEnded(TestGroupStats const& testGroupStats) override {
5926             auto node = std::make_shared<TestGroupNode>(testGroupStats);
5927             node->children.swap(m_testCases);
5928             m_testGroups.push_back(node);
5929         }
5930         void testRunEnded(TestRunStats const& testRunStats) override {
5931             auto node = std::make_shared<TestRunNode>(testRunStats);
5932             node->children.swap(m_testGroups);
5933             m_testRuns.push_back(node);
5934             testRunEndedCumulative();
5935         }
5936         virtual void testRunEndedCumulative() = 0;
5937
5938         void skipTest(TestCaseInfo const&) override {}
5939
5940         IConfigPtr m_config;
5941         std::ostream& stream;
5942         std::vector<AssertionStats> m_assertions;
5943         std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
5944         std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
5945         std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
5946
5947         std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
5948
5949         std::shared_ptr<SectionNode> m_rootSection;
5950         std::shared_ptr<SectionNode> m_deepestSection;
5951         std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
5952         ReporterPreferences m_reporterPrefs;
5953     };
5954
5955     template<char C>
5956     char const* getLineOfChars() {
5957         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
5958         if( !*line ) {
5959             std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
5960             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
5961         }
5962         return line;
5963     }
5964
5965     struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
5966         TestEventListenerBase( ReporterConfig const& _config );
5967
5968         static std::set<Verbosity> getSupportedVerbosities();
5969
5970         void assertionStarting(AssertionInfo const&) override;
5971         bool assertionEnded(AssertionStats const&) override;
5972     };
5973
5974 } // end namespace Catch
5975
5976 // end catch_reporter_bases.hpp
5977 // start catch_console_colour.h
5978
5979 namespace Catch {
5980
5981     struct Colour {
5982         enum Code {
5983             None = 0,
5984
5985             White,
5986             Red,
5987             Green,
5988             Blue,
5989             Cyan,
5990             Yellow,
5991             Grey,
5992
5993             Bright = 0x10,
5994
5995             BrightRed = Bright | Red,
5996             BrightGreen = Bright | Green,
5997             LightGrey = Bright | Grey,
5998             BrightWhite = Bright | White,
5999             BrightYellow = Bright | Yellow,
6000
6001             // By intention
6002             FileName = LightGrey,
6003             Warning = BrightYellow,
6004             ResultError = BrightRed,
6005             ResultSuccess = BrightGreen,
6006             ResultExpectedFailure = Warning,
6007
6008             Error = BrightRed,
6009             Success = Green,
6010
6011             OriginalExpression = Cyan,
6012             ReconstructedExpression = BrightYellow,
6013
6014             SecondaryText = LightGrey,
6015             Headers = White
6016         };
6017
6018         // Use constructed object for RAII guard
6019         Colour( Code _colourCode );
6020         Colour( Colour&& other ) noexcept;
6021         Colour& operator=( Colour&& other ) noexcept;
6022         ~Colour();
6023
6024         // Use static method for one-shot changes
6025         static void use( Code _colourCode );
6026
6027     private:
6028         bool m_moved = false;
6029     };
6030
6031     std::ostream& operator << ( std::ostream& os, Colour const& );
6032
6033 } // end namespace Catch
6034
6035 // end catch_console_colour.h
6036 // start catch_reporter_registrars.hpp
6037
6038
6039 namespace Catch {
6040
6041     template<typename T>
6042     class ReporterRegistrar {
6043
6044         class ReporterFactory : public IReporterFactory {
6045
6046             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
6047                 return std::unique_ptr<T>( new T( config ) );
6048             }
6049
6050             std::string getDescription() const override {
6051                 return T::getDescription();
6052             }
6053         };
6054
6055     public:
6056
6057         explicit ReporterRegistrar( std::string const& name ) {
6058             getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
6059         }
6060     };
6061
6062     template<typename T>
6063     class ListenerRegistrar {
6064
6065         class ListenerFactory : public IReporterFactory {
6066
6067             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
6068                 return std::unique_ptr<T>( new T( config ) );
6069             }
6070             std::string getDescription() const override {
6071                 return std::string();
6072             }
6073         };
6074
6075     public:
6076
6077         ListenerRegistrar() {
6078             getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
6079         }
6080     };
6081 }
6082
6083 #if !defined(CATCH_CONFIG_DISABLE)
6084
6085 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
6086     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
6087     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
6088     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
6089     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6090
6091 #define CATCH_REGISTER_LISTENER( listenerType ) \
6092     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
6093     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
6094     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
6095     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6096 #else // CATCH_CONFIG_DISABLE
6097
6098 #define CATCH_REGISTER_REPORTER(name, reporterType)
6099 #define CATCH_REGISTER_LISTENER(listenerType)
6100
6101 #endif // CATCH_CONFIG_DISABLE
6102
6103 // end catch_reporter_registrars.hpp
6104 // Allow users to base their work off existing reporters
6105 // start catch_reporter_compact.h
6106
6107 namespace Catch {
6108
6109     struct CompactReporter : StreamingReporterBase<CompactReporter> {
6110
6111         using StreamingReporterBase::StreamingReporterBase;
6112
6113         ~CompactReporter() override;
6114
6115         static std::string getDescription();
6116
6117         ReporterPreferences getPreferences() const override;
6118
6119         void noMatchingTestCases(std::string const& spec) override;
6120
6121         void assertionStarting(AssertionInfo const&) override;
6122
6123         bool assertionEnded(AssertionStats const& _assertionStats) override;
6124
6125         void sectionEnded(SectionStats const& _sectionStats) override;
6126
6127         void testRunEnded(TestRunStats const& _testRunStats) override;
6128
6129     };
6130
6131 } // end namespace Catch
6132
6133 // end catch_reporter_compact.h
6134 // start catch_reporter_console.h
6135
6136 #if defined(_MSC_VER)
6137 #pragma warning(push)
6138 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
6139                               // Note that 4062 (not all labels are handled
6140                               // and default is missing) is enabled
6141 #endif
6142
6143 namespace Catch {
6144     // Fwd decls
6145     struct SummaryColumn;
6146     class TablePrinter;
6147
6148     struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
6149         std::unique_ptr<TablePrinter> m_tablePrinter;
6150
6151         ConsoleReporter(ReporterConfig const& config);
6152         ~ConsoleReporter() override;
6153         static std::string getDescription();
6154
6155         void noMatchingTestCases(std::string const& spec) override;
6156
6157         void reportInvalidArguments(std::string const&arg) override;
6158
6159         void assertionStarting(AssertionInfo const&) override;
6160
6161         bool assertionEnded(AssertionStats const& _assertionStats) override;
6162
6163         void sectionStarting(SectionInfo const& _sectionInfo) override;
6164         void sectionEnded(SectionStats const& _sectionStats) override;
6165
6166 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6167         void benchmarkPreparing(std::string const& name) override;
6168         void benchmarkStarting(BenchmarkInfo const& info) override;
6169         void benchmarkEnded(BenchmarkStats<> const& stats) override;
6170         void benchmarkFailed(std::string const& error) override;
6171 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6172
6173         void testCaseEnded(TestCaseStats const& _testCaseStats) override;
6174         void testGroupEnded(TestGroupStats const& _testGroupStats) override;
6175         void testRunEnded(TestRunStats const& _testRunStats) override;
6176         void testRunStarting(TestRunInfo const& _testRunInfo) override;
6177     private:
6178
6179         void lazyPrint();
6180
6181         void lazyPrintWithoutClosingBenchmarkTable();
6182         void lazyPrintRunInfo();
6183         void lazyPrintGroupInfo();
6184         void printTestCaseAndSectionHeader();
6185
6186         void printClosedHeader(std::string const& _name);
6187         void printOpenHeader(std::string const& _name);
6188
6189         // if string has a : in first line will set indent to follow it on
6190         // subsequent lines
6191         void printHeaderString(std::string const& _string, std::size_t indent = 0);
6192
6193         void printTotals(Totals const& totals);
6194         void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
6195
6196         void printTotalsDivider(Totals const& totals);
6197         void printSummaryDivider();
6198         void printTestFilters();
6199
6200     private:
6201         bool m_headerPrinted = false;
6202     };
6203
6204 } // end namespace Catch
6205
6206 #if defined(_MSC_VER)
6207 #pragma warning(pop)
6208 #endif
6209
6210 // end catch_reporter_console.h
6211 // start catch_reporter_junit.h
6212
6213 // start catch_xmlwriter.h
6214
6215 #include <vector>
6216
6217 namespace Catch {
6218     enum class XmlFormatting {
6219         None = 0x00,
6220         Indent = 0x01,
6221         Newline = 0x02,
6222     };
6223
6224     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
6225     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
6226
6227     class XmlEncode {
6228     public:
6229         enum ForWhat { ForTextNodes, ForAttributes };
6230
6231         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
6232
6233         void encodeTo( std::ostream& os ) const;
6234
6235         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
6236
6237     private:
6238         std::string m_str;
6239         ForWhat m_forWhat;
6240     };
6241
6242     class XmlWriter {
6243     public:
6244
6245         class ScopedElement {
6246         public:
6247             ScopedElement( XmlWriter* writer, XmlFormatting fmt );
6248
6249             ScopedElement( ScopedElement&& other ) noexcept;
6250             ScopedElement& operator=( ScopedElement&& other ) noexcept;
6251
6252             ~ScopedElement();
6253
6254             ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
6255
6256             template<typename T>
6257             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
6258                 m_writer->writeAttribute( name, attribute );
6259                 return *this;
6260             }
6261
6262         private:
6263             mutable XmlWriter* m_writer = nullptr;
6264             XmlFormatting m_fmt;
6265         };
6266
6267         XmlWriter( std::ostream& os = Catch::cout() );
6268         ~XmlWriter();
6269
6270         XmlWriter( XmlWriter const& ) = delete;
6271         XmlWriter& operator=( XmlWriter const& ) = delete;
6272
6273         XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6274
6275         ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6276
6277         XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6278
6279         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
6280
6281         XmlWriter& writeAttribute( std::string const& name, bool attribute );
6282
6283         template<typename T>
6284         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
6285             ReusableStringStream rss;
6286             rss << attribute;
6287             return writeAttribute( name, rss.str() );
6288         }
6289
6290         XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6291
6292         XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6293
6294         void writeStylesheetRef( std::string const& url );
6295
6296         XmlWriter& writeBlankLine();
6297
6298         void ensureTagClosed();
6299
6300     private:
6301
6302         void applyFormatting(XmlFormatting fmt);
6303
6304         void writeDeclaration();
6305
6306         void newlineIfNecessary();
6307
6308         bool m_tagIsOpen = false;
6309         bool m_needsNewline = false;
6310         std::vector<std::string> m_tags;
6311         std::string m_indent;
6312         std::ostream& m_os;
6313     };
6314
6315 }
6316
6317 // end catch_xmlwriter.h
6318 namespace Catch {
6319
6320     class JunitReporter : public CumulativeReporterBase<JunitReporter> {
6321     public:
6322         JunitReporter(ReporterConfig const& _config);
6323
6324         ~JunitReporter() override;
6325
6326         static std::string getDescription();
6327
6328         void noMatchingTestCases(std::string const& /*spec*/) override;
6329
6330         void testRunStarting(TestRunInfo const& runInfo) override;
6331
6332         void testGroupStarting(GroupInfo const& groupInfo) override;
6333
6334         void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
6335         bool assertionEnded(AssertionStats const& assertionStats) override;
6336
6337         void testCaseEnded(TestCaseStats const& testCaseStats) override;
6338
6339         void testGroupEnded(TestGroupStats const& testGroupStats) override;
6340
6341         void testRunEndedCumulative() override;
6342
6343         void writeGroup(TestGroupNode const& groupNode, double suiteTime);
6344
6345         void writeTestCase(TestCaseNode const& testCaseNode);
6346
6347         void writeSection(std::string const& className,
6348                           std::string const& rootName,
6349                           SectionNode const& sectionNode);
6350
6351         void writeAssertions(SectionNode const& sectionNode);
6352         void writeAssertion(AssertionStats const& stats);
6353
6354         XmlWriter xml;
6355         Timer suiteTimer;
6356         std::string stdOutForSuite;
6357         std::string stdErrForSuite;
6358         unsigned int unexpectedExceptions = 0;
6359         bool m_okToFail = false;
6360     };
6361
6362 } // end namespace Catch
6363
6364 // end catch_reporter_junit.h
6365 // start catch_reporter_xml.h
6366
6367 namespace Catch {
6368     class XmlReporter : public StreamingReporterBase<XmlReporter> {
6369     public:
6370         XmlReporter(ReporterConfig const& _config);
6371
6372         ~XmlReporter() override;
6373
6374         static std::string getDescription();
6375
6376         virtual std::string getStylesheetRef() const;
6377
6378         void writeSourceInfo(SourceLineInfo const& sourceInfo);
6379
6380     public: // StreamingReporterBase
6381
6382         void noMatchingTestCases(std::string const& s) override;
6383
6384         void testRunStarting(TestRunInfo const& testInfo) override;
6385
6386         void testGroupStarting(GroupInfo const& groupInfo) override;
6387
6388         void testCaseStarting(TestCaseInfo const& testInfo) override;
6389
6390         void sectionStarting(SectionInfo const& sectionInfo) override;
6391
6392         void assertionStarting(AssertionInfo const&) override;
6393
6394         bool assertionEnded(AssertionStats const& assertionStats) override;
6395
6396         void sectionEnded(SectionStats const& sectionStats) override;
6397
6398         void testCaseEnded(TestCaseStats const& testCaseStats) override;
6399
6400         void testGroupEnded(TestGroupStats const& testGroupStats) override;
6401
6402         void testRunEnded(TestRunStats const& testRunStats) override;
6403
6404 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6405         void benchmarkPreparing(std::string const& name) override;
6406         void benchmarkStarting(BenchmarkInfo const&) override;
6407         void benchmarkEnded(BenchmarkStats<> const&) override;
6408         void benchmarkFailed(std::string const&) override;
6409 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6410
6411     private:
6412         Timer m_testCaseTimer;
6413         XmlWriter m_xml;
6414         int m_sectionDepth = 0;
6415     };
6416
6417 } // end namespace Catch
6418
6419 // end catch_reporter_xml.h
6420
6421 // end catch_external_interfaces.h
6422 #endif
6423
6424 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6425 // start catch_benchmarking_all.hpp
6426
6427 // A proxy header that includes all of the benchmarking headers to allow
6428 // concise include of the benchmarking features. You should prefer the
6429 // individual includes in standard use.
6430
6431 // start catch_benchmark.hpp
6432
6433  // Benchmark
6434
6435 // start catch_chronometer.hpp
6436
6437 // User-facing chronometer
6438
6439
6440 // start catch_clock.hpp
6441
6442 // Clocks
6443
6444
6445 #include <chrono>
6446 #include <ratio>
6447
6448 namespace Catch {
6449     namespace Benchmark {
6450         template <typename Clock>
6451         using ClockDuration = typename Clock::duration;
6452         template <typename Clock>
6453         using FloatDuration = std::chrono::duration<double, typename Clock::period>;
6454
6455         template <typename Clock>
6456         using TimePoint = typename Clock::time_point;
6457
6458         using default_clock = std::chrono::steady_clock;
6459
6460         template <typename Clock>
6461         struct now {
6462             TimePoint<Clock> operator()() const {
6463                 return Clock::now();
6464             }
6465         };
6466
6467         using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
6468     } // namespace Benchmark
6469 } // namespace Catch
6470
6471 // end catch_clock.hpp
6472 // start catch_optimizer.hpp
6473
6474  // Hinting the optimizer
6475
6476
6477 #if defined(_MSC_VER)
6478 #   include <atomic> // atomic_thread_fence
6479 #endif
6480
6481 namespace Catch {
6482     namespace Benchmark {
6483 #if defined(__GNUC__) || defined(__clang__)
6484         template <typename T>
6485         inline void keep_memory(T* p) {
6486             asm volatile("" : : "g"(p) : "memory");
6487         }
6488         inline void keep_memory() {
6489             asm volatile("" : : : "memory");
6490         }
6491
6492         namespace Detail {
6493             inline void optimizer_barrier() { keep_memory(); }
6494         } // namespace Detail
6495 #elif defined(_MSC_VER)
6496
6497 #pragma optimize("", off)
6498         template <typename T>
6499         inline void keep_memory(T* p) {
6500             // thanks @milleniumbug
6501             *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
6502         }
6503         // TODO equivalent keep_memory()
6504 #pragma optimize("", on)
6505
6506         namespace Detail {
6507             inline void optimizer_barrier() {
6508                 std::atomic_thread_fence(std::memory_order_seq_cst);
6509             }
6510         } // namespace Detail
6511
6512 #endif
6513
6514         template <typename T>
6515         inline void deoptimize_value(T&& x) {
6516             keep_memory(&x);
6517         }
6518
6519         template <typename Fn, typename... Args>
6520         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
6521             deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
6522         }
6523
6524         template <typename Fn, typename... Args>
6525         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
6526             std::forward<Fn>(fn) (std::forward<Args...>(args...));
6527         }
6528     } // namespace Benchmark
6529 } // namespace Catch
6530
6531 // end catch_optimizer.hpp
6532 // start catch_complete_invoke.hpp
6533
6534 // Invoke with a special case for void
6535
6536
6537 #include <type_traits>
6538 #include <utility>
6539
6540 namespace Catch {
6541     namespace Benchmark {
6542         namespace Detail {
6543             template <typename T>
6544             struct CompleteType { using type = T; };
6545             template <>
6546             struct CompleteType<void> { struct type {}; };
6547
6548             template <typename T>
6549             using CompleteType_t = typename CompleteType<T>::type;
6550
6551             template <typename Result>
6552             struct CompleteInvoker {
6553                 template <typename Fun, typename... Args>
6554                 static Result invoke(Fun&& fun, Args&&... args) {
6555                     return std::forward<Fun>(fun)(std::forward<Args>(args)...);
6556                 }
6557             };
6558             template <>
6559             struct CompleteInvoker<void> {
6560                 template <typename Fun, typename... Args>
6561                 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
6562                     std::forward<Fun>(fun)(std::forward<Args>(args)...);
6563                     return {};
6564                 }
6565             };
6566
6567             // invoke and not return void :(
6568             template <typename Fun, typename... Args>
6569             CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
6570                 return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
6571             }
6572
6573             const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
6574         } // namespace Detail
6575
6576         template <typename Fun>
6577         Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
6578             CATCH_TRY{
6579                 return Detail::complete_invoke(std::forward<Fun>(fun));
6580             } CATCH_CATCH_ALL{
6581                 getResultCapture().benchmarkFailed(translateActiveException());
6582                 CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
6583             }
6584         }
6585     } // namespace Benchmark
6586 } // namespace Catch
6587
6588 // end catch_complete_invoke.hpp
6589 namespace Catch {
6590     namespace Benchmark {
6591         namespace Detail {
6592             struct ChronometerConcept {
6593                 virtual void start() = 0;
6594                 virtual void finish() = 0;
6595                 virtual ~ChronometerConcept() = default;
6596             };
6597             template <typename Clock>
6598             struct ChronometerModel final : public ChronometerConcept {
6599                 void start() override { started = Clock::now(); }
6600                 void finish() override { finished = Clock::now(); }
6601
6602                 ClockDuration<Clock> elapsed() const { return finished - started; }
6603
6604                 TimePoint<Clock> started;
6605                 TimePoint<Clock> finished;
6606             };
6607         } // namespace Detail
6608
6609         struct Chronometer {
6610         public:
6611             template <typename Fun>
6612             void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
6613
6614             int runs() const { return k; }
6615
6616             Chronometer(Detail::ChronometerConcept& meter, int k)
6617                 : impl(&meter)
6618                 , k(k) {}
6619
6620         private:
6621             template <typename Fun>
6622             void measure(Fun&& fun, std::false_type) {
6623                 measure([&fun](int) { return fun(); }, std::true_type());
6624             }
6625
6626             template <typename Fun>
6627             void measure(Fun&& fun, std::true_type) {
6628                 Detail::optimizer_barrier();
6629                 impl->start();
6630                 for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
6631                 impl->finish();
6632                 Detail::optimizer_barrier();
6633             }
6634
6635             Detail::ChronometerConcept* impl;
6636             int k;
6637         };
6638     } // namespace Benchmark
6639 } // namespace Catch
6640
6641 // end catch_chronometer.hpp
6642 // start catch_environment.hpp
6643
6644 // Environment information
6645
6646
6647 namespace Catch {
6648     namespace Benchmark {
6649         template <typename Duration>
6650         struct EnvironmentEstimate {
6651             Duration mean;
6652             OutlierClassification outliers;
6653
6654             template <typename Duration2>
6655             operator EnvironmentEstimate<Duration2>() const {
6656                 return { mean, outliers };
6657             }
6658         };
6659         template <typename Clock>
6660         struct Environment {
6661             using clock_type = Clock;
6662             EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
6663             EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
6664         };
6665     } // namespace Benchmark
6666 } // namespace Catch
6667
6668 // end catch_environment.hpp
6669 // start catch_execution_plan.hpp
6670
6671  // Execution plan
6672
6673
6674 // start catch_benchmark_function.hpp
6675
6676  // Dumb std::function implementation for consistent call overhead
6677
6678
6679 #include <cassert>
6680 #include <type_traits>
6681 #include <utility>
6682 #include <memory>
6683
6684 namespace Catch {
6685     namespace Benchmark {
6686         namespace Detail {
6687             template <typename T>
6688             using Decay = typename std::decay<T>::type;
6689             template <typename T, typename U>
6690             struct is_related
6691                 : std::is_same<Decay<T>, Decay<U>> {};
6692
6693             /// We need to reinvent std::function because every piece of code that might add overhead
6694             /// in a measurement context needs to have consistent performance characteristics so that we
6695             /// can account for it in the measurement.
6696             /// Implementations of std::function with optimizations that aren't always applicable, like
6697             /// small buffer optimizations, are not uncommon.
6698             /// This is effectively an implementation of std::function without any such optimizations;
6699             /// it may be slow, but it is consistently slow.
6700             struct BenchmarkFunction {
6701             private:
6702                 struct callable {
6703                     virtual void call(Chronometer meter) const = 0;
6704                     virtual callable* clone() const = 0;
6705                     virtual ~callable() = default;
6706                 };
6707                 template <typename Fun>
6708                 struct model : public callable {
6709                     model(Fun&& fun) : fun(std::move(fun)) {}
6710                     model(Fun const& fun) : fun(fun) {}
6711
6712                     model<Fun>* clone() const override { return new model<Fun>(*this); }
6713
6714                     void call(Chronometer meter) const override {
6715                         call(meter, is_callable<Fun(Chronometer)>());
6716                     }
6717                     void call(Chronometer meter, std::true_type) const {
6718                         fun(meter);
6719                     }
6720                     void call(Chronometer meter, std::false_type) const {
6721                         meter.measure(fun);
6722                     }
6723
6724                     Fun fun;
6725                 };
6726
6727                 struct do_nothing { void operator()() const {} };
6728
6729                 template <typename T>
6730                 BenchmarkFunction(model<T>* c) : f(c) {}
6731
6732             public:
6733                 BenchmarkFunction()
6734                     : f(new model<do_nothing>{ {} }) {}
6735
6736                 template <typename Fun,
6737                     typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
6738                     BenchmarkFunction(Fun&& fun)
6739                     : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
6740
6741                 BenchmarkFunction(BenchmarkFunction&& that)
6742                     : f(std::move(that.f)) {}
6743
6744                 BenchmarkFunction(BenchmarkFunction const& that)
6745                     : f(that.f->clone()) {}
6746
6747                 BenchmarkFunction& operator=(BenchmarkFunction&& that) {
6748                     f = std::move(that.f);
6749                     return *this;
6750                 }
6751
6752                 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
6753                     f.reset(that.f->clone());
6754                     return *this;
6755                 }
6756
6757                 void operator()(Chronometer meter) const { f->call(meter); }
6758
6759             private:
6760                 std::unique_ptr<callable> f;
6761             };
6762         } // namespace Detail
6763     } // namespace Benchmark
6764 } // namespace Catch
6765
6766 // end catch_benchmark_function.hpp
6767 // start catch_repeat.hpp
6768
6769 // repeat algorithm
6770
6771
6772 #include <type_traits>
6773 #include <utility>
6774
6775 namespace Catch {
6776     namespace Benchmark {
6777         namespace Detail {
6778             template <typename Fun>
6779             struct repeater {
6780                 void operator()(int k) const {
6781                     for (int i = 0; i < k; ++i) {
6782                         fun();
6783                     }
6784                 }
6785                 Fun fun;
6786             };
6787             template <typename Fun>
6788             repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
6789                 return { std::forward<Fun>(fun) };
6790             }
6791         } // namespace Detail
6792     } // namespace Benchmark
6793 } // namespace Catch
6794
6795 // end catch_repeat.hpp
6796 // start catch_run_for_at_least.hpp
6797
6798 // Run a function for a minimum amount of time
6799
6800
6801 // start catch_measure.hpp
6802
6803 // Measure
6804
6805
6806 // start catch_timing.hpp
6807
6808 // Timing
6809
6810
6811 #include <tuple>
6812 #include <type_traits>
6813
6814 namespace Catch {
6815     namespace Benchmark {
6816         template <typename Duration, typename Result>
6817         struct Timing {
6818             Duration elapsed;
6819             Result result;
6820             int iterations;
6821         };
6822         template <typename Clock, typename Func, typename... Args>
6823         using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
6824     } // namespace Benchmark
6825 } // namespace Catch
6826
6827 // end catch_timing.hpp
6828 #include <utility>
6829
6830 namespace Catch {
6831     namespace Benchmark {
6832         namespace Detail {
6833             template <typename Clock, typename Fun, typename... Args>
6834             TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
6835                 auto start = Clock::now();
6836                 auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
6837                 auto end = Clock::now();
6838                 auto delta = end - start;
6839                 return { delta, std::forward<decltype(r)>(r), 1 };
6840             }
6841         } // namespace Detail
6842     } // namespace Benchmark
6843 } // namespace Catch
6844
6845 // end catch_measure.hpp
6846 #include <utility>
6847 #include <type_traits>
6848
6849 namespace Catch {
6850     namespace Benchmark {
6851         namespace Detail {
6852             template <typename Clock, typename Fun>
6853             TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
6854                 return Detail::measure<Clock>(fun, iters);
6855             }
6856             template <typename Clock, typename Fun>
6857             TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
6858                 Detail::ChronometerModel<Clock> meter;
6859                 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
6860
6861                 return { meter.elapsed(), std::move(result), iters };
6862             }
6863
6864             template <typename Clock, typename Fun>
6865             using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
6866
6867             struct optimized_away_error : std::exception {
6868                 const char* what() const noexcept override {
6869                     return "could not measure benchmark, maybe it was optimized away";
6870                 }
6871             };
6872
6873             template <typename Clock, typename Fun>
6874             TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
6875                 auto iters = seed;
6876                 while (iters < (1 << 30)) {
6877                     auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
6878
6879                     if (Timing.elapsed >= how_long) {
6880                         return { Timing.elapsed, std::move(Timing.result), iters };
6881                     }
6882                     iters *= 2;
6883                 }
6884                 throw optimized_away_error{};
6885             }
6886         } // namespace Detail
6887     } // namespace Benchmark
6888 } // namespace Catch
6889
6890 // end catch_run_for_at_least.hpp
6891 #include <algorithm>
6892
6893 namespace Catch {
6894     namespace Benchmark {
6895         template <typename Duration>
6896         struct ExecutionPlan {
6897             int iterations_per_sample;
6898             Duration estimated_duration;
6899             Detail::BenchmarkFunction benchmark;
6900             Duration warmup_time;
6901             int warmup_iterations;
6902
6903             template <typename Duration2>
6904             operator ExecutionPlan<Duration2>() const {
6905                 return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
6906             }
6907
6908             template <typename Clock>
6909             std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
6910                 // warmup a bit
6911                 Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
6912
6913                 std::vector<FloatDuration<Clock>> times;
6914                 times.reserve(cfg.benchmarkSamples());
6915                 std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
6916                     Detail::ChronometerModel<Clock> model;
6917                     this->benchmark(Chronometer(model, iterations_per_sample));
6918                     auto sample_time = model.elapsed() - env.clock_cost.mean;
6919                     if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
6920                     return sample_time / iterations_per_sample;
6921                 });
6922                 return times;
6923             }
6924         };
6925     } // namespace Benchmark
6926 } // namespace Catch
6927
6928 // end catch_execution_plan.hpp
6929 // start catch_estimate_clock.hpp
6930
6931  // Environment measurement
6932
6933
6934 // start catch_stats.hpp
6935
6936 // Statistical analysis tools
6937
6938
6939 #include <algorithm>
6940 #include <functional>
6941 #include <vector>
6942 #include <iterator>
6943 #include <numeric>
6944 #include <tuple>
6945 #include <cmath>
6946 #include <utility>
6947 #include <cstddef>
6948 #include <random>
6949
6950 namespace Catch {
6951     namespace Benchmark {
6952         namespace Detail {
6953             using sample = std::vector<double>;
6954
6955             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
6956
6957             template <typename Iterator>
6958             OutlierClassification classify_outliers(Iterator first, Iterator last) {
6959                 std::vector<double> copy(first, last);
6960
6961                 auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
6962                 auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
6963                 auto iqr = q3 - q1;
6964                 auto los = q1 - (iqr * 3.);
6965                 auto lom = q1 - (iqr * 1.5);
6966                 auto him = q3 + (iqr * 1.5);
6967                 auto his = q3 + (iqr * 3.);
6968
6969                 OutlierClassification o;
6970                 for (; first != last; ++first) {
6971                     auto&& t = *first;
6972                     if (t < los) ++o.low_severe;
6973                     else if (t < lom) ++o.low_mild;
6974                     else if (t > his) ++o.high_severe;
6975                     else if (t > him) ++o.high_mild;
6976                     ++o.samples_seen;
6977                 }
6978                 return o;
6979             }
6980
6981             template <typename Iterator>
6982             double mean(Iterator first, Iterator last) {
6983                 auto count = last - first;
6984                 double sum = std::accumulate(first, last, 0.);
6985                 return sum / count;
6986             }
6987
6988             template <typename URng, typename Iterator, typename Estimator>
6989             sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
6990                 auto n = last - first;
6991                 std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
6992
6993                 sample out;
6994                 out.reserve(resamples);
6995                 std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
6996                     std::vector<double> resampled;
6997                     resampled.reserve(n);
6998                     std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
6999                     return estimator(resampled.begin(), resampled.end());
7000                 });
7001                 std::sort(out.begin(), out.end());
7002                 return out;
7003             }
7004
7005             template <typename Estimator, typename Iterator>
7006             sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
7007                 auto n = last - first;
7008                 auto second = std::next(first);
7009                 sample results;
7010                 results.reserve(n);
7011
7012                 for (auto it = first; it != last; ++it) {
7013                     std::iter_swap(it, first);
7014                     results.push_back(estimator(second, last));
7015                 }
7016
7017                 return results;
7018             }
7019
7020             inline double normal_cdf(double x) {
7021                 return std::erfc(-x / std::sqrt(2.0)) / 2.0;
7022             }
7023
7024             double erfc_inv(double x);
7025
7026             double normal_quantile(double p);
7027
7028             template <typename Iterator, typename Estimator>
7029             Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
7030                 auto n_samples = last - first;
7031
7032                 double point = estimator(first, last);
7033                 // Degenerate case with a single sample
7034                 if (n_samples == 1) return { point, point, point, confidence_level };
7035
7036                 sample jack = jackknife(estimator, first, last);
7037                 double jack_mean = mean(jack.begin(), jack.end());
7038                 double sum_squares, sum_cubes;
7039                 std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
7040                     auto d = jack_mean - x;
7041                     auto d2 = d * d;
7042                     auto d3 = d2 * d;
7043                     return { sqcb.first + d2, sqcb.second + d3 };
7044                 });
7045
7046                 double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
7047                 int n = static_cast<int>(resample.size());
7048                 double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
7049                 // degenerate case with uniform samples
7050                 if (prob_n == 0) return { point, point, point, confidence_level };
7051
7052                 double bias = normal_quantile(prob_n);
7053                 double z1 = normal_quantile((1. - confidence_level) / 2.);
7054
7055                 auto cumn = [n](double x) -> int {
7056                     return std::lround(normal_cdf(x) * n); };
7057                 auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
7058                 double b1 = bias + z1;
7059                 double b2 = bias - z1;
7060                 double a1 = a(b1);
7061                 double a2 = a(b2);
7062                 auto lo = std::max(cumn(a1), 0);
7063                 auto hi = std::min(cumn(a2), n - 1);
7064
7065                 return { point, resample[lo], resample[hi], confidence_level };
7066             }
7067
7068             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
7069
7070             struct bootstrap_analysis {
7071                 Estimate<double> mean;
7072                 Estimate<double> standard_deviation;
7073                 double outlier_variance;
7074             };
7075
7076             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
7077         } // namespace Detail
7078     } // namespace Benchmark
7079 } // namespace Catch
7080
7081 // end catch_stats.hpp
7082 #include <algorithm>
7083 #include <iterator>
7084 #include <tuple>
7085 #include <vector>
7086 #include <cmath>
7087
7088 namespace Catch {
7089     namespace Benchmark {
7090         namespace Detail {
7091             template <typename Clock>
7092             std::vector<double> resolution(int k) {
7093                 std::vector<TimePoint<Clock>> times;
7094                 times.reserve(k + 1);
7095                 std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
7096
7097                 std::vector<double> deltas;
7098                 deltas.reserve(k);
7099                 std::transform(std::next(times.begin()), times.end(), times.begin(),
7100                     std::back_inserter(deltas),
7101                     [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
7102
7103                 return deltas;
7104             }
7105
7106             const auto warmup_iterations = 10000;
7107             const auto warmup_time = std::chrono::milliseconds(100);
7108             const auto minimum_ticks = 1000;
7109             const auto warmup_seed = 10000;
7110             const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
7111             const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
7112             const auto clock_cost_estimation_tick_limit = 100000;
7113             const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
7114             const auto clock_cost_estimation_iterations = 10000;
7115
7116             template <typename Clock>
7117             int warmup() {
7118                 return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
7119                     .iterations;
7120             }
7121             template <typename Clock>
7122             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
7123                 auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
7124                     .result;
7125                 return {
7126                     FloatDuration<Clock>(mean(r.begin(), r.end())),
7127                     classify_outliers(r.begin(), r.end()),
7128                 };
7129             }
7130             template <typename Clock>
7131             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
7132                 auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
7133                 auto time_clock = [](int k) {
7134                     return Detail::measure<Clock>([k] {
7135                         for (int i = 0; i < k; ++i) {
7136                             volatile auto ignored = Clock::now();
7137                             (void)ignored;
7138                         }
7139                     }).elapsed;
7140                 };
7141                 time_clock(1);
7142                 int iters = clock_cost_estimation_iterations;
7143                 auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
7144                 std::vector<double> times;
7145                 int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
7146                 times.reserve(nsamples);
7147                 std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
7148                     return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
7149                 });
7150                 return {
7151                     FloatDuration<Clock>(mean(times.begin(), times.end())),
7152                     classify_outliers(times.begin(), times.end()),
7153                 };
7154             }
7155
7156             template <typename Clock>
7157             Environment<FloatDuration<Clock>> measure_environment() {
7158                 static Environment<FloatDuration<Clock>>* env = nullptr;
7159                 if (env) {
7160                     return *env;
7161                 }
7162
7163                 auto iters = Detail::warmup<Clock>();
7164                 auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
7165                 auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
7166
7167                 env = new Environment<FloatDuration<Clock>>{ resolution, cost };
7168                 return *env;
7169             }
7170         } // namespace Detail
7171     } // namespace Benchmark
7172 } // namespace Catch
7173
7174 // end catch_estimate_clock.hpp
7175 // start catch_analyse.hpp
7176
7177  // Run and analyse one benchmark
7178
7179
7180 // start catch_sample_analysis.hpp
7181
7182 // Benchmark results
7183
7184
7185 #include <algorithm>
7186 #include <vector>
7187 #include <string>
7188 #include <iterator>
7189
7190 namespace Catch {
7191     namespace Benchmark {
7192         template <typename Duration>
7193         struct SampleAnalysis {
7194             std::vector<Duration> samples;
7195             Estimate<Duration> mean;
7196             Estimate<Duration> standard_deviation;
7197             OutlierClassification outliers;
7198             double outlier_variance;
7199
7200             template <typename Duration2>
7201             operator SampleAnalysis<Duration2>() const {
7202                 std::vector<Duration2> samples2;
7203                 samples2.reserve(samples.size());
7204                 std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
7205                 return {
7206                     std::move(samples2),
7207                     mean,
7208                     standard_deviation,
7209                     outliers,
7210                     outlier_variance,
7211                 };
7212             }
7213         };
7214     } // namespace Benchmark
7215 } // namespace Catch
7216
7217 // end catch_sample_analysis.hpp
7218 #include <algorithm>
7219 #include <iterator>
7220 #include <vector>
7221
7222 namespace Catch {
7223     namespace Benchmark {
7224         namespace Detail {
7225             template <typename Duration, typename Iterator>
7226             SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
7227                 if (!cfg.benchmarkNoAnalysis()) {
7228                     std::vector<double> samples;
7229                     samples.reserve(last - first);
7230                     std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
7231
7232                     auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
7233                     auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
7234
7235                     auto wrap_estimate = [](Estimate<double> e) {
7236                         return Estimate<Duration> {
7237                             Duration(e.point),
7238                                 Duration(e.lower_bound),
7239                                 Duration(e.upper_bound),
7240                                 e.confidence_interval,
7241                         };
7242                     };
7243                     std::vector<Duration> samples2;
7244                     samples2.reserve(samples.size());
7245                     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
7246                     return {
7247                         std::move(samples2),
7248                         wrap_estimate(analysis.mean),
7249                         wrap_estimate(analysis.standard_deviation),
7250                         outliers,
7251                         analysis.outlier_variance,
7252                     };
7253                 } else {
7254                     std::vector<Duration> samples;
7255                     samples.reserve(last - first);
7256
7257                     Duration mean = Duration(0);
7258                     int i = 0;
7259                     for (auto it = first; it < last; ++it, ++i) {
7260                         samples.push_back(Duration(*it));
7261                         mean += Duration(*it);
7262                     }
7263                     mean /= i;
7264
7265                     return {
7266                         std::move(samples),
7267                         Estimate<Duration>{mean, mean, mean, 0.0},
7268                         Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
7269                         OutlierClassification{},
7270                         0.0
7271                     };
7272                 }
7273             }
7274         } // namespace Detail
7275     } // namespace Benchmark
7276 } // namespace Catch
7277
7278 // end catch_analyse.hpp
7279 #include <algorithm>
7280 #include <functional>
7281 #include <string>
7282 #include <vector>
7283 #include <cmath>
7284
7285 namespace Catch {
7286     namespace Benchmark {
7287         struct Benchmark {
7288             Benchmark(std::string &&name)
7289                 : name(std::move(name)) {}
7290
7291             template <class FUN>
7292             Benchmark(std::string &&name, FUN &&func)
7293                 : fun(std::move(func)), name(std::move(name)) {}
7294
7295             template <typename Clock>
7296             ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
7297                 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
7298                 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
7299                 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
7300                 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
7301                 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
7302             }
7303
7304             template <typename Clock = default_clock>
7305             void run() {
7306                 IConfigPtr cfg = getCurrentContext().getConfig();
7307
7308                 auto env = Detail::measure_environment<Clock>();
7309
7310                 getResultCapture().benchmarkPreparing(name);
7311                 CATCH_TRY{
7312                     auto plan = user_code([&] {
7313                         return prepare<Clock>(*cfg, env);
7314                     });
7315
7316                     BenchmarkInfo info {
7317                         name,
7318                         plan.estimated_duration.count(),
7319                         plan.iterations_per_sample,
7320                         cfg->benchmarkSamples(),
7321                         cfg->benchmarkResamples(),
7322                         env.clock_resolution.mean.count(),
7323                         env.clock_cost.mean.count()
7324                     };
7325
7326                     getResultCapture().benchmarkStarting(info);
7327
7328                     auto samples = user_code([&] {
7329                         return plan.template run<Clock>(*cfg, env);
7330                     });
7331
7332                     auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
7333                     BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
7334                     getResultCapture().benchmarkEnded(stats);
7335
7336                 } CATCH_CATCH_ALL{
7337                     if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
7338                         std::rethrow_exception(std::current_exception());
7339                 }
7340             }
7341
7342             // sets lambda to be used in fun *and* executes benchmark!
7343             template <typename Fun,
7344                 typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
7345                 Benchmark & operator=(Fun func) {
7346                 fun = Detail::BenchmarkFunction(func);
7347                 run();
7348                 return *this;
7349             }
7350
7351             explicit operator bool() {
7352                 return true;
7353             }
7354
7355         private:
7356             Detail::BenchmarkFunction fun;
7357             std::string name;
7358         };
7359     }
7360 } // namespace Catch
7361
7362 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
7363 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
7364
7365 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
7366     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7367         BenchmarkName = [&](int benchmarkIndex)
7368
7369 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
7370     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7371         BenchmarkName = [&]
7372
7373 // end catch_benchmark.hpp
7374 // start catch_constructor.hpp
7375
7376 // Constructor and destructor helpers
7377
7378
7379 #include <type_traits>
7380
7381 namespace Catch {
7382     namespace Benchmark {
7383         namespace Detail {
7384             template <typename T, bool Destruct>
7385             struct ObjectStorage
7386             {
7387                 using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
7388
7389                 ObjectStorage() : data() {}
7390
7391                 ObjectStorage(const ObjectStorage& other)
7392                 {
7393                     new(&data) T(other.stored_object());
7394                 }
7395
7396                 ObjectStorage(ObjectStorage&& other)
7397                 {
7398                     new(&data) T(std::move(other.stored_object()));
7399                 }
7400
7401                 ~ObjectStorage() { destruct_on_exit<T>(); }
7402
7403                 template <typename... Args>
7404                 void construct(Args&&... args)
7405                 {
7406                     new (&data) T(std::forward<Args>(args)...);
7407                 }
7408
7409                 template <bool AllowManualDestruction = !Destruct>
7410                 typename std::enable_if<AllowManualDestruction>::type destruct()
7411                 {
7412                     stored_object().~T();
7413                 }
7414
7415             private:
7416                 // If this is a constructor benchmark, destruct the underlying object
7417                 template <typename U>
7418                 void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
7419                 // Otherwise, don't
7420                 template <typename U>
7421                 void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
7422
7423                 T& stored_object() {
7424                     return *static_cast<T*>(static_cast<void*>(&data));
7425                 }
7426
7427                 T const& stored_object() const {
7428                     return *static_cast<T*>(static_cast<void*>(&data));
7429                 }
7430
7431                 TStorage data;
7432             };
7433         }
7434
7435         template <typename T>
7436         using storage_for = Detail::ObjectStorage<T, true>;
7437
7438         template <typename T>
7439         using destructable_object = Detail::ObjectStorage<T, false>;
7440     }
7441 }
7442
7443 // end catch_constructor.hpp
7444 // end catch_benchmarking_all.hpp
7445 #endif
7446
7447 #endif // ! CATCH_CONFIG_IMPL_ONLY
7448
7449 #ifdef CATCH_IMPL
7450 // start catch_impl.hpp
7451
7452 #ifdef __clang__
7453 #pragma clang diagnostic push
7454 #pragma clang diagnostic ignored "-Wweak-vtables"
7455 #endif
7456
7457 // Keep these here for external reporters
7458 // start catch_test_case_tracker.h
7459
7460 #include <string>
7461 #include <vector>
7462 #include <memory>
7463
7464 namespace Catch {
7465 namespace TestCaseTracking {
7466
7467     struct NameAndLocation {
7468         std::string name;
7469         SourceLineInfo location;
7470
7471         NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
7472         friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
7473             return lhs.name == rhs.name
7474                 && lhs.location == rhs.location;
7475         }
7476     };
7477
7478     class ITracker;
7479
7480     using ITrackerPtr = std::shared_ptr<ITracker>;
7481
7482     class  ITracker {
7483         NameAndLocation m_nameAndLocation;
7484
7485     public:
7486         ITracker(NameAndLocation const& nameAndLoc) :
7487             m_nameAndLocation(nameAndLoc)
7488         {}
7489
7490         // static queries
7491         NameAndLocation const& nameAndLocation() const {
7492             return m_nameAndLocation;
7493         }
7494
7495         virtual ~ITracker();
7496
7497         // dynamic queries
7498         virtual bool isComplete() const = 0; // Successfully completed or failed
7499         virtual bool isSuccessfullyCompleted() const = 0;
7500         virtual bool isOpen() const = 0; // Started but not complete
7501         virtual bool hasChildren() const = 0;
7502
7503         virtual ITracker& parent() = 0;
7504
7505         // actions
7506         virtual void close() = 0; // Successfully complete
7507         virtual void fail() = 0;
7508         virtual void markAsNeedingAnotherRun() = 0;
7509
7510         virtual void addChild( ITrackerPtr const& child ) = 0;
7511         virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
7512         virtual void openChild() = 0;
7513
7514         // Debug/ checking
7515         virtual bool isSectionTracker() const = 0;
7516         virtual bool isGeneratorTracker() const = 0;
7517     };
7518
7519     class TrackerContext {
7520
7521         enum RunState {
7522             NotStarted,
7523             Executing,
7524             CompletedCycle
7525         };
7526
7527         ITrackerPtr m_rootTracker;
7528         ITracker* m_currentTracker = nullptr;
7529         RunState m_runState = NotStarted;
7530
7531     public:
7532
7533         ITracker& startRun();
7534         void endRun();
7535
7536         void startCycle();
7537         void completeCycle();
7538
7539         bool completedCycle() const;
7540         ITracker& currentTracker();
7541         void setCurrentTracker( ITracker* tracker );
7542     };
7543
7544     class TrackerBase : public ITracker {
7545     protected:
7546         enum CycleState {
7547             NotStarted,
7548             Executing,
7549             ExecutingChildren,
7550             NeedsAnotherRun,
7551             CompletedSuccessfully,
7552             Failed
7553         };
7554
7555         using Children = std::vector<ITrackerPtr>;
7556         TrackerContext& m_ctx;
7557         ITracker* m_parent;
7558         Children m_children;
7559         CycleState m_runState = NotStarted;
7560
7561     public:
7562         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7563
7564         bool isComplete() const override;
7565         bool isSuccessfullyCompleted() const override;
7566         bool isOpen() const override;
7567         bool hasChildren() const override;
7568
7569         void addChild( ITrackerPtr const& child ) override;
7570
7571         ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
7572         ITracker& parent() override;
7573
7574         void openChild() override;
7575
7576         bool isSectionTracker() const override;
7577         bool isGeneratorTracker() const override;
7578
7579         void open();
7580
7581         void close() override;
7582         void fail() override;
7583         void markAsNeedingAnotherRun() override;
7584
7585     private:
7586         void moveToParent();
7587         void moveToThis();
7588     };
7589
7590     class SectionTracker : public TrackerBase {
7591         std::vector<std::string> m_filters;
7592         std::string m_trimmed_name;
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     };
7607
7608 } // namespace TestCaseTracking
7609
7610 using TestCaseTracking::ITracker;
7611 using TestCaseTracking::TrackerContext;
7612 using TestCaseTracking::SectionTracker;
7613
7614 } // namespace Catch
7615
7616 // end catch_test_case_tracker.h
7617
7618 // start catch_leak_detector.h
7619
7620 namespace Catch {
7621
7622     struct LeakDetector {
7623         LeakDetector();
7624         ~LeakDetector();
7625     };
7626
7627 }
7628 // end catch_leak_detector.h
7629 // Cpp files will be included in the single-header file here
7630 // start catch_stats.cpp
7631
7632 // Statistical analysis tools
7633
7634 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
7635
7636 #include <cassert>
7637 #include <random>
7638
7639 #if defined(CATCH_CONFIG_USE_ASYNC)
7640 #include <future>
7641 #endif
7642
7643 namespace {
7644     double erf_inv(double x) {
7645         // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
7646         double w, p;
7647
7648         w = -log((1.0 - x) * (1.0 + x));
7649
7650         if (w < 6.250000) {
7651             w = w - 3.125000;
7652             p = -3.6444120640178196996e-21;
7653             p = -1.685059138182016589e-19 + p * w;
7654             p = 1.2858480715256400167e-18 + p * w;
7655             p = 1.115787767802518096e-17 + p * w;
7656             p = -1.333171662854620906e-16 + p * w;
7657             p = 2.0972767875968561637e-17 + p * w;
7658             p = 6.6376381343583238325e-15 + p * w;
7659             p = -4.0545662729752068639e-14 + p * w;
7660             p = -8.1519341976054721522e-14 + p * w;
7661             p = 2.6335093153082322977e-12 + p * w;
7662             p = -1.2975133253453532498e-11 + p * w;
7663             p = -5.4154120542946279317e-11 + p * w;
7664             p = 1.051212273321532285e-09 + p * w;
7665             p = -4.1126339803469836976e-09 + p * w;
7666             p = -2.9070369957882005086e-08 + p * w;
7667             p = 4.2347877827932403518e-07 + p * w;
7668             p = -1.3654692000834678645e-06 + p * w;
7669             p = -1.3882523362786468719e-05 + p * w;
7670             p = 0.0001867342080340571352 + p * w;
7671             p = -0.00074070253416626697512 + p * w;
7672             p = -0.0060336708714301490533 + p * w;
7673             p = 0.24015818242558961693 + p * w;
7674             p = 1.6536545626831027356 + p * w;
7675         } else if (w < 16.000000) {
7676             w = sqrt(w) - 3.250000;
7677             p = 2.2137376921775787049e-09;
7678             p = 9.0756561938885390979e-08 + p * w;
7679             p = -2.7517406297064545428e-07 + p * w;
7680             p = 1.8239629214389227755e-08 + p * w;
7681             p = 1.5027403968909827627e-06 + p * w;
7682             p = -4.013867526981545969e-06 + p * w;
7683             p = 2.9234449089955446044e-06 + p * w;
7684             p = 1.2475304481671778723e-05 + p * w;
7685             p = -4.7318229009055733981e-05 + p * w;
7686             p = 6.8284851459573175448e-05 + p * w;
7687             p = 2.4031110387097893999e-05 + p * w;
7688             p = -0.0003550375203628474796 + p * w;
7689             p = 0.00095328937973738049703 + p * w;
7690             p = -0.0016882755560235047313 + p * w;
7691             p = 0.0024914420961078508066 + p * w;
7692             p = -0.0037512085075692412107 + p * w;
7693             p = 0.005370914553590063617 + p * w;
7694             p = 1.0052589676941592334 + p * w;
7695             p = 3.0838856104922207635 + p * w;
7696         } else {
7697             w = sqrt(w) - 5.000000;
7698             p = -2.7109920616438573243e-11;
7699             p = -2.5556418169965252055e-10 + p * w;
7700             p = 1.5076572693500548083e-09 + p * w;
7701             p = -3.7894654401267369937e-09 + p * w;
7702             p = 7.6157012080783393804e-09 + p * w;
7703             p = -1.4960026627149240478e-08 + p * w;
7704             p = 2.9147953450901080826e-08 + p * w;
7705             p = -6.7711997758452339498e-08 + p * w;
7706             p = 2.2900482228026654717e-07 + p * w;
7707             p = -9.9298272942317002539e-07 + p * w;
7708             p = 4.5260625972231537039e-06 + p * w;
7709             p = -1.9681778105531670567e-05 + p * w;
7710             p = 7.5995277030017761139e-05 + p * w;
7711             p = -0.00021503011930044477347 + p * w;
7712             p = -0.00013871931833623122026 + p * w;
7713             p = 1.0103004648645343977 + p * w;
7714             p = 4.8499064014085844221 + p * w;
7715         }
7716         return p * x;
7717     }
7718
7719     double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
7720         auto m = Catch::Benchmark::Detail::mean(first, last);
7721         double variance = std::accumulate(first, last, 0., [m](double a, double b) {
7722             double diff = b - m;
7723             return a + diff * diff;
7724             }) / (last - first);
7725             return std::sqrt(variance);
7726     }
7727
7728 }
7729
7730 namespace Catch {
7731     namespace Benchmark {
7732         namespace Detail {
7733
7734             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7735                 auto count = last - first;
7736                 double idx = (count - 1) * k / static_cast<double>(q);
7737                 int j = static_cast<int>(idx);
7738                 double g = idx - j;
7739                 std::nth_element(first, first + j, last);
7740                 auto xj = first[j];
7741                 if (g == 0) return xj;
7742
7743                 auto xj1 = *std::min_element(first + (j + 1), last);
7744                 return xj + g * (xj1 - xj);
7745             }
7746
7747             double erfc_inv(double x) {
7748                 return erf_inv(1.0 - x);
7749             }
7750
7751             double normal_quantile(double p) {
7752                 static const double ROOT_TWO = std::sqrt(2.0);
7753
7754                 double result = 0.0;
7755                 assert(p >= 0 && p <= 1);
7756                 if (p < 0 || p > 1) {
7757                     return result;
7758                 }
7759
7760                 result = -erfc_inv(2.0 * p);
7761                 // result *= normal distribution standard deviation (1.0) * sqrt(2)
7762                 result *= /*sd * */ ROOT_TWO;
7763                 // result += normal disttribution mean (0)
7764                 return result;
7765             }
7766
7767             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
7768                 double sb = stddev.point;
7769                 double mn = mean.point / n;
7770                 double mg_min = mn / 2.;
7771                 double sg = std::min(mg_min / 4., sb / std::sqrt(n));
7772                 double sg2 = sg * sg;
7773                 double sb2 = sb * sb;
7774
7775                 auto c_max = [n, mn, sb2, sg2](double x) -> double {
7776                     double k = mn - x;
7777                     double d = k * k;
7778                     double nd = n * d;
7779                     double k0 = -n * nd;
7780                     double k1 = sb2 - n * sg2 + nd;
7781                     double det = k1 * k1 - 4 * sg2 * k0;
7782                     return (int)(-2. * k0 / (k1 + std::sqrt(det)));
7783                 };
7784
7785                 auto var_out = [n, sb2, sg2](double c) {
7786                     double nc = n - c;
7787                     return (nc / n) * (sb2 - nc * sg2);
7788                 };
7789
7790                 return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
7791             }
7792
7793             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7794                 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
7795                 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
7796                 static std::random_device entropy;
7797                 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
7798
7799                 auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
7800
7801                 auto mean = &Detail::mean<std::vector<double>::iterator>;
7802                 auto stddev = &standard_deviation;
7803
7804 #if defined(CATCH_CONFIG_USE_ASYNC)
7805                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7806                     auto seed = entropy();
7807                     return std::async(std::launch::async, [=] {
7808                         std::mt19937 rng(seed);
7809                         auto resampled = resample(rng, n_resamples, first, last, f);
7810                         return bootstrap(confidence_level, first, last, resampled, f);
7811                     });
7812                 };
7813
7814                 auto mean_future = Estimate(mean);
7815                 auto stddev_future = Estimate(stddev);
7816
7817                 auto mean_estimate = mean_future.get();
7818                 auto stddev_estimate = stddev_future.get();
7819 #else
7820                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7821                     auto seed = entropy();
7822                     std::mt19937 rng(seed);
7823                     auto resampled = resample(rng, n_resamples, first, last, f);
7824                     return bootstrap(confidence_level, first, last, resampled, f);
7825                 };
7826
7827                 auto mean_estimate = Estimate(mean);
7828                 auto stddev_estimate = Estimate(stddev);
7829 #endif // CATCH_USE_ASYNC
7830
7831                 double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
7832
7833                 return { mean_estimate, stddev_estimate, outlier_variance };
7834             }
7835         } // namespace Detail
7836     } // namespace Benchmark
7837 } // namespace Catch
7838
7839 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
7840 // end catch_stats.cpp
7841 // start catch_approx.cpp
7842
7843 #include <cmath>
7844 #include <limits>
7845
7846 namespace {
7847
7848 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
7849 // But without the subtraction to allow for INFINITY in comparison
7850 bool marginComparison(double lhs, double rhs, double margin) {
7851     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
7852 }
7853
7854 }
7855
7856 namespace Catch {
7857 namespace Detail {
7858
7859     Approx::Approx ( double value )
7860     :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
7861         m_margin( 0.0 ),
7862         m_scale( 0.0 ),
7863         m_value( value )
7864     {}
7865
7866     Approx Approx::custom() {
7867         return Approx( 0 );
7868     }
7869
7870     Approx Approx::operator-() const {
7871         auto temp(*this);
7872         temp.m_value = -temp.m_value;
7873         return temp;
7874     }
7875
7876     std::string Approx::toString() const {
7877         ReusableStringStream rss;
7878         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
7879         return rss.str();
7880     }
7881
7882     bool Approx::equalityComparisonImpl(const double other) const {
7883         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
7884         // Thanks to Richard Harris for his help refining the scaled margin value
7885         return marginComparison(m_value, other, m_margin)
7886             || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
7887     }
7888
7889     void Approx::setMargin(double newMargin) {
7890         CATCH_ENFORCE(newMargin >= 0,
7891             "Invalid Approx::margin: " << newMargin << '.'
7892             << " Approx::Margin has to be non-negative.");
7893         m_margin = newMargin;
7894     }
7895
7896     void Approx::setEpsilon(double newEpsilon) {
7897         CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
7898             "Invalid Approx::epsilon: " << newEpsilon << '.'
7899             << " Approx::epsilon has to be in [0, 1]");
7900         m_epsilon = newEpsilon;
7901     }
7902
7903 } // end namespace Detail
7904
7905 namespace literals {
7906     Detail::Approx operator "" _a(long double val) {
7907         return Detail::Approx(val);
7908     }
7909     Detail::Approx operator "" _a(unsigned long long val) {
7910         return Detail::Approx(val);
7911     }
7912 } // end namespace literals
7913
7914 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
7915     return value.toString();
7916 }
7917
7918 } // end namespace Catch
7919 // end catch_approx.cpp
7920 // start catch_assertionhandler.cpp
7921
7922 // start catch_debugger.h
7923
7924 namespace Catch {
7925     bool isDebuggerActive();
7926 }
7927
7928 #ifdef CATCH_PLATFORM_MAC
7929
7930     #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
7931
7932 #elif defined(CATCH_PLATFORM_IPHONE)
7933
7934     // use inline assembler
7935     #if defined(__i386__) || defined(__x86_64__)
7936         #define CATCH_TRAP()  __asm__("int $3")
7937     #elif defined(__aarch64__)
7938         #define CATCH_TRAP()  __asm__(".inst 0xd4200000")
7939     #elif defined(__arm__) && !defined(__thumb__)
7940         #define CATCH_TRAP()  __asm__(".inst 0xe7f001f0")
7941     #elif defined(__arm__) &&  defined(__thumb__)
7942         #define CATCH_TRAP()  __asm__(".inst 0xde01")
7943     #endif
7944
7945 #elif defined(CATCH_PLATFORM_LINUX)
7946     // If we can use inline assembler, do it because this allows us to break
7947     // directly at the location of the failing check instead of breaking inside
7948     // raise() called from it, i.e. one stack frame below.
7949     #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
7950         #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
7951     #else // Fall back to the generic way.
7952         #include <signal.h>
7953
7954         #define CATCH_TRAP() raise(SIGTRAP)
7955     #endif
7956 #elif defined(_MSC_VER)
7957     #define CATCH_TRAP() __debugbreak()
7958 #elif defined(__MINGW32__)
7959     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
7960     #define CATCH_TRAP() DebugBreak()
7961 #endif
7962
7963 #ifndef CATCH_BREAK_INTO_DEBUGGER
7964     #ifdef CATCH_TRAP
7965         #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
7966     #else
7967         #define CATCH_BREAK_INTO_DEBUGGER() []{}()
7968     #endif
7969 #endif
7970
7971 // end catch_debugger.h
7972 // start catch_run_context.h
7973
7974 // start catch_fatal_condition.h
7975
7976 // start catch_windows_h_proxy.h
7977
7978
7979 #if defined(CATCH_PLATFORM_WINDOWS)
7980
7981 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
7982 #  define CATCH_DEFINED_NOMINMAX
7983 #  define NOMINMAX
7984 #endif
7985 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
7986 #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
7987 #  define WIN32_LEAN_AND_MEAN
7988 #endif
7989
7990 #ifdef __AFXDLL
7991 #include <AfxWin.h>
7992 #else
7993 #include <windows.h>
7994 #endif
7995
7996 #ifdef CATCH_DEFINED_NOMINMAX
7997 #  undef NOMINMAX
7998 #endif
7999 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
8000 #  undef WIN32_LEAN_AND_MEAN
8001 #endif
8002
8003 #endif // defined(CATCH_PLATFORM_WINDOWS)
8004
8005 // end catch_windows_h_proxy.h
8006 #if defined( CATCH_CONFIG_WINDOWS_SEH )
8007
8008 namespace Catch {
8009
8010     struct FatalConditionHandler {
8011
8012         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
8013         FatalConditionHandler();
8014         static void reset();
8015         ~FatalConditionHandler();
8016
8017     private:
8018         static bool isSet;
8019         static ULONG guaranteeSize;
8020         static PVOID exceptionHandlerHandle;
8021     };
8022
8023 } // namespace Catch
8024
8025 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
8026
8027 #include <signal.h>
8028
8029 namespace Catch {
8030
8031     struct FatalConditionHandler {
8032
8033         static bool isSet;
8034         static struct sigaction oldSigActions[];
8035         static stack_t oldSigStack;
8036         static char altStackMem[];
8037
8038         static void handleSignal( int sig );
8039
8040         FatalConditionHandler();
8041         ~FatalConditionHandler();
8042         static void reset();
8043     };
8044
8045 } // namespace Catch
8046
8047 #else
8048
8049 namespace Catch {
8050     struct FatalConditionHandler {
8051         void reset();
8052     };
8053 }
8054
8055 #endif
8056
8057 // end catch_fatal_condition.h
8058 #include <string>
8059
8060 namespace Catch {
8061
8062     struct IMutableContext;
8063
8064     ///////////////////////////////////////////////////////////////////////////
8065
8066     class RunContext : public IResultCapture, public IRunner {
8067
8068     public:
8069         RunContext( RunContext const& ) = delete;
8070         RunContext& operator =( RunContext const& ) = delete;
8071
8072         explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
8073
8074         ~RunContext() override;
8075
8076         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
8077         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
8078
8079         Totals runTest(TestCase const& testCase);
8080
8081         IConfigPtr config() const;
8082         IStreamingReporter& reporter() const;
8083
8084     public: // IResultCapture
8085
8086         // Assertion handlers
8087         void handleExpr
8088                 (   AssertionInfo const& info,
8089                     ITransientExpression const& expr,
8090                     AssertionReaction& reaction ) override;
8091         void handleMessage
8092                 (   AssertionInfo const& info,
8093                     ResultWas::OfType resultType,
8094                     StringRef const& message,
8095                     AssertionReaction& reaction ) override;
8096         void handleUnexpectedExceptionNotThrown
8097                 (   AssertionInfo const& info,
8098                     AssertionReaction& reaction ) override;
8099         void handleUnexpectedInflightException
8100                 (   AssertionInfo const& info,
8101                     std::string const& message,
8102                     AssertionReaction& reaction ) override;
8103         void handleIncomplete
8104                 (   AssertionInfo const& info ) override;
8105         void handleNonExpr
8106                 (   AssertionInfo const &info,
8107                     ResultWas::OfType resultType,
8108                     AssertionReaction &reaction ) override;
8109
8110         bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
8111
8112         void sectionEnded( SectionEndInfo const& endInfo ) override;
8113         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
8114
8115         auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
8116
8117 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
8118         void benchmarkPreparing( std::string const& name ) override;
8119         void benchmarkStarting( BenchmarkInfo const& info ) override;
8120         void benchmarkEnded( BenchmarkStats<> const& stats ) override;
8121         void benchmarkFailed( std::string const& error ) override;
8122 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
8123
8124         void pushScopedMessage( MessageInfo const& message ) override;
8125         void popScopedMessage( MessageInfo const& message ) override;
8126
8127         void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
8128
8129         std::string getCurrentTestName() const override;
8130
8131         const AssertionResult* getLastResult() const override;
8132
8133         void exceptionEarlyReported() override;
8134
8135         void handleFatalErrorCondition( StringRef message ) override;
8136
8137         bool lastAssertionPassed() override;
8138
8139         void assertionPassed() override;
8140
8141     public:
8142         // !TBD We need to do this another way!
8143         bool aborting() const final;
8144
8145     private:
8146
8147         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
8148         void invokeActiveTestCase();
8149
8150         void resetAssertionInfo();
8151         bool testForMissingAssertions( Counts& assertions );
8152
8153         void assertionEnded( AssertionResult const& result );
8154         void reportExpr
8155                 (   AssertionInfo const &info,
8156                     ResultWas::OfType resultType,
8157                     ITransientExpression const *expr,
8158                     bool negated );
8159
8160         void populateReaction( AssertionReaction& reaction );
8161
8162     private:
8163
8164         void handleUnfinishedSections();
8165
8166         TestRunInfo m_runInfo;
8167         IMutableContext& m_context;
8168         TestCase const* m_activeTestCase = nullptr;
8169         ITracker* m_testCaseTracker = nullptr;
8170         Option<AssertionResult> m_lastResult;
8171
8172         IConfigPtr m_config;
8173         Totals m_totals;
8174         IStreamingReporterPtr m_reporter;
8175         std::vector<MessageInfo> m_messages;
8176         std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
8177         AssertionInfo m_lastAssertionInfo;
8178         std::vector<SectionEndInfo> m_unfinishedSections;
8179         std::vector<ITracker*> m_activeSections;
8180         TrackerContext m_trackerContext;
8181         bool m_lastAssertionPassed = false;
8182         bool m_shouldReportUnexpected = true;
8183         bool m_includeSuccessfulResults;
8184     };
8185
8186     void seedRng(IConfig const& config);
8187     unsigned int rngSeed();
8188 } // end namespace Catch
8189
8190 // end catch_run_context.h
8191 namespace Catch {
8192
8193     namespace {
8194         auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
8195             expr.streamReconstructedExpression( os );
8196             return os;
8197         }
8198     }
8199
8200     LazyExpression::LazyExpression( bool isNegated )
8201     :   m_isNegated( isNegated )
8202     {}
8203
8204     LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
8205
8206     LazyExpression::operator bool() const {
8207         return m_transientExpression != nullptr;
8208     }
8209
8210     auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
8211         if( lazyExpr.m_isNegated )
8212             os << "!";
8213
8214         if( lazyExpr ) {
8215             if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
8216                 os << "(" << *lazyExpr.m_transientExpression << ")";
8217             else
8218                 os << *lazyExpr.m_transientExpression;
8219         }
8220         else {
8221             os << "{** error - unchecked empty expression requested **}";
8222         }
8223         return os;
8224     }
8225
8226     AssertionHandler::AssertionHandler
8227         (   StringRef const& macroName,
8228             SourceLineInfo const& lineInfo,
8229             StringRef capturedExpression,
8230             ResultDisposition::Flags resultDisposition )
8231     :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
8232         m_resultCapture( getResultCapture() )
8233     {}
8234
8235     void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
8236         m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
8237     }
8238     void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
8239         m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
8240     }
8241
8242     auto AssertionHandler::allowThrows() const -> bool {
8243         return getCurrentContext().getConfig()->allowThrows();
8244     }
8245
8246     void AssertionHandler::complete() {
8247         setCompleted();
8248         if( m_reaction.shouldDebugBreak ) {
8249
8250             // If you find your debugger stopping you here then go one level up on the
8251             // call-stack for the code that caused it (typically a failed assertion)
8252
8253             // (To go back to the test and change execution, jump over the throw, next)
8254             CATCH_BREAK_INTO_DEBUGGER();
8255         }
8256         if (m_reaction.shouldThrow) {
8257 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8258             throw Catch::TestFailureException();
8259 #else
8260             CATCH_ERROR( "Test failure requires aborting test!" );
8261 #endif
8262         }
8263     }
8264     void AssertionHandler::setCompleted() {
8265         m_completed = true;
8266     }
8267
8268     void AssertionHandler::handleUnexpectedInflightException() {
8269         m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
8270     }
8271
8272     void AssertionHandler::handleExceptionThrownAsExpected() {
8273         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8274     }
8275     void AssertionHandler::handleExceptionNotThrownAsExpected() {
8276         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8277     }
8278
8279     void AssertionHandler::handleUnexpectedExceptionNotThrown() {
8280         m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
8281     }
8282
8283     void AssertionHandler::handleThrowingCallSkipped() {
8284         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8285     }
8286
8287     // This is the overload that takes a string and infers the Equals matcher from it
8288     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
8289     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
8290         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
8291     }
8292
8293 } // namespace Catch
8294 // end catch_assertionhandler.cpp
8295 // start catch_assertionresult.cpp
8296
8297 namespace Catch {
8298     AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
8299         lazyExpression(_lazyExpression),
8300         resultType(_resultType) {}
8301
8302     std::string AssertionResultData::reconstructExpression() const {
8303
8304         if( reconstructedExpression.empty() ) {
8305             if( lazyExpression ) {
8306                 ReusableStringStream rss;
8307                 rss << lazyExpression;
8308                 reconstructedExpression = rss.str();
8309             }
8310         }
8311         return reconstructedExpression;
8312     }
8313
8314     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
8315     :   m_info( info ),
8316         m_resultData( data )
8317     {}
8318
8319     // Result was a success
8320     bool AssertionResult::succeeded() const {
8321         return Catch::isOk( m_resultData.resultType );
8322     }
8323
8324     // Result was a success, or failure is suppressed
8325     bool AssertionResult::isOk() const {
8326         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
8327     }
8328
8329     ResultWas::OfType AssertionResult::getResultType() const {
8330         return m_resultData.resultType;
8331     }
8332
8333     bool AssertionResult::hasExpression() const {
8334         return !m_info.capturedExpression.empty();
8335     }
8336
8337     bool AssertionResult::hasMessage() const {
8338         return !m_resultData.message.empty();
8339     }
8340
8341     std::string AssertionResult::getExpression() const {
8342         // Possibly overallocating by 3 characters should be basically free
8343         std::string expr; 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         std::string expr;
8356         if( m_info.macroName.empty() )
8357             expr = static_cast<std::string>(m_info.capturedExpression);
8358         else {
8359             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
8360             expr += m_info.macroName;
8361             expr += "( ";
8362             expr += m_info.capturedExpression;
8363             expr += " )";
8364         }
8365         return expr;
8366     }
8367
8368     bool AssertionResult::hasExpandedExpression() const {
8369         return hasExpression() && getExpandedExpression() != getExpression();
8370     }
8371
8372     std::string AssertionResult::getExpandedExpression() const {
8373         std::string expr = m_resultData.reconstructExpression();
8374         return expr.empty()
8375                 ? getExpression()
8376                 : expr;
8377     }
8378
8379     std::string AssertionResult::getMessage() const {
8380         return m_resultData.message;
8381     }
8382     SourceLineInfo AssertionResult::getSourceInfo() const {
8383         return m_info.lineInfo;
8384     }
8385
8386     StringRef AssertionResult::getTestMacroName() const {
8387         return m_info.macroName;
8388     }
8389
8390 } // end namespace Catch
8391 // end catch_assertionresult.cpp
8392 // start catch_capture_matchers.cpp
8393
8394 namespace Catch {
8395
8396     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
8397
8398     // This is the general overload that takes a any string matcher
8399     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
8400     // the Equals matcher (so the header does not mention matchers)
8401     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
8402         std::string exceptionMessage = Catch::translateActiveException();
8403         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
8404         handler.handleExpr( expr );
8405     }
8406
8407 } // namespace Catch
8408 // end catch_capture_matchers.cpp
8409 // start catch_commandline.cpp
8410
8411 // start catch_commandline.h
8412
8413 // start catch_clara.h
8414
8415 // Use Catch's value for console width (store Clara's off to the side, if present)
8416 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
8417 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8418 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8419 #endif
8420 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
8421
8422 #ifdef __clang__
8423 #pragma clang diagnostic push
8424 #pragma clang diagnostic ignored "-Wweak-vtables"
8425 #pragma clang diagnostic ignored "-Wexit-time-destructors"
8426 #pragma clang diagnostic ignored "-Wshadow"
8427 #endif
8428
8429 // start clara.hpp
8430 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
8431 //
8432 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8433 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8434 //
8435 // See https://github.com/philsquared/Clara for more details
8436
8437 // Clara v1.1.5
8438
8439
8440 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8441 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
8442 #endif
8443
8444 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8445 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8446 #endif
8447
8448 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
8449 #ifdef __has_include
8450 #if __has_include(<optional>) && __cplusplus >= 201703L
8451 #include <optional>
8452 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
8453 #endif
8454 #endif
8455 #endif
8456
8457 // ----------- #included from clara_textflow.hpp -----------
8458
8459 // TextFlowCpp
8460 //
8461 // A single-header library for wrapping and laying out basic text, by Phil Nash
8462 //
8463 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8464 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8465 //
8466 // This project is hosted at https://github.com/philsquared/textflowcpp
8467
8468
8469 #include <cassert>
8470 #include <ostream>
8471 #include <sstream>
8472 #include <vector>
8473
8474 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8475 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
8476 #endif
8477
8478 namespace Catch {
8479 namespace clara {
8480 namespace TextFlow {
8481
8482 inline auto isWhitespace(char c) -> bool {
8483         static std::string chars = " \t\n\r";
8484         return chars.find(c) != std::string::npos;
8485 }
8486 inline auto isBreakableBefore(char c) -> bool {
8487         static std::string chars = "[({<|";
8488         return chars.find(c) != std::string::npos;
8489 }
8490 inline auto isBreakableAfter(char c) -> bool {
8491         static std::string chars = "])}>.,:;*+-=&/\\";
8492         return chars.find(c) != std::string::npos;
8493 }
8494
8495 class Columns;
8496
8497 class Column {
8498         std::vector<std::string> m_strings;
8499         size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
8500         size_t m_indent = 0;
8501         size_t m_initialIndent = std::string::npos;
8502
8503 public:
8504         class iterator {
8505                 friend Column;
8506
8507                 Column const& m_column;
8508                 size_t m_stringIndex = 0;
8509                 size_t m_pos = 0;
8510
8511                 size_t m_len = 0;
8512                 size_t m_end = 0;
8513                 bool m_suffix = false;
8514
8515                 iterator(Column const& column, size_t stringIndex)
8516                         : m_column(column),
8517                         m_stringIndex(stringIndex) {}
8518
8519                 auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
8520
8521                 auto isBoundary(size_t at) const -> bool {
8522                         assert(at > 0);
8523                         assert(at <= line().size());
8524
8525                         return at == line().size() ||
8526                                 (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
8527                                 isBreakableBefore(line()[at]) ||
8528                                 isBreakableAfter(line()[at - 1]);
8529                 }
8530
8531                 void calcLength() {
8532                         assert(m_stringIndex < m_column.m_strings.size());
8533
8534                         m_suffix = false;
8535                         auto width = m_column.m_width - indent();
8536                         m_end = m_pos;
8537                         if (line()[m_pos] == '\n') {
8538                                 ++m_end;
8539                         }
8540                         while (m_end < line().size() && line()[m_end] != '\n')
8541                                 ++m_end;
8542
8543                         if (m_end < m_pos + width) {
8544                                 m_len = m_end - m_pos;
8545                         } else {
8546                                 size_t len = width;
8547                                 while (len > 0 && !isBoundary(m_pos + len))
8548                                         --len;
8549                                 while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
8550                                         --len;
8551
8552                                 if (len > 0) {
8553                                         m_len = len;
8554                                 } else {
8555                                         m_suffix = true;
8556                                         m_len = width - 1;
8557                                 }
8558                         }
8559                 }
8560
8561                 auto indent() const -> size_t {
8562                         auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
8563                         return initial == std::string::npos ? m_column.m_indent : initial;
8564                 }
8565
8566                 auto addIndentAndSuffix(std::string const &plain) const -> std::string {
8567                         return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
8568                 }
8569
8570         public:
8571                 using difference_type = std::ptrdiff_t;
8572                 using value_type = std::string;
8573                 using pointer = value_type * ;
8574                 using reference = value_type & ;
8575                 using iterator_category = std::forward_iterator_tag;
8576
8577                 explicit iterator(Column const& column) : m_column(column) {
8578                         assert(m_column.m_width > m_column.m_indent);
8579                         assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
8580                         calcLength();
8581                         if (m_len == 0)
8582                                 m_stringIndex++; // Empty string
8583                 }
8584
8585                 auto operator *() const -> std::string {
8586                         assert(m_stringIndex < m_column.m_strings.size());
8587                         assert(m_pos <= m_end);
8588                         return addIndentAndSuffix(line().substr(m_pos, m_len));
8589                 }
8590
8591                 auto operator ++() -> iterator& {
8592                         m_pos += m_len;
8593                         if (m_pos < line().size() && line()[m_pos] == '\n')
8594                                 m_pos += 1;
8595                         else
8596                                 while (m_pos < line().size() && isWhitespace(line()[m_pos]))
8597                                         ++m_pos;
8598
8599                         if (m_pos == line().size()) {
8600                                 m_pos = 0;
8601                                 ++m_stringIndex;
8602                         }
8603                         if (m_stringIndex < m_column.m_strings.size())
8604                                 calcLength();
8605                         return *this;
8606                 }
8607                 auto operator ++(int) -> iterator {
8608                         iterator prev(*this);
8609                         operator++();
8610                         return prev;
8611                 }
8612
8613                 auto operator ==(iterator const& other) const -> bool {
8614                         return
8615                                 m_pos == other.m_pos &&
8616                                 m_stringIndex == other.m_stringIndex &&
8617                                 &m_column == &other.m_column;
8618                 }
8619                 auto operator !=(iterator const& other) const -> bool {
8620                         return !operator==(other);
8621                 }
8622         };
8623         using const_iterator = iterator;
8624
8625         explicit Column(std::string const& text) { m_strings.push_back(text); }
8626
8627         auto width(size_t newWidth) -> Column& {
8628                 assert(newWidth > 0);
8629                 m_width = newWidth;
8630                 return *this;
8631         }
8632         auto indent(size_t newIndent) -> Column& {
8633                 m_indent = newIndent;
8634                 return *this;
8635         }
8636         auto initialIndent(size_t newIndent) -> Column& {
8637                 m_initialIndent = newIndent;
8638                 return *this;
8639         }
8640
8641         auto width() const -> size_t { return m_width; }
8642         auto begin() const -> iterator { return iterator(*this); }
8643         auto end() const -> iterator { return { *this, m_strings.size() }; }
8644
8645         inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
8646                 bool first = true;
8647                 for (auto line : col) {
8648                         if (first)
8649                                 first = false;
8650                         else
8651                                 os << "\n";
8652                         os << line;
8653                 }
8654                 return os;
8655         }
8656
8657         auto operator + (Column const& other)->Columns;
8658
8659         auto toString() const -> std::string {
8660                 std::ostringstream oss;
8661                 oss << *this;
8662                 return oss.str();
8663         }
8664 };
8665
8666 class Spacer : public Column {
8667
8668 public:
8669         explicit Spacer(size_t spaceWidth) : Column("") {
8670                 width(spaceWidth);
8671         }
8672 };
8673
8674 class Columns {
8675         std::vector<Column> m_columns;
8676
8677 public:
8678
8679         class iterator {
8680                 friend Columns;
8681                 struct EndTag {};
8682
8683                 std::vector<Column> const& m_columns;
8684                 std::vector<Column::iterator> m_iterators;
8685                 size_t m_activeIterators;
8686
8687                 iterator(Columns const& columns, EndTag)
8688                         : m_columns(columns.m_columns),
8689                         m_activeIterators(0) {
8690                         m_iterators.reserve(m_columns.size());
8691
8692                         for (auto const& col : m_columns)
8693                                 m_iterators.push_back(col.end());
8694                 }
8695
8696         public:
8697                 using difference_type = std::ptrdiff_t;
8698                 using value_type = std::string;
8699                 using pointer = value_type * ;
8700                 using reference = value_type & ;
8701                 using iterator_category = std::forward_iterator_tag;
8702
8703                 explicit iterator(Columns const& columns)
8704                         : m_columns(columns.m_columns),
8705                         m_activeIterators(m_columns.size()) {
8706                         m_iterators.reserve(m_columns.size());
8707
8708                         for (auto const& col : m_columns)
8709                                 m_iterators.push_back(col.begin());
8710                 }
8711
8712                 auto operator ==(iterator const& other) const -> bool {
8713                         return m_iterators == other.m_iterators;
8714                 }
8715                 auto operator !=(iterator const& other) const -> bool {
8716                         return m_iterators != other.m_iterators;
8717                 }
8718                 auto operator *() const -> std::string {
8719                         std::string row, padding;
8720
8721                         for (size_t i = 0; i < m_columns.size(); ++i) {
8722                                 auto width = m_columns[i].width();
8723                                 if (m_iterators[i] != m_columns[i].end()) {
8724                                         std::string col = *m_iterators[i];
8725                                         row += padding + col;
8726                                         if (col.size() < width)
8727                                                 padding = std::string(width - col.size(), ' ');
8728                                         else
8729                                                 padding = "";
8730                                 } else {
8731                                         padding += std::string(width, ' ');
8732                                 }
8733                         }
8734                         return row;
8735                 }
8736                 auto operator ++() -> iterator& {
8737                         for (size_t i = 0; i < m_columns.size(); ++i) {
8738                                 if (m_iterators[i] != m_columns[i].end())
8739                                         ++m_iterators[i];
8740                         }
8741                         return *this;
8742                 }
8743                 auto operator ++(int) -> iterator {
8744                         iterator prev(*this);
8745                         operator++();
8746                         return prev;
8747                 }
8748         };
8749         using const_iterator = iterator;
8750
8751         auto begin() const -> iterator { return iterator(*this); }
8752         auto end() const -> iterator { return { *this, iterator::EndTag() }; }
8753
8754         auto operator += (Column const& col) -> Columns& {
8755                 m_columns.push_back(col);
8756                 return *this;
8757         }
8758         auto operator + (Column const& col) -> Columns {
8759                 Columns combined = *this;
8760                 combined += col;
8761                 return combined;
8762         }
8763
8764         inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
8765
8766                 bool first = true;
8767                 for (auto line : cols) {
8768                         if (first)
8769                                 first = false;
8770                         else
8771                                 os << "\n";
8772                         os << line;
8773                 }
8774                 return os;
8775         }
8776
8777         auto toString() const -> std::string {
8778                 std::ostringstream oss;
8779                 oss << *this;
8780                 return oss.str();
8781         }
8782 };
8783
8784 inline auto Column::operator + (Column const& other) -> Columns {
8785         Columns cols;
8786         cols += *this;
8787         cols += other;
8788         return cols;
8789 }
8790 }
8791
8792 }
8793 }
8794
8795 // ----------- end of #include from clara_textflow.hpp -----------
8796 // ........... back in clara.hpp
8797
8798 #include <cctype>
8799 #include <string>
8800 #include <memory>
8801 #include <set>
8802 #include <algorithm>
8803
8804 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
8805 #define CATCH_PLATFORM_WINDOWS
8806 #endif
8807
8808 namespace Catch { namespace clara {
8809 namespace detail {
8810
8811     // Traits for extracting arg and return type of lambdas (for single argument lambdas)
8812     template<typename L>
8813     struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
8814
8815     template<typename ClassT, typename ReturnT, typename... Args>
8816     struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
8817         static const bool isValid = false;
8818     };
8819
8820     template<typename ClassT, typename ReturnT, typename ArgT>
8821     struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
8822         static const bool isValid = true;
8823         using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
8824         using ReturnType = ReturnT;
8825     };
8826
8827     class TokenStream;
8828
8829     // Transport for raw args (copied from main args, or supplied via init list for testing)
8830     class Args {
8831         friend TokenStream;
8832         std::string m_exeName;
8833         std::vector<std::string> m_args;
8834
8835     public:
8836         Args( int argc, char const* const* argv )
8837             : m_exeName(argv[0]),
8838               m_args(argv + 1, argv + argc) {}
8839
8840         Args( std::initializer_list<std::string> args )
8841         :   m_exeName( *args.begin() ),
8842             m_args( args.begin()+1, args.end() )
8843         {}
8844
8845         auto exeName() const -> std::string {
8846             return m_exeName;
8847         }
8848     };
8849
8850     // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
8851     // may encode an option + its argument if the : or = form is used
8852     enum class TokenType {
8853         Option, Argument
8854     };
8855     struct Token {
8856         TokenType type;
8857         std::string token;
8858     };
8859
8860     inline auto isOptPrefix( char c ) -> bool {
8861         return c == '-'
8862 #ifdef CATCH_PLATFORM_WINDOWS
8863             || c == '/'
8864 #endif
8865         ;
8866     }
8867
8868     // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
8869     class TokenStream {
8870         using Iterator = std::vector<std::string>::const_iterator;
8871         Iterator it;
8872         Iterator itEnd;
8873         std::vector<Token> m_tokenBuffer;
8874
8875         void loadBuffer() {
8876             m_tokenBuffer.resize( 0 );
8877
8878             // Skip any empty strings
8879             while( it != itEnd && it->empty() )
8880                 ++it;
8881
8882             if( it != itEnd ) {
8883                 auto const &next = *it;
8884                 if( isOptPrefix( next[0] ) ) {
8885                     auto delimiterPos = next.find_first_of( " :=" );
8886                     if( delimiterPos != std::string::npos ) {
8887                         m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
8888                         m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
8889                     } else {
8890                         if( next[1] != '-' && next.size() > 2 ) {
8891                             std::string opt = "- ";
8892                             for( size_t i = 1; i < next.size(); ++i ) {
8893                                 opt[1] = next[i];
8894                                 m_tokenBuffer.push_back( { TokenType::Option, opt } );
8895                             }
8896                         } else {
8897                             m_tokenBuffer.push_back( { TokenType::Option, next } );
8898                         }
8899                     }
8900                 } else {
8901                     m_tokenBuffer.push_back( { TokenType::Argument, next } );
8902                 }
8903             }
8904         }
8905
8906     public:
8907         explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
8908
8909         TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
8910             loadBuffer();
8911         }
8912
8913         explicit operator bool() const {
8914             return !m_tokenBuffer.empty() || it != itEnd;
8915         }
8916
8917         auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
8918
8919         auto operator*() const -> Token {
8920             assert( !m_tokenBuffer.empty() );
8921             return m_tokenBuffer.front();
8922         }
8923
8924         auto operator->() const -> Token const * {
8925             assert( !m_tokenBuffer.empty() );
8926             return &m_tokenBuffer.front();
8927         }
8928
8929         auto operator++() -> TokenStream & {
8930             if( m_tokenBuffer.size() >= 2 ) {
8931                 m_tokenBuffer.erase( m_tokenBuffer.begin() );
8932             } else {
8933                 if( it != itEnd )
8934                     ++it;
8935                 loadBuffer();
8936             }
8937             return *this;
8938         }
8939     };
8940
8941     class ResultBase {
8942     public:
8943         enum Type {
8944             Ok, LogicError, RuntimeError
8945         };
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>
8957     class ResultValueBase : public ResultBase {
8958     public:
8959         auto value() const -> T const & {
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             if( m_type == ResultBase::Ok )
8969                 new( &m_value ) T( other.m_value );
8970         }
8971
8972         ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
8973             new( &m_value ) T( value );
8974         }
8975
8976         auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
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             if( m_type == Ok )
8987                 m_value.~T();
8988         }
8989
8990         union {
8991             T m_value;
8992         };
8993     };
8994
8995     template<>
8996     class ResultValueBase<void> : public ResultBase {
8997     protected:
8998         using ResultBase::ResultBase;
8999     };
9000
9001     template<typename T = void>
9002     class BasicResult : public ResultValueBase<T> {
9003     public:
9004         template<typename U>
9005         explicit BasicResult( BasicResult<U> const &other )
9006         :   ResultValueBase<T>( other.type() ),
9007             m_errorMessage( other.errorMessage() )
9008         {
9009             assert( type() != ResultBase::Ok );
9010         }
9011
9012         template<typename U>
9013         static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
9014         static auto ok() -> BasicResult { return { ResultBase::Ok }; }
9015         static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
9016         static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
9017
9018         explicit operator bool() const { return m_type == ResultBase::Ok; }
9019         auto type() const -> ResultBase::Type { return m_type; }
9020         auto errorMessage() const -> std::string { return m_errorMessage; }
9021
9022     protected:
9023         void enforceOk() const override {
9024
9025             // Errors shouldn't reach this point, but if they do
9026             // the actual error message will be in m_errorMessage
9027             assert( m_type != ResultBase::LogicError );
9028             assert( m_type != ResultBase::RuntimeError );
9029             if( m_type != ResultBase::Ok )
9030                 std::abort();
9031         }
9032
9033         std::string m_errorMessage; // Only populated if resultType is an error
9034
9035         BasicResult( ResultBase::Type type, std::string const &message )
9036         :   ResultValueBase<T>(type),
9037             m_errorMessage(message)
9038         {
9039             assert( m_type != ResultBase::Ok );
9040         }
9041
9042         using ResultValueBase<T>::ResultValueBase;
9043         using ResultBase::m_type;
9044     };
9045
9046     enum class ParseResultType {
9047         Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
9048     };
9049
9050     class ParseState {
9051     public:
9052
9053         ParseState( ParseResultType type, TokenStream const &remainingTokens )
9054         : m_type(type),
9055           m_remainingTokens( remainingTokens )
9056         {}
9057
9058         auto type() const -> ParseResultType { return m_type; }
9059         auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
9060
9061     private:
9062         ParseResultType m_type;
9063         TokenStream m_remainingTokens;
9064     };
9065
9066     using Result = BasicResult<void>;
9067     using ParserResult = BasicResult<ParseResultType>;
9068     using InternalParseResult = BasicResult<ParseState>;
9069
9070     struct HelpColumns {
9071         std::string left;
9072         std::string right;
9073     };
9074
9075     template<typename T>
9076     inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
9077         std::stringstream ss;
9078         ss << source;
9079         ss >> target;
9080         if( ss.fail() )
9081             return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
9082         else
9083             return ParserResult::ok( ParseResultType::Matched );
9084     }
9085     inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
9086         target = source;
9087         return ParserResult::ok( ParseResultType::Matched );
9088     }
9089     inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
9090         std::string srcLC = source;
9091         std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
9092         if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
9093             target = true;
9094         else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
9095             target = false;
9096         else
9097             return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
9098         return ParserResult::ok( ParseResultType::Matched );
9099     }
9100 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
9101     template<typename T>
9102     inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
9103         T temp;
9104         auto result = convertInto( source, temp );
9105         if( result )
9106             target = std::move(temp);
9107         return result;
9108     }
9109 #endif // CLARA_CONFIG_OPTIONAL_TYPE
9110
9111     struct NonCopyable {
9112         NonCopyable() = default;
9113         NonCopyable( NonCopyable const & ) = delete;
9114         NonCopyable( NonCopyable && ) = delete;
9115         NonCopyable &operator=( NonCopyable const & ) = delete;
9116         NonCopyable &operator=( NonCopyable && ) = delete;
9117     };
9118
9119     struct BoundRef : NonCopyable {
9120         virtual ~BoundRef() = default;
9121         virtual auto isContainer() const -> bool { return false; }
9122         virtual auto isFlag() const -> bool { return false; }
9123     };
9124     struct BoundValueRefBase : BoundRef {
9125         virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
9126     };
9127     struct BoundFlagRefBase : BoundRef {
9128         virtual auto setFlag( bool flag ) -> ParserResult = 0;
9129         virtual auto isFlag() const -> bool { return true; }
9130     };
9131
9132     template<typename T>
9133     struct BoundValueRef : BoundValueRefBase {
9134         T &m_ref;
9135
9136         explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
9137
9138         auto setValue( std::string const &arg ) -> ParserResult override {
9139             return convertInto( arg, m_ref );
9140         }
9141     };
9142
9143     template<typename T>
9144     struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
9145         std::vector<T> &m_ref;
9146
9147         explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
9148
9149         auto isContainer() const -> bool override { return true; }
9150
9151         auto setValue( std::string const &arg ) -> ParserResult override {
9152             T temp;
9153             auto result = convertInto( arg, temp );
9154             if( result )
9155                 m_ref.push_back( temp );
9156             return result;
9157         }
9158     };
9159
9160     struct BoundFlagRef : BoundFlagRefBase {
9161         bool &m_ref;
9162
9163         explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
9164
9165         auto setFlag( bool flag ) -> ParserResult override {
9166             m_ref = flag;
9167             return ParserResult::ok( ParseResultType::Matched );
9168         }
9169     };
9170
9171     template<typename ReturnType>
9172     struct LambdaInvoker {
9173         static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
9174
9175         template<typename L, typename ArgType>
9176         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9177             return lambda( arg );
9178         }
9179     };
9180
9181     template<>
9182     struct LambdaInvoker<void> {
9183         template<typename L, typename ArgType>
9184         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9185             lambda( arg );
9186             return ParserResult::ok( ParseResultType::Matched );
9187         }
9188     };
9189
9190     template<typename ArgType, typename L>
9191     inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
9192         ArgType temp{};
9193         auto result = convertInto( arg, temp );
9194         return !result
9195            ? result
9196            : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
9197     }
9198
9199     template<typename L>
9200     struct BoundLambda : BoundValueRefBase {
9201         L m_lambda;
9202
9203         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9204         explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
9205
9206         auto setValue( std::string const &arg ) -> ParserResult override {
9207             return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
9208         }
9209     };
9210
9211     template<typename L>
9212     struct BoundFlagLambda : BoundFlagRefBase {
9213         L m_lambda;
9214
9215         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9216         static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
9217
9218         explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
9219
9220         auto setFlag( bool flag ) -> ParserResult override {
9221             return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
9222         }
9223     };
9224
9225     enum class Optionality { Optional, Required };
9226
9227     struct Parser;
9228
9229     class ParserBase {
9230     public:
9231         virtual ~ParserBase() = default;
9232         virtual auto validate() const -> Result { return Result::ok(); }
9233         virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
9234         virtual auto cardinality() const -> size_t { return 1; }
9235
9236         auto parse( Args const &args ) const -> InternalParseResult {
9237             return parse( args.exeName(), TokenStream( args ) );
9238         }
9239     };
9240
9241     template<typename DerivedT>
9242     class ComposableParserImpl : public ParserBase {
9243     public:
9244         template<typename T>
9245         auto operator|( T const &other ) const -> Parser;
9246
9247                 template<typename T>
9248         auto operator+( T const &other ) const -> Parser;
9249     };
9250
9251     // Common code and state for Args and Opts
9252     template<typename DerivedT>
9253     class ParserRefImpl : public ComposableParserImpl<DerivedT> {
9254     protected:
9255         Optionality m_optionality = Optionality::Optional;
9256         std::shared_ptr<BoundRef> m_ref;
9257         std::string m_hint;
9258         std::string m_description;
9259
9260         explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
9261
9262     public:
9263         template<typename T>
9264         ParserRefImpl( T &ref, std::string const &hint )
9265         :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
9266             m_hint( hint )
9267         {}
9268
9269         template<typename LambdaT>
9270         ParserRefImpl( LambdaT const &ref, std::string const &hint )
9271         :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
9272             m_hint(hint)
9273         {}
9274
9275         auto operator()( std::string const &description ) -> DerivedT & {
9276             m_description = description;
9277             return static_cast<DerivedT &>( *this );
9278         }
9279
9280         auto optional() -> DerivedT & {
9281             m_optionality = Optionality::Optional;
9282             return static_cast<DerivedT &>( *this );
9283         };
9284
9285         auto required() -> DerivedT & {
9286             m_optionality = Optionality::Required;
9287             return static_cast<DerivedT &>( *this );
9288         };
9289
9290         auto isOptional() const -> bool {
9291             return m_optionality == Optionality::Optional;
9292         }
9293
9294         auto cardinality() const -> size_t override {
9295             if( m_ref->isContainer() )
9296                 return 0;
9297             else
9298                 return 1;
9299         }
9300
9301         auto hint() const -> std::string { return m_hint; }
9302     };
9303
9304     class ExeName : public ComposableParserImpl<ExeName> {
9305         std::shared_ptr<std::string> m_name;
9306         std::shared_ptr<BoundValueRefBase> m_ref;
9307
9308         template<typename LambdaT>
9309         static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
9310             return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
9311         }
9312
9313     public:
9314         ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
9315
9316         explicit ExeName( std::string &ref ) : ExeName() {
9317             m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
9318         }
9319
9320         template<typename LambdaT>
9321         explicit ExeName( LambdaT const& lambda ) : ExeName() {
9322             m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
9323         }
9324
9325         // The exe name is not parsed out of the normal tokens, but is handled specially
9326         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9327             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9328         }
9329
9330         auto name() const -> std::string { return *m_name; }
9331         auto set( std::string const& newName ) -> ParserResult {
9332
9333             auto lastSlash = newName.find_last_of( "\\/" );
9334             auto filename = ( lastSlash == std::string::npos )
9335                     ? newName
9336                     : newName.substr( lastSlash+1 );
9337
9338             *m_name = filename;
9339             if( m_ref )
9340                 return m_ref->setValue( filename );
9341             else
9342                 return ParserResult::ok( ParseResultType::Matched );
9343         }
9344     };
9345
9346     class Arg : public ParserRefImpl<Arg> {
9347     public:
9348         using ParserRefImpl::ParserRefImpl;
9349
9350         auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
9351             auto validationResult = validate();
9352             if( !validationResult )
9353                 return InternalParseResult( validationResult );
9354
9355             auto remainingTokens = tokens;
9356             auto const &token = *remainingTokens;
9357             if( token.type != TokenType::Argument )
9358                 return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9359
9360             assert( !m_ref->isFlag() );
9361             auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9362
9363             auto result = valueRef->setValue( remainingTokens->token );
9364             if( !result )
9365                 return InternalParseResult( result );
9366             else
9367                 return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9368         }
9369     };
9370
9371     inline auto normaliseOpt( std::string const &optName ) -> std::string {
9372 #ifdef CATCH_PLATFORM_WINDOWS
9373         if( optName[0] == '/' )
9374             return "-" + optName.substr( 1 );
9375         else
9376 #endif
9377             return optName;
9378     }
9379
9380     class Opt : public ParserRefImpl<Opt> {
9381     protected:
9382         std::vector<std::string> m_optNames;
9383
9384     public:
9385         template<typename LambdaT>
9386         explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
9387
9388         explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
9389
9390         template<typename LambdaT>
9391         Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9392
9393         template<typename T>
9394         Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9395
9396         auto operator[]( std::string const &optName ) -> Opt & {
9397             m_optNames.push_back( optName );
9398             return *this;
9399         }
9400
9401         auto getHelpColumns() const -> std::vector<HelpColumns> {
9402             std::ostringstream oss;
9403             bool first = true;
9404             for( auto const &opt : m_optNames ) {
9405                 if (first)
9406                     first = false;
9407                 else
9408                     oss << ", ";
9409                 oss << opt;
9410             }
9411             if( !m_hint.empty() )
9412                 oss << " <" << m_hint << ">";
9413             return { { oss.str(), m_description } };
9414         }
9415
9416         auto isMatch( std::string const &optToken ) const -> bool {
9417             auto normalisedToken = normaliseOpt( optToken );
9418             for( auto const &name : m_optNames ) {
9419                 if( normaliseOpt( name ) == normalisedToken )
9420                     return true;
9421             }
9422             return false;
9423         }
9424
9425         using ParserBase::parse;
9426
9427         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9428             auto validationResult = validate();
9429             if( !validationResult )
9430                 return InternalParseResult( validationResult );
9431
9432             auto remainingTokens = tokens;
9433             if( remainingTokens && remainingTokens->type == TokenType::Option ) {
9434                 auto const &token = *remainingTokens;
9435                 if( isMatch(token.token ) ) {
9436                     if( m_ref->isFlag() ) {
9437                         auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
9438                         auto result = flagRef->setFlag( true );
9439                         if( !result )
9440                             return InternalParseResult( result );
9441                         if( result.value() == ParseResultType::ShortCircuitAll )
9442                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9443                     } else {
9444                         auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9445                         ++remainingTokens;
9446                         if( !remainingTokens )
9447                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9448                         auto const &argToken = *remainingTokens;
9449                         if( argToken.type != TokenType::Argument )
9450                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9451                         auto result = valueRef->setValue( argToken.token );
9452                         if( !result )
9453                             return InternalParseResult( result );
9454                         if( result.value() == ParseResultType::ShortCircuitAll )
9455                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9456                     }
9457                     return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9458                 }
9459             }
9460             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9461         }
9462
9463         auto validate() const -> Result override {
9464             if( m_optNames.empty() )
9465                 return Result::logicError( "No options supplied to Opt" );
9466             for( auto const &name : m_optNames ) {
9467                 if( name.empty() )
9468                     return Result::logicError( "Option name cannot be empty" );
9469 #ifdef CATCH_PLATFORM_WINDOWS
9470                 if( name[0] != '-' && name[0] != '/' )
9471                     return Result::logicError( "Option name must begin with '-' or '/'" );
9472 #else
9473                 if( name[0] != '-' )
9474                     return Result::logicError( "Option name must begin with '-'" );
9475 #endif
9476             }
9477             return ParserRefImpl::validate();
9478         }
9479     };
9480
9481     struct Help : Opt {
9482         Help( bool &showHelpFlag )
9483         :   Opt([&]( bool flag ) {
9484                 showHelpFlag = flag;
9485                 return ParserResult::ok( ParseResultType::ShortCircuitAll );
9486             })
9487         {
9488             static_cast<Opt &>( *this )
9489                     ("display usage information")
9490                     ["-?"]["-h"]["--help"]
9491                     .optional();
9492         }
9493     };
9494
9495     struct Parser : ParserBase {
9496
9497         mutable ExeName m_exeName;
9498         std::vector<Opt> m_options;
9499         std::vector<Arg> m_args;
9500
9501         auto operator|=( ExeName const &exeName ) -> Parser & {
9502             m_exeName = exeName;
9503             return *this;
9504         }
9505
9506         auto operator|=( Arg const &arg ) -> Parser & {
9507             m_args.push_back(arg);
9508             return *this;
9509         }
9510
9511         auto operator|=( Opt const &opt ) -> Parser & {
9512             m_options.push_back(opt);
9513             return *this;
9514         }
9515
9516         auto operator|=( Parser const &other ) -> Parser & {
9517             m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
9518             m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
9519             return *this;
9520         }
9521
9522         template<typename T>
9523         auto operator|( T const &other ) const -> Parser {
9524             return Parser( *this ) |= other;
9525         }
9526
9527         // Forward deprecated interface with '+' instead of '|'
9528         template<typename T>
9529         auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
9530         template<typename T>
9531         auto operator+( T const &other ) const -> Parser { return operator|( other ); }
9532
9533         auto getHelpColumns() const -> std::vector<HelpColumns> {
9534             std::vector<HelpColumns> cols;
9535             for (auto const &o : m_options) {
9536                 auto childCols = o.getHelpColumns();
9537                 cols.insert( cols.end(), childCols.begin(), childCols.end() );
9538             }
9539             return cols;
9540         }
9541
9542         void writeToStream( std::ostream &os ) const {
9543             if (!m_exeName.name().empty()) {
9544                 os << "usage:\n" << "  " << m_exeName.name() << " ";
9545                 bool required = true, first = true;
9546                 for( auto const &arg : m_args ) {
9547                     if (first)
9548                         first = false;
9549                     else
9550                         os << " ";
9551                     if( arg.isOptional() && required ) {
9552                         os << "[";
9553                         required = false;
9554                     }
9555                     os << "<" << arg.hint() << ">";
9556                     if( arg.cardinality() == 0 )
9557                         os << " ... ";
9558                 }
9559                 if( !required )
9560                     os << "]";
9561                 if( !m_options.empty() )
9562                     os << " options";
9563                 os << "\n\nwhere options are:" << std::endl;
9564             }
9565
9566             auto rows = getHelpColumns();
9567             size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
9568             size_t optWidth = 0;
9569             for( auto const &cols : rows )
9570                 optWidth = (std::max)(optWidth, cols.left.size() + 2);
9571
9572             optWidth = (std::min)(optWidth, consoleWidth/2);
9573
9574             for( auto const &cols : rows ) {
9575                 auto row =
9576                         TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
9577                         TextFlow::Spacer(4) +
9578                         TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
9579                 os << row << std::endl;
9580             }
9581         }
9582
9583         friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
9584             parser.writeToStream( os );
9585             return os;
9586         }
9587
9588         auto validate() const -> Result override {
9589             for( auto const &opt : m_options ) {
9590                 auto result = opt.validate();
9591                 if( !result )
9592                     return result;
9593             }
9594             for( auto const &arg : m_args ) {
9595                 auto result = arg.validate();
9596                 if( !result )
9597                     return result;
9598             }
9599             return Result::ok();
9600         }
9601
9602         using ParserBase::parse;
9603
9604         auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
9605
9606             struct ParserInfo {
9607                 ParserBase const* parser = nullptr;
9608                 size_t count = 0;
9609             };
9610             const size_t totalParsers = m_options.size() + m_args.size();
9611             assert( totalParsers < 512 );
9612             // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
9613             ParserInfo parseInfos[512];
9614
9615             {
9616                 size_t i = 0;
9617                 for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
9618                 for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
9619             }
9620
9621             m_exeName.set( exeName );
9622
9623             auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9624             while( result.value().remainingTokens() ) {
9625                 bool tokenParsed = false;
9626
9627                 for( size_t i = 0; i < totalParsers; ++i ) {
9628                     auto&  parseInfo = parseInfos[i];
9629                     if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
9630                         result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
9631                         if (!result)
9632                             return result;
9633                         if (result.value().type() != ParseResultType::NoMatch) {
9634                             tokenParsed = true;
9635                             ++parseInfo.count;
9636                             break;
9637                         }
9638                     }
9639                 }
9640
9641                 if( result.value().type() == ParseResultType::ShortCircuitAll )
9642                     return result;
9643                 if( !tokenParsed )
9644                     return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
9645             }
9646             // !TBD Check missing required options
9647             return result;
9648         }
9649     };
9650
9651     template<typename DerivedT>
9652     template<typename T>
9653     auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
9654         return Parser() | static_cast<DerivedT const &>( *this ) | other;
9655     }
9656 } // namespace detail
9657
9658 // A Combined parser
9659 using detail::Parser;
9660
9661 // A parser for options
9662 using detail::Opt;
9663
9664 // A parser for arguments
9665 using detail::Arg;
9666
9667 // Wrapper for argc, argv from main()
9668 using detail::Args;
9669
9670 // Specifies the name of the executable
9671 using detail::ExeName;
9672
9673 // Convenience wrapper for option parser that specifies the help option
9674 using detail::Help;
9675
9676 // enum of result types from a parse
9677 using detail::ParseResultType;
9678
9679 // Result type for parser operation
9680 using detail::ParserResult;
9681
9682 }} // namespace Catch::clara
9683
9684 // end clara.hpp
9685 #ifdef __clang__
9686 #pragma clang diagnostic pop
9687 #endif
9688
9689 // Restore Clara's value for console width, if present
9690 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9691 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9692 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9693 #endif
9694
9695 // end catch_clara.h
9696 namespace Catch {
9697
9698     clara::Parser makeCommandLineParser( ConfigData& config );
9699
9700 } // end namespace Catch
9701
9702 // end catch_commandline.h
9703 #include <fstream>
9704 #include <ctime>
9705
9706 namespace Catch {
9707
9708     clara::Parser makeCommandLineParser( ConfigData& config ) {
9709
9710         using namespace clara;
9711
9712         auto const setWarning = [&]( std::string const& warning ) {
9713                 auto warningSet = [&]() {
9714                     if( warning == "NoAssertions" )
9715                         return WarnAbout::NoAssertions;
9716
9717                     if ( warning == "NoTests" )
9718                         return WarnAbout::NoTests;
9719
9720                     return WarnAbout::Nothing;
9721                 }();
9722
9723                 if (warningSet == WarnAbout::Nothing)
9724                     return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
9725                 config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
9726                 return ParserResult::ok( ParseResultType::Matched );
9727             };
9728         auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
9729                 std::ifstream f( filename.c_str() );
9730                 if( !f.is_open() )
9731                     return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
9732
9733                 std::string line;
9734                 while( std::getline( f, line ) ) {
9735                     line = trim(line);
9736                     if( !line.empty() && !startsWith( line, '#' ) ) {
9737                         if( !startsWith( line, '"' ) )
9738                             line = '"' + line + '"';
9739                         config.testsOrTags.push_back( line );
9740                         config.testsOrTags.emplace_back( "," );
9741                     }
9742                 }
9743                 //Remove comma in the end
9744                 if(!config.testsOrTags.empty())
9745                     config.testsOrTags.erase( config.testsOrTags.end()-1 );
9746
9747                 return ParserResult::ok( ParseResultType::Matched );
9748             };
9749         auto const setTestOrder = [&]( std::string const& order ) {
9750                 if( startsWith( "declared", order ) )
9751                     config.runOrder = RunTests::InDeclarationOrder;
9752                 else if( startsWith( "lexical", order ) )
9753                     config.runOrder = RunTests::InLexicographicalOrder;
9754                 else if( startsWith( "random", order ) )
9755                     config.runOrder = RunTests::InRandomOrder;
9756                 else
9757                     return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
9758                 return ParserResult::ok( ParseResultType::Matched );
9759             };
9760         auto const setRngSeed = [&]( std::string const& seed ) {
9761                 if( seed != "time" )
9762                     return clara::detail::convertInto( seed, config.rngSeed );
9763                 config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
9764                 return ParserResult::ok( ParseResultType::Matched );
9765             };
9766         auto const setColourUsage = [&]( std::string const& useColour ) {
9767                     auto mode = toLower( useColour );
9768
9769                     if( mode == "yes" )
9770                         config.useColour = UseColour::Yes;
9771                     else if( mode == "no" )
9772                         config.useColour = UseColour::No;
9773                     else if( mode == "auto" )
9774                         config.useColour = UseColour::Auto;
9775                     else
9776                         return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
9777                 return ParserResult::ok( ParseResultType::Matched );
9778             };
9779         auto const setWaitForKeypress = [&]( std::string const& keypress ) {
9780                 auto keypressLc = toLower( keypress );
9781                 if (keypressLc == "never")
9782                     config.waitForKeypress = WaitForKeypress::Never;
9783                 else if( keypressLc == "start" )
9784                     config.waitForKeypress = WaitForKeypress::BeforeStart;
9785                 else if( keypressLc == "exit" )
9786                     config.waitForKeypress = WaitForKeypress::BeforeExit;
9787                 else if( keypressLc == "both" )
9788                     config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
9789                 else
9790                     return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
9791             return ParserResult::ok( ParseResultType::Matched );
9792             };
9793         auto const setVerbosity = [&]( std::string const& verbosity ) {
9794             auto lcVerbosity = toLower( verbosity );
9795             if( lcVerbosity == "quiet" )
9796                 config.verbosity = Verbosity::Quiet;
9797             else if( lcVerbosity == "normal" )
9798                 config.verbosity = Verbosity::Normal;
9799             else if( lcVerbosity == "high" )
9800                 config.verbosity = Verbosity::High;
9801             else
9802                 return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
9803             return ParserResult::ok( ParseResultType::Matched );
9804         };
9805         auto const setReporter = [&]( std::string const& reporter ) {
9806             IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
9807
9808             auto lcReporter = toLower( reporter );
9809             auto result = factories.find( lcReporter );
9810
9811             if( factories.end() != result )
9812                 config.reporterName = lcReporter;
9813             else
9814                 return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
9815             return ParserResult::ok( ParseResultType::Matched );
9816         };
9817
9818         auto cli
9819             = ExeName( config.processName )
9820             | Help( config.showHelp )
9821             | Opt( config.listTests )
9822                 ["-l"]["--list-tests"]
9823                 ( "list all/matching test cases" )
9824             | Opt( config.listTags )
9825                 ["-t"]["--list-tags"]
9826                 ( "list all/matching tags" )
9827             | Opt( config.showSuccessfulTests )
9828                 ["-s"]["--success"]
9829                 ( "include successful tests in output" )
9830             | Opt( config.shouldDebugBreak )
9831                 ["-b"]["--break"]
9832                 ( "break into debugger on failure" )
9833             | Opt( config.noThrow )
9834                 ["-e"]["--nothrow"]
9835                 ( "skip exception tests" )
9836             | Opt( config.showInvisibles )
9837                 ["-i"]["--invisibles"]
9838                 ( "show invisibles (tabs, newlines)" )
9839             | Opt( config.outputFilename, "filename" )
9840                 ["-o"]["--out"]
9841                 ( "output filename" )
9842             | Opt( setReporter, "name" )
9843                 ["-r"]["--reporter"]
9844                 ( "reporter to use (defaults to console)" )
9845             | Opt( config.name, "name" )
9846                 ["-n"]["--name"]
9847                 ( "suite name" )
9848             | Opt( [&]( bool ){ config.abortAfter = 1; } )
9849                 ["-a"]["--abort"]
9850                 ( "abort at first failure" )
9851             | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
9852                 ["-x"]["--abortx"]
9853                 ( "abort after x failures" )
9854             | Opt( setWarning, "warning name" )
9855                 ["-w"]["--warn"]
9856                 ( "enable warnings" )
9857             | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
9858                 ["-d"]["--durations"]
9859                 ( "show test durations" )
9860             | Opt( loadTestNamesFromFile, "filename" )
9861                 ["-f"]["--input-file"]
9862                 ( "load test names to run from a file" )
9863             | Opt( config.filenamesAsTags )
9864                 ["-#"]["--filenames-as-tags"]
9865                 ( "adds a tag for the filename" )
9866             | Opt( config.sectionsToRun, "section name" )
9867                 ["-c"]["--section"]
9868                 ( "specify section to run" )
9869             | Opt( setVerbosity, "quiet|normal|high" )
9870                 ["-v"]["--verbosity"]
9871                 ( "set output verbosity" )
9872             | Opt( config.listTestNamesOnly )
9873                 ["--list-test-names-only"]
9874                 ( "list all/matching test cases names only" )
9875             | Opt( config.listReporters )
9876                 ["--list-reporters"]
9877                 ( "list all reporters" )
9878             | Opt( setTestOrder, "decl|lex|rand" )
9879                 ["--order"]
9880                 ( "test case order (defaults to decl)" )
9881             | Opt( setRngSeed, "'time'|number" )
9882                 ["--rng-seed"]
9883                 ( "set a specific seed for random numbers" )
9884             | Opt( setColourUsage, "yes|no" )
9885                 ["--use-colour"]
9886                 ( "should output be colourised" )
9887             | Opt( config.libIdentify )
9888                 ["--libidentify"]
9889                 ( "report name and version according to libidentify standard" )
9890             | Opt( setWaitForKeypress, "never|start|exit|both" )
9891                 ["--wait-for-keypress"]
9892                 ( "waits for a keypress before exiting" )
9893             | Opt( config.benchmarkSamples, "samples" )
9894                 ["--benchmark-samples"]
9895                 ( "number of samples to collect (default: 100)" )
9896             | Opt( config.benchmarkResamples, "resamples" )
9897                 ["--benchmark-resamples"]
9898                 ( "number of resamples for the bootstrap (default: 100000)" )
9899             | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
9900                 ["--benchmark-confidence-interval"]
9901                 ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
9902             | Opt( config.benchmarkNoAnalysis )
9903                 ["--benchmark-no-analysis"]
9904                 ( "perform only measurements; do not perform any analysis" )
9905             | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
9906                 ["--benchmark-warmup-time"]
9907                 ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
9908             | Arg( config.testsOrTags, "test name|pattern|tags" )
9909                 ( "which test or tests to use" );
9910
9911         return cli;
9912     }
9913
9914 } // end namespace Catch
9915 // end catch_commandline.cpp
9916 // start catch_common.cpp
9917
9918 #include <cstring>
9919 #include <ostream>
9920
9921 namespace Catch {
9922
9923     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
9924         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
9925     }
9926     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
9927         // We can assume that the same file will usually have the same pointer.
9928         // Thus, if the pointers are the same, there is no point in calling the strcmp
9929         return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
9930     }
9931
9932     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
9933 #ifndef __GNUG__
9934         os << info.file << '(' << info.line << ')';
9935 #else
9936         os << info.file << ':' << info.line;
9937 #endif
9938         return os;
9939     }
9940
9941     std::string StreamEndStop::operator+() const {
9942         return std::string();
9943     }
9944
9945     NonCopyable::NonCopyable() = default;
9946     NonCopyable::~NonCopyable() = default;
9947
9948 }
9949 // end catch_common.cpp
9950 // start catch_config.cpp
9951
9952 namespace Catch {
9953
9954     Config::Config( ConfigData const& data )
9955     :   m_data( data ),
9956         m_stream( openStream() )
9957     {
9958         // We need to trim filter specs to avoid trouble with superfluous
9959         // whitespace (esp. important for bdd macros, as those are manually
9960         // aligned with whitespace).
9961
9962         for (auto& elem : m_data.testsOrTags) {
9963             elem = trim(elem);
9964         }
9965         for (auto& elem : m_data.sectionsToRun) {
9966             elem = trim(elem);
9967         }
9968
9969         TestSpecParser parser(ITagAliasRegistry::get());
9970         if (!m_data.testsOrTags.empty()) {
9971             m_hasTestFilters = true;
9972             for (auto const& testOrTags : m_data.testsOrTags) {
9973                 parser.parse(testOrTags);
9974             }
9975         }
9976         m_testSpec = parser.testSpec();
9977     }
9978
9979     std::string const& Config::getFilename() const {
9980         return m_data.outputFilename ;
9981     }
9982
9983     bool Config::listTests() const          { return m_data.listTests; }
9984     bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }
9985     bool Config::listTags() const           { return m_data.listTags; }
9986     bool Config::listReporters() const      { return m_data.listReporters; }
9987
9988     std::string Config::getProcessName() const { return m_data.processName; }
9989     std::string const& Config::getReporterName() const { return m_data.reporterName; }
9990
9991     std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
9992     std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
9993
9994     TestSpec const& Config::testSpec() const { return m_testSpec; }
9995     bool Config::hasTestFilters() const { return m_hasTestFilters; }
9996
9997     bool Config::showHelp() const { return m_data.showHelp; }
9998
9999     // IConfig interface
10000     bool Config::allowThrows() const                   { return !m_data.noThrow; }
10001     std::ostream& Config::stream() const               { return m_stream->stream(); }
10002     std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }
10003     bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }
10004     bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }
10005     bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }
10006     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
10007     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
10008     unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
10009     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
10010     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
10011     int Config::abortAfter() const                     { return m_data.abortAfter; }
10012     bool Config::showInvisibles() const                { return m_data.showInvisibles; }
10013     Verbosity Config::verbosity() const                { return m_data.verbosity; }
10014
10015     bool Config::benchmarkNoAnalysis() const                      { return m_data.benchmarkNoAnalysis; }
10016     int Config::benchmarkSamples() const                          { return m_data.benchmarkSamples; }
10017     double Config::benchmarkConfidenceInterval() const            { return m_data.benchmarkConfidenceInterval; }
10018     unsigned int Config::benchmarkResamples() const               { return m_data.benchmarkResamples; }
10019     std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
10020
10021     IStream const* Config::openStream() {
10022         return Catch::makeStream(m_data.outputFilename);
10023     }
10024
10025 } // end namespace Catch
10026 // end catch_config.cpp
10027 // start catch_console_colour.cpp
10028
10029 #if defined(__clang__)
10030 #    pragma clang diagnostic push
10031 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
10032 #endif
10033
10034 // start catch_errno_guard.h
10035
10036 namespace Catch {
10037
10038     class ErrnoGuard {
10039     public:
10040         ErrnoGuard();
10041         ~ErrnoGuard();
10042     private:
10043         int m_oldErrno;
10044     };
10045
10046 }
10047
10048 // end catch_errno_guard.h
10049 #include <sstream>
10050
10051 namespace Catch {
10052     namespace {
10053
10054         struct IColourImpl {
10055             virtual ~IColourImpl() = default;
10056             virtual void use( Colour::Code _colourCode ) = 0;
10057         };
10058
10059         struct NoColourImpl : IColourImpl {
10060             void use( Colour::Code ) override {}
10061
10062             static IColourImpl* instance() {
10063                 static NoColourImpl s_instance;
10064                 return &s_instance;
10065             }
10066         };
10067
10068     } // anon namespace
10069 } // namespace Catch
10070
10071 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
10072 #   ifdef CATCH_PLATFORM_WINDOWS
10073 #       define CATCH_CONFIG_COLOUR_WINDOWS
10074 #   else
10075 #       define CATCH_CONFIG_COLOUR_ANSI
10076 #   endif
10077 #endif
10078
10079 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
10080
10081 namespace Catch {
10082 namespace {
10083
10084     class Win32ColourImpl : public IColourImpl {
10085     public:
10086         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
10087         {
10088             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
10089             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
10090             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
10091             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
10092         }
10093
10094         void use( Colour::Code _colourCode ) override {
10095             switch( _colourCode ) {
10096                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
10097                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10098                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
10099                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
10100                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
10101                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
10102                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
10103                 case Colour::Grey:      return setTextAttribute( 0 );
10104
10105                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
10106                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
10107                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
10108                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10109                 case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
10110
10111                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10112
10113                 default:
10114                     CATCH_ERROR( "Unknown colour requested" );
10115             }
10116         }
10117
10118     private:
10119         void setTextAttribute( WORD _textAttribute ) {
10120             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
10121         }
10122         HANDLE stdoutHandle;
10123         WORD originalForegroundAttributes;
10124         WORD originalBackgroundAttributes;
10125     };
10126
10127     IColourImpl* platformColourInstance() {
10128         static Win32ColourImpl s_instance;
10129
10130         IConfigPtr config = getCurrentContext().getConfig();
10131         UseColour::YesOrNo colourMode = config
10132             ? config->useColour()
10133             : UseColour::Auto;
10134         if( colourMode == UseColour::Auto )
10135             colourMode = UseColour::Yes;
10136         return colourMode == UseColour::Yes
10137             ? &s_instance
10138             : NoColourImpl::instance();
10139     }
10140
10141 } // end anon namespace
10142 } // end namespace Catch
10143
10144 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
10145
10146 #include <unistd.h>
10147
10148 namespace Catch {
10149 namespace {
10150
10151     // use POSIX/ ANSI console terminal codes
10152     // Thanks to Adam Strzelecki for original contribution
10153     // (http://github.com/nanoant)
10154     // https://github.com/philsquared/Catch/pull/131
10155     class PosixColourImpl : public IColourImpl {
10156     public:
10157         void use( Colour::Code _colourCode ) override {
10158             switch( _colourCode ) {
10159                 case Colour::None:
10160                 case Colour::White:     return setColour( "[0m" );
10161                 case Colour::Red:       return setColour( "[0;31m" );
10162                 case Colour::Green:     return setColour( "[0;32m" );
10163                 case Colour::Blue:      return setColour( "[0;34m" );
10164                 case Colour::Cyan:      return setColour( "[0;36m" );
10165                 case Colour::Yellow:    return setColour( "[0;33m" );
10166                 case Colour::Grey:      return setColour( "[1;30m" );
10167
10168                 case Colour::LightGrey:     return setColour( "[0;37m" );
10169                 case Colour::BrightRed:     return setColour( "[1;31m" );
10170                 case Colour::BrightGreen:   return setColour( "[1;32m" );
10171                 case Colour::BrightWhite:   return setColour( "[1;37m" );
10172                 case Colour::BrightYellow:  return setColour( "[1;33m" );
10173
10174                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10175                 default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
10176             }
10177         }
10178         static IColourImpl* instance() {
10179             static PosixColourImpl s_instance;
10180             return &s_instance;
10181         }
10182
10183     private:
10184         void setColour( const char* _escapeCode ) {
10185             getCurrentContext().getConfig()->stream()
10186                 << '\033' << _escapeCode;
10187         }
10188     };
10189
10190     bool useColourOnPlatform() {
10191         return
10192 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10193             !isDebuggerActive() &&
10194 #endif
10195 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
10196             isatty(STDOUT_FILENO)
10197 #else
10198             false
10199 #endif
10200             ;
10201     }
10202     IColourImpl* platformColourInstance() {
10203         ErrnoGuard guard;
10204         IConfigPtr config = getCurrentContext().getConfig();
10205         UseColour::YesOrNo colourMode = config
10206             ? config->useColour()
10207             : UseColour::Auto;
10208         if( colourMode == UseColour::Auto )
10209             colourMode = useColourOnPlatform()
10210                 ? UseColour::Yes
10211                 : UseColour::No;
10212         return colourMode == UseColour::Yes
10213             ? PosixColourImpl::instance()
10214             : NoColourImpl::instance();
10215     }
10216
10217 } // end anon namespace
10218 } // end namespace Catch
10219
10220 #else  // not Windows or ANSI ///////////////////////////////////////////////
10221
10222 namespace Catch {
10223
10224     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
10225
10226 } // end namespace Catch
10227
10228 #endif // Windows/ ANSI/ None
10229
10230 namespace Catch {
10231
10232     Colour::Colour( Code _colourCode ) { use( _colourCode ); }
10233     Colour::Colour( Colour&& other ) noexcept {
10234         m_moved = other.m_moved;
10235         other.m_moved = true;
10236     }
10237     Colour& Colour::operator=( Colour&& other ) noexcept {
10238         m_moved = other.m_moved;
10239         other.m_moved  = true;
10240         return *this;
10241     }
10242
10243     Colour::~Colour(){ if( !m_moved ) use( None ); }
10244
10245     void Colour::use( Code _colourCode ) {
10246         static IColourImpl* impl = platformColourInstance();
10247         // Strictly speaking, this cannot possibly happen.
10248         // However, under some conditions it does happen (see #1626),
10249         // and this change is small enough that we can let practicality
10250         // triumph over purity in this case.
10251         if (impl != nullptr) {
10252             impl->use( _colourCode );
10253         }
10254     }
10255
10256     std::ostream& operator << ( std::ostream& os, Colour const& ) {
10257         return os;
10258     }
10259
10260 } // end namespace Catch
10261
10262 #if defined(__clang__)
10263 #    pragma clang diagnostic pop
10264 #endif
10265
10266 // end catch_console_colour.cpp
10267 // start catch_context.cpp
10268
10269 namespace Catch {
10270
10271     class Context : public IMutableContext, NonCopyable {
10272
10273     public: // IContext
10274         IResultCapture* getResultCapture() override {
10275             return m_resultCapture;
10276         }
10277         IRunner* getRunner() override {
10278             return m_runner;
10279         }
10280
10281         IConfigPtr const& getConfig() const override {
10282             return m_config;
10283         }
10284
10285         ~Context() override;
10286
10287     public: // IMutableContext
10288         void setResultCapture( IResultCapture* resultCapture ) override {
10289             m_resultCapture = resultCapture;
10290         }
10291         void setRunner( IRunner* runner ) override {
10292             m_runner = runner;
10293         }
10294         void setConfig( IConfigPtr const& config ) override {
10295             m_config = config;
10296         }
10297
10298         friend IMutableContext& getCurrentMutableContext();
10299
10300     private:
10301         IConfigPtr m_config;
10302         IRunner* m_runner = nullptr;
10303         IResultCapture* m_resultCapture = nullptr;
10304     };
10305
10306     IMutableContext *IMutableContext::currentContext = nullptr;
10307
10308     void IMutableContext::createContext()
10309     {
10310         currentContext = new Context();
10311     }
10312
10313     void cleanUpContext() {
10314         delete IMutableContext::currentContext;
10315         IMutableContext::currentContext = nullptr;
10316     }
10317     IContext::~IContext() = default;
10318     IMutableContext::~IMutableContext() = default;
10319     Context::~Context() = default;
10320
10321     SimplePcg32& rng() {
10322         static SimplePcg32 s_rng;
10323         return s_rng;
10324     }
10325
10326 }
10327 // end catch_context.cpp
10328 // start catch_debug_console.cpp
10329
10330 // start catch_debug_console.h
10331
10332 #include <string>
10333
10334 namespace Catch {
10335     void writeToDebugConsole( std::string const& text );
10336 }
10337
10338 // end catch_debug_console.h
10339 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
10340 #include <android/log.h>
10341
10342     namespace Catch {
10343         void writeToDebugConsole( std::string const& text ) {
10344             __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
10345         }
10346     }
10347
10348 #elif defined(CATCH_PLATFORM_WINDOWS)
10349
10350     namespace Catch {
10351         void writeToDebugConsole( std::string const& text ) {
10352             ::OutputDebugStringA( text.c_str() );
10353         }
10354     }
10355
10356 #else
10357
10358     namespace Catch {
10359         void writeToDebugConsole( std::string const& text ) {
10360             // !TBD: Need a version for Mac/ XCode and other IDEs
10361             Catch::cout() << text;
10362         }
10363     }
10364
10365 #endif // Platform
10366 // end catch_debug_console.cpp
10367 // start catch_debugger.cpp
10368
10369 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10370
10371 #  include <cassert>
10372 #  include <sys/types.h>
10373 #  include <unistd.h>
10374 #  include <cstddef>
10375 #  include <ostream>
10376
10377 #ifdef __apple_build_version__
10378     // These headers will only compile with AppleClang (XCode)
10379     // For other compilers (Clang, GCC, ... ) we need to exclude them
10380 #  include <sys/sysctl.h>
10381 #endif
10382
10383     namespace Catch {
10384         #ifdef __apple_build_version__
10385         // The following function is taken directly from the following technical note:
10386         // https://developer.apple.com/library/archive/qa/qa1361/_index.html
10387
10388         // Returns true if the current process is being debugged (either
10389         // running under the debugger or has a debugger attached post facto).
10390         bool isDebuggerActive(){
10391             int                 mib[4];
10392             struct kinfo_proc   info;
10393             std::size_t         size;
10394
10395             // Initialize the flags so that, if sysctl fails for some bizarre
10396             // reason, we get a predictable result.
10397
10398             info.kp_proc.p_flag = 0;
10399
10400             // Initialize mib, which tells sysctl the info we want, in this case
10401             // we're looking for information about a specific process ID.
10402
10403             mib[0] = CTL_KERN;
10404             mib[1] = KERN_PROC;
10405             mib[2] = KERN_PROC_PID;
10406             mib[3] = getpid();
10407
10408             // Call sysctl.
10409
10410             size = sizeof(info);
10411             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
10412                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
10413                 return false;
10414             }
10415
10416             // We're being debugged if the P_TRACED flag is set.
10417
10418             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
10419         }
10420         #else
10421         bool isDebuggerActive() {
10422             // We need to find another way to determine this for non-appleclang compilers on macOS
10423             return false;
10424         }
10425         #endif
10426     } // namespace Catch
10427
10428 #elif defined(CATCH_PLATFORM_LINUX)
10429     #include <fstream>
10430     #include <string>
10431
10432     namespace Catch{
10433         // The standard POSIX way of detecting a debugger is to attempt to
10434         // ptrace() the process, but this needs to be done from a child and not
10435         // this process itself to still allow attaching to this process later
10436         // if wanted, so is rather heavy. Under Linux we have the PID of the
10437         // "debugger" (which doesn't need to be gdb, of course, it could also
10438         // be strace, for example) in /proc/$PID/status, so just get it from
10439         // there instead.
10440         bool isDebuggerActive(){
10441             // Libstdc++ has a bug, where std::ifstream sets errno to 0
10442             // This way our users can properly assert over errno values
10443             ErrnoGuard guard;
10444             std::ifstream in("/proc/self/status");
10445             for( std::string line; std::getline(in, line); ) {
10446                 static const int PREFIX_LEN = 11;
10447                 if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
10448                     // We're traced if the PID is not 0 and no other PID starts
10449                     // with 0 digit, so it's enough to check for just a single
10450                     // character.
10451                     return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
10452                 }
10453             }
10454
10455             return false;
10456         }
10457     } // namespace Catch
10458 #elif defined(_MSC_VER)
10459     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10460     namespace Catch {
10461         bool isDebuggerActive() {
10462             return IsDebuggerPresent() != 0;
10463         }
10464     }
10465 #elif defined(__MINGW32__)
10466     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10467     namespace Catch {
10468         bool isDebuggerActive() {
10469             return IsDebuggerPresent() != 0;
10470         }
10471     }
10472 #else
10473     namespace Catch {
10474        bool isDebuggerActive() { return false; }
10475     }
10476 #endif // Platform
10477 // end catch_debugger.cpp
10478 // start catch_decomposer.cpp
10479
10480 namespace Catch {
10481
10482     ITransientExpression::~ITransientExpression() = default;
10483
10484     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
10485         if( lhs.size() + rhs.size() < 40 &&
10486                 lhs.find('\n') == std::string::npos &&
10487                 rhs.find('\n') == std::string::npos )
10488             os << lhs << " " << op << " " << rhs;
10489         else
10490             os << lhs << "\n" << op << "\n" << rhs;
10491     }
10492 }
10493 // end catch_decomposer.cpp
10494 // start catch_enforce.cpp
10495
10496 #include <stdexcept>
10497
10498 namespace Catch {
10499 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
10500     [[noreturn]]
10501     void throw_exception(std::exception const& e) {
10502         Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
10503                       << "The message was: " << e.what() << '\n';
10504         std::terminate();
10505     }
10506 #endif
10507
10508     [[noreturn]]
10509     void throw_logic_error(std::string const& msg) {
10510         throw_exception(std::logic_error(msg));
10511     }
10512
10513     [[noreturn]]
10514     void throw_domain_error(std::string const& msg) {
10515         throw_exception(std::domain_error(msg));
10516     }
10517
10518     [[noreturn]]
10519     void throw_runtime_error(std::string const& msg) {
10520         throw_exception(std::runtime_error(msg));
10521     }
10522
10523 } // namespace Catch;
10524 // end catch_enforce.cpp
10525 // start catch_enum_values_registry.cpp
10526 // start catch_enum_values_registry.h
10527
10528 #include <vector>
10529 #include <memory>
10530
10531 namespace Catch {
10532
10533     namespace Detail {
10534
10535         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
10536
10537         class EnumValuesRegistry : public IMutableEnumValuesRegistry {
10538
10539             std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
10540
10541             EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
10542         };
10543
10544         std::vector<StringRef> parseEnums( StringRef enums );
10545
10546     } // Detail
10547
10548 } // Catch
10549
10550 // end catch_enum_values_registry.h
10551
10552 #include <map>
10553 #include <cassert>
10554
10555 namespace Catch {
10556
10557     IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
10558
10559     namespace Detail {
10560
10561         namespace {
10562             // Extracts the actual name part of an enum instance
10563             // In other words, it returns the Blue part of Bikeshed::Colour::Blue
10564             StringRef extractInstanceName(StringRef enumInstance) {
10565                 // Find last occurence of ":"
10566                 size_t name_start = enumInstance.size();
10567                 while (name_start > 0 && enumInstance[name_start - 1] != ':') {
10568                     --name_start;
10569                 }
10570                 return enumInstance.substr(name_start, enumInstance.size() - name_start);
10571             }
10572         }
10573
10574         std::vector<StringRef> parseEnums( StringRef enums ) {
10575             auto enumValues = splitStringRef( enums, ',' );
10576             std::vector<StringRef> parsed;
10577             parsed.reserve( enumValues.size() );
10578             for( auto const& enumValue : enumValues ) {
10579                 parsed.push_back(trim(extractInstanceName(enumValue)));
10580             }
10581             return parsed;
10582         }
10583
10584         EnumInfo::~EnumInfo() {}
10585
10586         StringRef EnumInfo::lookup( int value ) const {
10587             for( auto const& valueToName : m_values ) {
10588                 if( valueToName.first == value )
10589                     return valueToName.second;
10590             }
10591             return "{** unexpected enum value **}"_sr;
10592         }
10593
10594         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10595             std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
10596             enumInfo->m_name = enumName;
10597             enumInfo->m_values.reserve( values.size() );
10598
10599             const auto valueNames = Catch::Detail::parseEnums( allValueNames );
10600             assert( valueNames.size() == values.size() );
10601             std::size_t i = 0;
10602             for( auto value : values )
10603                 enumInfo->m_values.emplace_back(value, valueNames[i++]);
10604
10605             return enumInfo;
10606         }
10607
10608         EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10609             m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
10610             return *m_enumInfos.back();
10611         }
10612
10613     } // Detail
10614 } // Catch
10615
10616 // end catch_enum_values_registry.cpp
10617 // start catch_errno_guard.cpp
10618
10619 #include <cerrno>
10620
10621 namespace Catch {
10622         ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
10623         ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
10624 }
10625 // end catch_errno_guard.cpp
10626 // start catch_exception_translator_registry.cpp
10627
10628 // start catch_exception_translator_registry.h
10629
10630 #include <vector>
10631 #include <string>
10632 #include <memory>
10633
10634 namespace Catch {
10635
10636     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
10637     public:
10638         ~ExceptionTranslatorRegistry();
10639         virtual void registerTranslator( const IExceptionTranslator* translator );
10640         std::string translateActiveException() const override;
10641         std::string tryTranslators() const;
10642
10643     private:
10644         std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
10645     };
10646 }
10647
10648 // end catch_exception_translator_registry.h
10649 #ifdef __OBJC__
10650 #import "Foundation/Foundation.h"
10651 #endif
10652
10653 namespace Catch {
10654
10655     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
10656     }
10657
10658     void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
10659         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
10660     }
10661
10662 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10663     std::string ExceptionTranslatorRegistry::translateActiveException() const {
10664         try {
10665 #ifdef __OBJC__
10666             // In Objective-C try objective-c exceptions first
10667             @try {
10668                 return tryTranslators();
10669             }
10670             @catch (NSException *exception) {
10671                 return Catch::Detail::stringify( [exception description] );
10672             }
10673 #else
10674             // Compiling a mixed mode project with MSVC means that CLR
10675             // exceptions will be caught in (...) as well. However, these
10676             // do not fill-in std::current_exception and thus lead to crash
10677             // when attempting rethrow.
10678             // /EHa switch also causes structured exceptions to be caught
10679             // here, but they fill-in current_exception properly, so
10680             // at worst the output should be a little weird, instead of
10681             // causing a crash.
10682             if (std::current_exception() == nullptr) {
10683                 return "Non C++ exception. Possibly a CLR exception.";
10684             }
10685             return tryTranslators();
10686 #endif
10687         }
10688         catch( TestFailureException& ) {
10689             std::rethrow_exception(std::current_exception());
10690         }
10691         catch( std::exception& ex ) {
10692             return ex.what();
10693         }
10694         catch( std::string& msg ) {
10695             return msg;
10696         }
10697         catch( const char* msg ) {
10698             return msg;
10699         }
10700         catch(...) {
10701             return "Unknown exception";
10702         }
10703     }
10704
10705     std::string ExceptionTranslatorRegistry::tryTranslators() const {
10706         if (m_translators.empty()) {
10707             std::rethrow_exception(std::current_exception());
10708         } else {
10709             return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
10710         }
10711     }
10712
10713 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
10714     std::string ExceptionTranslatorRegistry::translateActiveException() const {
10715         CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10716     }
10717
10718     std::string ExceptionTranslatorRegistry::tryTranslators() const {
10719         CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10720     }
10721 #endif
10722
10723 }
10724 // end catch_exception_translator_registry.cpp
10725 // start catch_fatal_condition.cpp
10726
10727 #if defined(__GNUC__)
10728 #    pragma GCC diagnostic push
10729 #    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
10730 #endif
10731
10732 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
10733
10734 namespace {
10735     // Report the error condition
10736     void reportFatal( char const * const message ) {
10737         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
10738     }
10739 }
10740
10741 #endif // signals/SEH handling
10742
10743 #if defined( CATCH_CONFIG_WINDOWS_SEH )
10744
10745 namespace Catch {
10746     struct SignalDefs { DWORD id; const char* name; };
10747
10748     // There is no 1-1 mapping between signals and windows exceptions.
10749     // Windows can easily distinguish between SO and SigSegV,
10750     // but SigInt, SigTerm, etc are handled differently.
10751     static SignalDefs signalDefs[] = {
10752         { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  "SIGILL - Illegal instruction signal" },
10753         { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
10754         { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
10755         { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
10756     };
10757
10758     LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
10759         for (auto const& def : signalDefs) {
10760             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
10761                 reportFatal(def.name);
10762             }
10763         }
10764         // If its not an exception we care about, pass it along.
10765         // This stops us from eating debugger breaks etc.
10766         return EXCEPTION_CONTINUE_SEARCH;
10767     }
10768
10769     FatalConditionHandler::FatalConditionHandler() {
10770         isSet = true;
10771         // 32k seems enough for Catch to handle stack overflow,
10772         // but the value was found experimentally, so there is no strong guarantee
10773         guaranteeSize = 32 * 1024;
10774         exceptionHandlerHandle = nullptr;
10775         // Register as first handler in current chain
10776         exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
10777         // Pass in guarantee size to be filled
10778         SetThreadStackGuarantee(&guaranteeSize);
10779     }
10780
10781     void FatalConditionHandler::reset() {
10782         if (isSet) {
10783             RemoveVectoredExceptionHandler(exceptionHandlerHandle);
10784             SetThreadStackGuarantee(&guaranteeSize);
10785             exceptionHandlerHandle = nullptr;
10786             isSet = false;
10787         }
10788     }
10789
10790     FatalConditionHandler::~FatalConditionHandler() {
10791         reset();
10792     }
10793
10794 bool FatalConditionHandler::isSet = false;
10795 ULONG FatalConditionHandler::guaranteeSize = 0;
10796 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
10797
10798 } // namespace Catch
10799
10800 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
10801
10802 namespace Catch {
10803
10804     struct SignalDefs {
10805         int id;
10806         const char* name;
10807     };
10808
10809     // 32kb for the alternate stack seems to be sufficient. However, this value
10810     // is experimentally determined, so that's not guaranteed.
10811     static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
10812
10813     static SignalDefs signalDefs[] = {
10814         { SIGINT,  "SIGINT - Terminal interrupt signal" },
10815         { SIGILL,  "SIGILL - Illegal instruction signal" },
10816         { SIGFPE,  "SIGFPE - Floating point error signal" },
10817         { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
10818         { SIGTERM, "SIGTERM - Termination request signal" },
10819         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
10820     };
10821
10822     void FatalConditionHandler::handleSignal( int sig ) {
10823         char const * name = "<unknown signal>";
10824         for (auto const& def : signalDefs) {
10825             if (sig == def.id) {
10826                 name = def.name;
10827                 break;
10828             }
10829         }
10830         reset();
10831         reportFatal(name);
10832         raise( sig );
10833     }
10834
10835     FatalConditionHandler::FatalConditionHandler() {
10836         isSet = true;
10837         stack_t sigStack;
10838         sigStack.ss_sp = altStackMem;
10839         sigStack.ss_size = sigStackSize;
10840         sigStack.ss_flags = 0;
10841         sigaltstack(&sigStack, &oldSigStack);
10842         struct sigaction sa = { };
10843
10844         sa.sa_handler = handleSignal;
10845         sa.sa_flags = SA_ONSTACK;
10846         for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
10847             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
10848         }
10849     }
10850
10851     FatalConditionHandler::~FatalConditionHandler() {
10852         reset();
10853     }
10854
10855     void FatalConditionHandler::reset() {
10856         if( isSet ) {
10857             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
10858             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
10859                 sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
10860             }
10861             // Return the old stack
10862             sigaltstack(&oldSigStack, nullptr);
10863             isSet = false;
10864         }
10865     }
10866
10867     bool FatalConditionHandler::isSet = false;
10868     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
10869     stack_t FatalConditionHandler::oldSigStack = {};
10870     char FatalConditionHandler::altStackMem[sigStackSize] = {};
10871
10872 } // namespace Catch
10873
10874 #else
10875
10876 namespace Catch {
10877     void FatalConditionHandler::reset() {}
10878 }
10879
10880 #endif // signals/SEH handling
10881
10882 #if defined(__GNUC__)
10883 #    pragma GCC diagnostic pop
10884 #endif
10885 // end catch_fatal_condition.cpp
10886 // start catch_generators.cpp
10887
10888 #include <limits>
10889 #include <set>
10890
10891 namespace Catch {
10892
10893 IGeneratorTracker::~IGeneratorTracker() {}
10894
10895 const char* GeneratorException::what() const noexcept {
10896     return m_msg;
10897 }
10898
10899 namespace Generators {
10900
10901     GeneratorUntypedBase::~GeneratorUntypedBase() {}
10902
10903     auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
10904         return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
10905     }
10906
10907 } // namespace Generators
10908 } // namespace Catch
10909 // end catch_generators.cpp
10910 // start catch_interfaces_capture.cpp
10911
10912 namespace Catch {
10913     IResultCapture::~IResultCapture() = default;
10914 }
10915 // end catch_interfaces_capture.cpp
10916 // start catch_interfaces_config.cpp
10917
10918 namespace Catch {
10919     IConfig::~IConfig() = default;
10920 }
10921 // end catch_interfaces_config.cpp
10922 // start catch_interfaces_exception.cpp
10923
10924 namespace Catch {
10925     IExceptionTranslator::~IExceptionTranslator() = default;
10926     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
10927 }
10928 // end catch_interfaces_exception.cpp
10929 // start catch_interfaces_registry_hub.cpp
10930
10931 namespace Catch {
10932     IRegistryHub::~IRegistryHub() = default;
10933     IMutableRegistryHub::~IMutableRegistryHub() = default;
10934 }
10935 // end catch_interfaces_registry_hub.cpp
10936 // start catch_interfaces_reporter.cpp
10937
10938 // start catch_reporter_listening.h
10939
10940 namespace Catch {
10941
10942     class ListeningReporter : public IStreamingReporter {
10943         using Reporters = std::vector<IStreamingReporterPtr>;
10944         Reporters m_listeners;
10945         IStreamingReporterPtr m_reporter = nullptr;
10946         ReporterPreferences m_preferences;
10947
10948     public:
10949         ListeningReporter();
10950
10951         void addListener( IStreamingReporterPtr&& listener );
10952         void addReporter( IStreamingReporterPtr&& reporter );
10953
10954     public: // IStreamingReporter
10955
10956         ReporterPreferences getPreferences() const override;
10957
10958         void noMatchingTestCases( std::string const& spec ) override;
10959
10960         void reportInvalidArguments(std::string const&arg) override;
10961
10962         static std::set<Verbosity> getSupportedVerbosities();
10963
10964 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
10965         void benchmarkPreparing(std::string const& name) override;
10966         void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
10967         void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
10968         void benchmarkFailed(std::string const&) override;
10969 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
10970
10971         void testRunStarting( TestRunInfo const& testRunInfo ) override;
10972         void testGroupStarting( GroupInfo const& groupInfo ) override;
10973         void testCaseStarting( TestCaseInfo const& testInfo ) override;
10974         void sectionStarting( SectionInfo const& sectionInfo ) override;
10975         void assertionStarting( AssertionInfo const& assertionInfo ) override;
10976
10977         // The return value indicates if the messages buffer should be cleared:
10978         bool assertionEnded( AssertionStats const& assertionStats ) override;
10979         void sectionEnded( SectionStats const& sectionStats ) override;
10980         void testCaseEnded( TestCaseStats const& testCaseStats ) override;
10981         void testGroupEnded( TestGroupStats const& testGroupStats ) override;
10982         void testRunEnded( TestRunStats const& testRunStats ) override;
10983
10984         void skipTest( TestCaseInfo const& testInfo ) override;
10985         bool isMulti() const override;
10986
10987     };
10988
10989 } // end namespace Catch
10990
10991 // end catch_reporter_listening.h
10992 namespace Catch {
10993
10994     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
10995     :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
10996
10997     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
10998     :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
10999
11000     std::ostream& ReporterConfig::stream() const { return *m_stream; }
11001     IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
11002
11003     TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
11004
11005     GroupInfo::GroupInfo(  std::string const& _name,
11006                            std::size_t _groupIndex,
11007                            std::size_t _groupsCount )
11008     :   name( _name ),
11009         groupIndex( _groupIndex ),
11010         groupsCounts( _groupsCount )
11011     {}
11012
11013      AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
11014                                      std::vector<MessageInfo> const& _infoMessages,
11015                                      Totals const& _totals )
11016     :   assertionResult( _assertionResult ),
11017         infoMessages( _infoMessages ),
11018         totals( _totals )
11019     {
11020         assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
11021
11022         if( assertionResult.hasMessage() ) {
11023             // Copy message into messages list.
11024             // !TBD This should have been done earlier, somewhere
11025             MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
11026             builder << assertionResult.getMessage();
11027             builder.m_info.message = builder.m_stream.str();
11028
11029             infoMessages.push_back( builder.m_info );
11030         }
11031     }
11032
11033      AssertionStats::~AssertionStats() = default;
11034
11035     SectionStats::SectionStats(  SectionInfo const& _sectionInfo,
11036                                  Counts const& _assertions,
11037                                  double _durationInSeconds,
11038                                  bool _missingAssertions )
11039     :   sectionInfo( _sectionInfo ),
11040         assertions( _assertions ),
11041         durationInSeconds( _durationInSeconds ),
11042         missingAssertions( _missingAssertions )
11043     {}
11044
11045     SectionStats::~SectionStats() = default;
11046
11047     TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,
11048                                    Totals const& _totals,
11049                                    std::string const& _stdOut,
11050                                    std::string const& _stdErr,
11051                                    bool _aborting )
11052     : testInfo( _testInfo ),
11053         totals( _totals ),
11054         stdOut( _stdOut ),
11055         stdErr( _stdErr ),
11056         aborting( _aborting )
11057     {}
11058
11059     TestCaseStats::~TestCaseStats() = default;
11060
11061     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
11062                                     Totals const& _totals,
11063                                     bool _aborting )
11064     :   groupInfo( _groupInfo ),
11065         totals( _totals ),
11066         aborting( _aborting )
11067     {}
11068
11069     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
11070     :   groupInfo( _groupInfo ),
11071         aborting( false )
11072     {}
11073
11074     TestGroupStats::~TestGroupStats() = default;
11075
11076     TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,
11077                     Totals const& _totals,
11078                     bool _aborting )
11079     :   runInfo( _runInfo ),
11080         totals( _totals ),
11081         aborting( _aborting )
11082     {}
11083
11084     TestRunStats::~TestRunStats() = default;
11085
11086     void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
11087     bool IStreamingReporter::isMulti() const { return false; }
11088
11089     IReporterFactory::~IReporterFactory() = default;
11090     IReporterRegistry::~IReporterRegistry() = default;
11091
11092 } // end namespace Catch
11093 // end catch_interfaces_reporter.cpp
11094 // start catch_interfaces_runner.cpp
11095
11096 namespace Catch {
11097     IRunner::~IRunner() = default;
11098 }
11099 // end catch_interfaces_runner.cpp
11100 // start catch_interfaces_testcase.cpp
11101
11102 namespace Catch {
11103     ITestInvoker::~ITestInvoker() = default;
11104     ITestCaseRegistry::~ITestCaseRegistry() = default;
11105 }
11106 // end catch_interfaces_testcase.cpp
11107 // start catch_leak_detector.cpp
11108
11109 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
11110 #include <crtdbg.h>
11111
11112 namespace Catch {
11113
11114     LeakDetector::LeakDetector() {
11115         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
11116         flag |= _CRTDBG_LEAK_CHECK_DF;
11117         flag |= _CRTDBG_ALLOC_MEM_DF;
11118         _CrtSetDbgFlag(flag);
11119         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
11120         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
11121         // Change this to leaking allocation's number to break there
11122         _CrtSetBreakAlloc(-1);
11123     }
11124 }
11125
11126 #else
11127
11128     Catch::LeakDetector::LeakDetector() {}
11129
11130 #endif
11131
11132 Catch::LeakDetector::~LeakDetector() {
11133     Catch::cleanUp();
11134 }
11135 // end catch_leak_detector.cpp
11136 // start catch_list.cpp
11137
11138 // start catch_list.h
11139
11140 #include <set>
11141
11142 namespace Catch {
11143
11144     std::size_t listTests( Config const& config );
11145
11146     std::size_t listTestsNamesOnly( Config const& config );
11147
11148     struct TagInfo {
11149         void add( std::string const& spelling );
11150         std::string all() const;
11151
11152         std::set<std::string> spellings;
11153         std::size_t count = 0;
11154     };
11155
11156     std::size_t listTags( Config const& config );
11157
11158     std::size_t listReporters();
11159
11160     Option<std::size_t> list( std::shared_ptr<Config> const& config );
11161
11162 } // end namespace Catch
11163
11164 // end catch_list.h
11165 // start catch_text.h
11166
11167 namespace Catch {
11168     using namespace clara::TextFlow;
11169 }
11170
11171 // end catch_text.h
11172 #include <limits>
11173 #include <algorithm>
11174 #include <iomanip>
11175
11176 namespace Catch {
11177
11178     std::size_t listTests( Config const& config ) {
11179         TestSpec const& testSpec = config.testSpec();
11180         if( config.hasTestFilters() )
11181             Catch::cout() << "Matching test cases:\n";
11182         else {
11183             Catch::cout() << "All available test cases:\n";
11184         }
11185
11186         auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11187         for( auto const& testCaseInfo : matchedTestCases ) {
11188             Colour::Code colour = testCaseInfo.isHidden()
11189                 ? Colour::SecondaryText
11190                 : Colour::None;
11191             Colour colourGuard( colour );
11192
11193             Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
11194             if( config.verbosity() >= Verbosity::High ) {
11195                 Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
11196                 std::string description = testCaseInfo.description;
11197                 if( description.empty() )
11198                     description = "(NO DESCRIPTION)";
11199                 Catch::cout() << Column( description ).indent(4) << std::endl;
11200             }
11201             if( !testCaseInfo.tags.empty() )
11202                 Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
11203         }
11204
11205         if( !config.hasTestFilters() )
11206             Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
11207         else
11208             Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
11209         return matchedTestCases.size();
11210     }
11211
11212     std::size_t listTestsNamesOnly( Config const& config ) {
11213         TestSpec const& testSpec = config.testSpec();
11214         std::size_t matchedTests = 0;
11215         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11216         for( auto const& testCaseInfo : matchedTestCases ) {
11217             matchedTests++;
11218             if( startsWith( testCaseInfo.name, '#' ) )
11219                Catch::cout() << '"' << testCaseInfo.name << '"';
11220             else
11221                Catch::cout() << testCaseInfo.name;
11222             if ( config.verbosity() >= Verbosity::High )
11223                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
11224             Catch::cout() << std::endl;
11225         }
11226         return matchedTests;
11227     }
11228
11229     void TagInfo::add( std::string const& spelling ) {
11230         ++count;
11231         spellings.insert( spelling );
11232     }
11233
11234     std::string TagInfo::all() const {
11235         size_t size = 0;
11236         for (auto const& spelling : spellings) {
11237             // Add 2 for the brackes
11238             size += spelling.size() + 2;
11239         }
11240
11241         std::string out; out.reserve(size);
11242         for (auto const& spelling : spellings) {
11243             out += '[';
11244             out += spelling;
11245             out += ']';
11246         }
11247         return out;
11248     }
11249
11250     std::size_t listTags( Config const& config ) {
11251         TestSpec const& testSpec = config.testSpec();
11252         if( config.hasTestFilters() )
11253             Catch::cout() << "Tags for matching test cases:\n";
11254         else {
11255             Catch::cout() << "All available tags:\n";
11256         }
11257
11258         std::map<std::string, TagInfo> tagCounts;
11259
11260         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11261         for( auto const& testCase : matchedTestCases ) {
11262             for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
11263                 std::string lcaseTagName = toLower( tagName );
11264                 auto countIt = tagCounts.find( lcaseTagName );
11265                 if( countIt == tagCounts.end() )
11266                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
11267                 countIt->second.add( tagName );
11268             }
11269         }
11270
11271         for( auto const& tagCount : tagCounts ) {
11272             ReusableStringStream rss;
11273             rss << "  " << std::setw(2) << tagCount.second.count << "  ";
11274             auto str = rss.str();
11275             auto wrapper = Column( tagCount.second.all() )
11276                                                     .initialIndent( 0 )
11277                                                     .indent( str.size() )
11278                                                     .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
11279             Catch::cout() << str << wrapper << '\n';
11280         }
11281         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
11282         return tagCounts.size();
11283     }
11284
11285     std::size_t listReporters() {
11286         Catch::cout() << "Available reporters:\n";
11287         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
11288         std::size_t maxNameLen = 0;
11289         for( auto const& factoryKvp : factories )
11290             maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
11291
11292         for( auto const& factoryKvp : factories ) {
11293             Catch::cout()
11294                     << Column( factoryKvp.first + ":" )
11295                             .indent(2)
11296                             .width( 5+maxNameLen )
11297                     +  Column( factoryKvp.second->getDescription() )
11298                             .initialIndent(0)
11299                             .indent(2)
11300                             .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
11301                     << "\n";
11302         }
11303         Catch::cout() << std::endl;
11304         return factories.size();
11305     }
11306
11307     Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
11308         Option<std::size_t> listedCount;
11309         getCurrentMutableContext().setConfig( config );
11310         if( config->listTests() )
11311             listedCount = listedCount.valueOr(0) + listTests( *config );
11312         if( config->listTestNamesOnly() )
11313             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
11314         if( config->listTags() )
11315             listedCount = listedCount.valueOr(0) + listTags( *config );
11316         if( config->listReporters() )
11317             listedCount = listedCount.valueOr(0) + listReporters();
11318         return listedCount;
11319     }
11320
11321 } // end namespace Catch
11322 // end catch_list.cpp
11323 // start catch_matchers.cpp
11324
11325 namespace Catch {
11326 namespace Matchers {
11327     namespace Impl {
11328
11329         std::string MatcherUntypedBase::toString() const {
11330             if( m_cachedToString.empty() )
11331                 m_cachedToString = describe();
11332             return m_cachedToString;
11333         }
11334
11335         MatcherUntypedBase::~MatcherUntypedBase() = default;
11336
11337     } // namespace Impl
11338 } // namespace Matchers
11339
11340 using namespace Matchers;
11341 using Matchers::Impl::MatcherBase;
11342
11343 } // namespace Catch
11344 // end catch_matchers.cpp
11345 // start catch_matchers_exception.cpp
11346
11347 namespace Catch {
11348 namespace Matchers {
11349 namespace Exception {
11350
11351 bool ExceptionMessageMatcher::match(std::exception const& ex) const {
11352     return ex.what() == m_message;
11353 }
11354
11355 std::string ExceptionMessageMatcher::describe() const {
11356     return "exception message matches \"" + m_message + "\"";
11357 }
11358
11359 }
11360 Exception::ExceptionMessageMatcher Message(std::string const& message) {
11361     return Exception::ExceptionMessageMatcher(message);
11362 }
11363
11364 // namespace Exception
11365 } // namespace Matchers
11366 } // namespace Catch
11367 // end catch_matchers_exception.cpp
11368 // start catch_matchers_floating.cpp
11369
11370 // start catch_polyfills.hpp
11371
11372 namespace Catch {
11373     bool isnan(float f);
11374     bool isnan(double d);
11375 }
11376
11377 // end catch_polyfills.hpp
11378 // start catch_to_string.hpp
11379
11380 #include <string>
11381
11382 namespace Catch {
11383     template <typename T>
11384     std::string to_string(T const& t) {
11385 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11386         return std::to_string(t);
11387 #else
11388         ReusableStringStream rss;
11389         rss << t;
11390         return rss.str();
11391 #endif
11392     }
11393 } // end namespace Catch
11394
11395 // end catch_to_string.hpp
11396 #include <algorithm>
11397 #include <cmath>
11398 #include <cstdlib>
11399 #include <cstdint>
11400 #include <cstring>
11401 #include <sstream>
11402 #include <type_traits>
11403 #include <iomanip>
11404 #include <limits>
11405
11406 namespace Catch {
11407 namespace {
11408
11409     int32_t convert(float f) {
11410         static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
11411         int32_t i;
11412         std::memcpy(&i, &f, sizeof(f));
11413         return i;
11414     }
11415
11416     int64_t convert(double d) {
11417         static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
11418         int64_t i;
11419         std::memcpy(&i, &d, sizeof(d));
11420         return i;
11421     }
11422
11423     template <typename FP>
11424     bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
11425         // Comparison with NaN should always be false.
11426         // This way we can rule it out before getting into the ugly details
11427         if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
11428             return false;
11429         }
11430
11431         auto lc = convert(lhs);
11432         auto rc = convert(rhs);
11433
11434         if ((lc < 0) != (rc < 0)) {
11435             // Potentially we can have +0 and -0
11436             return lhs == rhs;
11437         }
11438
11439         auto ulpDiff = std::abs(lc - rc);
11440         return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
11441     }
11442
11443 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11444
11445     float nextafter(float x, float y) {
11446         return ::nextafterf(x, y);
11447     }
11448
11449     double nextafter(double x, double y) {
11450         return ::nextafter(x, y);
11451     }
11452
11453 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
11454
11455 template <typename FP>
11456 FP step(FP start, FP direction, uint64_t steps) {
11457     for (uint64_t i = 0; i < steps; ++i) {
11458 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11459         start = Catch::nextafter(start, direction);
11460 #else
11461         start = std::nextafter(start, direction);
11462 #endif
11463     }
11464     return start;
11465 }
11466
11467 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11468 // But without the subtraction to allow for INFINITY in comparison
11469 bool marginComparison(double lhs, double rhs, double margin) {
11470     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
11471 }
11472
11473 template <typename FloatingPoint>
11474 void write(std::ostream& out, FloatingPoint num) {
11475     out << std::scientific
11476         << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
11477         << num;
11478 }
11479
11480 } // end anonymous namespace
11481
11482 namespace Matchers {
11483 namespace Floating {
11484
11485     enum class FloatingPointKind : uint8_t {
11486         Float,
11487         Double
11488     };
11489
11490     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
11491         :m_target{ target }, m_margin{ margin } {
11492         CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
11493             << " Margin has to be non-negative.");
11494     }
11495
11496     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11497     // But without the subtraction to allow for INFINITY in comparison
11498     bool WithinAbsMatcher::match(double const& matchee) const {
11499         return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
11500     }
11501
11502     std::string WithinAbsMatcher::describe() const {
11503         return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
11504     }
11505
11506     WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
11507         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
11508         CATCH_ENFORCE(m_type == FloatingPointKind::Double
11509                    || m_ulps < (std::numeric_limits<uint32_t>::max)(),
11510             "Provided ULP is impossibly large for a float comparison.");
11511     }
11512
11513 #if defined(__clang__)
11514 #pragma clang diagnostic push
11515 // Clang <3.5 reports on the default branch in the switch below
11516 #pragma clang diagnostic ignored "-Wunreachable-code"
11517 #endif
11518
11519     bool WithinUlpsMatcher::match(double const& matchee) const {
11520         switch (m_type) {
11521         case FloatingPointKind::Float:
11522             return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
11523         case FloatingPointKind::Double:
11524             return almostEqualUlps<double>(matchee, m_target, m_ulps);
11525         default:
11526             CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
11527         }
11528     }
11529
11530 #if defined(__clang__)
11531 #pragma clang diagnostic pop
11532 #endif
11533
11534     std::string WithinUlpsMatcher::describe() const {
11535         std::stringstream ret;
11536
11537         ret << "is within " << m_ulps << " ULPs of ";
11538
11539         if (m_type == FloatingPointKind::Float) {
11540             write(ret, static_cast<float>(m_target));
11541             ret << 'f';
11542         } else {
11543             write(ret, m_target);
11544         }
11545
11546         ret << " ([";
11547         if (m_type == FloatingPointKind::Double) {
11548             write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
11549             ret << ", ";
11550             write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
11551         } else {
11552             // We have to cast INFINITY to float because of MinGW, see #1782
11553             write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
11554             ret << ", ";
11555             write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
11556         }
11557         ret << "])";
11558
11559         return ret.str();
11560     }
11561
11562     WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
11563         m_target(target),
11564         m_epsilon(epsilon){
11565         CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
11566         CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
11567     }
11568
11569     bool WithinRelMatcher::match(double const& matchee) const {
11570         const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
11571         return marginComparison(matchee, m_target,
11572                                 std::isinf(relMargin)? 0 : relMargin);
11573     }
11574
11575     std::string WithinRelMatcher::describe() const {
11576         Catch::ReusableStringStream sstr;
11577         sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
11578         return sstr.str();
11579     }
11580
11581 }// namespace Floating
11582
11583 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
11584     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
11585 }
11586
11587 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
11588     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
11589 }
11590
11591 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
11592     return Floating::WithinAbsMatcher(target, margin);
11593 }
11594
11595 Floating::WithinRelMatcher WithinRel(double target, double eps) {
11596     return Floating::WithinRelMatcher(target, eps);
11597 }
11598
11599 Floating::WithinRelMatcher WithinRel(double target) {
11600     return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
11601 }
11602
11603 Floating::WithinRelMatcher WithinRel(float target, float eps) {
11604     return Floating::WithinRelMatcher(target, eps);
11605 }
11606
11607 Floating::WithinRelMatcher WithinRel(float target) {
11608     return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
11609 }
11610
11611 } // namespace Matchers
11612 } // namespace Catch
11613
11614 // end catch_matchers_floating.cpp
11615 // start catch_matchers_generic.cpp
11616
11617 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
11618     if (desc.empty()) {
11619         return "matches undescribed predicate";
11620     } else {
11621         return "matches predicate: \"" + desc + '"';
11622     }
11623 }
11624 // end catch_matchers_generic.cpp
11625 // start catch_matchers_string.cpp
11626
11627 #include <regex>
11628
11629 namespace Catch {
11630 namespace Matchers {
11631
11632     namespace StdString {
11633
11634         CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
11635         :   m_caseSensitivity( caseSensitivity ),
11636             m_str( adjustString( str ) )
11637         {}
11638         std::string CasedString::adjustString( std::string const& str ) const {
11639             return m_caseSensitivity == CaseSensitive::No
11640                    ? toLower( str )
11641                    : str;
11642         }
11643         std::string CasedString::caseSensitivitySuffix() const {
11644             return m_caseSensitivity == CaseSensitive::No
11645                    ? " (case insensitive)"
11646                    : std::string();
11647         }
11648
11649         StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
11650         : m_comparator( comparator ),
11651           m_operation( operation ) {
11652         }
11653
11654         std::string StringMatcherBase::describe() const {
11655             std::string description;
11656             description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
11657                                         m_comparator.caseSensitivitySuffix().size());
11658             description += m_operation;
11659             description += ": \"";
11660             description += m_comparator.m_str;
11661             description += "\"";
11662             description += m_comparator.caseSensitivitySuffix();
11663             return description;
11664         }
11665
11666         EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
11667
11668         bool EqualsMatcher::match( std::string const& source ) const {
11669             return m_comparator.adjustString( source ) == m_comparator.m_str;
11670         }
11671
11672         ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
11673
11674         bool ContainsMatcher::match( std::string const& source ) const {
11675             return contains( m_comparator.adjustString( source ), m_comparator.m_str );
11676         }
11677
11678         StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
11679
11680         bool StartsWithMatcher::match( std::string const& source ) const {
11681             return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11682         }
11683
11684         EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
11685
11686         bool EndsWithMatcher::match( std::string const& source ) const {
11687             return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11688         }
11689
11690         RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
11691
11692         bool RegexMatcher::match(std::string const& matchee) const {
11693             auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
11694             if (m_caseSensitivity == CaseSensitive::Choice::No) {
11695                 flags |= std::regex::icase;
11696             }
11697             auto reg = std::regex(m_regex, flags);
11698             return std::regex_match(matchee, reg);
11699         }
11700
11701         std::string RegexMatcher::describe() const {
11702             return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
11703         }
11704
11705     } // namespace StdString
11706
11707     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11708         return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
11709     }
11710     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11711         return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
11712     }
11713     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11714         return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11715     }
11716     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11717         return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11718     }
11719
11720     StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
11721         return StdString::RegexMatcher(regex, caseSensitivity);
11722     }
11723
11724 } // namespace Matchers
11725 } // namespace Catch
11726 // end catch_matchers_string.cpp
11727 // start catch_message.cpp
11728
11729 // start catch_uncaught_exceptions.h
11730
11731 namespace Catch {
11732     bool uncaught_exceptions();
11733 } // end namespace Catch
11734
11735 // end catch_uncaught_exceptions.h
11736 #include <cassert>
11737 #include <stack>
11738
11739 namespace Catch {
11740
11741     MessageInfo::MessageInfo(   StringRef const& _macroName,
11742                                 SourceLineInfo const& _lineInfo,
11743                                 ResultWas::OfType _type )
11744     :   macroName( _macroName ),
11745         lineInfo( _lineInfo ),
11746         type( _type ),
11747         sequence( ++globalCount )
11748     {}
11749
11750     bool MessageInfo::operator==( MessageInfo const& other ) const {
11751         return sequence == other.sequence;
11752     }
11753
11754     bool MessageInfo::operator<( MessageInfo const& other ) const {
11755         return sequence < other.sequence;
11756     }
11757
11758     // This may need protecting if threading support is added
11759     unsigned int MessageInfo::globalCount = 0;
11760
11761     ////////////////////////////////////////////////////////////////////////////
11762
11763     Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
11764                                            SourceLineInfo const& lineInfo,
11765                                            ResultWas::OfType type )
11766         :m_info(macroName, lineInfo, type) {}
11767
11768     ////////////////////////////////////////////////////////////////////////////
11769
11770     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
11771     : m_info( builder.m_info ), m_moved()
11772     {
11773         m_info.message = builder.m_stream.str();
11774         getResultCapture().pushScopedMessage( m_info );
11775     }
11776
11777     ScopedMessage::ScopedMessage( ScopedMessage&& old )
11778     : m_info( old.m_info ), m_moved()
11779     {
11780         old.m_moved = true;
11781     }
11782
11783     ScopedMessage::~ScopedMessage() {
11784         if ( !uncaught_exceptions() && !m_moved ){
11785             getResultCapture().popScopedMessage(m_info);
11786         }
11787     }
11788
11789     Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
11790         auto trimmed = [&] (size_t start, size_t end) {
11791             while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
11792                 ++start;
11793             }
11794             while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
11795                 --end;
11796             }
11797             return names.substr(start, end - start + 1);
11798         };
11799         auto skipq = [&] (size_t start, char quote) {
11800             for (auto i = start + 1; i < names.size() ; ++i) {
11801                 if (names[i] == quote)
11802                     return i;
11803                 if (names[i] == '\\')
11804                     ++i;
11805             }
11806             CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
11807         };
11808
11809         size_t start = 0;
11810         std::stack<char> openings;
11811         for (size_t pos = 0; pos < names.size(); ++pos) {
11812             char c = names[pos];
11813             switch (c) {
11814             case '[':
11815             case '{':
11816             case '(':
11817             // It is basically impossible to disambiguate between
11818             // comparison and start of template args in this context
11819 //            case '<':
11820                 openings.push(c);
11821                 break;
11822             case ']':
11823             case '}':
11824             case ')':
11825 //           case '>':
11826                 openings.pop();
11827                 break;
11828             case '"':
11829             case '\'':
11830                 pos = skipq(pos, c);
11831                 break;
11832             case ',':
11833                 if (start != pos && openings.empty()) {
11834                     m_messages.emplace_back(macroName, lineInfo, resultType);
11835                     m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
11836                     m_messages.back().message += " := ";
11837                     start = pos;
11838                 }
11839             }
11840         }
11841         assert(openings.empty() && "Mismatched openings");
11842         m_messages.emplace_back(macroName, lineInfo, resultType);
11843         m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
11844         m_messages.back().message += " := ";
11845     }
11846     Capturer::~Capturer() {
11847         if ( !uncaught_exceptions() ){
11848             assert( m_captured == m_messages.size() );
11849             for( size_t i = 0; i < m_captured; ++i  )
11850                 m_resultCapture.popScopedMessage( m_messages[i] );
11851         }
11852     }
11853
11854     void Capturer::captureValue( size_t index, std::string const& value ) {
11855         assert( index < m_messages.size() );
11856         m_messages[index].message += value;
11857         m_resultCapture.pushScopedMessage( m_messages[index] );
11858         m_captured++;
11859     }
11860
11861 } // end namespace Catch
11862 // end catch_message.cpp
11863 // start catch_output_redirect.cpp
11864
11865 // start catch_output_redirect.h
11866 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11867 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11868
11869 #include <cstdio>
11870 #include <iosfwd>
11871 #include <string>
11872
11873 namespace Catch {
11874
11875     class RedirectedStream {
11876         std::ostream& m_originalStream;
11877         std::ostream& m_redirectionStream;
11878         std::streambuf* m_prevBuf;
11879
11880     public:
11881         RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
11882         ~RedirectedStream();
11883     };
11884
11885     class RedirectedStdOut {
11886         ReusableStringStream m_rss;
11887         RedirectedStream m_cout;
11888     public:
11889         RedirectedStdOut();
11890         auto str() const -> std::string;
11891     };
11892
11893     // StdErr has two constituent streams in C++, std::cerr and std::clog
11894     // This means that we need to redirect 2 streams into 1 to keep proper
11895     // order of writes
11896     class RedirectedStdErr {
11897         ReusableStringStream m_rss;
11898         RedirectedStream m_cerr;
11899         RedirectedStream m_clog;
11900     public:
11901         RedirectedStdErr();
11902         auto str() const -> std::string;
11903     };
11904
11905     class RedirectedStreams {
11906     public:
11907         RedirectedStreams(RedirectedStreams const&) = delete;
11908         RedirectedStreams& operator=(RedirectedStreams const&) = delete;
11909         RedirectedStreams(RedirectedStreams&&) = delete;
11910         RedirectedStreams& operator=(RedirectedStreams&&) = delete;
11911
11912         RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
11913         ~RedirectedStreams();
11914     private:
11915         std::string& m_redirectedCout;
11916         std::string& m_redirectedCerr;
11917         RedirectedStdOut m_redirectedStdOut;
11918         RedirectedStdErr m_redirectedStdErr;
11919     };
11920
11921 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11922
11923     // Windows's implementation of std::tmpfile is terrible (it tries
11924     // to create a file inside system folder, thus requiring elevated
11925     // privileges for the binary), so we have to use tmpnam(_s) and
11926     // create the file ourselves there.
11927     class TempFile {
11928     public:
11929         TempFile(TempFile const&) = delete;
11930         TempFile& operator=(TempFile const&) = delete;
11931         TempFile(TempFile&&) = delete;
11932         TempFile& operator=(TempFile&&) = delete;
11933
11934         TempFile();
11935         ~TempFile();
11936
11937         std::FILE* getFile();
11938         std::string getContents();
11939
11940     private:
11941         std::FILE* m_file = nullptr;
11942     #if defined(_MSC_VER)
11943         char m_buffer[L_tmpnam] = { 0 };
11944     #endif
11945     };
11946
11947     class OutputRedirect {
11948     public:
11949         OutputRedirect(OutputRedirect const&) = delete;
11950         OutputRedirect& operator=(OutputRedirect const&) = delete;
11951         OutputRedirect(OutputRedirect&&) = delete;
11952         OutputRedirect& operator=(OutputRedirect&&) = delete;
11953
11954         OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
11955         ~OutputRedirect();
11956
11957     private:
11958         int m_originalStdout = -1;
11959         int m_originalStderr = -1;
11960         TempFile m_stdoutFile;
11961         TempFile m_stderrFile;
11962         std::string& m_stdoutDest;
11963         std::string& m_stderrDest;
11964     };
11965
11966 #endif
11967
11968 } // end namespace Catch
11969
11970 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11971 // end catch_output_redirect.h
11972 #include <cstdio>
11973 #include <cstring>
11974 #include <fstream>
11975 #include <sstream>
11976 #include <stdexcept>
11977
11978 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11979     #if defined(_MSC_VER)
11980     #include <io.h>      //_dup and _dup2
11981     #define dup _dup
11982     #define dup2 _dup2
11983     #define fileno _fileno
11984     #else
11985     #include <unistd.h>  // dup and dup2
11986     #endif
11987 #endif
11988
11989 namespace Catch {
11990
11991     RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
11992     :   m_originalStream( originalStream ),
11993         m_redirectionStream( redirectionStream ),
11994         m_prevBuf( m_originalStream.rdbuf() )
11995     {
11996         m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
11997     }
11998
11999     RedirectedStream::~RedirectedStream() {
12000         m_originalStream.rdbuf( m_prevBuf );
12001     }
12002
12003     RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
12004     auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
12005
12006     RedirectedStdErr::RedirectedStdErr()
12007     :   m_cerr( Catch::cerr(), m_rss.get() ),
12008         m_clog( Catch::clog(), m_rss.get() )
12009     {}
12010     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
12011
12012     RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
12013     :   m_redirectedCout(redirectedCout),
12014         m_redirectedCerr(redirectedCerr)
12015     {}
12016
12017     RedirectedStreams::~RedirectedStreams() {
12018         m_redirectedCout += m_redirectedStdOut.str();
12019         m_redirectedCerr += m_redirectedStdErr.str();
12020     }
12021
12022 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12023
12024 #if defined(_MSC_VER)
12025     TempFile::TempFile() {
12026         if (tmpnam_s(m_buffer)) {
12027             CATCH_RUNTIME_ERROR("Could not get a temp filename");
12028         }
12029         if (fopen_s(&m_file, m_buffer, "w")) {
12030             char buffer[100];
12031             if (strerror_s(buffer, errno)) {
12032                 CATCH_RUNTIME_ERROR("Could not translate errno to a string");
12033             }
12034             CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
12035         }
12036     }
12037 #else
12038     TempFile::TempFile() {
12039         m_file = std::tmpfile();
12040         if (!m_file) {
12041             CATCH_RUNTIME_ERROR("Could not create a temp file.");
12042         }
12043     }
12044
12045 #endif
12046
12047     TempFile::~TempFile() {
12048          // TBD: What to do about errors here?
12049          std::fclose(m_file);
12050          // We manually create the file on Windows only, on Linux
12051          // it will be autodeleted
12052 #if defined(_MSC_VER)
12053          std::remove(m_buffer);
12054 #endif
12055     }
12056
12057     FILE* TempFile::getFile() {
12058         return m_file;
12059     }
12060
12061     std::string TempFile::getContents() {
12062         std::stringstream sstr;
12063         char buffer[100] = {};
12064         std::rewind(m_file);
12065         while (std::fgets(buffer, sizeof(buffer), m_file)) {
12066             sstr << buffer;
12067         }
12068         return sstr.str();
12069     }
12070
12071     OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
12072         m_originalStdout(dup(1)),
12073         m_originalStderr(dup(2)),
12074         m_stdoutDest(stdout_dest),
12075         m_stderrDest(stderr_dest) {
12076         dup2(fileno(m_stdoutFile.getFile()), 1);
12077         dup2(fileno(m_stderrFile.getFile()), 2);
12078     }
12079
12080     OutputRedirect::~OutputRedirect() {
12081         Catch::cout() << std::flush;
12082         fflush(stdout);
12083         // Since we support overriding these streams, we flush cerr
12084         // even though std::cerr is unbuffered
12085         Catch::cerr() << std::flush;
12086         Catch::clog() << std::flush;
12087         fflush(stderr);
12088
12089         dup2(m_originalStdout, 1);
12090         dup2(m_originalStderr, 2);
12091
12092         m_stdoutDest += m_stdoutFile.getContents();
12093         m_stderrDest += m_stderrFile.getContents();
12094     }
12095
12096 #endif // CATCH_CONFIG_NEW_CAPTURE
12097
12098 } // namespace Catch
12099
12100 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12101     #if defined(_MSC_VER)
12102     #undef dup
12103     #undef dup2
12104     #undef fileno
12105     #endif
12106 #endif
12107 // end catch_output_redirect.cpp
12108 // start catch_polyfills.cpp
12109
12110 #include <cmath>
12111
12112 namespace Catch {
12113
12114 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
12115     bool isnan(float f) {
12116         return std::isnan(f);
12117     }
12118     bool isnan(double d) {
12119         return std::isnan(d);
12120     }
12121 #else
12122     // For now we only use this for embarcadero
12123     bool isnan(float f) {
12124         return std::_isnan(f);
12125     }
12126     bool isnan(double d) {
12127         return std::_isnan(d);
12128     }
12129 #endif
12130
12131 } // end namespace Catch
12132 // end catch_polyfills.cpp
12133 // start catch_random_number_generator.cpp
12134
12135 namespace Catch {
12136
12137 namespace {
12138
12139 #if defined(_MSC_VER)
12140 #pragma warning(push)
12141 #pragma warning(disable:4146) // we negate uint32 during the rotate
12142 #endif
12143         // Safe rotr implementation thanks to John Regehr
12144         uint32_t rotate_right(uint32_t val, uint32_t count) {
12145             const uint32_t mask = 31;
12146             count &= mask;
12147             return (val >> count) | (val << (-count & mask));
12148         }
12149
12150 #if defined(_MSC_VER)
12151 #pragma warning(pop)
12152 #endif
12153
12154 }
12155
12156     SimplePcg32::SimplePcg32(result_type seed_) {
12157         seed(seed_);
12158     }
12159
12160     void SimplePcg32::seed(result_type seed_) {
12161         m_state = 0;
12162         (*this)();
12163         m_state += seed_;
12164         (*this)();
12165     }
12166
12167     void SimplePcg32::discard(uint64_t skip) {
12168         // We could implement this to run in O(log n) steps, but this
12169         // should suffice for our use case.
12170         for (uint64_t s = 0; s < skip; ++s) {
12171             static_cast<void>((*this)());
12172         }
12173     }
12174
12175     SimplePcg32::result_type SimplePcg32::operator()() {
12176         // prepare the output value
12177         const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
12178         const auto output = rotate_right(xorshifted, m_state >> 59u);
12179
12180         // advance state
12181         m_state = m_state * 6364136223846793005ULL + s_inc;
12182
12183         return output;
12184     }
12185
12186     bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12187         return lhs.m_state == rhs.m_state;
12188     }
12189
12190     bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12191         return lhs.m_state != rhs.m_state;
12192     }
12193 }
12194 // end catch_random_number_generator.cpp
12195 // start catch_registry_hub.cpp
12196
12197 // start catch_test_case_registry_impl.h
12198
12199 #include <vector>
12200 #include <set>
12201 #include <algorithm>
12202 #include <ios>
12203
12204 namespace Catch {
12205
12206     class TestCase;
12207     struct IConfig;
12208
12209     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
12210
12211     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
12212     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
12213
12214     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
12215
12216     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
12217     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
12218
12219     class TestRegistry : public ITestCaseRegistry {
12220     public:
12221         virtual ~TestRegistry() = default;
12222
12223         virtual void registerTest( TestCase const& testCase );
12224
12225         std::vector<TestCase> const& getAllTests() const override;
12226         std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
12227
12228     private:
12229         std::vector<TestCase> m_functions;
12230         mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
12231         mutable std::vector<TestCase> m_sortedFunctions;
12232         std::size_t m_unnamedCount = 0;
12233         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
12234     };
12235
12236     ///////////////////////////////////////////////////////////////////////////
12237
12238     class TestInvokerAsFunction : public ITestInvoker {
12239         void(*m_testAsFunction)();
12240     public:
12241         TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
12242
12243         void invoke() const override;
12244     };
12245
12246     std::string extractClassName( StringRef const& classOrQualifiedMethodName );
12247
12248     ///////////////////////////////////////////////////////////////////////////
12249
12250 } // end namespace Catch
12251
12252 // end catch_test_case_registry_impl.h
12253 // start catch_reporter_registry.h
12254
12255 #include <map>
12256
12257 namespace Catch {
12258
12259     class ReporterRegistry : public IReporterRegistry {
12260
12261     public:
12262
12263         ~ReporterRegistry() override;
12264
12265         IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
12266
12267         void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
12268         void registerListener( IReporterFactoryPtr const& factory );
12269
12270         FactoryMap const& getFactories() const override;
12271         Listeners const& getListeners() const override;
12272
12273     private:
12274         FactoryMap m_factories;
12275         Listeners m_listeners;
12276     };
12277 }
12278
12279 // end catch_reporter_registry.h
12280 // start catch_tag_alias_registry.h
12281
12282 // start catch_tag_alias.h
12283
12284 #include <string>
12285
12286 namespace Catch {
12287
12288     struct TagAlias {
12289         TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
12290
12291         std::string tag;
12292         SourceLineInfo lineInfo;
12293     };
12294
12295 } // end namespace Catch
12296
12297 // end catch_tag_alias.h
12298 #include <map>
12299
12300 namespace Catch {
12301
12302     class TagAliasRegistry : public ITagAliasRegistry {
12303     public:
12304         ~TagAliasRegistry() override;
12305         TagAlias const* find( std::string const& alias ) const override;
12306         std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
12307         void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
12308
12309     private:
12310         std::map<std::string, TagAlias> m_registry;
12311     };
12312
12313 } // end namespace Catch
12314
12315 // end catch_tag_alias_registry.h
12316 // start catch_startup_exception_registry.h
12317
12318 #include <vector>
12319 #include <exception>
12320
12321 namespace Catch {
12322
12323     class StartupExceptionRegistry {
12324 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12325     public:
12326         void add(std::exception_ptr const& exception) noexcept;
12327         std::vector<std::exception_ptr> const& getExceptions() const noexcept;
12328     private:
12329         std::vector<std::exception_ptr> m_exceptions;
12330 #endif
12331     };
12332
12333 } // end namespace Catch
12334
12335 // end catch_startup_exception_registry.h
12336 // start catch_singletons.hpp
12337
12338 namespace Catch {
12339
12340     struct ISingleton {
12341         virtual ~ISingleton();
12342     };
12343
12344     void addSingleton( ISingleton* singleton );
12345     void cleanupSingletons();
12346
12347     template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
12348     class Singleton : SingletonImplT, public ISingleton {
12349
12350         static auto getInternal() -> Singleton* {
12351             static Singleton* s_instance = nullptr;
12352             if( !s_instance ) {
12353                 s_instance = new Singleton;
12354                 addSingleton( s_instance );
12355             }
12356             return s_instance;
12357         }
12358
12359     public:
12360         static auto get() -> InterfaceT const& {
12361             return *getInternal();
12362         }
12363         static auto getMutable() -> MutableInterfaceT& {
12364             return *getInternal();
12365         }
12366     };
12367
12368 } // namespace Catch
12369
12370 // end catch_singletons.hpp
12371 namespace Catch {
12372
12373     namespace {
12374
12375         class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
12376                             private NonCopyable {
12377
12378         public: // IRegistryHub
12379             RegistryHub() = default;
12380             IReporterRegistry const& getReporterRegistry() const override {
12381                 return m_reporterRegistry;
12382             }
12383             ITestCaseRegistry const& getTestCaseRegistry() const override {
12384                 return m_testCaseRegistry;
12385             }
12386             IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
12387                 return m_exceptionTranslatorRegistry;
12388             }
12389             ITagAliasRegistry const& getTagAliasRegistry() const override {
12390                 return m_tagAliasRegistry;
12391             }
12392             StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
12393                 return m_exceptionRegistry;
12394             }
12395
12396         public: // IMutableRegistryHub
12397             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
12398                 m_reporterRegistry.registerReporter( name, factory );
12399             }
12400             void registerListener( IReporterFactoryPtr const& factory ) override {
12401                 m_reporterRegistry.registerListener( factory );
12402             }
12403             void registerTest( TestCase const& testInfo ) override {
12404                 m_testCaseRegistry.registerTest( testInfo );
12405             }
12406             void registerTranslator( const IExceptionTranslator* translator ) override {
12407                 m_exceptionTranslatorRegistry.registerTranslator( translator );
12408             }
12409             void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
12410                 m_tagAliasRegistry.add( alias, tag, lineInfo );
12411             }
12412             void registerStartupException() noexcept override {
12413 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12414                 m_exceptionRegistry.add(std::current_exception());
12415 #else
12416                 CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
12417 #endif
12418             }
12419             IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
12420                 return m_enumValuesRegistry;
12421             }
12422
12423         private:
12424             TestRegistry m_testCaseRegistry;
12425             ReporterRegistry m_reporterRegistry;
12426             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
12427             TagAliasRegistry m_tagAliasRegistry;
12428             StartupExceptionRegistry m_exceptionRegistry;
12429             Detail::EnumValuesRegistry m_enumValuesRegistry;
12430         };
12431     }
12432
12433     using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
12434
12435     IRegistryHub const& getRegistryHub() {
12436         return RegistryHubSingleton::get();
12437     }
12438     IMutableRegistryHub& getMutableRegistryHub() {
12439         return RegistryHubSingleton::getMutable();
12440     }
12441     void cleanUp() {
12442         cleanupSingletons();
12443         cleanUpContext();
12444     }
12445     std::string translateActiveException() {
12446         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
12447     }
12448
12449 } // end namespace Catch
12450 // end catch_registry_hub.cpp
12451 // start catch_reporter_registry.cpp
12452
12453 namespace Catch {
12454
12455     ReporterRegistry::~ReporterRegistry() = default;
12456
12457     IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
12458         auto it =  m_factories.find( name );
12459         if( it == m_factories.end() )
12460             return nullptr;
12461         return it->second->create( ReporterConfig( config ) );
12462     }
12463
12464     void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
12465         m_factories.emplace(name, factory);
12466     }
12467     void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
12468         m_listeners.push_back( factory );
12469     }
12470
12471     IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
12472         return m_factories;
12473     }
12474     IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
12475         return m_listeners;
12476     }
12477
12478 }
12479 // end catch_reporter_registry.cpp
12480 // start catch_result_type.cpp
12481
12482 namespace Catch {
12483
12484     bool isOk( ResultWas::OfType resultType ) {
12485         return ( resultType & ResultWas::FailureBit ) == 0;
12486     }
12487     bool isJustInfo( int flags ) {
12488         return flags == ResultWas::Info;
12489     }
12490
12491     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
12492         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
12493     }
12494
12495     bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
12496     bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
12497
12498 } // end namespace Catch
12499 // end catch_result_type.cpp
12500 // start catch_run_context.cpp
12501
12502 #include <cassert>
12503 #include <algorithm>
12504 #include <sstream>
12505
12506 namespace Catch {
12507
12508     namespace Generators {
12509         struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
12510             GeneratorBasePtr m_generator;
12511
12512             GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
12513             :   TrackerBase( nameAndLocation, ctx, parent )
12514             {}
12515             ~GeneratorTracker();
12516
12517             static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
12518                 std::shared_ptr<GeneratorTracker> tracker;
12519
12520                 ITracker& currentTracker = ctx.currentTracker();
12521                 // Under specific circumstances, the generator we want
12522                 // to acquire is also the current tracker. If this is
12523                 // the case, we have to avoid looking through current
12524                 // tracker's children, and instead return the current
12525                 // tracker.
12526                 // A case where this check is important is e.g.
12527                 //     for (int i = 0; i < 5; ++i) {
12528                 //         int n = GENERATE(1, 2);
12529                 //     }
12530                 //
12531                 // without it, the code above creates 5 nested generators.
12532                 if (currentTracker.nameAndLocation() == nameAndLocation) {
12533                     auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
12534                     assert(thisTracker);
12535                     assert(thisTracker->isGeneratorTracker());
12536                     tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
12537                 } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
12538                     assert( childTracker );
12539                     assert( childTracker->isGeneratorTracker() );
12540                     tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
12541                 } else {
12542                     tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
12543                     currentTracker.addChild( tracker );
12544                 }
12545
12546                 if( !ctx.completedCycle() && !tracker->isComplete() ) {
12547                     tracker->open();
12548                 }
12549
12550                 return *tracker;
12551             }
12552
12553             // TrackerBase interface
12554             bool isGeneratorTracker() const override { return true; }
12555             auto hasGenerator() const -> bool override {
12556                 return !!m_generator;
12557             }
12558             void close() override {
12559                 TrackerBase::close();
12560                 // Generator interface only finds out if it has another item on atual move
12561                 if (m_runState == CompletedSuccessfully && m_generator->next()) {
12562                     m_children.clear();
12563                     m_runState = Executing;
12564                 }
12565             }
12566
12567             // IGeneratorTracker interface
12568             auto getGenerator() const -> GeneratorBasePtr const& override {
12569                 return m_generator;
12570             }
12571             void setGenerator( GeneratorBasePtr&& generator ) override {
12572                 m_generator = std::move( generator );
12573             }
12574         };
12575         GeneratorTracker::~GeneratorTracker() {}
12576     }
12577
12578     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
12579     :   m_runInfo(_config->name()),
12580         m_context(getCurrentMutableContext()),
12581         m_config(_config),
12582         m_reporter(std::move(reporter)),
12583         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
12584         m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
12585     {
12586         m_context.setRunner(this);
12587         m_context.setConfig(m_config);
12588         m_context.setResultCapture(this);
12589         m_reporter->testRunStarting(m_runInfo);
12590     }
12591
12592     RunContext::~RunContext() {
12593         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
12594     }
12595
12596     void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
12597         m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
12598     }
12599
12600     void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
12601         m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
12602     }
12603
12604     Totals RunContext::runTest(TestCase const& testCase) {
12605         Totals prevTotals = m_totals;
12606
12607         std::string redirectedCout;
12608         std::string redirectedCerr;
12609
12610         auto const& testInfo = testCase.getTestCaseInfo();
12611
12612         m_reporter->testCaseStarting(testInfo);
12613
12614         m_activeTestCase = &testCase;
12615
12616         ITracker& rootTracker = m_trackerContext.startRun();
12617         assert(rootTracker.isSectionTracker());
12618         static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
12619         do {
12620             m_trackerContext.startCycle();
12621             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
12622             runCurrentTest(redirectedCout, redirectedCerr);
12623         } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
12624
12625         Totals deltaTotals = m_totals.delta(prevTotals);
12626         if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
12627             deltaTotals.assertions.failed++;
12628             deltaTotals.testCases.passed--;
12629             deltaTotals.testCases.failed++;
12630         }
12631         m_totals.testCases += deltaTotals.testCases;
12632         m_reporter->testCaseEnded(TestCaseStats(testInfo,
12633                                   deltaTotals,
12634                                   redirectedCout,
12635                                   redirectedCerr,
12636                                   aborting()));
12637
12638         m_activeTestCase = nullptr;
12639         m_testCaseTracker = nullptr;
12640
12641         return deltaTotals;
12642     }
12643
12644     IConfigPtr RunContext::config() const {
12645         return m_config;
12646     }
12647
12648     IStreamingReporter& RunContext::reporter() const {
12649         return *m_reporter;
12650     }
12651
12652     void RunContext::assertionEnded(AssertionResult const & result) {
12653         if (result.getResultType() == ResultWas::Ok) {
12654             m_totals.assertions.passed++;
12655             m_lastAssertionPassed = true;
12656         } else if (!result.isOk()) {
12657             m_lastAssertionPassed = false;
12658             if( m_activeTestCase->getTestCaseInfo().okToFail() )
12659                 m_totals.assertions.failedButOk++;
12660             else
12661                 m_totals.assertions.failed++;
12662         }
12663         else {
12664             m_lastAssertionPassed = true;
12665         }
12666
12667         // We have no use for the return value (whether messages should be cleared), because messages were made scoped
12668         // and should be let to clear themselves out.
12669         static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
12670
12671         if (result.getResultType() != ResultWas::Warning)
12672             m_messageScopes.clear();
12673
12674         // Reset working state
12675         resetAssertionInfo();
12676         m_lastResult = result;
12677     }
12678     void RunContext::resetAssertionInfo() {
12679         m_lastAssertionInfo.macroName = StringRef();
12680         m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
12681     }
12682
12683     bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
12684         ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
12685         if (!sectionTracker.isOpen())
12686             return false;
12687         m_activeSections.push_back(&sectionTracker);
12688
12689         m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
12690
12691         m_reporter->sectionStarting(sectionInfo);
12692
12693         assertions = m_totals.assertions;
12694
12695         return true;
12696     }
12697     auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
12698         using namespace Generators;
12699         GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
12700                                                               TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
12701         assert( tracker.isOpen() );
12702         m_lastAssertionInfo.lineInfo = lineInfo;
12703         return tracker;
12704     }
12705
12706     bool RunContext::testForMissingAssertions(Counts& assertions) {
12707         if (assertions.total() != 0)
12708             return false;
12709         if (!m_config->warnAboutMissingAssertions())
12710             return false;
12711         if (m_trackerContext.currentTracker().hasChildren())
12712             return false;
12713         m_totals.assertions.failed++;
12714         assertions.failed++;
12715         return true;
12716     }
12717
12718     void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
12719         Counts assertions = m_totals.assertions - endInfo.prevAssertions;
12720         bool missingAssertions = testForMissingAssertions(assertions);
12721
12722         if (!m_activeSections.empty()) {
12723             m_activeSections.back()->close();
12724             m_activeSections.pop_back();
12725         }
12726
12727         m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
12728         m_messages.clear();
12729         m_messageScopes.clear();
12730     }
12731
12732     void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
12733         if (m_unfinishedSections.empty())
12734             m_activeSections.back()->fail();
12735         else
12736             m_activeSections.back()->close();
12737         m_activeSections.pop_back();
12738
12739         m_unfinishedSections.push_back(endInfo);
12740     }
12741
12742 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
12743     void RunContext::benchmarkPreparing(std::string const& name) {
12744         m_reporter->benchmarkPreparing(name);
12745     }
12746     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
12747         m_reporter->benchmarkStarting( info );
12748     }
12749     void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
12750         m_reporter->benchmarkEnded( stats );
12751     }
12752     void RunContext::benchmarkFailed(std::string const & error) {
12753         m_reporter->benchmarkFailed(error);
12754     }
12755 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
12756
12757     void RunContext::pushScopedMessage(MessageInfo const & message) {
12758         m_messages.push_back(message);
12759     }
12760
12761     void RunContext::popScopedMessage(MessageInfo const & message) {
12762         m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
12763     }
12764
12765     void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
12766         m_messageScopes.emplace_back( builder );
12767     }
12768
12769     std::string RunContext::getCurrentTestName() const {
12770         return m_activeTestCase
12771             ? m_activeTestCase->getTestCaseInfo().name
12772             : std::string();
12773     }
12774
12775     const AssertionResult * RunContext::getLastResult() const {
12776         return &(*m_lastResult);
12777     }
12778
12779     void RunContext::exceptionEarlyReported() {
12780         m_shouldReportUnexpected = false;
12781     }
12782
12783     void RunContext::handleFatalErrorCondition( StringRef message ) {
12784         // First notify reporter that bad things happened
12785         m_reporter->fatalErrorEncountered(message);
12786
12787         // Don't rebuild the result -- the stringification itself can cause more fatal errors
12788         // Instead, fake a result data.
12789         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
12790         tempResult.message = static_cast<std::string>(message);
12791         AssertionResult result(m_lastAssertionInfo, tempResult);
12792
12793         assertionEnded(result);
12794
12795         handleUnfinishedSections();
12796
12797         // Recreate section for test case (as we will lose the one that was in scope)
12798         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12799         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12800
12801         Counts assertions;
12802         assertions.failed = 1;
12803         SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
12804         m_reporter->sectionEnded(testCaseSectionStats);
12805
12806         auto const& testInfo = m_activeTestCase->getTestCaseInfo();
12807
12808         Totals deltaTotals;
12809         deltaTotals.testCases.failed = 1;
12810         deltaTotals.assertions.failed = 1;
12811         m_reporter->testCaseEnded(TestCaseStats(testInfo,
12812                                   deltaTotals,
12813                                   std::string(),
12814                                   std::string(),
12815                                   false));
12816         m_totals.testCases.failed++;
12817         testGroupEnded(std::string(), m_totals, 1, 1);
12818         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
12819     }
12820
12821     bool RunContext::lastAssertionPassed() {
12822          return m_lastAssertionPassed;
12823     }
12824
12825     void RunContext::assertionPassed() {
12826         m_lastAssertionPassed = true;
12827         ++m_totals.assertions.passed;
12828         resetAssertionInfo();
12829         m_messageScopes.clear();
12830     }
12831
12832     bool RunContext::aborting() const {
12833         return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
12834     }
12835
12836     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
12837         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12838         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12839         m_reporter->sectionStarting(testCaseSection);
12840         Counts prevAssertions = m_totals.assertions;
12841         double duration = 0;
12842         m_shouldReportUnexpected = true;
12843         m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
12844
12845         seedRng(*m_config);
12846
12847         Timer timer;
12848         CATCH_TRY {
12849             if (m_reporter->getPreferences().shouldRedirectStdOut) {
12850 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
12851                 RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
12852
12853                 timer.start();
12854                 invokeActiveTestCase();
12855 #else
12856                 OutputRedirect r(redirectedCout, redirectedCerr);
12857                 timer.start();
12858                 invokeActiveTestCase();
12859 #endif
12860             } else {
12861                 timer.start();
12862                 invokeActiveTestCase();
12863             }
12864             duration = timer.getElapsedSeconds();
12865         } CATCH_CATCH_ANON (TestFailureException&) {
12866             // This just means the test was aborted due to failure
12867         } CATCH_CATCH_ALL {
12868             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
12869             // are reported without translation at the point of origin.
12870             if( m_shouldReportUnexpected ) {
12871                 AssertionReaction dummyReaction;
12872                 handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
12873             }
12874         }
12875         Counts assertions = m_totals.assertions - prevAssertions;
12876         bool missingAssertions = testForMissingAssertions(assertions);
12877
12878         m_testCaseTracker->close();
12879         handleUnfinishedSections();
12880         m_messages.clear();
12881         m_messageScopes.clear();
12882
12883         SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
12884         m_reporter->sectionEnded(testCaseSectionStats);
12885     }
12886
12887     void RunContext::invokeActiveTestCase() {
12888         FatalConditionHandler fatalConditionHandler; // Handle signals
12889         m_activeTestCase->invoke();
12890         fatalConditionHandler.reset();
12891     }
12892
12893     void RunContext::handleUnfinishedSections() {
12894         // If sections ended prematurely due to an exception we stored their
12895         // infos here so we can tear them down outside the unwind process.
12896         for (auto it = m_unfinishedSections.rbegin(),
12897              itEnd = m_unfinishedSections.rend();
12898              it != itEnd;
12899              ++it)
12900             sectionEnded(*it);
12901         m_unfinishedSections.clear();
12902     }
12903
12904     void RunContext::handleExpr(
12905         AssertionInfo const& info,
12906         ITransientExpression const& expr,
12907         AssertionReaction& reaction
12908     ) {
12909         m_reporter->assertionStarting( info );
12910
12911         bool negated = isFalseTest( info.resultDisposition );
12912         bool result = expr.getResult() != negated;
12913
12914         if( result ) {
12915             if (!m_includeSuccessfulResults) {
12916                 assertionPassed();
12917             }
12918             else {
12919                 reportExpr(info, ResultWas::Ok, &expr, negated);
12920             }
12921         }
12922         else {
12923             reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
12924             populateReaction( reaction );
12925         }
12926     }
12927     void RunContext::reportExpr(
12928             AssertionInfo const &info,
12929             ResultWas::OfType resultType,
12930             ITransientExpression const *expr,
12931             bool negated ) {
12932
12933         m_lastAssertionInfo = info;
12934         AssertionResultData data( resultType, LazyExpression( negated ) );
12935
12936         AssertionResult assertionResult{ info, data };
12937         assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
12938
12939         assertionEnded( assertionResult );
12940     }
12941
12942     void RunContext::handleMessage(
12943             AssertionInfo const& info,
12944             ResultWas::OfType resultType,
12945             StringRef const& message,
12946             AssertionReaction& reaction
12947     ) {
12948         m_reporter->assertionStarting( info );
12949
12950         m_lastAssertionInfo = info;
12951
12952         AssertionResultData data( resultType, LazyExpression( false ) );
12953         data.message = static_cast<std::string>(message);
12954         AssertionResult assertionResult{ m_lastAssertionInfo, data };
12955         assertionEnded( assertionResult );
12956         if( !assertionResult.isOk() )
12957             populateReaction( reaction );
12958     }
12959     void RunContext::handleUnexpectedExceptionNotThrown(
12960             AssertionInfo const& info,
12961             AssertionReaction& reaction
12962     ) {
12963         handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
12964     }
12965
12966     void RunContext::handleUnexpectedInflightException(
12967             AssertionInfo const& info,
12968             std::string const& message,
12969             AssertionReaction& reaction
12970     ) {
12971         m_lastAssertionInfo = info;
12972
12973         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
12974         data.message = message;
12975         AssertionResult assertionResult{ info, data };
12976         assertionEnded( assertionResult );
12977         populateReaction( reaction );
12978     }
12979
12980     void RunContext::populateReaction( AssertionReaction& reaction ) {
12981         reaction.shouldDebugBreak = m_config->shouldDebugBreak();
12982         reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
12983     }
12984
12985     void RunContext::handleIncomplete(
12986             AssertionInfo const& info
12987     ) {
12988         m_lastAssertionInfo = info;
12989
12990         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
12991         data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
12992         AssertionResult assertionResult{ info, data };
12993         assertionEnded( assertionResult );
12994     }
12995     void RunContext::handleNonExpr(
12996             AssertionInfo const &info,
12997             ResultWas::OfType resultType,
12998             AssertionReaction &reaction
12999     ) {
13000         m_lastAssertionInfo = info;
13001
13002         AssertionResultData data( resultType, LazyExpression( false ) );
13003         AssertionResult assertionResult{ info, data };
13004         assertionEnded( assertionResult );
13005
13006         if( !assertionResult.isOk() )
13007             populateReaction( reaction );
13008     }
13009
13010     IResultCapture& getResultCapture() {
13011         if (auto* capture = getCurrentContext().getResultCapture())
13012             return *capture;
13013         else
13014             CATCH_INTERNAL_ERROR("No result capture instance");
13015     }
13016
13017     void seedRng(IConfig const& config) {
13018         if (config.rngSeed() != 0) {
13019             std::srand(config.rngSeed());
13020             rng().seed(config.rngSeed());
13021         }
13022     }
13023
13024     unsigned int rngSeed() {
13025         return getCurrentContext().getConfig()->rngSeed();
13026     }
13027
13028 }
13029 // end catch_run_context.cpp
13030 // start catch_section.cpp
13031
13032 namespace Catch {
13033
13034     Section::Section( SectionInfo const& info )
13035     :   m_info( info ),
13036         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
13037     {
13038         m_timer.start();
13039     }
13040
13041     Section::~Section() {
13042         if( m_sectionIncluded ) {
13043             SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
13044             if( uncaught_exceptions() )
13045                 getResultCapture().sectionEndedEarly( endInfo );
13046             else
13047                 getResultCapture().sectionEnded( endInfo );
13048         }
13049     }
13050
13051     // This indicates whether the section should be executed or not
13052     Section::operator bool() const {
13053         return m_sectionIncluded;
13054     }
13055
13056 } // end namespace Catch
13057 // end catch_section.cpp
13058 // start catch_section_info.cpp
13059
13060 namespace Catch {
13061
13062     SectionInfo::SectionInfo
13063         (   SourceLineInfo const& _lineInfo,
13064             std::string const& _name )
13065     :   name( _name ),
13066         lineInfo( _lineInfo )
13067     {}
13068
13069 } // end namespace Catch
13070 // end catch_section_info.cpp
13071 // start catch_session.cpp
13072
13073 // start catch_session.h
13074
13075 #include <memory>
13076
13077 namespace Catch {
13078
13079     class Session : NonCopyable {
13080     public:
13081
13082         Session();
13083         ~Session() override;
13084
13085         void showHelp() const;
13086         void libIdentify();
13087
13088         int applyCommandLine( int argc, char const * const * argv );
13089     #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13090         int applyCommandLine( int argc, wchar_t const * const * argv );
13091     #endif
13092
13093         void useConfigData( ConfigData const& configData );
13094
13095         template<typename CharT>
13096         int run(int argc, CharT const * const argv[]) {
13097             if (m_startupExceptions)
13098                 return 1;
13099             int returnCode = applyCommandLine(argc, argv);
13100             if (returnCode == 0)
13101                 returnCode = run();
13102             return returnCode;
13103         }
13104
13105         int run();
13106
13107         clara::Parser const& cli() const;
13108         void cli( clara::Parser const& newParser );
13109         ConfigData& configData();
13110         Config& config();
13111     private:
13112         int runInternal();
13113
13114         clara::Parser m_cli;
13115         ConfigData m_configData;
13116         std::shared_ptr<Config> m_config;
13117         bool m_startupExceptions = false;
13118     };
13119
13120 } // end namespace Catch
13121
13122 // end catch_session.h
13123 // start catch_version.h
13124
13125 #include <iosfwd>
13126
13127 namespace Catch {
13128
13129     // Versioning information
13130     struct Version {
13131         Version( Version const& ) = delete;
13132         Version& operator=( Version const& ) = delete;
13133         Version(    unsigned int _majorVersion,
13134                     unsigned int _minorVersion,
13135                     unsigned int _patchNumber,
13136                     char const * const _branchName,
13137                     unsigned int _buildNumber );
13138
13139         unsigned int const majorVersion;
13140         unsigned int const minorVersion;
13141         unsigned int const patchNumber;
13142
13143         // buildNumber is only used if branchName is not null
13144         char const * const branchName;
13145         unsigned int const buildNumber;
13146
13147         friend std::ostream& operator << ( std::ostream& os, Version const& version );
13148     };
13149
13150     Version const& libraryVersion();
13151 }
13152
13153 // end catch_version.h
13154 #include <cstdlib>
13155 #include <iomanip>
13156 #include <set>
13157 #include <iterator>
13158
13159 namespace Catch {
13160
13161     namespace {
13162         const int MaxExitCode = 255;
13163
13164         IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
13165             auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
13166             CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
13167
13168             return reporter;
13169         }
13170
13171         IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
13172             if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
13173                 return createReporter(config->getReporterName(), config);
13174             }
13175
13176             // On older platforms, returning std::unique_ptr<ListeningReporter>
13177             // when the return type is std::unique_ptr<IStreamingReporter>
13178             // doesn't compile without a std::move call. However, this causes
13179             // a warning on newer platforms. Thus, we have to work around
13180             // it a bit and downcast the pointer manually.
13181             auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
13182             auto& multi = static_cast<ListeningReporter&>(*ret);
13183             auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
13184             for (auto const& listener : listeners) {
13185                 multi.addListener(listener->create(Catch::ReporterConfig(config)));
13186             }
13187             multi.addReporter(createReporter(config->getReporterName(), config));
13188             return ret;
13189         }
13190
13191         class TestGroup {
13192         public:
13193             explicit TestGroup(std::shared_ptr<Config> const& config)
13194             : m_config{config}
13195             , m_context{config, makeReporter(config)}
13196             {
13197                 auto const& allTestCases = getAllTestCasesSorted(*m_config);
13198                 m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
13199                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13200
13201                 if (m_matches.empty() && invalidArgs.empty()) {
13202                     for (auto const& test : allTestCases)
13203                         if (!test.isHidden())
13204                             m_tests.emplace(&test);
13205                 } else {
13206                     for (auto const& match : m_matches)
13207                         m_tests.insert(match.tests.begin(), match.tests.end());
13208                 }
13209             }
13210
13211             Totals execute() {
13212                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13213                 Totals totals;
13214                 m_context.testGroupStarting(m_config->name(), 1, 1);
13215                 for (auto const& testCase : m_tests) {
13216                     if (!m_context.aborting())
13217                         totals += m_context.runTest(*testCase);
13218                     else
13219                         m_context.reporter().skipTest(*testCase);
13220                 }
13221
13222                 for (auto const& match : m_matches) {
13223                     if (match.tests.empty()) {
13224                         m_context.reporter().noMatchingTestCases(match.name);
13225                         totals.error = -1;
13226                     }
13227                 }
13228
13229                 if (!invalidArgs.empty()) {
13230                     for (auto const& invalidArg: invalidArgs)
13231                          m_context.reporter().reportInvalidArguments(invalidArg);
13232                 }
13233
13234                 m_context.testGroupEnded(m_config->name(), totals, 1, 1);
13235                 return totals;
13236             }
13237
13238         private:
13239             using Tests = std::set<TestCase const*>;
13240
13241             std::shared_ptr<Config> m_config;
13242             RunContext m_context;
13243             Tests m_tests;
13244             TestSpec::Matches m_matches;
13245         };
13246
13247         void applyFilenamesAsTags(Catch::IConfig const& config) {
13248             auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
13249             for (auto& testCase : tests) {
13250                 auto tags = testCase.tags;
13251
13252                 std::string filename = testCase.lineInfo.file;
13253                 auto lastSlash = filename.find_last_of("\\/");
13254                 if (lastSlash != std::string::npos) {
13255                     filename.erase(0, lastSlash);
13256                     filename[0] = '#';
13257                 }
13258
13259                 auto lastDot = filename.find_last_of('.');
13260                 if (lastDot != std::string::npos) {
13261                     filename.erase(lastDot);
13262                 }
13263
13264                 tags.push_back(std::move(filename));
13265                 setTags(testCase, tags);
13266             }
13267         }
13268
13269     } // anon namespace
13270
13271     Session::Session() {
13272         static bool alreadyInstantiated = false;
13273         if( alreadyInstantiated ) {
13274             CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
13275             CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
13276         }
13277
13278         // There cannot be exceptions at startup in no-exception mode.
13279 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13280         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
13281         if ( !exceptions.empty() ) {
13282             config();
13283             getCurrentMutableContext().setConfig(m_config);
13284
13285             m_startupExceptions = true;
13286             Colour colourGuard( Colour::Red );
13287             Catch::cerr() << "Errors occurred during startup!" << '\n';
13288             // iterate over all exceptions and notify user
13289             for ( const auto& ex_ptr : exceptions ) {
13290                 try {
13291                     std::rethrow_exception(ex_ptr);
13292                 } catch ( std::exception const& ex ) {
13293                     Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
13294                 }
13295             }
13296         }
13297 #endif
13298
13299         alreadyInstantiated = true;
13300         m_cli = makeCommandLineParser( m_configData );
13301     }
13302     Session::~Session() {
13303         Catch::cleanUp();
13304     }
13305
13306     void Session::showHelp() const {
13307         Catch::cout()
13308                 << "\nCatch v" << libraryVersion() << "\n"
13309                 << m_cli << std::endl
13310                 << "For more detailed usage please see the project docs\n" << std::endl;
13311     }
13312     void Session::libIdentify() {
13313         Catch::cout()
13314                 << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
13315                 << std::left << std::setw(16) << "category: " << "testframework\n"
13316                 << std::left << std::setw(16) << "framework: " << "Catch Test\n"
13317                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
13318     }
13319
13320     int Session::applyCommandLine( int argc, char const * const * argv ) {
13321         if( m_startupExceptions )
13322             return 1;
13323
13324         auto result = m_cli.parse( clara::Args( argc, argv ) );
13325         if( !result ) {
13326             config();
13327             getCurrentMutableContext().setConfig(m_config);
13328             Catch::cerr()
13329                 << Colour( Colour::Red )
13330                 << "\nError(s) in input:\n"
13331                 << Column( result.errorMessage() ).indent( 2 )
13332                 << "\n\n";
13333             Catch::cerr() << "Run with -? for usage\n" << std::endl;
13334             return MaxExitCode;
13335         }
13336
13337         if( m_configData.showHelp )
13338             showHelp();
13339         if( m_configData.libIdentify )
13340             libIdentify();
13341         m_config.reset();
13342         return 0;
13343     }
13344
13345 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13346     int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
13347
13348         char **utf8Argv = new char *[ argc ];
13349
13350         for ( int i = 0; i < argc; ++i ) {
13351             int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
13352
13353             utf8Argv[ i ] = new char[ bufSize ];
13354
13355             WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
13356         }
13357
13358         int returnCode = applyCommandLine( argc, utf8Argv );
13359
13360         for ( int i = 0; i < argc; ++i )
13361             delete [] utf8Argv[ i ];
13362
13363         delete [] utf8Argv;
13364
13365         return returnCode;
13366     }
13367 #endif
13368
13369     void Session::useConfigData( ConfigData const& configData ) {
13370         m_configData = configData;
13371         m_config.reset();
13372     }
13373
13374     int Session::run() {
13375         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
13376             Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
13377             static_cast<void>(std::getchar());
13378         }
13379         int exitCode = runInternal();
13380         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
13381             Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
13382             static_cast<void>(std::getchar());
13383         }
13384         return exitCode;
13385     }
13386
13387     clara::Parser const& Session::cli() const {
13388         return m_cli;
13389     }
13390     void Session::cli( clara::Parser const& newParser ) {
13391         m_cli = newParser;
13392     }
13393     ConfigData& Session::configData() {
13394         return m_configData;
13395     }
13396     Config& Session::config() {
13397         if( !m_config )
13398             m_config = std::make_shared<Config>( m_configData );
13399         return *m_config;
13400     }
13401
13402     int Session::runInternal() {
13403         if( m_startupExceptions )
13404             return 1;
13405
13406         if (m_configData.showHelp || m_configData.libIdentify) {
13407             return 0;
13408         }
13409
13410         CATCH_TRY {
13411             config(); // Force config to be constructed
13412
13413             seedRng( *m_config );
13414
13415             if( m_configData.filenamesAsTags )
13416                 applyFilenamesAsTags( *m_config );
13417
13418             // Handle list request
13419             if( Option<std::size_t> listed = list( m_config ) )
13420                 return static_cast<int>( *listed );
13421
13422             TestGroup tests { m_config };
13423             auto const totals = tests.execute();
13424
13425             if( m_config->warnAboutNoTests() && totals.error == -1 )
13426                 return 2;
13427
13428             // Note that on unices only the lower 8 bits are usually used, clamping
13429             // the return value to 255 prevents false negative when some multiple
13430             // of 256 tests has failed
13431             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
13432         }
13433 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13434         catch( std::exception& ex ) {
13435             Catch::cerr() << ex.what() << std::endl;
13436             return MaxExitCode;
13437         }
13438 #endif
13439     }
13440
13441 } // end namespace Catch
13442 // end catch_session.cpp
13443 // start catch_singletons.cpp
13444
13445 #include <vector>
13446
13447 namespace Catch {
13448
13449     namespace {
13450         static auto getSingletons() -> std::vector<ISingleton*>*& {
13451             static std::vector<ISingleton*>* g_singletons = nullptr;
13452             if( !g_singletons )
13453                 g_singletons = new std::vector<ISingleton*>();
13454             return g_singletons;
13455         }
13456     }
13457
13458     ISingleton::~ISingleton() {}
13459
13460     void addSingleton(ISingleton* singleton ) {
13461         getSingletons()->push_back( singleton );
13462     }
13463     void cleanupSingletons() {
13464         auto& singletons = getSingletons();
13465         for( auto singleton : *singletons )
13466             delete singleton;
13467         delete singletons;
13468         singletons = nullptr;
13469     }
13470
13471 } // namespace Catch
13472 // end catch_singletons.cpp
13473 // start catch_startup_exception_registry.cpp
13474
13475 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13476 namespace Catch {
13477 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
13478         CATCH_TRY {
13479             m_exceptions.push_back(exception);
13480         } CATCH_CATCH_ALL {
13481             // If we run out of memory during start-up there's really not a lot more we can do about it
13482             std::terminate();
13483         }
13484     }
13485
13486     std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
13487         return m_exceptions;
13488     }
13489
13490 } // end namespace Catch
13491 #endif
13492 // end catch_startup_exception_registry.cpp
13493 // start catch_stream.cpp
13494
13495 #include <cstdio>
13496 #include <iostream>
13497 #include <fstream>
13498 #include <sstream>
13499 #include <vector>
13500 #include <memory>
13501
13502 namespace Catch {
13503
13504     Catch::IStream::~IStream() = default;
13505
13506     namespace Detail { namespace {
13507         template<typename WriterF, std::size_t bufferSize=256>
13508         class StreamBufImpl : public std::streambuf {
13509             char data[bufferSize];
13510             WriterF m_writer;
13511
13512         public:
13513             StreamBufImpl() {
13514                 setp( data, data + sizeof(data) );
13515             }
13516
13517             ~StreamBufImpl() noexcept {
13518                 StreamBufImpl::sync();
13519             }
13520
13521         private:
13522             int overflow( int c ) override {
13523                 sync();
13524
13525                 if( c != EOF ) {
13526                     if( pbase() == epptr() )
13527                         m_writer( std::string( 1, static_cast<char>( c ) ) );
13528                     else
13529                         sputc( static_cast<char>( c ) );
13530                 }
13531                 return 0;
13532             }
13533
13534             int sync() override {
13535                 if( pbase() != pptr() ) {
13536                     m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
13537                     setp( pbase(), epptr() );
13538                 }
13539                 return 0;
13540             }
13541         };
13542
13543         ///////////////////////////////////////////////////////////////////////////
13544
13545         struct OutputDebugWriter {
13546
13547             void operator()( std::string const&str ) {
13548                 writeToDebugConsole( str );
13549             }
13550         };
13551
13552         ///////////////////////////////////////////////////////////////////////////
13553
13554         class FileStream : public IStream {
13555             mutable std::ofstream m_ofs;
13556         public:
13557             FileStream( StringRef filename ) {
13558                 m_ofs.open( filename.c_str() );
13559                 CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
13560             }
13561             ~FileStream() override = default;
13562         public: // IStream
13563             std::ostream& stream() const override {
13564                 return m_ofs;
13565             }
13566         };
13567
13568         ///////////////////////////////////////////////////////////////////////////
13569
13570         class CoutStream : public IStream {
13571             mutable std::ostream m_os;
13572         public:
13573             // Store the streambuf from cout up-front because
13574             // cout may get redirected when running tests
13575             CoutStream() : m_os( Catch::cout().rdbuf() ) {}
13576             ~CoutStream() override = default;
13577
13578         public: // IStream
13579             std::ostream& stream() const override { return m_os; }
13580         };
13581
13582         ///////////////////////////////////////////////////////////////////////////
13583
13584         class DebugOutStream : public IStream {
13585             std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
13586             mutable std::ostream m_os;
13587         public:
13588             DebugOutStream()
13589             :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
13590                 m_os( m_streamBuf.get() )
13591             {}
13592
13593             ~DebugOutStream() override = default;
13594
13595         public: // IStream
13596             std::ostream& stream() const override { return m_os; }
13597         };
13598
13599     }} // namespace anon::detail
13600
13601     ///////////////////////////////////////////////////////////////////////////
13602
13603     auto makeStream( StringRef const &filename ) -> IStream const* {
13604         if( filename.empty() )
13605             return new Detail::CoutStream();
13606         else if( filename[0] == '%' ) {
13607             if( filename == "%debug" )
13608                 return new Detail::DebugOutStream();
13609             else
13610                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
13611         }
13612         else
13613             return new Detail::FileStream( filename );
13614     }
13615
13616     // This class encapsulates the idea of a pool of ostringstreams that can be reused.
13617     struct StringStreams {
13618         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
13619         std::vector<std::size_t> m_unused;
13620         std::ostringstream m_referenceStream; // Used for copy state/ flags from
13621
13622         auto add() -> std::size_t {
13623             if( m_unused.empty() ) {
13624                 m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
13625                 return m_streams.size()-1;
13626             }
13627             else {
13628                 auto index = m_unused.back();
13629                 m_unused.pop_back();
13630                 return index;
13631             }
13632         }
13633
13634         void release( std::size_t index ) {
13635             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
13636             m_unused.push_back(index);
13637         }
13638     };
13639
13640     ReusableStringStream::ReusableStringStream()
13641     :   m_index( Singleton<StringStreams>::getMutable().add() ),
13642         m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
13643     {}
13644
13645     ReusableStringStream::~ReusableStringStream() {
13646         static_cast<std::ostringstream*>( m_oss )->str("");
13647         m_oss->clear();
13648         Singleton<StringStreams>::getMutable().release( m_index );
13649     }
13650
13651     auto ReusableStringStream::str() const -> std::string {
13652         return static_cast<std::ostringstream*>( m_oss )->str();
13653     }
13654
13655     ///////////////////////////////////////////////////////////////////////////
13656
13657 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
13658     std::ostream& cout() { return std::cout; }
13659     std::ostream& cerr() { return std::cerr; }
13660     std::ostream& clog() { return std::clog; }
13661 #endif
13662 }
13663 // end catch_stream.cpp
13664 // start catch_string_manip.cpp
13665
13666 #include <algorithm>
13667 #include <ostream>
13668 #include <cstring>
13669 #include <cctype>
13670 #include <vector>
13671
13672 namespace Catch {
13673
13674     namespace {
13675         char toLowerCh(char c) {
13676             return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
13677         }
13678     }
13679
13680     bool startsWith( std::string const& s, std::string const& prefix ) {
13681         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
13682     }
13683     bool startsWith( std::string const& s, char prefix ) {
13684         return !s.empty() && s[0] == prefix;
13685     }
13686     bool endsWith( std::string const& s, std::string const& suffix ) {
13687         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
13688     }
13689     bool endsWith( std::string const& s, char suffix ) {
13690         return !s.empty() && s[s.size()-1] == suffix;
13691     }
13692     bool contains( std::string const& s, std::string const& infix ) {
13693         return s.find( infix ) != std::string::npos;
13694     }
13695     void toLowerInPlace( std::string& s ) {
13696         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
13697     }
13698     std::string toLower( std::string const& s ) {
13699         std::string lc = s;
13700         toLowerInPlace( lc );
13701         return lc;
13702     }
13703     std::string trim( std::string const& str ) {
13704         static char const* whitespaceChars = "\n\r\t ";
13705         std::string::size_type start = str.find_first_not_of( whitespaceChars );
13706         std::string::size_type end = str.find_last_not_of( whitespaceChars );
13707
13708         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
13709     }
13710
13711     StringRef trim(StringRef ref) {
13712         const auto is_ws = [](char c) {
13713             return c == ' ' || c == '\t' || c == '\n' || c == '\r';
13714         };
13715         size_t real_begin = 0;
13716         while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
13717         size_t real_end = ref.size();
13718         while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
13719
13720         return ref.substr(real_begin, real_end - real_begin);
13721     }
13722
13723     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
13724         bool replaced = false;
13725         std::size_t i = str.find( replaceThis );
13726         while( i != std::string::npos ) {
13727             replaced = true;
13728             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
13729             if( i < str.size()-withThis.size() )
13730                 i = str.find( replaceThis, i+withThis.size() );
13731             else
13732                 i = std::string::npos;
13733         }
13734         return replaced;
13735     }
13736
13737     std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
13738         std::vector<StringRef> subStrings;
13739         std::size_t start = 0;
13740         for(std::size_t pos = 0; pos < str.size(); ++pos ) {
13741             if( str[pos] == delimiter ) {
13742                 if( pos - start > 1 )
13743                     subStrings.push_back( str.substr( start, pos-start ) );
13744                 start = pos+1;
13745             }
13746         }
13747         if( start < str.size() )
13748             subStrings.push_back( str.substr( start, str.size()-start ) );
13749         return subStrings;
13750     }
13751
13752     pluralise::pluralise( std::size_t count, std::string const& label )
13753     :   m_count( count ),
13754         m_label( label )
13755     {}
13756
13757     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
13758         os << pluraliser.m_count << ' ' << pluraliser.m_label;
13759         if( pluraliser.m_count != 1 )
13760             os << 's';
13761         return os;
13762     }
13763
13764 }
13765 // end catch_string_manip.cpp
13766 // start catch_stringref.cpp
13767
13768 #include <algorithm>
13769 #include <ostream>
13770 #include <cstring>
13771 #include <cstdint>
13772
13773 namespace Catch {
13774     StringRef::StringRef( char const* rawChars ) noexcept
13775     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
13776     {}
13777
13778     auto StringRef::c_str() const -> char const* {
13779         CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
13780         return m_start;
13781     }
13782     auto StringRef::data() const noexcept -> char const* {
13783         return m_start;
13784     }
13785
13786     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
13787         if (start < m_size) {
13788             return StringRef(m_start + start, (std::min)(m_size - start, size));
13789         } else {
13790             return StringRef();
13791         }
13792     }
13793     auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
13794         return m_size == other.m_size
13795             && (std::memcmp( m_start, other.m_start, m_size ) == 0);
13796     }
13797
13798     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
13799         return os.write(str.data(), str.size());
13800     }
13801
13802     auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
13803         lhs.append(rhs.data(), rhs.size());
13804         return lhs;
13805     }
13806
13807 } // namespace Catch
13808 // end catch_stringref.cpp
13809 // start catch_tag_alias.cpp
13810
13811 namespace Catch {
13812     TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
13813 }
13814 // end catch_tag_alias.cpp
13815 // start catch_tag_alias_autoregistrar.cpp
13816
13817 namespace Catch {
13818
13819     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
13820         CATCH_TRY {
13821             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
13822         } CATCH_CATCH_ALL {
13823             // Do not throw when constructing global objects, instead register the exception to be processed later
13824             getMutableRegistryHub().registerStartupException();
13825         }
13826     }
13827
13828 }
13829 // end catch_tag_alias_autoregistrar.cpp
13830 // start catch_tag_alias_registry.cpp
13831
13832 #include <sstream>
13833
13834 namespace Catch {
13835
13836     TagAliasRegistry::~TagAliasRegistry() {}
13837
13838     TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
13839         auto it = m_registry.find( alias );
13840         if( it != m_registry.end() )
13841             return &(it->second);
13842         else
13843             return nullptr;
13844     }
13845
13846     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
13847         std::string expandedTestSpec = unexpandedTestSpec;
13848         for( auto const& registryKvp : m_registry ) {
13849             std::size_t pos = expandedTestSpec.find( registryKvp.first );
13850             if( pos != std::string::npos ) {
13851                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
13852                                     registryKvp.second.tag +
13853                                     expandedTestSpec.substr( pos + registryKvp.first.size() );
13854             }
13855         }
13856         return expandedTestSpec;
13857     }
13858
13859     void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
13860         CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
13861                       "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
13862
13863         CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
13864                       "error: tag alias, '" << alias << "' already registered.\n"
13865                       << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
13866                       << "\tRedefined at: " << lineInfo );
13867     }
13868
13869     ITagAliasRegistry::~ITagAliasRegistry() {}
13870
13871     ITagAliasRegistry const& ITagAliasRegistry::get() {
13872         return getRegistryHub().getTagAliasRegistry();
13873     }
13874
13875 } // end namespace Catch
13876 // end catch_tag_alias_registry.cpp
13877 // start catch_test_case_info.cpp
13878
13879 #include <cctype>
13880 #include <exception>
13881 #include <algorithm>
13882 #include <sstream>
13883
13884 namespace Catch {
13885
13886     namespace {
13887         TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
13888             if( startsWith( tag, '.' ) ||
13889                 tag == "!hide" )
13890                 return TestCaseInfo::IsHidden;
13891             else if( tag == "!throws" )
13892                 return TestCaseInfo::Throws;
13893             else if( tag == "!shouldfail" )
13894                 return TestCaseInfo::ShouldFail;
13895             else if( tag == "!mayfail" )
13896                 return TestCaseInfo::MayFail;
13897             else if( tag == "!nonportable" )
13898                 return TestCaseInfo::NonPortable;
13899             else if( tag == "!benchmark" )
13900                 return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
13901             else
13902                 return TestCaseInfo::None;
13903         }
13904         bool isReservedTag( std::string const& tag ) {
13905             return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
13906         }
13907         void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
13908             CATCH_ENFORCE( !isReservedTag(tag),
13909                           "Tag name: [" << tag << "] is not allowed.\n"
13910                           << "Tag names starting with non alphanumeric characters are reserved\n"
13911                           << _lineInfo );
13912         }
13913     }
13914
13915     TestCase makeTestCase(  ITestInvoker* _testCase,
13916                             std::string const& _className,
13917                             NameAndTags const& nameAndTags,
13918                             SourceLineInfo const& _lineInfo )
13919     {
13920         bool isHidden = false;
13921
13922         // Parse out tags
13923         std::vector<std::string> tags;
13924         std::string desc, tag;
13925         bool inTag = false;
13926         for (char c : nameAndTags.tags) {
13927             if( !inTag ) {
13928                 if( c == '[' )
13929                     inTag = true;
13930                 else
13931                     desc += c;
13932             }
13933             else {
13934                 if( c == ']' ) {
13935                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
13936                     if( ( prop & TestCaseInfo::IsHidden ) != 0 )
13937                         isHidden = true;
13938                     else if( prop == TestCaseInfo::None )
13939                         enforceNotReservedTag( tag, _lineInfo );
13940
13941                     // Merged hide tags like `[.approvals]` should be added as
13942                     // `[.][approvals]`. The `[.]` is added at later point, so
13943                     // we only strip the prefix
13944                     if (startsWith(tag, '.') && tag.size() > 1) {
13945                         tag.erase(0, 1);
13946                     }
13947                     tags.push_back( tag );
13948                     tag.clear();
13949                     inTag = false;
13950                 }
13951                 else
13952                     tag += c;
13953             }
13954         }
13955         if( isHidden ) {
13956             // Add all "hidden" tags to make them behave identically
13957             tags.insert( tags.end(), { ".", "!hide" } );
13958         }
13959
13960         TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
13961         return TestCase( _testCase, std::move(info) );
13962     }
13963
13964     void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
13965         std::sort(begin(tags), end(tags));
13966         tags.erase(std::unique(begin(tags), end(tags)), end(tags));
13967         testCaseInfo.lcaseTags.clear();
13968
13969         for( auto const& tag : tags ) {
13970             std::string lcaseTag = toLower( tag );
13971             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
13972             testCaseInfo.lcaseTags.push_back( lcaseTag );
13973         }
13974         testCaseInfo.tags = std::move(tags);
13975     }
13976
13977     TestCaseInfo::TestCaseInfo( std::string const& _name,
13978                                 std::string const& _className,
13979                                 std::string const& _description,
13980                                 std::vector<std::string> const& _tags,
13981                                 SourceLineInfo const& _lineInfo )
13982     :   name( _name ),
13983         className( _className ),
13984         description( _description ),
13985         lineInfo( _lineInfo ),
13986         properties( None )
13987     {
13988         setTags( *this, _tags );
13989     }
13990
13991     bool TestCaseInfo::isHidden() const {
13992         return ( properties & IsHidden ) != 0;
13993     }
13994     bool TestCaseInfo::throws() const {
13995         return ( properties & Throws ) != 0;
13996     }
13997     bool TestCaseInfo::okToFail() const {
13998         return ( properties & (ShouldFail | MayFail ) ) != 0;
13999     }
14000     bool TestCaseInfo::expectedToFail() const {
14001         return ( properties & (ShouldFail ) ) != 0;
14002     }
14003
14004     std::string TestCaseInfo::tagsAsString() const {
14005         std::string ret;
14006         // '[' and ']' per tag
14007         std::size_t full_size = 2 * tags.size();
14008         for (const auto& tag : tags) {
14009             full_size += tag.size();
14010         }
14011         ret.reserve(full_size);
14012         for (const auto& tag : tags) {
14013             ret.push_back('[');
14014             ret.append(tag);
14015             ret.push_back(']');
14016         }
14017
14018         return ret;
14019     }
14020
14021     TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
14022
14023     TestCase TestCase::withName( std::string const& _newName ) const {
14024         TestCase other( *this );
14025         other.name = _newName;
14026         return other;
14027     }
14028
14029     void TestCase::invoke() const {
14030         test->invoke();
14031     }
14032
14033     bool TestCase::operator == ( TestCase const& other ) const {
14034         return  test.get() == other.test.get() &&
14035                 name == other.name &&
14036                 className == other.className;
14037     }
14038
14039     bool TestCase::operator < ( TestCase const& other ) const {
14040         return name < other.name;
14041     }
14042
14043     TestCaseInfo const& TestCase::getTestCaseInfo() const
14044     {
14045         return *this;
14046     }
14047
14048 } // end namespace Catch
14049 // end catch_test_case_info.cpp
14050 // start catch_test_case_registry_impl.cpp
14051
14052 #include <algorithm>
14053 #include <sstream>
14054
14055 namespace Catch {
14056
14057     namespace {
14058         struct TestHasher {
14059             explicit TestHasher(Catch::SimplePcg32& rng) {
14060                 basis = rng();
14061                 basis <<= 32;
14062                 basis |= rng();
14063             }
14064
14065             uint64_t basis;
14066
14067             uint64_t operator()(TestCase const& t) const {
14068                 // Modified FNV-1a hash
14069                 static constexpr uint64_t prime = 1099511628211;
14070                 uint64_t hash = basis;
14071                 for (const char c : t.name) {
14072                     hash ^= c;
14073                     hash *= prime;
14074                 }
14075                 return hash;
14076             }
14077         };
14078     } // end unnamed namespace
14079
14080     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
14081         switch( config.runOrder() ) {
14082             case RunTests::InDeclarationOrder:
14083                 // already in declaration order
14084                 break;
14085
14086             case RunTests::InLexicographicalOrder: {
14087                 std::vector<TestCase> sorted = unsortedTestCases;
14088                 std::sort( sorted.begin(), sorted.end() );
14089                 return sorted;
14090             }
14091
14092             case RunTests::InRandomOrder: {
14093                 seedRng( config );
14094                 TestHasher h( rng() );
14095
14096                 using hashedTest = std::pair<uint64_t, TestCase const*>;
14097                 std::vector<hashedTest> indexed_tests;
14098                 indexed_tests.reserve( unsortedTestCases.size() );
14099
14100                 for (auto const& testCase : unsortedTestCases) {
14101                     indexed_tests.emplace_back(h(testCase), &testCase);
14102                 }
14103
14104                 std::sort(indexed_tests.begin(), indexed_tests.end(),
14105                           [](hashedTest const& lhs, hashedTest const& rhs) {
14106                           if (lhs.first == rhs.first) {
14107                               return lhs.second->name < rhs.second->name;
14108                           }
14109                           return lhs.first < rhs.first;
14110                 });
14111
14112                 std::vector<TestCase> sorted;
14113                 sorted.reserve( indexed_tests.size() );
14114
14115                 for (auto const& hashed : indexed_tests) {
14116                     sorted.emplace_back(*hashed.second);
14117                 }
14118
14119                 return sorted;
14120             }
14121         }
14122         return unsortedTestCases;
14123     }
14124
14125     bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
14126         return !testCase.throws() || config.allowThrows();
14127     }
14128
14129     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
14130         return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
14131     }
14132
14133     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
14134         std::set<TestCase> seenFunctions;
14135         for( auto const& function : functions ) {
14136             auto prev = seenFunctions.insert( function );
14137             CATCH_ENFORCE( prev.second,
14138                     "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
14139                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
14140                     << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
14141         }
14142     }
14143
14144     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
14145         std::vector<TestCase> filtered;
14146         filtered.reserve( testCases.size() );
14147         for (auto const& testCase : testCases) {
14148             if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
14149                 (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
14150                 filtered.push_back(testCase);
14151             }
14152         }
14153         return filtered;
14154     }
14155     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
14156         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
14157     }
14158
14159     void TestRegistry::registerTest( TestCase const& testCase ) {
14160         std::string name = testCase.getTestCaseInfo().name;
14161         if( name.empty() ) {
14162             ReusableStringStream rss;
14163             rss << "Anonymous test case " << ++m_unnamedCount;
14164             return registerTest( testCase.withName( rss.str() ) );
14165         }
14166         m_functions.push_back( testCase );
14167     }
14168
14169     std::vector<TestCase> const& TestRegistry::getAllTests() const {
14170         return m_functions;
14171     }
14172     std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
14173         if( m_sortedFunctions.empty() )
14174             enforceNoDuplicateTestCases( m_functions );
14175
14176         if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
14177             m_sortedFunctions = sortTests( config, m_functions );
14178             m_currentSortOrder = config.runOrder();
14179         }
14180         return m_sortedFunctions;
14181     }
14182
14183     ///////////////////////////////////////////////////////////////////////////
14184     TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
14185
14186     void TestInvokerAsFunction::invoke() const {
14187         m_testAsFunction();
14188     }
14189
14190     std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
14191         std::string className(classOrQualifiedMethodName);
14192         if( startsWith( className, '&' ) )
14193         {
14194             std::size_t lastColons = className.rfind( "::" );
14195             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
14196             if( penultimateColons == std::string::npos )
14197                 penultimateColons = 1;
14198             className = className.substr( penultimateColons, lastColons-penultimateColons );
14199         }
14200         return className;
14201     }
14202
14203 } // end namespace Catch
14204 // end catch_test_case_registry_impl.cpp
14205 // start catch_test_case_tracker.cpp
14206
14207 #include <algorithm>
14208 #include <cassert>
14209 #include <stdexcept>
14210 #include <memory>
14211 #include <sstream>
14212
14213 #if defined(__clang__)
14214 #    pragma clang diagnostic push
14215 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
14216 #endif
14217
14218 namespace Catch {
14219 namespace TestCaseTracking {
14220
14221     NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
14222     :   name( _name ),
14223         location( _location )
14224     {}
14225
14226     ITracker::~ITracker() = default;
14227
14228     ITracker& TrackerContext::startRun() {
14229         m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
14230         m_currentTracker = nullptr;
14231         m_runState = Executing;
14232         return *m_rootTracker;
14233     }
14234
14235     void TrackerContext::endRun() {
14236         m_rootTracker.reset();
14237         m_currentTracker = nullptr;
14238         m_runState = NotStarted;
14239     }
14240
14241     void TrackerContext::startCycle() {
14242         m_currentTracker = m_rootTracker.get();
14243         m_runState = Executing;
14244     }
14245     void TrackerContext::completeCycle() {
14246         m_runState = CompletedCycle;
14247     }
14248
14249     bool TrackerContext::completedCycle() const {
14250         return m_runState == CompletedCycle;
14251     }
14252     ITracker& TrackerContext::currentTracker() {
14253         return *m_currentTracker;
14254     }
14255     void TrackerContext::setCurrentTracker( ITracker* tracker ) {
14256         m_currentTracker = tracker;
14257     }
14258
14259     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
14260         ITracker(nameAndLocation),
14261         m_ctx( ctx ),
14262         m_parent( parent )
14263     {}
14264
14265     bool TrackerBase::isComplete() const {
14266         return m_runState == CompletedSuccessfully || m_runState == Failed;
14267     }
14268     bool TrackerBase::isSuccessfullyCompleted() const {
14269         return m_runState == CompletedSuccessfully;
14270     }
14271     bool TrackerBase::isOpen() const {
14272         return m_runState != NotStarted && !isComplete();
14273     }
14274     bool TrackerBase::hasChildren() const {
14275         return !m_children.empty();
14276     }
14277
14278     void TrackerBase::addChild( ITrackerPtr const& child ) {
14279         m_children.push_back( child );
14280     }
14281
14282     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
14283         auto it = std::find_if( m_children.begin(), m_children.end(),
14284             [&nameAndLocation]( ITrackerPtr const& tracker ){
14285                 return
14286                     tracker->nameAndLocation().location == nameAndLocation.location &&
14287                     tracker->nameAndLocation().name == nameAndLocation.name;
14288             } );
14289         return( it != m_children.end() )
14290             ? *it
14291             : nullptr;
14292     }
14293     ITracker& TrackerBase::parent() {
14294         assert( m_parent ); // Should always be non-null except for root
14295         return *m_parent;
14296     }
14297
14298     void TrackerBase::openChild() {
14299         if( m_runState != ExecutingChildren ) {
14300             m_runState = ExecutingChildren;
14301             if( m_parent )
14302                 m_parent->openChild();
14303         }
14304     }
14305
14306     bool TrackerBase::isSectionTracker() const { return false; }
14307     bool TrackerBase::isGeneratorTracker() const { return false; }
14308
14309     void TrackerBase::open() {
14310         m_runState = Executing;
14311         moveToThis();
14312         if( m_parent )
14313             m_parent->openChild();
14314     }
14315
14316     void TrackerBase::close() {
14317
14318         // Close any still open children (e.g. generators)
14319         while( &m_ctx.currentTracker() != this )
14320             m_ctx.currentTracker().close();
14321
14322         switch( m_runState ) {
14323             case NeedsAnotherRun:
14324                 break;
14325
14326             case Executing:
14327                 m_runState = CompletedSuccessfully;
14328                 break;
14329             case ExecutingChildren:
14330                 if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
14331                     m_runState = CompletedSuccessfully;
14332                 break;
14333
14334             case NotStarted:
14335             case CompletedSuccessfully:
14336             case Failed:
14337                 CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
14338
14339             default:
14340                 CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
14341         }
14342         moveToParent();
14343         m_ctx.completeCycle();
14344     }
14345     void TrackerBase::fail() {
14346         m_runState = Failed;
14347         if( m_parent )
14348             m_parent->markAsNeedingAnotherRun();
14349         moveToParent();
14350         m_ctx.completeCycle();
14351     }
14352     void TrackerBase::markAsNeedingAnotherRun() {
14353         m_runState = NeedsAnotherRun;
14354     }
14355
14356     void TrackerBase::moveToParent() {
14357         assert( m_parent );
14358         m_ctx.setCurrentTracker( m_parent );
14359     }
14360     void TrackerBase::moveToThis() {
14361         m_ctx.setCurrentTracker( this );
14362     }
14363
14364     SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
14365     :   TrackerBase( nameAndLocation, ctx, parent ),
14366         m_trimmed_name(trim(nameAndLocation.name))
14367     {
14368         if( parent ) {
14369             while( !parent->isSectionTracker() )
14370                 parent = &parent->parent();
14371
14372             SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
14373             addNextFilters( parentSection.m_filters );
14374         }
14375     }
14376
14377     bool SectionTracker::isComplete() const {
14378         bool complete = true;
14379
14380         if ((m_filters.empty() || m_filters[0] == "")
14381             || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
14382             complete = TrackerBase::isComplete();
14383         }
14384         return complete;
14385     }
14386
14387     bool SectionTracker::isSectionTracker() const { return true; }
14388
14389     SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
14390         std::shared_ptr<SectionTracker> section;
14391
14392         ITracker& currentTracker = ctx.currentTracker();
14393         if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
14394             assert( childTracker );
14395             assert( childTracker->isSectionTracker() );
14396             section = std::static_pointer_cast<SectionTracker>( childTracker );
14397         }
14398         else {
14399             section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
14400             currentTracker.addChild( section );
14401         }
14402         if( !ctx.completedCycle() )
14403             section->tryOpen();
14404         return *section;
14405     }
14406
14407     void SectionTracker::tryOpen() {
14408         if( !isComplete() )
14409             open();
14410     }
14411
14412     void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
14413         if( !filters.empty() ) {
14414             m_filters.reserve( m_filters.size() + filters.size() + 2 );
14415             m_filters.emplace_back(""); // Root - should never be consulted
14416             m_filters.emplace_back(""); // Test Case - not a section filter
14417             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
14418         }
14419     }
14420     void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
14421         if( filters.size() > 1 )
14422             m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
14423     }
14424
14425 } // namespace TestCaseTracking
14426
14427 using TestCaseTracking::ITracker;
14428 using TestCaseTracking::TrackerContext;
14429 using TestCaseTracking::SectionTracker;
14430
14431 } // namespace Catch
14432
14433 #if defined(__clang__)
14434 #    pragma clang diagnostic pop
14435 #endif
14436 // end catch_test_case_tracker.cpp
14437 // start catch_test_registry.cpp
14438
14439 namespace Catch {
14440
14441     auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
14442         return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
14443     }
14444
14445     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
14446
14447     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
14448         CATCH_TRY {
14449             getMutableRegistryHub()
14450                     .registerTest(
14451                         makeTestCase(
14452                             invoker,
14453                             extractClassName( classOrMethod ),
14454                             nameAndTags,
14455                             lineInfo));
14456         } CATCH_CATCH_ALL {
14457             // Do not throw when constructing global objects, instead register the exception to be processed later
14458             getMutableRegistryHub().registerStartupException();
14459         }
14460     }
14461
14462     AutoReg::~AutoReg() = default;
14463 }
14464 // end catch_test_registry.cpp
14465 // start catch_test_spec.cpp
14466
14467 #include <algorithm>
14468 #include <string>
14469 #include <vector>
14470 #include <memory>
14471
14472 namespace Catch {
14473
14474     TestSpec::Pattern::Pattern( std::string const& name )
14475     : m_name( name )
14476     {}
14477
14478     TestSpec::Pattern::~Pattern() = default;
14479
14480     std::string const& TestSpec::Pattern::name() const {
14481         return m_name;
14482     }
14483
14484     TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
14485     : Pattern( filterString )
14486     , m_wildcardPattern( toLower( name ), CaseSensitive::No )
14487     {}
14488
14489     bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
14490         return m_wildcardPattern.matches( testCase.name );
14491     }
14492
14493     TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
14494     : Pattern( filterString )
14495     , m_tag( toLower( tag ) )
14496     {}
14497
14498     bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
14499         return std::find(begin(testCase.lcaseTags),
14500                          end(testCase.lcaseTags),
14501                          m_tag) != end(testCase.lcaseTags);
14502     }
14503
14504     TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
14505     : Pattern( underlyingPattern->name() )
14506     , m_underlyingPattern( underlyingPattern )
14507     {}
14508
14509     bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
14510         return !m_underlyingPattern->matches( testCase );
14511     }
14512
14513     bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
14514         return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
14515     }
14516
14517     std::string TestSpec::Filter::name() const {
14518         std::string name;
14519         for( auto const& p : m_patterns )
14520             name += p->name();
14521         return name;
14522     }
14523
14524     bool TestSpec::hasFilters() const {
14525         return !m_filters.empty();
14526     }
14527
14528     bool TestSpec::matches( TestCaseInfo const& testCase ) const {
14529         return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
14530     }
14531
14532     TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
14533     {
14534         Matches matches( m_filters.size() );
14535         std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
14536             std::vector<TestCase const*> currentMatches;
14537             for( auto const& test : testCases )
14538                 if( isThrowSafe( test, config ) && filter.matches( test ) )
14539                     currentMatches.emplace_back( &test );
14540             return FilterMatch{ filter.name(), currentMatches };
14541         } );
14542         return matches;
14543     }
14544
14545     const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
14546         return  (m_invalidArgs);
14547     }
14548
14549 }
14550 // end catch_test_spec.cpp
14551 // start catch_test_spec_parser.cpp
14552
14553 namespace Catch {
14554
14555     TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
14556
14557     TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
14558         m_mode = None;
14559         m_exclusion = false;
14560         m_arg = m_tagAliases->expandAliases( arg );
14561         m_escapeChars.clear();
14562         m_substring.reserve(m_arg.size());
14563         m_patternName.reserve(m_arg.size());
14564         m_realPatternPos = 0;
14565
14566         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
14567           //if visitChar fails
14568            if( !visitChar( m_arg[m_pos] ) ){
14569                m_testSpec.m_invalidArgs.push_back(arg);
14570                break;
14571            }
14572         endMode();
14573         return *this;
14574     }
14575     TestSpec TestSpecParser::testSpec() {
14576         addFilter();
14577         return m_testSpec;
14578     }
14579     bool TestSpecParser::visitChar( char c ) {
14580         if( (m_mode != EscapedName) && (c == '\\') ) {
14581             escape();
14582             addCharToPattern(c);
14583             return true;
14584         }else if((m_mode != EscapedName) && (c == ',') )  {
14585             return separate();
14586         }
14587
14588         switch( m_mode ) {
14589         case None:
14590             if( processNoneChar( c ) )
14591                 return true;
14592             break;
14593         case Name:
14594             processNameChar( c );
14595             break;
14596         case EscapedName:
14597             endMode();
14598             addCharToPattern(c);
14599             return true;
14600         default:
14601         case Tag:
14602         case QuotedName:
14603             if( processOtherChar( c ) )
14604                 return true;
14605             break;
14606         }
14607
14608         m_substring += c;
14609         if( !isControlChar( c ) ) {
14610             m_patternName += c;
14611             m_realPatternPos++;
14612         }
14613         return true;
14614     }
14615     // Two of the processing methods return true to signal the caller to return
14616     // without adding the given character to the current pattern strings
14617     bool TestSpecParser::processNoneChar( char c ) {
14618         switch( c ) {
14619         case ' ':
14620             return true;
14621         case '~':
14622             m_exclusion = true;
14623             return false;
14624         case '[':
14625             startNewMode( Tag );
14626             return false;
14627         case '"':
14628             startNewMode( QuotedName );
14629             return false;
14630         default:
14631             startNewMode( Name );
14632             return false;
14633         }
14634     }
14635     void TestSpecParser::processNameChar( char c ) {
14636         if( c == '[' ) {
14637             if( m_substring == "exclude:" )
14638                 m_exclusion = true;
14639             else
14640                 endMode();
14641             startNewMode( Tag );
14642         }
14643     }
14644     bool TestSpecParser::processOtherChar( char c ) {
14645         if( !isControlChar( c ) )
14646             return false;
14647         m_substring += c;
14648         endMode();
14649         return true;
14650     }
14651     void TestSpecParser::startNewMode( Mode mode ) {
14652         m_mode = mode;
14653     }
14654     void TestSpecParser::endMode() {
14655         switch( m_mode ) {
14656         case Name:
14657         case QuotedName:
14658             return addNamePattern();
14659         case Tag:
14660             return addTagPattern();
14661         case EscapedName:
14662             revertBackToLastMode();
14663             return;
14664         case None:
14665         default:
14666             return startNewMode( None );
14667         }
14668     }
14669     void TestSpecParser::escape() {
14670         saveLastMode();
14671         m_mode = EscapedName;
14672         m_escapeChars.push_back(m_realPatternPos);
14673     }
14674     bool TestSpecParser::isControlChar( char c ) const {
14675         switch( m_mode ) {
14676             default:
14677                 return false;
14678             case None:
14679                 return c == '~';
14680             case Name:
14681                 return c == '[';
14682             case EscapedName:
14683                 return true;
14684             case QuotedName:
14685                 return c == '"';
14686             case Tag:
14687                 return c == '[' || c == ']';
14688         }
14689     }
14690
14691     void TestSpecParser::addFilter() {
14692         if( !m_currentFilter.m_patterns.empty() ) {
14693             m_testSpec.m_filters.push_back( m_currentFilter );
14694             m_currentFilter = TestSpec::Filter();
14695         }
14696     }
14697
14698     void TestSpecParser::saveLastMode() {
14699       lastMode = m_mode;
14700     }
14701
14702     void TestSpecParser::revertBackToLastMode() {
14703       m_mode = lastMode;
14704     }
14705
14706     bool TestSpecParser::separate() {
14707       if( (m_mode==QuotedName) || (m_mode==Tag) ){
14708          //invalid argument, signal failure to previous scope.
14709          m_mode = None;
14710          m_pos = m_arg.size();
14711          m_substring.clear();
14712          m_patternName.clear();
14713          m_realPatternPos = 0;
14714          return false;
14715       }
14716       endMode();
14717       addFilter();
14718       return true; //success
14719     }
14720
14721     std::string TestSpecParser::preprocessPattern() {
14722         std::string token = m_patternName;
14723         for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
14724             token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
14725         m_escapeChars.clear();
14726         if (startsWith(token, "exclude:")) {
14727             m_exclusion = true;
14728             token = token.substr(8);
14729         }
14730
14731         m_patternName.clear();
14732         m_realPatternPos = 0;
14733
14734         return token;
14735     }
14736
14737     void TestSpecParser::addNamePattern() {
14738         auto token = preprocessPattern();
14739
14740         if (!token.empty()) {
14741             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
14742             if (m_exclusion)
14743                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14744             m_currentFilter.m_patterns.push_back(pattern);
14745         }
14746         m_substring.clear();
14747         m_exclusion = false;
14748         m_mode = None;
14749     }
14750
14751     void TestSpecParser::addTagPattern() {
14752         auto token = preprocessPattern();
14753
14754         if (!token.empty()) {
14755             // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
14756             // we have to create a separate hide tag and shorten the real one
14757             if (token.size() > 1 && token[0] == '.') {
14758                 token.erase(token.begin());
14759                 TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
14760                 if (m_exclusion) {
14761                     pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14762                 }
14763                 m_currentFilter.m_patterns.push_back(pattern);
14764             }
14765
14766             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
14767
14768             if (m_exclusion) {
14769                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14770             }
14771             m_currentFilter.m_patterns.push_back(pattern);
14772         }
14773         m_substring.clear();
14774         m_exclusion = false;
14775         m_mode = None;
14776     }
14777
14778     TestSpec parseTestSpec( std::string const& arg ) {
14779         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
14780     }
14781
14782 } // namespace Catch
14783 // end catch_test_spec_parser.cpp
14784 // start catch_timer.cpp
14785
14786 #include <chrono>
14787
14788 static const uint64_t nanosecondsInSecond = 1000000000;
14789
14790 namespace Catch {
14791
14792     auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
14793         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
14794     }
14795
14796     namespace {
14797         auto estimateClockResolution() -> uint64_t {
14798             uint64_t sum = 0;
14799             static const uint64_t iterations = 1000000;
14800
14801             auto startTime = getCurrentNanosecondsSinceEpoch();
14802
14803             for( std::size_t i = 0; i < iterations; ++i ) {
14804
14805                 uint64_t ticks;
14806                 uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
14807                 do {
14808                     ticks = getCurrentNanosecondsSinceEpoch();
14809                 } while( ticks == baseTicks );
14810
14811                 auto delta = ticks - baseTicks;
14812                 sum += delta;
14813
14814                 // If we have been calibrating for over 3 seconds -- the clock
14815                 // is terrible and we should move on.
14816                 // TBD: How to signal that the measured resolution is probably wrong?
14817                 if (ticks > startTime + 3 * nanosecondsInSecond) {
14818                     return sum / ( i + 1u );
14819                 }
14820             }
14821
14822             // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
14823             // - and potentially do more iterations if there's a high variance.
14824             return sum/iterations;
14825         }
14826     }
14827     auto getEstimatedClockResolution() -> uint64_t {
14828         static auto s_resolution = estimateClockResolution();
14829         return s_resolution;
14830     }
14831
14832     void Timer::start() {
14833        m_nanoseconds = getCurrentNanosecondsSinceEpoch();
14834     }
14835     auto Timer::getElapsedNanoseconds() const -> uint64_t {
14836         return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
14837     }
14838     auto Timer::getElapsedMicroseconds() const -> uint64_t {
14839         return getElapsedNanoseconds()/1000;
14840     }
14841     auto Timer::getElapsedMilliseconds() const -> unsigned int {
14842         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
14843     }
14844     auto Timer::getElapsedSeconds() const -> double {
14845         return getElapsedMicroseconds()/1000000.0;
14846     }
14847
14848 } // namespace Catch
14849 // end catch_timer.cpp
14850 // start catch_tostring.cpp
14851
14852 #if defined(__clang__)
14853 #    pragma clang diagnostic push
14854 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
14855 #    pragma clang diagnostic ignored "-Wglobal-constructors"
14856 #endif
14857
14858 // Enable specific decls locally
14859 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
14860 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
14861 #endif
14862
14863 #include <cmath>
14864 #include <iomanip>
14865
14866 namespace Catch {
14867
14868 namespace Detail {
14869
14870     const std::string unprintableString = "{?}";
14871
14872     namespace {
14873         const int hexThreshold = 255;
14874
14875         struct Endianness {
14876             enum Arch { Big, Little };
14877
14878             static Arch which() {
14879                 int one = 1;
14880                 // If the lowest byte we read is non-zero, we can assume
14881                 // that little endian format is used.
14882                 auto value = *reinterpret_cast<char*>(&one);
14883                 return value ? Little : Big;
14884             }
14885         };
14886     }
14887
14888     std::string rawMemoryToString( const void *object, std::size_t size ) {
14889         // Reverse order for little endian architectures
14890         int i = 0, end = static_cast<int>( size ), inc = 1;
14891         if( Endianness::which() == Endianness::Little ) {
14892             i = end-1;
14893             end = inc = -1;
14894         }
14895
14896         unsigned char const *bytes = static_cast<unsigned char const *>(object);
14897         ReusableStringStream rss;
14898         rss << "0x" << std::setfill('0') << std::hex;
14899         for( ; i != end; i += inc )
14900              rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
14901        return rss.str();
14902     }
14903 }
14904
14905 template<typename T>
14906 std::string fpToString( T value, int precision ) {
14907     if (Catch::isnan(value)) {
14908         return "nan";
14909     }
14910
14911     ReusableStringStream rss;
14912     rss << std::setprecision( precision )
14913         << std::fixed
14914         << value;
14915     std::string d = rss.str();
14916     std::size_t i = d.find_last_not_of( '0' );
14917     if( i != std::string::npos && i != d.size()-1 ) {
14918         if( d[i] == '.' )
14919             i++;
14920         d = d.substr( 0, i+1 );
14921     }
14922     return d;
14923 }
14924
14925 //// ======================================================= ////
14926 //
14927 //   Out-of-line defs for full specialization of StringMaker
14928 //
14929 //// ======================================================= ////
14930
14931 std::string StringMaker<std::string>::convert(const std::string& str) {
14932     if (!getCurrentContext().getConfig()->showInvisibles()) {
14933         return '"' + str + '"';
14934     }
14935
14936     std::string s("\"");
14937     for (char c : str) {
14938         switch (c) {
14939         case '\n':
14940             s.append("\\n");
14941             break;
14942         case '\t':
14943             s.append("\\t");
14944             break;
14945         default:
14946             s.push_back(c);
14947             break;
14948         }
14949     }
14950     s.append("\"");
14951     return s;
14952 }
14953
14954 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
14955 std::string StringMaker<std::string_view>::convert(std::string_view str) {
14956     return ::Catch::Detail::stringify(std::string{ str });
14957 }
14958 #endif
14959
14960 std::string StringMaker<char const*>::convert(char const* str) {
14961     if (str) {
14962         return ::Catch::Detail::stringify(std::string{ str });
14963     } else {
14964         return{ "{null string}" };
14965     }
14966 }
14967 std::string StringMaker<char*>::convert(char* str) {
14968     if (str) {
14969         return ::Catch::Detail::stringify(std::string{ str });
14970     } else {
14971         return{ "{null string}" };
14972     }
14973 }
14974
14975 #ifdef CATCH_CONFIG_WCHAR
14976 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
14977     std::string s;
14978     s.reserve(wstr.size());
14979     for (auto c : wstr) {
14980         s += (c <= 0xff) ? static_cast<char>(c) : '?';
14981     }
14982     return ::Catch::Detail::stringify(s);
14983 }
14984
14985 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
14986 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
14987     return StringMaker<std::wstring>::convert(std::wstring(str));
14988 }
14989 # endif
14990
14991 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
14992     if (str) {
14993         return ::Catch::Detail::stringify(std::wstring{ str });
14994     } else {
14995         return{ "{null string}" };
14996     }
14997 }
14998 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
14999     if (str) {
15000         return ::Catch::Detail::stringify(std::wstring{ str });
15001     } else {
15002         return{ "{null string}" };
15003     }
15004 }
15005 #endif
15006
15007 #if defined(CATCH_CONFIG_CPP17_BYTE)
15008 #include <cstddef>
15009 std::string StringMaker<std::byte>::convert(std::byte value) {
15010     return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
15011 }
15012 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
15013
15014 std::string StringMaker<int>::convert(int value) {
15015     return ::Catch::Detail::stringify(static_cast<long long>(value));
15016 }
15017 std::string StringMaker<long>::convert(long value) {
15018     return ::Catch::Detail::stringify(static_cast<long long>(value));
15019 }
15020 std::string StringMaker<long long>::convert(long long value) {
15021     ReusableStringStream rss;
15022     rss << value;
15023     if (value > Detail::hexThreshold) {
15024         rss << " (0x" << std::hex << value << ')';
15025     }
15026     return rss.str();
15027 }
15028
15029 std::string StringMaker<unsigned int>::convert(unsigned int value) {
15030     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15031 }
15032 std::string StringMaker<unsigned long>::convert(unsigned long value) {
15033     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15034 }
15035 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
15036     ReusableStringStream rss;
15037     rss << value;
15038     if (value > Detail::hexThreshold) {
15039         rss << " (0x" << std::hex << value << ')';
15040     }
15041     return rss.str();
15042 }
15043
15044 std::string StringMaker<bool>::convert(bool b) {
15045     return b ? "true" : "false";
15046 }
15047
15048 std::string StringMaker<signed char>::convert(signed char value) {
15049     if (value == '\r') {
15050         return "'\\r'";
15051     } else if (value == '\f') {
15052         return "'\\f'";
15053     } else if (value == '\n') {
15054         return "'\\n'";
15055     } else if (value == '\t') {
15056         return "'\\t'";
15057     } else if ('\0' <= value && value < ' ') {
15058         return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
15059     } else {
15060         char chstr[] = "' '";
15061         chstr[1] = value;
15062         return chstr;
15063     }
15064 }
15065 std::string StringMaker<char>::convert(char c) {
15066     return ::Catch::Detail::stringify(static_cast<signed char>(c));
15067 }
15068 std::string StringMaker<unsigned char>::convert(unsigned char c) {
15069     return ::Catch::Detail::stringify(static_cast<char>(c));
15070 }
15071
15072 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
15073     return "nullptr";
15074 }
15075
15076 int StringMaker<float>::precision = 5;
15077
15078 std::string StringMaker<float>::convert(float value) {
15079     return fpToString(value, precision) + 'f';
15080 }
15081
15082 int StringMaker<double>::precision = 10;
15083
15084 std::string StringMaker<double>::convert(double value) {
15085     return fpToString(value, precision);
15086 }
15087
15088 std::string ratio_string<std::atto>::symbol() { return "a"; }
15089 std::string ratio_string<std::femto>::symbol() { return "f"; }
15090 std::string ratio_string<std::pico>::symbol() { return "p"; }
15091 std::string ratio_string<std::nano>::symbol() { return "n"; }
15092 std::string ratio_string<std::micro>::symbol() { return "u"; }
15093 std::string ratio_string<std::milli>::symbol() { return "m"; }
15094
15095 } // end namespace Catch
15096
15097 #if defined(__clang__)
15098 #    pragma clang diagnostic pop
15099 #endif
15100
15101 // end catch_tostring.cpp
15102 // start catch_totals.cpp
15103
15104 namespace Catch {
15105
15106     Counts Counts::operator - ( Counts const& other ) const {
15107         Counts diff;
15108         diff.passed = passed - other.passed;
15109         diff.failed = failed - other.failed;
15110         diff.failedButOk = failedButOk - other.failedButOk;
15111         return diff;
15112     }
15113
15114     Counts& Counts::operator += ( Counts const& other ) {
15115         passed += other.passed;
15116         failed += other.failed;
15117         failedButOk += other.failedButOk;
15118         return *this;
15119     }
15120
15121     std::size_t Counts::total() const {
15122         return passed + failed + failedButOk;
15123     }
15124     bool Counts::allPassed() const {
15125         return failed == 0 && failedButOk == 0;
15126     }
15127     bool Counts::allOk() const {
15128         return failed == 0;
15129     }
15130
15131     Totals Totals::operator - ( Totals const& other ) const {
15132         Totals diff;
15133         diff.assertions = assertions - other.assertions;
15134         diff.testCases = testCases - other.testCases;
15135         return diff;
15136     }
15137
15138     Totals& Totals::operator += ( Totals const& other ) {
15139         assertions += other.assertions;
15140         testCases += other.testCases;
15141         return *this;
15142     }
15143
15144     Totals Totals::delta( Totals const& prevTotals ) const {
15145         Totals diff = *this - prevTotals;
15146         if( diff.assertions.failed > 0 )
15147             ++diff.testCases.failed;
15148         else if( diff.assertions.failedButOk > 0 )
15149             ++diff.testCases.failedButOk;
15150         else
15151             ++diff.testCases.passed;
15152         return diff;
15153     }
15154
15155 }
15156 // end catch_totals.cpp
15157 // start catch_uncaught_exceptions.cpp
15158
15159 #include <exception>
15160
15161 namespace Catch {
15162     bool uncaught_exceptions() {
15163 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
15164         return false;
15165 #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15166         return std::uncaught_exceptions() > 0;
15167 #else
15168         return std::uncaught_exception();
15169 #endif
15170   }
15171 } // end namespace Catch
15172 // end catch_uncaught_exceptions.cpp
15173 // start catch_version.cpp
15174
15175 #include <ostream>
15176
15177 namespace Catch {
15178
15179     Version::Version
15180         (   unsigned int _majorVersion,
15181             unsigned int _minorVersion,
15182             unsigned int _patchNumber,
15183             char const * const _branchName,
15184             unsigned int _buildNumber )
15185     :   majorVersion( _majorVersion ),
15186         minorVersion( _minorVersion ),
15187         patchNumber( _patchNumber ),
15188         branchName( _branchName ),
15189         buildNumber( _buildNumber )
15190     {}
15191
15192     std::ostream& operator << ( std::ostream& os, Version const& version ) {
15193         os  << version.majorVersion << '.'
15194             << version.minorVersion << '.'
15195             << version.patchNumber;
15196         // branchName is never null -> 0th char is \0 if it is empty
15197         if (version.branchName[0]) {
15198             os << '-' << version.branchName
15199                << '.' << version.buildNumber;
15200         }
15201         return os;
15202     }
15203
15204     Version const& libraryVersion() {
15205         static Version version( 2, 12, 3, "", 0 );
15206         return version;
15207     }
15208
15209 }
15210 // end catch_version.cpp
15211 // start catch_wildcard_pattern.cpp
15212
15213 namespace Catch {
15214
15215     WildcardPattern::WildcardPattern( std::string const& pattern,
15216                                       CaseSensitive::Choice caseSensitivity )
15217     :   m_caseSensitivity( caseSensitivity ),
15218         m_pattern( normaliseString( pattern ) )
15219     {
15220         if( startsWith( m_pattern, '*' ) ) {
15221             m_pattern = m_pattern.substr( 1 );
15222             m_wildcard = WildcardAtStart;
15223         }
15224         if( endsWith( m_pattern, '*' ) ) {
15225             m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
15226             m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
15227         }
15228     }
15229
15230     bool WildcardPattern::matches( std::string const& str ) const {
15231         switch( m_wildcard ) {
15232             case NoWildcard:
15233                 return m_pattern == normaliseString( str );
15234             case WildcardAtStart:
15235                 return endsWith( normaliseString( str ), m_pattern );
15236             case WildcardAtEnd:
15237                 return startsWith( normaliseString( str ), m_pattern );
15238             case WildcardAtBothEnds:
15239                 return contains( normaliseString( str ), m_pattern );
15240             default:
15241                 CATCH_INTERNAL_ERROR( "Unknown enum" );
15242         }
15243     }
15244
15245     std::string WildcardPattern::normaliseString( std::string const& str ) const {
15246         return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
15247     }
15248 }
15249 // end catch_wildcard_pattern.cpp
15250 // start catch_xmlwriter.cpp
15251
15252 #include <iomanip>
15253 #include <type_traits>
15254
15255 namespace Catch {
15256
15257 namespace {
15258
15259     size_t trailingBytes(unsigned char c) {
15260         if ((c & 0xE0) == 0xC0) {
15261             return 2;
15262         }
15263         if ((c & 0xF0) == 0xE0) {
15264             return 3;
15265         }
15266         if ((c & 0xF8) == 0xF0) {
15267             return 4;
15268         }
15269         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15270     }
15271
15272     uint32_t headerValue(unsigned char c) {
15273         if ((c & 0xE0) == 0xC0) {
15274             return c & 0x1F;
15275         }
15276         if ((c & 0xF0) == 0xE0) {
15277             return c & 0x0F;
15278         }
15279         if ((c & 0xF8) == 0xF0) {
15280             return c & 0x07;
15281         }
15282         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15283     }
15284
15285     void hexEscapeChar(std::ostream& os, unsigned char c) {
15286         std::ios_base::fmtflags f(os.flags());
15287         os << "\\x"
15288             << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
15289             << static_cast<int>(c);
15290         os.flags(f);
15291     }
15292
15293     bool shouldNewline(XmlFormatting fmt) {
15294         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
15295     }
15296
15297     bool shouldIndent(XmlFormatting fmt) {
15298         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
15299     }
15300
15301 } // anonymous namespace
15302
15303     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
15304         return static_cast<XmlFormatting>(
15305             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
15306             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
15307         );
15308     }
15309
15310     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
15311         return static_cast<XmlFormatting>(
15312             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
15313             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
15314         );
15315     }
15316
15317     XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
15318     :   m_str( str ),
15319         m_forWhat( forWhat )
15320     {}
15321
15322     void XmlEncode::encodeTo( std::ostream& os ) const {
15323         // Apostrophe escaping not necessary if we always use " to write attributes
15324         // (see: http://www.w3.org/TR/xml/#syntax)
15325
15326         for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
15327             unsigned char c = m_str[idx];
15328             switch (c) {
15329             case '<':   os << "&lt;"; break;
15330             case '&':   os << "&amp;"; break;
15331
15332             case '>':
15333                 // See: http://www.w3.org/TR/xml/#syntax
15334                 if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
15335                     os << "&gt;";
15336                 else
15337                     os << c;
15338                 break;
15339
15340             case '\"':
15341                 if (m_forWhat == ForAttributes)
15342                     os << "&quot;";
15343                 else
15344                     os << c;
15345                 break;
15346
15347             default:
15348                 // Check for control characters and invalid utf-8
15349
15350                 // Escape control characters in standard ascii
15351                 // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
15352                 if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
15353                     hexEscapeChar(os, c);
15354                     break;
15355                 }
15356
15357                 // Plain ASCII: Write it to stream
15358                 if (c < 0x7F) {
15359                     os << c;
15360                     break;
15361                 }
15362
15363                 // UTF-8 territory
15364                 // Check if the encoding is valid and if it is not, hex escape bytes.
15365                 // Important: We do not check the exact decoded values for validity, only the encoding format
15366                 // First check that this bytes is a valid lead byte:
15367                 // This means that it is not encoded as 1111 1XXX
15368                 // Or as 10XX XXXX
15369                 if (c <  0xC0 ||
15370                     c >= 0xF8) {
15371                     hexEscapeChar(os, c);
15372                     break;
15373                 }
15374
15375                 auto encBytes = trailingBytes(c);
15376                 // Are there enough bytes left to avoid accessing out-of-bounds memory?
15377                 if (idx + encBytes - 1 >= m_str.size()) {
15378                     hexEscapeChar(os, c);
15379                     break;
15380                 }
15381                 // The header is valid, check data
15382                 // The next encBytes bytes must together be a valid utf-8
15383                 // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
15384                 bool valid = true;
15385                 uint32_t value = headerValue(c);
15386                 for (std::size_t n = 1; n < encBytes; ++n) {
15387                     unsigned char nc = m_str[idx + n];
15388                     valid &= ((nc & 0xC0) == 0x80);
15389                     value = (value << 6) | (nc & 0x3F);
15390                 }
15391
15392                 if (
15393                     // Wrong bit pattern of following bytes
15394                     (!valid) ||
15395                     // Overlong encodings
15396                     (value < 0x80) ||
15397                     (0x80 <= value && value < 0x800   && encBytes > 2) ||
15398                     (0x800 < value && value < 0x10000 && encBytes > 3) ||
15399                     // Encoded value out of range
15400                     (value >= 0x110000)
15401                     ) {
15402                     hexEscapeChar(os, c);
15403                     break;
15404                 }
15405
15406                 // If we got here, this is in fact a valid(ish) utf-8 sequence
15407                 for (std::size_t n = 0; n < encBytes; ++n) {
15408                     os << m_str[idx + n];
15409                 }
15410                 idx += encBytes - 1;
15411                 break;
15412             }
15413         }
15414     }
15415
15416     std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
15417         xmlEncode.encodeTo( os );
15418         return os;
15419     }
15420
15421     XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
15422     :   m_writer( writer ),
15423         m_fmt(fmt)
15424     {}
15425
15426     XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
15427     :   m_writer( other.m_writer ),
15428         m_fmt(other.m_fmt)
15429     {
15430         other.m_writer = nullptr;
15431         other.m_fmt = XmlFormatting::None;
15432     }
15433     XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
15434         if ( m_writer ) {
15435             m_writer->endElement();
15436         }
15437         m_writer = other.m_writer;
15438         other.m_writer = nullptr;
15439         m_fmt = other.m_fmt;
15440         other.m_fmt = XmlFormatting::None;
15441         return *this;
15442     }
15443
15444     XmlWriter::ScopedElement::~ScopedElement() {
15445         if (m_writer) {
15446             m_writer->endElement(m_fmt);
15447         }
15448     }
15449
15450     XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
15451         m_writer->writeText( text, fmt );
15452         return *this;
15453     }
15454
15455     XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
15456     {
15457         writeDeclaration();
15458     }
15459
15460     XmlWriter::~XmlWriter() {
15461         while (!m_tags.empty()) {
15462             endElement();
15463         }
15464         newlineIfNecessary();
15465     }
15466
15467     XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
15468         ensureTagClosed();
15469         newlineIfNecessary();
15470         if (shouldIndent(fmt)) {
15471             m_os << m_indent;
15472             m_indent += "  ";
15473         }
15474         m_os << '<' << name;
15475         m_tags.push_back( name );
15476         m_tagIsOpen = true;
15477         applyFormatting(fmt);
15478         return *this;
15479     }
15480
15481     XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
15482         ScopedElement scoped( this, fmt );
15483         startElement( name, fmt );
15484         return scoped;
15485     }
15486
15487     XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
15488         m_indent = m_indent.substr(0, m_indent.size() - 2);
15489
15490         if( m_tagIsOpen ) {
15491             m_os << "/>";
15492             m_tagIsOpen = false;
15493         } else {
15494             newlineIfNecessary();
15495             if (shouldIndent(fmt)) {
15496                 m_os << m_indent;
15497             }
15498             m_os << "</" << m_tags.back() << ">";
15499         }
15500         m_os << std::flush;
15501         applyFormatting(fmt);
15502         m_tags.pop_back();
15503         return *this;
15504     }
15505
15506     XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
15507         if( !name.empty() && !attribute.empty() )
15508             m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
15509         return *this;
15510     }
15511
15512     XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
15513         m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
15514         return *this;
15515     }
15516
15517     XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
15518         if( !text.empty() ){
15519             bool tagWasOpen = m_tagIsOpen;
15520             ensureTagClosed();
15521             if (tagWasOpen && shouldIndent(fmt)) {
15522                 m_os << m_indent;
15523             }
15524             m_os << XmlEncode( text );
15525             applyFormatting(fmt);
15526         }
15527         return *this;
15528     }
15529
15530     XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
15531         ensureTagClosed();
15532         if (shouldIndent(fmt)) {
15533             m_os << m_indent;
15534         }
15535         m_os << "<!--" << text << "-->";
15536         applyFormatting(fmt);
15537         return *this;
15538     }
15539
15540     void XmlWriter::writeStylesheetRef( std::string const& url ) {
15541         m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
15542     }
15543
15544     XmlWriter& XmlWriter::writeBlankLine() {
15545         ensureTagClosed();
15546         m_os << '\n';
15547         return *this;
15548     }
15549
15550     void XmlWriter::ensureTagClosed() {
15551         if( m_tagIsOpen ) {
15552             m_os << '>' << std::flush;
15553             newlineIfNecessary();
15554             m_tagIsOpen = false;
15555         }
15556     }
15557
15558     void XmlWriter::applyFormatting(XmlFormatting fmt) {
15559         m_needsNewline = shouldNewline(fmt);
15560     }
15561
15562     void XmlWriter::writeDeclaration() {
15563         m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
15564     }
15565
15566     void XmlWriter::newlineIfNecessary() {
15567         if( m_needsNewline ) {
15568             m_os << std::endl;
15569             m_needsNewline = false;
15570         }
15571     }
15572 }
15573 // end catch_xmlwriter.cpp
15574 // start catch_reporter_bases.cpp
15575
15576 #include <cstring>
15577 #include <cfloat>
15578 #include <cstdio>
15579 #include <cassert>
15580 #include <memory>
15581
15582 namespace Catch {
15583     void prepareExpandedExpression(AssertionResult& result) {
15584         result.getExpandedExpression();
15585     }
15586
15587     // Because formatting using c++ streams is stateful, drop down to C is required
15588     // Alternatively we could use stringstream, but its performance is... not good.
15589     std::string getFormattedDuration( double duration ) {
15590         // Max exponent + 1 is required to represent the whole part
15591         // + 1 for decimal point
15592         // + 3 for the 3 decimal places
15593         // + 1 for null terminator
15594         const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
15595         char buffer[maxDoubleSize];
15596
15597         // Save previous errno, to prevent sprintf from overwriting it
15598         ErrnoGuard guard;
15599 #ifdef _MSC_VER
15600         sprintf_s(buffer, "%.3f", duration);
15601 #else
15602         std::sprintf(buffer, "%.3f", duration);
15603 #endif
15604         return std::string(buffer);
15605     }
15606
15607     std::string serializeFilters( std::vector<std::string> const& container ) {
15608         ReusableStringStream oss;
15609         bool first = true;
15610         for (auto&& filter : container)
15611         {
15612             if (!first)
15613                 oss << ' ';
15614             else
15615                 first = false;
15616
15617             oss << filter;
15618         }
15619         return oss.str();
15620     }
15621
15622     TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
15623         :StreamingReporterBase(_config) {}
15624
15625     std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
15626         return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
15627     }
15628
15629     void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
15630
15631     bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
15632         return false;
15633     }
15634
15635 } // end namespace Catch
15636 // end catch_reporter_bases.cpp
15637 // start catch_reporter_compact.cpp
15638
15639 namespace {
15640
15641 #ifdef CATCH_PLATFORM_MAC
15642     const char* failedString() { return "FAILED"; }
15643     const char* passedString() { return "PASSED"; }
15644 #else
15645     const char* failedString() { return "failed"; }
15646     const char* passedString() { return "passed"; }
15647 #endif
15648
15649     // Colour::LightGrey
15650     Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
15651
15652     std::string bothOrAll( std::size_t count ) {
15653         return count == 1 ? std::string() :
15654                count == 2 ? "both " : "all " ;
15655     }
15656
15657 } // anon namespace
15658
15659 namespace Catch {
15660 namespace {
15661 // Colour, message variants:
15662 // - white: No tests ran.
15663 // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
15664 // - white: Passed [both/all] N test cases (no assertions).
15665 // -   red: Failed N tests cases, failed M assertions.
15666 // - green: Passed [both/all] N tests cases with M assertions.
15667 void printTotals(std::ostream& out, const Totals& totals) {
15668     if (totals.testCases.total() == 0) {
15669         out << "No tests ran.";
15670     } else if (totals.testCases.failed == totals.testCases.total()) {
15671         Colour colour(Colour::ResultError);
15672         const std::string qualify_assertions_failed =
15673             totals.assertions.failed == totals.assertions.total() ?
15674             bothOrAll(totals.assertions.failed) : std::string();
15675         out <<
15676             "Failed " << bothOrAll(totals.testCases.failed)
15677             << pluralise(totals.testCases.failed, "test case") << ", "
15678             "failed " << qualify_assertions_failed <<
15679             pluralise(totals.assertions.failed, "assertion") << '.';
15680     } else if (totals.assertions.total() == 0) {
15681         out <<
15682             "Passed " << bothOrAll(totals.testCases.total())
15683             << pluralise(totals.testCases.total(), "test case")
15684             << " (no assertions).";
15685     } else if (totals.assertions.failed) {
15686         Colour colour(Colour::ResultError);
15687         out <<
15688             "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
15689             "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
15690     } else {
15691         Colour colour(Colour::ResultSuccess);
15692         out <<
15693             "Passed " << bothOrAll(totals.testCases.passed)
15694             << pluralise(totals.testCases.passed, "test case") <<
15695             " with " << pluralise(totals.assertions.passed, "assertion") << '.';
15696     }
15697 }
15698
15699 // Implementation of CompactReporter formatting
15700 class AssertionPrinter {
15701 public:
15702     AssertionPrinter& operator= (AssertionPrinter const&) = delete;
15703     AssertionPrinter(AssertionPrinter const&) = delete;
15704     AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15705         : stream(_stream)
15706         , result(_stats.assertionResult)
15707         , messages(_stats.infoMessages)
15708         , itMessage(_stats.infoMessages.begin())
15709         , printInfoMessages(_printInfoMessages) {}
15710
15711     void print() {
15712         printSourceInfo();
15713
15714         itMessage = messages.begin();
15715
15716         switch (result.getResultType()) {
15717         case ResultWas::Ok:
15718             printResultType(Colour::ResultSuccess, passedString());
15719             printOriginalExpression();
15720             printReconstructedExpression();
15721             if (!result.hasExpression())
15722                 printRemainingMessages(Colour::None);
15723             else
15724                 printRemainingMessages();
15725             break;
15726         case ResultWas::ExpressionFailed:
15727             if (result.isOk())
15728                 printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
15729             else
15730                 printResultType(Colour::Error, failedString());
15731             printOriginalExpression();
15732             printReconstructedExpression();
15733             printRemainingMessages();
15734             break;
15735         case ResultWas::ThrewException:
15736             printResultType(Colour::Error, failedString());
15737             printIssue("unexpected exception with message:");
15738             printMessage();
15739             printExpressionWas();
15740             printRemainingMessages();
15741             break;
15742         case ResultWas::FatalErrorCondition:
15743             printResultType(Colour::Error, failedString());
15744             printIssue("fatal error condition with message:");
15745             printMessage();
15746             printExpressionWas();
15747             printRemainingMessages();
15748             break;
15749         case ResultWas::DidntThrowException:
15750             printResultType(Colour::Error, failedString());
15751             printIssue("expected exception, got none");
15752             printExpressionWas();
15753             printRemainingMessages();
15754             break;
15755         case ResultWas::Info:
15756             printResultType(Colour::None, "info");
15757             printMessage();
15758             printRemainingMessages();
15759             break;
15760         case ResultWas::Warning:
15761             printResultType(Colour::None, "warning");
15762             printMessage();
15763             printRemainingMessages();
15764             break;
15765         case ResultWas::ExplicitFailure:
15766             printResultType(Colour::Error, failedString());
15767             printIssue("explicitly");
15768             printRemainingMessages(Colour::None);
15769             break;
15770             // These cases are here to prevent compiler warnings
15771         case ResultWas::Unknown:
15772         case ResultWas::FailureBit:
15773         case ResultWas::Exception:
15774             printResultType(Colour::Error, "** internal error **");
15775             break;
15776         }
15777     }
15778
15779 private:
15780     void printSourceInfo() const {
15781         Colour colourGuard(Colour::FileName);
15782         stream << result.getSourceInfo() << ':';
15783     }
15784
15785     void printResultType(Colour::Code colour, std::string const& passOrFail) const {
15786         if (!passOrFail.empty()) {
15787             {
15788                 Colour colourGuard(colour);
15789                 stream << ' ' << passOrFail;
15790             }
15791             stream << ':';
15792         }
15793     }
15794
15795     void printIssue(std::string const& issue) const {
15796         stream << ' ' << issue;
15797     }
15798
15799     void printExpressionWas() {
15800         if (result.hasExpression()) {
15801             stream << ';';
15802             {
15803                 Colour colour(dimColour());
15804                 stream << " expression was:";
15805             }
15806             printOriginalExpression();
15807         }
15808     }
15809
15810     void printOriginalExpression() const {
15811         if (result.hasExpression()) {
15812             stream << ' ' << result.getExpression();
15813         }
15814     }
15815
15816     void printReconstructedExpression() const {
15817         if (result.hasExpandedExpression()) {
15818             {
15819                 Colour colour(dimColour());
15820                 stream << " for: ";
15821             }
15822             stream << result.getExpandedExpression();
15823         }
15824     }
15825
15826     void printMessage() {
15827         if (itMessage != messages.end()) {
15828             stream << " '" << itMessage->message << '\'';
15829             ++itMessage;
15830         }
15831     }
15832
15833     void printRemainingMessages(Colour::Code colour = dimColour()) {
15834         if (itMessage == messages.end())
15835             return;
15836
15837         const auto itEnd = messages.cend();
15838         const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
15839
15840         {
15841             Colour colourGuard(colour);
15842             stream << " with " << pluralise(N, "message") << ':';
15843         }
15844
15845         while (itMessage != itEnd) {
15846             // If this assertion is a warning ignore any INFO messages
15847             if (printInfoMessages || itMessage->type != ResultWas::Info) {
15848                 printMessage();
15849                 if (itMessage != itEnd) {
15850                     Colour colourGuard(dimColour());
15851                     stream << " and";
15852                 }
15853                 continue;
15854             }
15855             ++itMessage;
15856         }
15857     }
15858
15859 private:
15860     std::ostream& stream;
15861     AssertionResult const& result;
15862     std::vector<MessageInfo> messages;
15863     std::vector<MessageInfo>::const_iterator itMessage;
15864     bool printInfoMessages;
15865 };
15866
15867 } // anon namespace
15868
15869         std::string CompactReporter::getDescription() {
15870             return "Reports test results on a single line, suitable for IDEs";
15871         }
15872
15873         ReporterPreferences CompactReporter::getPreferences() const {
15874             return m_reporterPrefs;
15875         }
15876
15877         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
15878             stream << "No test cases matched '" << spec << '\'' << std::endl;
15879         }
15880
15881         void CompactReporter::assertionStarting( AssertionInfo const& ) {}
15882
15883         bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
15884             AssertionResult const& result = _assertionStats.assertionResult;
15885
15886             bool printInfoMessages = true;
15887
15888             // Drop out if result was successful and we're not printing those
15889             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
15890                 if( result.getResultType() != ResultWas::Warning )
15891                     return false;
15892                 printInfoMessages = false;
15893             }
15894
15895             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
15896             printer.print();
15897
15898             stream << std::endl;
15899             return true;
15900         }
15901
15902         void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
15903             if (m_config->showDurations() == ShowDurations::Always) {
15904                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
15905             }
15906         }
15907
15908         void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
15909             printTotals( stream, _testRunStats.totals );
15910             stream << '\n' << std::endl;
15911             StreamingReporterBase::testRunEnded( _testRunStats );
15912         }
15913
15914         CompactReporter::~CompactReporter() {}
15915
15916     CATCH_REGISTER_REPORTER( "compact", CompactReporter )
15917
15918 } // end namespace Catch
15919 // end catch_reporter_compact.cpp
15920 // start catch_reporter_console.cpp
15921
15922 #include <cfloat>
15923 #include <cstdio>
15924
15925 #if defined(_MSC_VER)
15926 #pragma warning(push)
15927 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
15928  // Note that 4062 (not all labels are handled and default is missing) is enabled
15929 #endif
15930
15931 #if defined(__clang__)
15932 #  pragma clang diagnostic push
15933 // For simplicity, benchmarking-only helpers are always enabled
15934 #  pragma clang diagnostic ignored "-Wunused-function"
15935 #endif
15936
15937 namespace Catch {
15938
15939 namespace {
15940
15941 // Formatter impl for ConsoleReporter
15942 class ConsoleAssertionPrinter {
15943 public:
15944     ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
15945     ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
15946     ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15947         : stream(_stream),
15948         stats(_stats),
15949         result(_stats.assertionResult),
15950         colour(Colour::None),
15951         message(result.getMessage()),
15952         messages(_stats.infoMessages),
15953         printInfoMessages(_printInfoMessages) {
15954         switch (result.getResultType()) {
15955         case ResultWas::Ok:
15956             colour = Colour::Success;
15957             passOrFail = "PASSED";
15958             //if( result.hasMessage() )
15959             if (_stats.infoMessages.size() == 1)
15960                 messageLabel = "with message";
15961             if (_stats.infoMessages.size() > 1)
15962                 messageLabel = "with messages";
15963             break;
15964         case ResultWas::ExpressionFailed:
15965             if (result.isOk()) {
15966                 colour = Colour::Success;
15967                 passOrFail = "FAILED - but was ok";
15968             } else {
15969                 colour = Colour::Error;
15970                 passOrFail = "FAILED";
15971             }
15972             if (_stats.infoMessages.size() == 1)
15973                 messageLabel = "with message";
15974             if (_stats.infoMessages.size() > 1)
15975                 messageLabel = "with messages";
15976             break;
15977         case ResultWas::ThrewException:
15978             colour = Colour::Error;
15979             passOrFail = "FAILED";
15980             messageLabel = "due to unexpected exception with ";
15981             if (_stats.infoMessages.size() == 1)
15982                 messageLabel += "message";
15983             if (_stats.infoMessages.size() > 1)
15984                 messageLabel += "messages";
15985             break;
15986         case ResultWas::FatalErrorCondition:
15987             colour = Colour::Error;
15988             passOrFail = "FAILED";
15989             messageLabel = "due to a fatal error condition";
15990             break;
15991         case ResultWas::DidntThrowException:
15992             colour = Colour::Error;
15993             passOrFail = "FAILED";
15994             messageLabel = "because no exception was thrown where one was expected";
15995             break;
15996         case ResultWas::Info:
15997             messageLabel = "info";
15998             break;
15999         case ResultWas::Warning:
16000             messageLabel = "warning";
16001             break;
16002         case ResultWas::ExplicitFailure:
16003             passOrFail = "FAILED";
16004             colour = Colour::Error;
16005             if (_stats.infoMessages.size() == 1)
16006                 messageLabel = "explicitly with message";
16007             if (_stats.infoMessages.size() > 1)
16008                 messageLabel = "explicitly with messages";
16009             break;
16010             // These cases are here to prevent compiler warnings
16011         case ResultWas::Unknown:
16012         case ResultWas::FailureBit:
16013         case ResultWas::Exception:
16014             passOrFail = "** internal error **";
16015             colour = Colour::Error;
16016             break;
16017         }
16018     }
16019
16020     void print() const {
16021         printSourceInfo();
16022         if (stats.totals.assertions.total() > 0) {
16023             printResultType();
16024             printOriginalExpression();
16025             printReconstructedExpression();
16026         } else {
16027             stream << '\n';
16028         }
16029         printMessage();
16030     }
16031
16032 private:
16033     void printResultType() const {
16034         if (!passOrFail.empty()) {
16035             Colour colourGuard(colour);
16036             stream << passOrFail << ":\n";
16037         }
16038     }
16039     void printOriginalExpression() const {
16040         if (result.hasExpression()) {
16041             Colour colourGuard(Colour::OriginalExpression);
16042             stream << "  ";
16043             stream << result.getExpressionInMacro();
16044             stream << '\n';
16045         }
16046     }
16047     void printReconstructedExpression() const {
16048         if (result.hasExpandedExpression()) {
16049             stream << "with expansion:\n";
16050             Colour colourGuard(Colour::ReconstructedExpression);
16051             stream << Column(result.getExpandedExpression()).indent(2) << '\n';
16052         }
16053     }
16054     void printMessage() const {
16055         if (!messageLabel.empty())
16056             stream << messageLabel << ':' << '\n';
16057         for (auto const& msg : messages) {
16058             // If this assertion is a warning ignore any INFO messages
16059             if (printInfoMessages || msg.type != ResultWas::Info)
16060                 stream << Column(msg.message).indent(2) << '\n';
16061         }
16062     }
16063     void printSourceInfo() const {
16064         Colour colourGuard(Colour::FileName);
16065         stream << result.getSourceInfo() << ": ";
16066     }
16067
16068     std::ostream& stream;
16069     AssertionStats const& stats;
16070     AssertionResult const& result;
16071     Colour::Code colour;
16072     std::string passOrFail;
16073     std::string messageLabel;
16074     std::string message;
16075     std::vector<MessageInfo> messages;
16076     bool printInfoMessages;
16077 };
16078
16079 std::size_t makeRatio(std::size_t number, std::size_t total) {
16080     std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
16081     return (ratio == 0 && number > 0) ? 1 : ratio;
16082 }
16083
16084 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
16085     if (i > j && i > k)
16086         return i;
16087     else if (j > k)
16088         return j;
16089     else
16090         return k;
16091 }
16092
16093 struct ColumnInfo {
16094     enum Justification { Left, Right };
16095     std::string name;
16096     int width;
16097     Justification justification;
16098 };
16099 struct ColumnBreak {};
16100 struct RowBreak {};
16101
16102 class Duration {
16103     enum class Unit {
16104         Auto,
16105         Nanoseconds,
16106         Microseconds,
16107         Milliseconds,
16108         Seconds,
16109         Minutes
16110     };
16111     static const uint64_t s_nanosecondsInAMicrosecond = 1000;
16112     static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
16113     static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
16114     static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
16115
16116     double m_inNanoseconds;
16117     Unit m_units;
16118
16119 public:
16120     explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
16121         : m_inNanoseconds(inNanoseconds),
16122         m_units(units) {
16123         if (m_units == Unit::Auto) {
16124             if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
16125                 m_units = Unit::Nanoseconds;
16126             else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
16127                 m_units = Unit::Microseconds;
16128             else if (m_inNanoseconds < s_nanosecondsInASecond)
16129                 m_units = Unit::Milliseconds;
16130             else if (m_inNanoseconds < s_nanosecondsInAMinute)
16131                 m_units = Unit::Seconds;
16132             else
16133                 m_units = Unit::Minutes;
16134         }
16135
16136     }
16137
16138     auto value() const -> double {
16139         switch (m_units) {
16140         case Unit::Microseconds:
16141             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
16142         case Unit::Milliseconds:
16143             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
16144         case Unit::Seconds:
16145             return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
16146         case Unit::Minutes:
16147             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
16148         default:
16149             return m_inNanoseconds;
16150         }
16151     }
16152     auto unitsAsString() const -> std::string {
16153         switch (m_units) {
16154         case Unit::Nanoseconds:
16155             return "ns";
16156         case Unit::Microseconds:
16157             return "us";
16158         case Unit::Milliseconds:
16159             return "ms";
16160         case Unit::Seconds:
16161             return "s";
16162         case Unit::Minutes:
16163             return "m";
16164         default:
16165             return "** internal error **";
16166         }
16167
16168     }
16169     friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
16170         return os << duration.value() << ' ' << duration.unitsAsString();
16171     }
16172 };
16173 } // end anon namespace
16174
16175 class TablePrinter {
16176     std::ostream& m_os;
16177     std::vector<ColumnInfo> m_columnInfos;
16178     std::ostringstream m_oss;
16179     int m_currentColumn = -1;
16180     bool m_isOpen = false;
16181
16182 public:
16183     TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
16184     :   m_os( os ),
16185         m_columnInfos( std::move( columnInfos ) ) {}
16186
16187     auto columnInfos() const -> std::vector<ColumnInfo> const& {
16188         return m_columnInfos;
16189     }
16190
16191     void open() {
16192         if (!m_isOpen) {
16193             m_isOpen = true;
16194             *this << RowBreak();
16195
16196                         Columns headerCols;
16197                         Spacer spacer(2);
16198                         for (auto const& info : m_columnInfos) {
16199                                 headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
16200                                 headerCols += spacer;
16201                         }
16202                         m_os << headerCols << '\n';
16203
16204             m_os << Catch::getLineOfChars<'-'>() << '\n';
16205         }
16206     }
16207     void close() {
16208         if (m_isOpen) {
16209             *this << RowBreak();
16210             m_os << std::endl;
16211             m_isOpen = false;
16212         }
16213     }
16214
16215     template<typename T>
16216     friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
16217         tp.m_oss << value;
16218         return tp;
16219     }
16220
16221     friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
16222         auto colStr = tp.m_oss.str();
16223         const auto strSize = colStr.size();
16224         tp.m_oss.str("");
16225         tp.open();
16226         if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
16227             tp.m_currentColumn = -1;
16228             tp.m_os << '\n';
16229         }
16230         tp.m_currentColumn++;
16231
16232         auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
16233         auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
16234             ? std::string(colInfo.width - (strSize + 1), ' ')
16235             : std::string();
16236         if (colInfo.justification == ColumnInfo::Left)
16237             tp.m_os << colStr << padding << ' ';
16238         else
16239             tp.m_os << padding << colStr << ' ';
16240         return tp;
16241     }
16242
16243     friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
16244         if (tp.m_currentColumn > 0) {
16245             tp.m_os << '\n';
16246             tp.m_currentColumn = -1;
16247         }
16248         return tp;
16249     }
16250 };
16251
16252 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
16253     : StreamingReporterBase(config),
16254     m_tablePrinter(new TablePrinter(config.stream(),
16255         [&config]() -> std::vector<ColumnInfo> {
16256         if (config.fullConfig()->benchmarkNoAnalysis())
16257         {
16258             return{
16259                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16260                 { "     samples", 14, ColumnInfo::Right },
16261                 { "  iterations", 14, ColumnInfo::Right },
16262                 { "        mean", 14, ColumnInfo::Right }
16263             };
16264         }
16265         else
16266         {
16267             return{
16268                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16269                 { "samples      mean       std dev", 14, ColumnInfo::Right },
16270                 { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
16271                 { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
16272             };
16273         }
16274     }())) {}
16275 ConsoleReporter::~ConsoleReporter() = default;
16276
16277 std::string ConsoleReporter::getDescription() {
16278     return "Reports test results as plain lines of text";
16279 }
16280
16281 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
16282     stream << "No test cases matched '" << spec << '\'' << std::endl;
16283 }
16284
16285 void ConsoleReporter::reportInvalidArguments(std::string const&arg){
16286     stream << "Invalid Filter: " << arg << std::endl;
16287 }
16288
16289 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
16290
16291 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
16292     AssertionResult const& result = _assertionStats.assertionResult;
16293
16294     bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16295
16296     // Drop out if result was successful but we're not printing them.
16297     if (!includeResults && result.getResultType() != ResultWas::Warning)
16298         return false;
16299
16300     lazyPrint();
16301
16302     ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
16303     printer.print();
16304     stream << std::endl;
16305     return true;
16306 }
16307
16308 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
16309     m_tablePrinter->close();
16310     m_headerPrinted = false;
16311     StreamingReporterBase::sectionStarting(_sectionInfo);
16312 }
16313 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
16314     m_tablePrinter->close();
16315     if (_sectionStats.missingAssertions) {
16316         lazyPrint();
16317         Colour colour(Colour::ResultError);
16318         if (m_sectionStack.size() > 1)
16319             stream << "\nNo assertions in section";
16320         else
16321             stream << "\nNo assertions in test case";
16322         stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
16323     }
16324     if (m_config->showDurations() == ShowDurations::Always) {
16325         stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16326     }
16327     if (m_headerPrinted) {
16328         m_headerPrinted = false;
16329     }
16330     StreamingReporterBase::sectionEnded(_sectionStats);
16331 }
16332
16333 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16334 void ConsoleReporter::benchmarkPreparing(std::string const& name) {
16335         lazyPrintWithoutClosingBenchmarkTable();
16336
16337         auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
16338
16339         bool firstLine = true;
16340         for (auto line : nameCol) {
16341                 if (!firstLine)
16342                         (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
16343                 else
16344                         firstLine = false;
16345
16346                 (*m_tablePrinter) << line << ColumnBreak();
16347         }
16348 }
16349
16350 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
16351     (*m_tablePrinter) << info.samples << ColumnBreak()
16352         << info.iterations << ColumnBreak();
16353     if (!m_config->benchmarkNoAnalysis())
16354         (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
16355 }
16356 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
16357     if (m_config->benchmarkNoAnalysis())
16358     {
16359         (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
16360     }
16361     else
16362     {
16363         (*m_tablePrinter) << ColumnBreak()
16364             << Duration(stats.mean.point.count()) << ColumnBreak()
16365             << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
16366             << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
16367             << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
16368             << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
16369             << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
16370     }
16371 }
16372
16373 void ConsoleReporter::benchmarkFailed(std::string const& error) {
16374         Colour colour(Colour::Red);
16375     (*m_tablePrinter)
16376         << "Benchmark failed (" << error << ')'
16377         << ColumnBreak() << RowBreak();
16378 }
16379 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16380
16381 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
16382     m_tablePrinter->close();
16383     StreamingReporterBase::testCaseEnded(_testCaseStats);
16384     m_headerPrinted = false;
16385 }
16386 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
16387     if (currentGroupInfo.used) {
16388         printSummaryDivider();
16389         stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
16390         printTotals(_testGroupStats.totals);
16391         stream << '\n' << std::endl;
16392     }
16393     StreamingReporterBase::testGroupEnded(_testGroupStats);
16394 }
16395 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
16396     printTotalsDivider(_testRunStats.totals);
16397     printTotals(_testRunStats.totals);
16398     stream << std::endl;
16399     StreamingReporterBase::testRunEnded(_testRunStats);
16400 }
16401 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
16402     StreamingReporterBase::testRunStarting(_testInfo);
16403     printTestFilters();
16404 }
16405
16406 void ConsoleReporter::lazyPrint() {
16407
16408     m_tablePrinter->close();
16409     lazyPrintWithoutClosingBenchmarkTable();
16410 }
16411
16412 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
16413
16414     if (!currentTestRunInfo.used)
16415         lazyPrintRunInfo();
16416     if (!currentGroupInfo.used)
16417         lazyPrintGroupInfo();
16418
16419     if (!m_headerPrinted) {
16420         printTestCaseAndSectionHeader();
16421         m_headerPrinted = true;
16422     }
16423 }
16424 void ConsoleReporter::lazyPrintRunInfo() {
16425     stream << '\n' << getLineOfChars<'~'>() << '\n';
16426     Colour colour(Colour::SecondaryText);
16427     stream << currentTestRunInfo->name
16428         << " is a Catch v" << libraryVersion() << " host application.\n"
16429         << "Run with -? for options\n\n";
16430
16431     if (m_config->rngSeed() != 0)
16432         stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
16433
16434     currentTestRunInfo.used = true;
16435 }
16436 void ConsoleReporter::lazyPrintGroupInfo() {
16437     if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
16438         printClosedHeader("Group: " + currentGroupInfo->name);
16439         currentGroupInfo.used = true;
16440     }
16441 }
16442 void ConsoleReporter::printTestCaseAndSectionHeader() {
16443     assert(!m_sectionStack.empty());
16444     printOpenHeader(currentTestCaseInfo->name);
16445
16446     if (m_sectionStack.size() > 1) {
16447         Colour colourGuard(Colour::Headers);
16448
16449         auto
16450             it = m_sectionStack.begin() + 1, // Skip first section (test case)
16451             itEnd = m_sectionStack.end();
16452         for (; it != itEnd; ++it)
16453             printHeaderString(it->name, 2);
16454     }
16455
16456     SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
16457
16458     stream << getLineOfChars<'-'>() << '\n';
16459     Colour colourGuard(Colour::FileName);
16460     stream << lineInfo << '\n';
16461     stream << getLineOfChars<'.'>() << '\n' << std::endl;
16462 }
16463
16464 void ConsoleReporter::printClosedHeader(std::string const& _name) {
16465     printOpenHeader(_name);
16466     stream << getLineOfChars<'.'>() << '\n';
16467 }
16468 void ConsoleReporter::printOpenHeader(std::string const& _name) {
16469     stream << getLineOfChars<'-'>() << '\n';
16470     {
16471         Colour colourGuard(Colour::Headers);
16472         printHeaderString(_name);
16473     }
16474 }
16475
16476 // if string has a : in first line will set indent to follow it on
16477 // subsequent lines
16478 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
16479     std::size_t i = _string.find(": ");
16480     if (i != std::string::npos)
16481         i += 2;
16482     else
16483         i = 0;
16484     stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
16485 }
16486
16487 struct SummaryColumn {
16488
16489     SummaryColumn( std::string _label, Colour::Code _colour )
16490     :   label( std::move( _label ) ),
16491         colour( _colour ) {}
16492     SummaryColumn addRow( std::size_t count ) {
16493         ReusableStringStream rss;
16494         rss << count;
16495         std::string row = rss.str();
16496         for (auto& oldRow : rows) {
16497             while (oldRow.size() < row.size())
16498                 oldRow = ' ' + oldRow;
16499             while (oldRow.size() > row.size())
16500                 row = ' ' + row;
16501         }
16502         rows.push_back(row);
16503         return *this;
16504     }
16505
16506     std::string label;
16507     Colour::Code colour;
16508     std::vector<std::string> rows;
16509
16510 };
16511
16512 void ConsoleReporter::printTotals( Totals const& totals ) {
16513     if (totals.testCases.total() == 0) {
16514         stream << Colour(Colour::Warning) << "No tests ran\n";
16515     } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
16516         stream << Colour(Colour::ResultSuccess) << "All tests passed";
16517         stream << " ("
16518             << pluralise(totals.assertions.passed, "assertion") << " in "
16519             << pluralise(totals.testCases.passed, "test case") << ')'
16520             << '\n';
16521     } else {
16522
16523         std::vector<SummaryColumn> columns;
16524         columns.push_back(SummaryColumn("", Colour::None)
16525                           .addRow(totals.testCases.total())
16526                           .addRow(totals.assertions.total()));
16527         columns.push_back(SummaryColumn("passed", Colour::Success)
16528                           .addRow(totals.testCases.passed)
16529                           .addRow(totals.assertions.passed));
16530         columns.push_back(SummaryColumn("failed", Colour::ResultError)
16531                           .addRow(totals.testCases.failed)
16532                           .addRow(totals.assertions.failed));
16533         columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
16534                           .addRow(totals.testCases.failedButOk)
16535                           .addRow(totals.assertions.failedButOk));
16536
16537         printSummaryRow("test cases", columns, 0);
16538         printSummaryRow("assertions", columns, 1);
16539     }
16540 }
16541 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
16542     for (auto col : cols) {
16543         std::string value = col.rows[row];
16544         if (col.label.empty()) {
16545             stream << label << ": ";
16546             if (value != "0")
16547                 stream << value;
16548             else
16549                 stream << Colour(Colour::Warning) << "- none -";
16550         } else if (value != "0") {
16551             stream << Colour(Colour::LightGrey) << " | ";
16552             stream << Colour(col.colour)
16553                 << value << ' ' << col.label;
16554         }
16555     }
16556     stream << '\n';
16557 }
16558
16559 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
16560     if (totals.testCases.total() > 0) {
16561         std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
16562         std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
16563         std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
16564         while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
16565             findMax(failedRatio, failedButOkRatio, passedRatio)++;
16566         while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
16567             findMax(failedRatio, failedButOkRatio, passedRatio)--;
16568
16569         stream << Colour(Colour::Error) << std::string(failedRatio, '=');
16570         stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
16571         if (totals.testCases.allPassed())
16572             stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
16573         else
16574             stream << Colour(Colour::Success) << std::string(passedRatio, '=');
16575     } else {
16576         stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
16577     }
16578     stream << '\n';
16579 }
16580 void ConsoleReporter::printSummaryDivider() {
16581     stream << getLineOfChars<'-'>() << '\n';
16582 }
16583
16584 void ConsoleReporter::printTestFilters() {
16585     if (m_config->testSpec().hasFilters()) {
16586         Colour guard(Colour::BrightYellow);
16587         stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
16588     }
16589 }
16590
16591 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
16592
16593 } // end namespace Catch
16594
16595 #if defined(_MSC_VER)
16596 #pragma warning(pop)
16597 #endif
16598
16599 #if defined(__clang__)
16600 #  pragma clang diagnostic pop
16601 #endif
16602 // end catch_reporter_console.cpp
16603 // start catch_reporter_junit.cpp
16604
16605 #include <cassert>
16606 #include <sstream>
16607 #include <ctime>
16608 #include <algorithm>
16609
16610 namespace Catch {
16611
16612     namespace {
16613         std::string getCurrentTimestamp() {
16614             // Beware, this is not reentrant because of backward compatibility issues
16615             // Also, UTC only, again because of backward compatibility (%z is C++11)
16616             time_t rawtime;
16617             std::time(&rawtime);
16618             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
16619
16620 #ifdef _MSC_VER
16621             std::tm timeInfo = {};
16622             gmtime_s(&timeInfo, &rawtime);
16623 #else
16624             std::tm* timeInfo;
16625             timeInfo = std::gmtime(&rawtime);
16626 #endif
16627
16628             char timeStamp[timeStampSize];
16629             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
16630
16631 #ifdef _MSC_VER
16632             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
16633 #else
16634             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
16635 #endif
16636             return std::string(timeStamp);
16637         }
16638
16639         std::string fileNameTag(const std::vector<std::string> &tags) {
16640             auto it = std::find_if(begin(tags),
16641                                    end(tags),
16642                                    [] (std::string const& tag) {return tag.front() == '#'; });
16643             if (it != tags.end())
16644                 return it->substr(1);
16645             return std::string();
16646         }
16647     } // anonymous namespace
16648
16649     JunitReporter::JunitReporter( ReporterConfig const& _config )
16650         :   CumulativeReporterBase( _config ),
16651             xml( _config.stream() )
16652         {
16653             m_reporterPrefs.shouldRedirectStdOut = true;
16654             m_reporterPrefs.shouldReportAllAssertions = true;
16655         }
16656
16657     JunitReporter::~JunitReporter() {}
16658
16659     std::string JunitReporter::getDescription() {
16660         return "Reports test results in an XML format that looks like Ant's junitreport target";
16661     }
16662
16663     void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
16664
16665     void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
16666         CumulativeReporterBase::testRunStarting( runInfo );
16667         xml.startElement( "testsuites" );
16668     }
16669
16670     void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16671         suiteTimer.start();
16672         stdOutForSuite.clear();
16673         stdErrForSuite.clear();
16674         unexpectedExceptions = 0;
16675         CumulativeReporterBase::testGroupStarting( groupInfo );
16676     }
16677
16678     void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
16679         m_okToFail = testCaseInfo.okToFail();
16680     }
16681
16682     bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
16683         if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
16684             unexpectedExceptions++;
16685         return CumulativeReporterBase::assertionEnded( assertionStats );
16686     }
16687
16688     void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
16689         stdOutForSuite += testCaseStats.stdOut;
16690         stdErrForSuite += testCaseStats.stdErr;
16691         CumulativeReporterBase::testCaseEnded( testCaseStats );
16692     }
16693
16694     void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
16695         double suiteTime = suiteTimer.getElapsedSeconds();
16696         CumulativeReporterBase::testGroupEnded( testGroupStats );
16697         writeGroup( *m_testGroups.back(), suiteTime );
16698     }
16699
16700     void JunitReporter::testRunEndedCumulative() {
16701         xml.endElement();
16702     }
16703
16704     void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
16705         XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
16706
16707         TestGroupStats const& stats = groupNode.value;
16708         xml.writeAttribute( "name", stats.groupInfo.name );
16709         xml.writeAttribute( "errors", unexpectedExceptions );
16710         xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
16711         xml.writeAttribute( "tests", stats.totals.assertions.total() );
16712         xml.writeAttribute( "hostname", "tbd" ); // !TBD
16713         if( m_config->showDurations() == ShowDurations::Never )
16714             xml.writeAttribute( "time", "" );
16715         else
16716             xml.writeAttribute( "time", suiteTime );
16717         xml.writeAttribute( "timestamp", getCurrentTimestamp() );
16718
16719         // Write properties if there are any
16720         if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
16721             auto properties = xml.scopedElement("properties");
16722             if (m_config->hasTestFilters()) {
16723                 xml.scopedElement("property")
16724                     .writeAttribute("name", "filters")
16725                     .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
16726             }
16727             if (m_config->rngSeed() != 0) {
16728                 xml.scopedElement("property")
16729                     .writeAttribute("name", "random-seed")
16730                     .writeAttribute("value", m_config->rngSeed());
16731             }
16732         }
16733
16734         // Write test cases
16735         for( auto const& child : groupNode.children )
16736             writeTestCase( *child );
16737
16738         xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
16739         xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
16740     }
16741
16742     void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
16743         TestCaseStats const& stats = testCaseNode.value;
16744
16745         // All test cases have exactly one section - which represents the
16746         // test case itself. That section may have 0-n nested sections
16747         assert( testCaseNode.children.size() == 1 );
16748         SectionNode const& rootSection = *testCaseNode.children.front();
16749
16750         std::string className = stats.testInfo.className;
16751
16752         if( className.empty() ) {
16753             className = fileNameTag(stats.testInfo.tags);
16754             if ( className.empty() )
16755                 className = "global";
16756         }
16757
16758         if ( !m_config->name().empty() )
16759             className = m_config->name() + "." + className;
16760
16761         writeSection( className, "", rootSection );
16762     }
16763
16764     void JunitReporter::writeSection(  std::string const& className,
16765                         std::string const& rootName,
16766                         SectionNode const& sectionNode ) {
16767         std::string name = trim( sectionNode.stats.sectionInfo.name );
16768         if( !rootName.empty() )
16769             name = rootName + '/' + name;
16770
16771         if( !sectionNode.assertions.empty() ||
16772             !sectionNode.stdOut.empty() ||
16773             !sectionNode.stdErr.empty() ) {
16774             XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
16775             if( className.empty() ) {
16776                 xml.writeAttribute( "classname", name );
16777                 xml.writeAttribute( "name", "root" );
16778             }
16779             else {
16780                 xml.writeAttribute( "classname", className );
16781                 xml.writeAttribute( "name", name );
16782             }
16783             xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
16784             // This is not ideal, but it should be enough to mimic gtest's
16785             // junit output.
16786             // Ideally the JUnit reporter would also handle `skipTest`
16787             // events and write those out appropriately.
16788             xml.writeAttribute( "status", "run" );
16789
16790             writeAssertions( sectionNode );
16791
16792             if( !sectionNode.stdOut.empty() )
16793                 xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
16794             if( !sectionNode.stdErr.empty() )
16795                 xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
16796         }
16797         for( auto const& childNode : sectionNode.childSections )
16798             if( className.empty() )
16799                 writeSection( name, "", *childNode );
16800             else
16801                 writeSection( className, name, *childNode );
16802     }
16803
16804     void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
16805         for( auto const& assertion : sectionNode.assertions )
16806             writeAssertion( assertion );
16807     }
16808
16809     void JunitReporter::writeAssertion( AssertionStats const& stats ) {
16810         AssertionResult const& result = stats.assertionResult;
16811         if( !result.isOk() ) {
16812             std::string elementName;
16813             switch( result.getResultType() ) {
16814                 case ResultWas::ThrewException:
16815                 case ResultWas::FatalErrorCondition:
16816                     elementName = "error";
16817                     break;
16818                 case ResultWas::ExplicitFailure:
16819                 case ResultWas::ExpressionFailed:
16820                 case ResultWas::DidntThrowException:
16821                     elementName = "failure";
16822                     break;
16823
16824                 // We should never see these here:
16825                 case ResultWas::Info:
16826                 case ResultWas::Warning:
16827                 case ResultWas::Ok:
16828                 case ResultWas::Unknown:
16829                 case ResultWas::FailureBit:
16830                 case ResultWas::Exception:
16831                     elementName = "internalError";
16832                     break;
16833             }
16834
16835             XmlWriter::ScopedElement e = xml.scopedElement( elementName );
16836
16837             xml.writeAttribute( "message", result.getExpression() );
16838             xml.writeAttribute( "type", result.getTestMacroName() );
16839
16840             ReusableStringStream rss;
16841             if (stats.totals.assertions.total() > 0) {
16842                 rss << "FAILED" << ":\n";
16843                 if (result.hasExpression()) {
16844                     rss << "  ";
16845                     rss << result.getExpressionInMacro();
16846                     rss << '\n';
16847                 }
16848                 if (result.hasExpandedExpression()) {
16849                     rss << "with expansion:\n";
16850                     rss << Column(result.getExpandedExpression()).indent(2) << '\n';
16851                 }
16852             } else {
16853                 rss << '\n';
16854             }
16855
16856             if( !result.getMessage().empty() )
16857                 rss << result.getMessage() << '\n';
16858             for( auto const& msg : stats.infoMessages )
16859                 if( msg.type == ResultWas::Info )
16860                     rss << msg.message << '\n';
16861
16862             rss << "at " << result.getSourceInfo();
16863             xml.writeText( rss.str(), XmlFormatting::Newline );
16864         }
16865     }
16866
16867     CATCH_REGISTER_REPORTER( "junit", JunitReporter )
16868
16869 } // end namespace Catch
16870 // end catch_reporter_junit.cpp
16871 // start catch_reporter_listening.cpp
16872
16873 #include <cassert>
16874
16875 namespace Catch {
16876
16877     ListeningReporter::ListeningReporter() {
16878         // We will assume that listeners will always want all assertions
16879         m_preferences.shouldReportAllAssertions = true;
16880     }
16881
16882     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
16883         m_listeners.push_back( std::move( listener ) );
16884     }
16885
16886     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
16887         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
16888         m_reporter = std::move( reporter );
16889         m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
16890     }
16891
16892     ReporterPreferences ListeningReporter::getPreferences() const {
16893         return m_preferences;
16894     }
16895
16896     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
16897         return std::set<Verbosity>{ };
16898     }
16899
16900     void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
16901         for ( auto const& listener : m_listeners ) {
16902             listener->noMatchingTestCases( spec );
16903         }
16904         m_reporter->noMatchingTestCases( spec );
16905     }
16906
16907     void ListeningReporter::reportInvalidArguments(std::string const&arg){
16908         for ( auto const& listener : m_listeners ) {
16909             listener->reportInvalidArguments( arg );
16910         }
16911         m_reporter->reportInvalidArguments( arg );
16912     }
16913
16914 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16915     void ListeningReporter::benchmarkPreparing( std::string const& name ) {
16916                 for (auto const& listener : m_listeners) {
16917                         listener->benchmarkPreparing(name);
16918                 }
16919                 m_reporter->benchmarkPreparing(name);
16920         }
16921     void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
16922         for ( auto const& listener : m_listeners ) {
16923             listener->benchmarkStarting( benchmarkInfo );
16924         }
16925         m_reporter->benchmarkStarting( benchmarkInfo );
16926     }
16927     void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
16928         for ( auto const& listener : m_listeners ) {
16929             listener->benchmarkEnded( benchmarkStats );
16930         }
16931         m_reporter->benchmarkEnded( benchmarkStats );
16932     }
16933
16934         void ListeningReporter::benchmarkFailed( std::string const& error ) {
16935                 for (auto const& listener : m_listeners) {
16936                         listener->benchmarkFailed(error);
16937                 }
16938                 m_reporter->benchmarkFailed(error);
16939         }
16940 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16941
16942     void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
16943         for ( auto const& listener : m_listeners ) {
16944             listener->testRunStarting( testRunInfo );
16945         }
16946         m_reporter->testRunStarting( testRunInfo );
16947     }
16948
16949     void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16950         for ( auto const& listener : m_listeners ) {
16951             listener->testGroupStarting( groupInfo );
16952         }
16953         m_reporter->testGroupStarting( groupInfo );
16954     }
16955
16956     void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
16957         for ( auto const& listener : m_listeners ) {
16958             listener->testCaseStarting( testInfo );
16959         }
16960         m_reporter->testCaseStarting( testInfo );
16961     }
16962
16963     void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
16964         for ( auto const& listener : m_listeners ) {
16965             listener->sectionStarting( sectionInfo );
16966         }
16967         m_reporter->sectionStarting( sectionInfo );
16968     }
16969
16970     void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
16971         for ( auto const& listener : m_listeners ) {
16972             listener->assertionStarting( assertionInfo );
16973         }
16974         m_reporter->assertionStarting( assertionInfo );
16975     }
16976
16977     // The return value indicates if the messages buffer should be cleared:
16978     bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
16979         for( auto const& listener : m_listeners ) {
16980             static_cast<void>( listener->assertionEnded( assertionStats ) );
16981         }
16982         return m_reporter->assertionEnded( assertionStats );
16983     }
16984
16985     void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
16986         for ( auto const& listener : m_listeners ) {
16987             listener->sectionEnded( sectionStats );
16988         }
16989         m_reporter->sectionEnded( sectionStats );
16990     }
16991
16992     void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
16993         for ( auto const& listener : m_listeners ) {
16994             listener->testCaseEnded( testCaseStats );
16995         }
16996         m_reporter->testCaseEnded( testCaseStats );
16997     }
16998
16999     void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17000         for ( auto const& listener : m_listeners ) {
17001             listener->testGroupEnded( testGroupStats );
17002         }
17003         m_reporter->testGroupEnded( testGroupStats );
17004     }
17005
17006     void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
17007         for ( auto const& listener : m_listeners ) {
17008             listener->testRunEnded( testRunStats );
17009         }
17010         m_reporter->testRunEnded( testRunStats );
17011     }
17012
17013     void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
17014         for ( auto const& listener : m_listeners ) {
17015             listener->skipTest( testInfo );
17016         }
17017         m_reporter->skipTest( testInfo );
17018     }
17019
17020     bool ListeningReporter::isMulti() const {
17021         return true;
17022     }
17023
17024 } // end namespace Catch
17025 // end catch_reporter_listening.cpp
17026 // start catch_reporter_xml.cpp
17027
17028 #if defined(_MSC_VER)
17029 #pragma warning(push)
17030 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
17031                               // Note that 4062 (not all labels are handled
17032                               // and default is missing) is enabled
17033 #endif
17034
17035 namespace Catch {
17036     XmlReporter::XmlReporter( ReporterConfig const& _config )
17037     :   StreamingReporterBase( _config ),
17038         m_xml(_config.stream())
17039     {
17040         m_reporterPrefs.shouldRedirectStdOut = true;
17041         m_reporterPrefs.shouldReportAllAssertions = true;
17042     }
17043
17044     XmlReporter::~XmlReporter() = default;
17045
17046     std::string XmlReporter::getDescription() {
17047         return "Reports test results as an XML document";
17048     }
17049
17050     std::string XmlReporter::getStylesheetRef() const {
17051         return std::string();
17052     }
17053
17054     void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
17055         m_xml
17056             .writeAttribute( "filename", sourceInfo.file )
17057             .writeAttribute( "line", sourceInfo.line );
17058     }
17059
17060     void XmlReporter::noMatchingTestCases( std::string const& s ) {
17061         StreamingReporterBase::noMatchingTestCases( s );
17062     }
17063
17064     void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
17065         StreamingReporterBase::testRunStarting( testInfo );
17066         std::string stylesheetRef = getStylesheetRef();
17067         if( !stylesheetRef.empty() )
17068             m_xml.writeStylesheetRef( stylesheetRef );
17069         m_xml.startElement( "Catch" );
17070         if( !m_config->name().empty() )
17071             m_xml.writeAttribute( "name", m_config->name() );
17072         if (m_config->testSpec().hasFilters())
17073             m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
17074         if( m_config->rngSeed() != 0 )
17075             m_xml.scopedElement( "Randomness" )
17076                 .writeAttribute( "seed", m_config->rngSeed() );
17077     }
17078
17079     void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
17080         StreamingReporterBase::testGroupStarting( groupInfo );
17081         m_xml.startElement( "Group" )
17082             .writeAttribute( "name", groupInfo.name );
17083     }
17084
17085     void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
17086         StreamingReporterBase::testCaseStarting(testInfo);
17087         m_xml.startElement( "TestCase" )
17088             .writeAttribute( "name", trim( testInfo.name ) )
17089             .writeAttribute( "description", testInfo.description )
17090             .writeAttribute( "tags", testInfo.tagsAsString() );
17091
17092         writeSourceInfo( testInfo.lineInfo );
17093
17094         if ( m_config->showDurations() == ShowDurations::Always )
17095             m_testCaseTimer.start();
17096         m_xml.ensureTagClosed();
17097     }
17098
17099     void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
17100         StreamingReporterBase::sectionStarting( sectionInfo );
17101         if( m_sectionDepth++ > 0 ) {
17102             m_xml.startElement( "Section" )
17103                 .writeAttribute( "name", trim( sectionInfo.name ) );
17104             writeSourceInfo( sectionInfo.lineInfo );
17105             m_xml.ensureTagClosed();
17106         }
17107     }
17108
17109     void XmlReporter::assertionStarting( AssertionInfo const& ) { }
17110
17111     bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
17112
17113         AssertionResult const& result = assertionStats.assertionResult;
17114
17115         bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
17116
17117         if( includeResults || result.getResultType() == ResultWas::Warning ) {
17118             // Print any info messages in <Info> tags.
17119             for( auto const& msg : assertionStats.infoMessages ) {
17120                 if( msg.type == ResultWas::Info && includeResults ) {
17121                     m_xml.scopedElement( "Info" )
17122                             .writeText( msg.message );
17123                 } else if ( msg.type == ResultWas::Warning ) {
17124                     m_xml.scopedElement( "Warning" )
17125                             .writeText( msg.message );
17126                 }
17127             }
17128         }
17129
17130         // Drop out if result was successful but we're not printing them.
17131         if( !includeResults && result.getResultType() != ResultWas::Warning )
17132             return true;
17133
17134         // Print the expression if there is one.
17135         if( result.hasExpression() ) {
17136             m_xml.startElement( "Expression" )
17137                 .writeAttribute( "success", result.succeeded() )
17138                 .writeAttribute( "type", result.getTestMacroName() );
17139
17140             writeSourceInfo( result.getSourceInfo() );
17141
17142             m_xml.scopedElement( "Original" )
17143                 .writeText( result.getExpression() );
17144             m_xml.scopedElement( "Expanded" )
17145                 .writeText( result.getExpandedExpression() );
17146         }
17147
17148         // And... Print a result applicable to each result type.
17149         switch( result.getResultType() ) {
17150             case ResultWas::ThrewException:
17151                 m_xml.startElement( "Exception" );
17152                 writeSourceInfo( result.getSourceInfo() );
17153                 m_xml.writeText( result.getMessage() );
17154                 m_xml.endElement();
17155                 break;
17156             case ResultWas::FatalErrorCondition:
17157                 m_xml.startElement( "FatalErrorCondition" );
17158                 writeSourceInfo( result.getSourceInfo() );
17159                 m_xml.writeText( result.getMessage() );
17160                 m_xml.endElement();
17161                 break;
17162             case ResultWas::Info:
17163                 m_xml.scopedElement( "Info" )
17164                     .writeText( result.getMessage() );
17165                 break;
17166             case ResultWas::Warning:
17167                 // Warning will already have been written
17168                 break;
17169             case ResultWas::ExplicitFailure:
17170                 m_xml.startElement( "Failure" );
17171                 writeSourceInfo( result.getSourceInfo() );
17172                 m_xml.writeText( result.getMessage() );
17173                 m_xml.endElement();
17174                 break;
17175             default:
17176                 break;
17177         }
17178
17179         if( result.hasExpression() )
17180             m_xml.endElement();
17181
17182         return true;
17183     }
17184
17185     void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
17186         StreamingReporterBase::sectionEnded( sectionStats );
17187         if( --m_sectionDepth > 0 ) {
17188             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
17189             e.writeAttribute( "successes", sectionStats.assertions.passed );
17190             e.writeAttribute( "failures", sectionStats.assertions.failed );
17191             e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
17192
17193             if ( m_config->showDurations() == ShowDurations::Always )
17194                 e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
17195
17196             m_xml.endElement();
17197         }
17198     }
17199
17200     void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
17201         StreamingReporterBase::testCaseEnded( testCaseStats );
17202         XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
17203         e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
17204
17205         if ( m_config->showDurations() == ShowDurations::Always )
17206             e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
17207
17208         if( !testCaseStats.stdOut.empty() )
17209             m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
17210         if( !testCaseStats.stdErr.empty() )
17211             m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
17212
17213         m_xml.endElement();
17214     }
17215
17216     void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17217         StreamingReporterBase::testGroupEnded( testGroupStats );
17218         // TODO: Check testGroupStats.aborting and act accordingly.
17219         m_xml.scopedElement( "OverallResults" )
17220             .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
17221             .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
17222             .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
17223         m_xml.scopedElement( "OverallResultsCases")
17224             .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
17225             .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
17226             .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
17227         m_xml.endElement();
17228     }
17229
17230     void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
17231         StreamingReporterBase::testRunEnded( testRunStats );
17232         m_xml.scopedElement( "OverallResults" )
17233             .writeAttribute( "successes", testRunStats.totals.assertions.passed )
17234             .writeAttribute( "failures", testRunStats.totals.assertions.failed )
17235             .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
17236         m_xml.scopedElement( "OverallResultsCases")
17237             .writeAttribute( "successes", testRunStats.totals.testCases.passed )
17238             .writeAttribute( "failures", testRunStats.totals.testCases.failed )
17239             .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
17240         m_xml.endElement();
17241     }
17242
17243 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17244     void XmlReporter::benchmarkPreparing(std::string const& name) {
17245         m_xml.startElement("BenchmarkResults")
17246             .writeAttribute("name", name);
17247     }
17248
17249     void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
17250         m_xml.writeAttribute("samples", info.samples)
17251             .writeAttribute("resamples", info.resamples)
17252             .writeAttribute("iterations", info.iterations)
17253             .writeAttribute("clockResolution", info.clockResolution)
17254             .writeAttribute("estimatedDuration", info.estimatedDuration)
17255             .writeComment("All values in nano seconds");
17256     }
17257
17258     void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
17259         m_xml.startElement("mean")
17260             .writeAttribute("value", benchmarkStats.mean.point.count())
17261             .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
17262             .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
17263             .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
17264         m_xml.endElement();
17265         m_xml.startElement("standardDeviation")
17266             .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
17267             .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
17268             .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
17269             .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
17270         m_xml.endElement();
17271         m_xml.startElement("outliers")
17272             .writeAttribute("variance", benchmarkStats.outlierVariance)
17273             .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
17274             .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
17275             .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
17276             .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
17277         m_xml.endElement();
17278         m_xml.endElement();
17279     }
17280
17281     void XmlReporter::benchmarkFailed(std::string const &error) {
17282         m_xml.scopedElement("failed").
17283             writeAttribute("message", error);
17284         m_xml.endElement();
17285     }
17286 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17287
17288     CATCH_REGISTER_REPORTER( "xml", XmlReporter )
17289
17290 } // end namespace Catch
17291
17292 #if defined(_MSC_VER)
17293 #pragma warning(pop)
17294 #endif
17295 // end catch_reporter_xml.cpp
17296
17297 namespace Catch {
17298     LeakDetector leakDetector;
17299 }
17300
17301 #ifdef __clang__
17302 #pragma clang diagnostic pop
17303 #endif
17304
17305 // end catch_impl.hpp
17306 #endif
17307
17308 #ifdef CATCH_CONFIG_MAIN
17309 // start catch_default_main.hpp
17310
17311 #ifndef __OBJC__
17312
17313 #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
17314 // Standard C/C++ Win32 Unicode wmain entry point
17315 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
17316 #else
17317 // Standard C/C++ main entry point
17318 int main (int argc, char * argv[]) {
17319 #endif
17320
17321     return Catch::Session().run( argc, argv );
17322 }
17323
17324 #else // __OBJC__
17325
17326 // Objective-C entry point
17327 int main (int argc, char * const argv[]) {
17328 #if !CATCH_ARC_ENABLED
17329     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
17330 #endif
17331
17332     Catch::registerTestMethods();
17333     int result = Catch::Session().run( argc, (char**)argv );
17334
17335 #if !CATCH_ARC_ENABLED
17336     [pool drain];
17337 #endif
17338
17339     return result;
17340 }
17341
17342 #endif // __OBJC__
17343
17344 // end catch_default_main.hpp
17345 #endif
17346
17347 #if !defined(CATCH_CONFIG_IMPL_ONLY)
17348
17349 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
17350 #  undef CLARA_CONFIG_MAIN
17351 #endif
17352
17353 #if !defined(CATCH_CONFIG_DISABLE)
17354 //////
17355 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17356 #ifdef CATCH_CONFIG_PREFIX_ALL
17357
17358 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17359 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17360
17361 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17362 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17363 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17364 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17365 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17366 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17367 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17368
17369 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17370 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17371 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17372 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17373 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17374
17375 #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17376 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17377 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17378 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17379 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17380 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17381 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17382
17383 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17384 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17385
17386 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17387 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17388
17389 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
17390 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
17391 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17392 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
17393
17394 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17395 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17396 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17397 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17398 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17399 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17400 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17401 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17402 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17403
17404 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17405
17406 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17407 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17408 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17409 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17410 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17411 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17412 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17413 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17414 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17415 #else
17416 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17417 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17418 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17419 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17420 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17421 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17422 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17423 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17424 #endif
17425
17426 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17427 #define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )
17428 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
17429 #else
17430 #define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )
17431 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
17432 #endif
17433
17434 // "BDD-style" convenience wrappers
17435 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
17436 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17437 #define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
17438 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17439 #define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
17440 #define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17441 #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
17442 #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
17443
17444 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17445 #define CATCH_BENCHMARK(...) \
17446     INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
17447 #define CATCH_BENCHMARK_ADVANCED(name) \
17448     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17449 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17450
17451 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17452 #else
17453
17454 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
17455 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17456
17457 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17458 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17459 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17460 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17461 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17462 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17463 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17464
17465 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17466 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17467 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17468 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17469 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17470
17471 #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17472 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17473 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17474 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17475 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17476 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17477 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17478
17479 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17480 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17481
17482 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17483 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17484
17485 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
17486 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
17487 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17488 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
17489
17490 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17491 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17492 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17493 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17494 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17495 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17496 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17497 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17498 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17499 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17500
17501 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17502 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17503 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17504 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17505 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17506 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17507 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17508 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17509 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17510 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
17511 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
17512 #else
17513 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17514 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17515 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17516 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17517 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17518 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17519 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17520 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17521 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
17522 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17523 #endif
17524
17525 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17526 #define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
17527 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
17528 #else
17529 #define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )
17530 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
17531 #endif
17532
17533 #endif
17534
17535 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
17536
17537 // "BDD-style" convenience wrappers
17538 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
17539 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17540
17541 #define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
17542 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17543 #define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
17544 #define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17545 #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
17546 #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
17547
17548 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17549 #define BENCHMARK(...) \
17550     INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
17551 #define BENCHMARK_ADVANCED(name) \
17552     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17553 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17554
17555 using Catch::Detail::Approx;
17556
17557 #else // CATCH_CONFIG_DISABLE
17558
17559 //////
17560 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17561 #ifdef CATCH_CONFIG_PREFIX_ALL
17562
17563 #define CATCH_REQUIRE( ... )        (void)(0)
17564 #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
17565
17566 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
17567 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17568 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
17569 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17570 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17571 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17572 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
17573
17574 #define CATCH_CHECK( ... )         (void)(0)
17575 #define CATCH_CHECK_FALSE( ... )   (void)(0)
17576 #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
17577 #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
17578 #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
17579
17580 #define CATCH_CHECK_THROWS( ... )  (void)(0)
17581 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17582 #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
17583 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17584 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17585 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17586 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
17587
17588 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17589 #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
17590
17591 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
17592 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17593
17594 #define CATCH_INFO( msg )          (void)(0)
17595 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
17596 #define CATCH_WARN( msg )          (void)(0)
17597 #define CATCH_CAPTURE( msg )       (void)(0)
17598
17599 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17600 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17601 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
17602 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
17603 #define CATCH_SECTION( ... )
17604 #define CATCH_DYNAMIC_SECTION( ... )
17605 #define CATCH_FAIL( ... ) (void)(0)
17606 #define CATCH_FAIL_CHECK( ... ) (void)(0)
17607 #define CATCH_SUCCEED( ... ) (void)(0)
17608
17609 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17610
17611 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17612 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17613 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17614 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17615 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17616 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17617 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17618 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17619 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17620 #else
17621 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17622 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17623 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17624 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17625 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17626 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17627 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17628 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17629 #endif
17630
17631 // "BDD-style" convenience wrappers
17632 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17633 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
17634 #define CATCH_GIVEN( desc )
17635 #define CATCH_AND_GIVEN( desc )
17636 #define CATCH_WHEN( desc )
17637 #define CATCH_AND_WHEN( desc )
17638 #define CATCH_THEN( desc )
17639 #define CATCH_AND_THEN( desc )
17640
17641 #define CATCH_STATIC_REQUIRE( ... )       (void)(0)
17642 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
17643
17644 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17645 #else
17646
17647 #define REQUIRE( ... )       (void)(0)
17648 #define REQUIRE_FALSE( ... ) (void)(0)
17649
17650 #define REQUIRE_THROWS( ... ) (void)(0)
17651 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17652 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
17653 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17654 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17655 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17656 #define REQUIRE_NOTHROW( ... ) (void)(0)
17657
17658 #define CHECK( ... ) (void)(0)
17659 #define CHECK_FALSE( ... ) (void)(0)
17660 #define CHECKED_IF( ... ) if (__VA_ARGS__)
17661 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
17662 #define CHECK_NOFAIL( ... ) (void)(0)
17663
17664 #define CHECK_THROWS( ... )  (void)(0)
17665 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17666 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
17667 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17668 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17669 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17670 #define CHECK_NOTHROW( ... ) (void)(0)
17671
17672 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17673 #define CHECK_THAT( arg, matcher ) (void)(0)
17674
17675 #define REQUIRE_THAT( arg, matcher ) (void)(0)
17676 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17677
17678 #define INFO( msg ) (void)(0)
17679 #define UNSCOPED_INFO( msg ) (void)(0)
17680 #define WARN( msg ) (void)(0)
17681 #define CAPTURE( msg ) (void)(0)
17682
17683 #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17684 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17685 #define METHOD_AS_TEST_CASE( method, ... )
17686 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
17687 #define SECTION( ... )
17688 #define DYNAMIC_SECTION( ... )
17689 #define FAIL( ... ) (void)(0)
17690 #define FAIL_CHECK( ... ) (void)(0)
17691 #define SUCCEED( ... ) (void)(0)
17692 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17693
17694 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17695 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17696 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17697 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17698 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17699 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17700 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17701 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17702 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17703 #else
17704 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17705 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17706 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17707 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17708 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17709 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17710 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17711 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17712 #endif
17713
17714 #define STATIC_REQUIRE( ... )       (void)(0)
17715 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
17716
17717 #endif
17718
17719 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
17720
17721 // "BDD-style" convenience wrappers
17722 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
17723 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
17724
17725 #define GIVEN( desc )
17726 #define AND_GIVEN( desc )
17727 #define WHEN( desc )
17728 #define AND_WHEN( desc )
17729 #define THEN( desc )
17730 #define AND_THEN( desc )
17731
17732 using Catch::Detail::Approx;
17733
17734 #endif
17735
17736 #endif // ! CATCH_CONFIG_IMPL_ONLY
17737
17738 // start catch_reenable_warnings.h
17739
17740
17741 #ifdef __clang__
17742 #    ifdef __ICC // icpc defines the __clang__ macro
17743 #        pragma warning(pop)
17744 #    else
17745 #        pragma clang diagnostic pop
17746 #    endif
17747 #elif defined __GNUC__
17748 #    pragma GCC diagnostic pop
17749 #endif
17750
17751 // end catch_reenable_warnings.h
17752 // end catch.hpp
17753 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED