Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of framagit.org:simgrid/simgrid
[simgrid.git] / src / include / catch.hpp
1 /*
2  *  Catch v2.11.1
3  *  Generated: 2019-12-28 21:22:11.930976
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2019 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 11
18 #define CATCH_VERSION_PATCH 1
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(CATCH_CPP17_OR_GREATER)
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 #endif
145
146 #if defined(__clang__)
147
148 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
149 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
150
151 #    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
152          _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
153          _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
154
155 #    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
156          _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
157
158 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
159          _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
160
161 #    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
162          _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
163
164 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
165          _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
166
167 #endif // __clang__
168
169 ////////////////////////////////////////////////////////////////////////////////
170 // Assume that non-Windows platforms support posix signals by default
171 #if !defined(CATCH_PLATFORM_WINDOWS)
172     #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
173 #endif
174
175 ////////////////////////////////////////////////////////////////////////////////
176 // We know some environments not to support full POSIX signals
177 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
178     #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
179 #endif
180
181 #ifdef __OS400__
182 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
183 #       define CATCH_CONFIG_COLOUR_NONE
184 #endif
185
186 ////////////////////////////////////////////////////////////////////////////////
187 // Android somehow still does not support std::to_string
188 #if defined(__ANDROID__)
189 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
190 #    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
191 #endif
192
193 ////////////////////////////////////////////////////////////////////////////////
194 // Not all Windows environments support SEH properly
195 #if defined(__MINGW32__)
196 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
197 #endif
198
199 ////////////////////////////////////////////////////////////////////////////////
200 // PS4
201 #if defined(__ORBIS__)
202 #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
203 #endif
204
205 ////////////////////////////////////////////////////////////////////////////////
206 // Cygwin
207 #ifdef __CYGWIN__
208
209 // Required for some versions of Cygwin to declare gettimeofday
210 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
211 #   define _BSD_SOURCE
212 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
213 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
214 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
215            && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
216
217 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
218
219 # endif
220 #endif // __CYGWIN__
221
222 ////////////////////////////////////////////////////////////////////////////////
223 // Visual C++
224 #if defined(_MSC_VER)
225
226 #  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
227 #  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
228
229 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
230 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
231 #  endif
232
233 // Universal Windows platform does not support SEH
234 // Or console colours (or console at all...)
235 #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
236 #    define CATCH_CONFIG_COLOUR_NONE
237 #  else
238 #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
239 #  endif
240
241 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
242 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
243 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
244 #  if !defined(__clang__) // Handle Clang masquerading for msvc
245 #    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
246 #      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
247 #    endif // MSVC_TRADITIONAL
248 #  endif // __clang__
249
250 #endif // _MSC_VER
251
252 #if defined(_REENTRANT) || defined(_MSC_VER)
253 // Enable async processing, as -pthread is specified or no additional linking is required
254 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
255 #endif // _MSC_VER
256
257 ////////////////////////////////////////////////////////////////////////////////
258 // Check if we are compiled with -fno-exceptions or equivalent
259 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
260 #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
261 #endif
262
263 ////////////////////////////////////////////////////////////////////////////////
264 // DJGPP
265 #ifdef __DJGPP__
266 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
267 #endif // __DJGPP__
268
269 ////////////////////////////////////////////////////////////////////////////////
270 // Embarcadero C++Build
271 #if defined(__BORLANDC__)
272     #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
273 #endif
274
275 ////////////////////////////////////////////////////////////////////////////////
276
277 // Use of __COUNTER__ is suppressed during code analysis in
278 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
279 // handled by it.
280 // Otherwise all supported compilers support COUNTER macro,
281 // but user still might want to turn it off
282 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
283     #define CATCH_INTERNAL_CONFIG_COUNTER
284 #endif
285
286 ////////////////////////////////////////////////////////////////////////////////
287
288 // RTX is a special version of Windows that is real time.
289 // This means that it is detected as Windows, but does not provide
290 // the same set of capabilities as real Windows does.
291 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
292     #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
293     #define CATCH_INTERNAL_CONFIG_NO_ASYNC
294     #define CATCH_CONFIG_COLOUR_NONE
295 #endif
296
297 #if defined(__UCLIBC__)
298 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
299 #endif
300
301 // Various stdlib support checks that require __has_include
302 #if defined(__has_include)
303   // Check if string_view is available and usable
304   #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
305   #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
306   #endif
307
308   // Check if optional is available and usable
309   #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
310   #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
311   #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
312
313   // Check if byte is available and usable
314   #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
315   #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
316   #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
317
318   // Check if variant is available and usable
319   #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
320   #    if defined(__clang__) && (__clang_major__ < 8)
321          // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
322          // fix should be in clang 8, workaround in libstdc++ 8.2
323   #      include <ciso646>
324   #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
325   #        define CATCH_CONFIG_NO_CPP17_VARIANT
326   #      else
327   #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
328   #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
329   #    else
330   #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
331   #    endif // defined(__clang__) && (__clang_major__ < 8)
332   #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
333 #endif // defined(__has_include)
334
335 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
336 #   define CATCH_CONFIG_COUNTER
337 #endif
338 #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)
339 #   define CATCH_CONFIG_WINDOWS_SEH
340 #endif
341 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
342 #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)
343 #   define CATCH_CONFIG_POSIX_SIGNALS
344 #endif
345 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
346 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
347 #   define CATCH_CONFIG_WCHAR
348 #endif
349
350 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
351 #    define CATCH_CONFIG_CPP11_TO_STRING
352 #endif
353
354 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
355 #  define CATCH_CONFIG_CPP17_OPTIONAL
356 #endif
357
358 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
359 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
360 #endif
361
362 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
363 #  define CATCH_CONFIG_CPP17_STRING_VIEW
364 #endif
365
366 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
367 #  define CATCH_CONFIG_CPP17_VARIANT
368 #endif
369
370 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
371 #  define CATCH_CONFIG_CPP17_BYTE
372 #endif
373
374 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
375 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
376 #endif
377
378 #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)
379 #  define CATCH_CONFIG_NEW_CAPTURE
380 #endif
381
382 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
383 #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
384 #endif
385
386 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
387 #  define CATCH_CONFIG_POLYFILL_ISNAN
388 #endif
389
390 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
391 #  define CATCH_CONFIG_USE_ASYNC
392 #endif
393
394 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
395 #  define CATCH_CONFIG_ANDROID_LOGWRITE
396 #endif
397
398 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
399 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
400 #endif
401
402 // Even if we do not think the compiler has that warning, we still have
403 // to provide a macro that can be used by the code.
404 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
405 #   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
406 #endif
407 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
408 #   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
409 #endif
410 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
411 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
412 #endif
413 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
414 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
415 #endif
416 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
417 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
418 #endif
419 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
420 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
421 #endif
422
423 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
424 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
425 #elif defined(__clang__) && (__clang_major__ < 5)
426 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
427 #endif
428
429 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
430 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
431 #endif
432
433 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
434 #define CATCH_TRY if ((true))
435 #define CATCH_CATCH_ALL if ((false))
436 #define CATCH_CATCH_ANON(type) if ((false))
437 #else
438 #define CATCH_TRY try
439 #define CATCH_CATCH_ALL catch (...)
440 #define CATCH_CATCH_ANON(type) catch (type)
441 #endif
442
443 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
444 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
445 #endif
446
447 // end catch_compiler_capabilities.h
448 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
449 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
450 #ifdef CATCH_CONFIG_COUNTER
451 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
452 #else
453 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
454 #endif
455
456 #include <iosfwd>
457 #include <string>
458 #include <cstdint>
459
460 // We need a dummy global operator<< so we can bring it into Catch namespace later
461 struct Catch_global_namespace_dummy {};
462 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
463
464 namespace Catch {
465
466     struct CaseSensitive { enum Choice {
467         Yes,
468         No
469     }; };
470
471     class NonCopyable {
472         NonCopyable( NonCopyable const& )              = delete;
473         NonCopyable( NonCopyable && )                  = delete;
474         NonCopyable& operator = ( NonCopyable const& ) = delete;
475         NonCopyable& operator = ( NonCopyable && )     = delete;
476
477     protected:
478         NonCopyable();
479         virtual ~NonCopyable();
480     };
481
482     struct SourceLineInfo {
483
484         SourceLineInfo() = delete;
485         SourceLineInfo( char const* _file, std::size_t _line ) noexcept
486         :   file( _file ),
487             line( _line )
488         {}
489
490         SourceLineInfo( SourceLineInfo const& other )            = default;
491         SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
492         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
493         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
494
495         bool empty() const noexcept { return file[0] == '\0'; }
496         bool operator == ( SourceLineInfo const& other ) const noexcept;
497         bool operator < ( SourceLineInfo const& other ) const noexcept;
498
499         char const* file;
500         std::size_t line;
501     };
502
503     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
504
505     // Bring in operator<< from global namespace into Catch namespace
506     // This is necessary because the overload of operator<< above makes
507     // lookup stop at namespace Catch
508     using ::operator<<;
509
510     // Use this in variadic streaming macros to allow
511     //    >> +StreamEndStop
512     // as well as
513     //    >> stuff +StreamEndStop
514     struct StreamEndStop {
515         std::string operator+() const;
516     };
517     template<typename T>
518     T const& operator + ( T const& value, StreamEndStop ) {
519         return value;
520     }
521 }
522
523 #define CATCH_INTERNAL_LINEINFO \
524     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
525
526 // end catch_common.h
527 namespace Catch {
528
529     struct RegistrarForTagAliases {
530         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
531     };
532
533 } // end namespace Catch
534
535 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
536     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
537     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
538     namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
539     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
540
541 // end catch_tag_alias_autoregistrar.h
542 // start catch_test_registry.h
543
544 // start catch_interfaces_testcase.h
545
546 #include <vector>
547
548 namespace Catch {
549
550     class TestSpec;
551
552     struct ITestInvoker {
553         virtual void invoke () const = 0;
554         virtual ~ITestInvoker();
555     };
556
557     class TestCase;
558     struct IConfig;
559
560     struct ITestCaseRegistry {
561         virtual ~ITestCaseRegistry();
562         virtual std::vector<TestCase> const& getAllTests() const = 0;
563         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
564     };
565
566     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
567     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
568     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
569     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
570
571 }
572
573 // end catch_interfaces_testcase.h
574 // start catch_stringref.h
575
576 #include <cstddef>
577 #include <string>
578 #include <iosfwd>
579 #include <cassert>
580
581 namespace Catch {
582
583     /// A non-owning string class (similar to the forthcoming std::string_view)
584     /// Note that, because a StringRef may be a substring of another string,
585     /// it may not be null terminated.
586     class StringRef {
587     public:
588         using size_type = std::size_t;
589         using const_iterator = const char*;
590
591     private:
592         static constexpr char const* const s_empty = "";
593
594         char const* m_start = s_empty;
595         size_type m_size = 0;
596
597     public: // construction
598         constexpr StringRef() noexcept = default;
599
600         StringRef( char const* rawChars ) noexcept;
601
602         constexpr StringRef( char const* rawChars, size_type size ) noexcept
603         :   m_start( rawChars ),
604             m_size( size )
605         {}
606
607         StringRef( std::string const& stdString ) noexcept
608         :   m_start( stdString.c_str() ),
609             m_size( stdString.size() )
610         {}
611
612         explicit operator std::string() const {
613             return std::string(m_start, m_size);
614         }
615
616     public: // operators
617         auto operator == ( StringRef const& other ) const noexcept -> bool;
618         auto operator != (StringRef const& other) const noexcept -> bool {
619             return !(*this == other);
620         }
621
622         auto operator[] ( size_type index ) const noexcept -> char {
623             assert(index < m_size);
624             return m_start[index];
625         }
626
627     public: // named queries
628         constexpr auto empty() const noexcept -> bool {
629             return m_size == 0;
630         }
631         constexpr auto size() const noexcept -> size_type {
632             return m_size;
633         }
634
635         // Returns the current start pointer. If the StringRef is not
636         // null-terminated, throws std::domain_exception
637         auto c_str() const -> char const*;
638
639     public: // substrings and searches
640         // Returns a substring of [start, start + length).
641         // If start + length > size(), then the substring is [start, size()).
642         // If start > size(), then the substring is empty.
643         auto substr( size_type start, size_type length ) const noexcept -> StringRef;
644
645         // Returns the current start pointer. May not be null-terminated.
646         auto data() const noexcept -> char const*;
647
648         constexpr auto isNullTerminated() const noexcept -> bool {
649             return m_start[m_size] == '\0';
650         }
651
652     public: // iterators
653         constexpr const_iterator begin() const { return m_start; }
654         constexpr const_iterator end() const { return m_start + m_size; }
655     };
656
657     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
658     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
659
660     constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
661         return StringRef( rawChars, size );
662     }
663 } // namespace Catch
664
665 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
666     return Catch::StringRef( rawChars, size );
667 }
668
669 // end catch_stringref.h
670 // start catch_preprocessor.hpp
671
672
673 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
674 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
675 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
676 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
677 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
678 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
679
680 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
681 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
682 // MSVC needs more evaluations
683 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
684 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
685 #else
686 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
687 #endif
688
689 #define CATCH_REC_END(...)
690 #define CATCH_REC_OUT
691
692 #define CATCH_EMPTY()
693 #define CATCH_DEFER(id) id CATCH_EMPTY()
694
695 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
696 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
697 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
698 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
699 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
700 #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
701
702 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
703 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
704 #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
705
706 #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__ )
707 #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__ )
708 #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__ )
709
710 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
711 // and passes userdata as the first parameter to each invocation,
712 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
713 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
714
715 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
716
717 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
718 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
719 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
720 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
721 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
722 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
723 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
724 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
725 #else
726 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
727 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
728 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
729 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
730 #endif
731
732 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
733 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
734
735 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
736
737 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
738 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
739 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
740 #else
741 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
742 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
743 #endif
744
745 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
746     CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
747
748 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
749 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
750 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
751 #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)
752 #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)
753 #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)
754 #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, _4, _5, _6)
755 #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)
756 #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)
757 #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)
758 #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)
759
760 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
761
762 #define INTERNAL_CATCH_TYPE_GEN\
763     template<typename...> struct TypeList {};\
764     template<typename...Ts>\
765     constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
766     template<template<typename...> class...> struct TemplateTypeList{};\
767     template<template<typename...> class...Cs>\
768     constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
769     template<typename...>\
770     struct append;\
771     template<typename...>\
772     struct rewrap;\
773     template<template<typename...> class, typename...>\
774     struct create;\
775     template<template<typename...> class, typename>\
776     struct convert;\
777     \
778     template<typename T> \
779     struct append<T> { using type = T; };\
780     template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
781     struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
782     template< template<typename...> class L1, typename...E1, typename...Rest>\
783     struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
784     \
785     template< template<typename...> class Container, template<typename...> class List, typename...elems>\
786     struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
787     template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
788     struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
789     \
790     template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
791     struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
792     template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
793     struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
794
795 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
796     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
797     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
798     constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
799     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
800     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
801     constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
802     \
803     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
804     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
805     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
806     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
807     template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
808     struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
809
810 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
811 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
812     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
813     static void TestName()
814 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
815     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
816     static void TestName()
817
818 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
819 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
820     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
821     static void TestName()
822 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
823     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
824     static void TestName()
825
826 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
827     template<typename Type>\
828     void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
829     {\
830         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
831     }
832
833 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
834     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
835     void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
836     {\
837         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
838     }
839
840 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
841     template<typename Type>\
842     void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
843     {\
844         Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
845     }
846
847 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
848     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
849     void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
850     {\
851         Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
852     }
853
854 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
855 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
856     template<typename TestType> \
857     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
858         void test();\
859     }
860
861 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
862     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
863     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
864         void test();\
865     }
866
867 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
868 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
869     template<typename TestType> \
870     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
871 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
872     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
873     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
874
875 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
876 #define INTERNAL_CATCH_NTTP_0
877 #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)
878 #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__)
879 #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__)
880 #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__)
881 #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__)
882 #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__)
883 #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__)
884 #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__)
885 #else
886 #define INTERNAL_CATCH_NTTP_0(signature)
887 #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__))
888 #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__))
889 #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__))
890 #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__))
891 #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__))
892 #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__))
893 #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__))
894 #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__))
895 #endif
896
897 // end catch_preprocessor.hpp
898 // start catch_meta.hpp
899
900
901 #include <type_traits>
902
903 namespace Catch {
904     template<typename T>
905     struct always_false : std::false_type {};
906
907     template <typename> struct true_given : std::true_type {};
908     struct is_callable_tester {
909         template <typename Fun, typename... Args>
910         true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
911         template <typename...>
912         std::false_type static test(...);
913     };
914
915     template <typename T>
916     struct is_callable;
917
918     template <typename Fun, typename... Args>
919     struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
920
921 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
922     // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
923     // replaced with std::invoke_result here. Also *_t format is preferred over
924     // typename *::type format.
925     template <typename Func, typename U>
926     using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
927 #else
928     template <typename Func, typename U>
929     using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
930 #endif
931
932 } // namespace Catch
933
934 namespace mpl_{
935     struct na;
936 }
937
938 // end catch_meta.hpp
939 namespace Catch {
940
941 template<typename C>
942 class TestInvokerAsMethod : public ITestInvoker {
943     void (C::*m_testAsMethod)();
944 public:
945     TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
946
947     void invoke() const override {
948         C obj;
949         (obj.*m_testAsMethod)();
950     }
951 };
952
953 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
954
955 template<typename C>
956 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
957     return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
958 }
959
960 struct NameAndTags {
961     NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
962     StringRef name;
963     StringRef tags;
964 };
965
966 struct AutoReg : NonCopyable {
967     AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
968     ~AutoReg();
969 };
970
971 } // end namespace Catch
972
973 #if defined(CATCH_CONFIG_DISABLE)
974     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
975         static void TestName()
976     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
977         namespace{                        \
978             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
979                 void test();              \
980             };                            \
981         }                                 \
982         void TestName::test()
983     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
984         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
985     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
986         namespace{                                                                                  \
987             namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
988             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
989         }                                                                                           \
990         }                                                                                           \
991         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
992
993     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
994         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
995             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__ )
996     #else
997         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
998             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__ ) )
999     #endif
1000
1001     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1002         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1003             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__ )
1004     #else
1005         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1006             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__ ) )
1007     #endif
1008
1009     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1010         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1011             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__ )
1012     #else
1013         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1014             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__ ) )
1015     #endif
1016
1017     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1018         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1019             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__ )
1020     #else
1021         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1022             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__ ) )
1023     #endif
1024 #endif
1025
1026     ///////////////////////////////////////////////////////////////////////////////
1027     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
1028         static void TestName(); \
1029         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1030         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1031         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1032         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1033         static void TestName()
1034     #define INTERNAL_CATCH_TESTCASE( ... ) \
1035         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
1036
1037     ///////////////////////////////////////////////////////////////////////////////
1038     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
1039         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1040         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1041         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1042         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1043
1044     ///////////////////////////////////////////////////////////////////////////////
1045     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
1046         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1047         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1048         namespace{ \
1049             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1050                 void test(); \
1051             }; \
1052             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1053         } \
1054         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1055         void TestName::test()
1056     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
1057         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
1058
1059     ///////////////////////////////////////////////////////////////////////////////
1060     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
1061         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1062         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1063         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1064         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1065
1066     ///////////////////////////////////////////////////////////////////////////////
1067     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
1068         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1069         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1070         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1071         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1072         INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1073         namespace {\
1074         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1075             INTERNAL_CATCH_TYPE_GEN\
1076             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1077             INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1078             template<typename...Types> \
1079             struct TestName{\
1080                 TestName(){\
1081                     int index = 0;                                    \
1082                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1083                     using expander = int[];\
1084                     (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
1085                 }\
1086             };\
1087             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1088             TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1089             return 0;\
1090         }();\
1091         }\
1092         }\
1093         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1094         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
1095
1096 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1097     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1098         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__ )
1099 #else
1100     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1101         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__ ) )
1102 #endif
1103
1104 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1105     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1106         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__ )
1107 #else
1108     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1109         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__ ) )
1110 #endif
1111
1112     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
1113         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
1114         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
1115         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
1116         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
1117         template<typename TestType> static void TestFuncName();       \
1118         namespace {\
1119         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
1120             INTERNAL_CATCH_TYPE_GEN                                                  \
1121             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
1122             template<typename... Types>                               \
1123             struct TestName {                                         \
1124                 void reg_tests() {                                          \
1125                     int index = 0;                                    \
1126                     using expander = int[];                           \
1127                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1128                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1129                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1130                     (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 */\
1131                 }                                                     \
1132             };                                                        \
1133             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1134                 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; \
1135                 TestInit t;                                           \
1136                 t.reg_tests();                                        \
1137                 return 0;                                             \
1138             }();                                                      \
1139         }                                                             \
1140         }                                                             \
1141         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
1142         template<typename TestType>                                   \
1143         static void TestFuncName()
1144
1145 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1146     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1147         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__)
1148 #else
1149     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1150         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__ ) )
1151 #endif
1152
1153 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1154     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1155         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__)
1156 #else
1157     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1158         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__ ) )
1159 #endif
1160
1161     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
1162         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1163         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1164         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1165         template<typename TestType> static void TestFunc();       \
1166         namespace {\
1167         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1168         INTERNAL_CATCH_TYPE_GEN\
1169         template<typename... Types>                               \
1170         struct TestName {                                         \
1171             void reg_tests() {                                          \
1172                 int index = 0;                                    \
1173                 using expander = int[];                           \
1174                 (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 */\
1175             }                                                     \
1176         };\
1177         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1178                 using TestInit = typename convert<TestName, TmplList>::type; \
1179                 TestInit t;                                           \
1180                 t.reg_tests();                                        \
1181                 return 0;                                             \
1182             }();                                                      \
1183         }}\
1184         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
1185         template<typename TestType>                                   \
1186         static void TestFunc()
1187
1188     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
1189         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 )
1190
1191     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1192         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1193         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1194         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1195         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1196         namespace {\
1197         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1198             INTERNAL_CATCH_TYPE_GEN\
1199             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1200             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1201             INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1202             template<typename...Types> \
1203             struct TestNameClass{\
1204                 TestNameClass(){\
1205                     int index = 0;                                    \
1206                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1207                     using expander = int[];\
1208                     (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
1209                 }\
1210             };\
1211             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1212                 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1213                 return 0;\
1214         }();\
1215         }\
1216         }\
1217         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1218         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1219
1220 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1221     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1222         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__ )
1223 #else
1224     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1225         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__ ) )
1226 #endif
1227
1228 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1229     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1230         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__ )
1231 #else
1232     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1233         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__ ) )
1234 #endif
1235
1236     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
1237         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1238         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1239         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1240         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1241         template<typename TestType> \
1242             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1243                 void test();\
1244             };\
1245         namespace {\
1246         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
1247             INTERNAL_CATCH_TYPE_GEN                  \
1248             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1249             template<typename...Types>\
1250             struct TestNameClass{\
1251                 void reg_tests(){\
1252                     int index = 0;\
1253                     using expander = int[];\
1254                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1255                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1256                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1257                     (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 */ \
1258                 }\
1259             };\
1260             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1261                 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;\
1262                 TestInit t;\
1263                 t.reg_tests();\
1264                 return 0;\
1265             }(); \
1266         }\
1267         }\
1268         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1269         template<typename TestType> \
1270         void TestName<TestType>::test()
1271
1272 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1273     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1274         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__ )
1275 #else
1276     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1277         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__ ) )
1278 #endif
1279
1280 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1281     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1282         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__ )
1283 #else
1284     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1285         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__ ) )
1286 #endif
1287
1288     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
1289         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1290         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1291         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1292         template<typename TestType> \
1293         struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1294             void test();\
1295         };\
1296         namespace {\
1297         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1298             INTERNAL_CATCH_TYPE_GEN\
1299             template<typename...Types>\
1300             struct TestNameClass{\
1301                 void reg_tests(){\
1302                     int index = 0;\
1303                     using expander = int[];\
1304                     (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 */ \
1305                 }\
1306             };\
1307             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1308                 using TestInit = typename convert<TestNameClass, TmplList>::type;\
1309                 TestInit t;\
1310                 t.reg_tests();\
1311                 return 0;\
1312             }(); \
1313         }}\
1314         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1315         template<typename TestType> \
1316         void TestName<TestType>::test()
1317
1318 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
1319         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 )
1320
1321 // end catch_test_registry.h
1322 // start catch_capture.hpp
1323
1324 // start catch_assertionhandler.h
1325
1326 // start catch_assertioninfo.h
1327
1328 // start catch_result_type.h
1329
1330 namespace Catch {
1331
1332     // ResultWas::OfType enum
1333     struct ResultWas { enum OfType {
1334         Unknown = -1,
1335         Ok = 0,
1336         Info = 1,
1337         Warning = 2,
1338
1339         FailureBit = 0x10,
1340
1341         ExpressionFailed = FailureBit | 1,
1342         ExplicitFailure = FailureBit | 2,
1343
1344         Exception = 0x100 | FailureBit,
1345
1346         ThrewException = Exception | 1,
1347         DidntThrowException = Exception | 2,
1348
1349         FatalErrorCondition = 0x200 | FailureBit
1350
1351     }; };
1352
1353     bool isOk( ResultWas::OfType resultType );
1354     bool isJustInfo( int flags );
1355
1356     // ResultDisposition::Flags enum
1357     struct ResultDisposition { enum Flags {
1358         Normal = 0x01,
1359
1360         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
1361         FalseTest = 0x04,           // Prefix expression with !
1362         SuppressFail = 0x08         // Failures are reported but do not fail the test
1363     }; };
1364
1365     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
1366
1367     bool shouldContinueOnFailure( int flags );
1368     inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
1369     bool shouldSuppressFailure( int flags );
1370
1371 } // end namespace Catch
1372
1373 // end catch_result_type.h
1374 namespace Catch {
1375
1376     struct AssertionInfo
1377     {
1378         StringRef macroName;
1379         SourceLineInfo lineInfo;
1380         StringRef capturedExpression;
1381         ResultDisposition::Flags resultDisposition;
1382
1383         // We want to delete this constructor but a compiler bug in 4.8 means
1384         // the struct is then treated as non-aggregate
1385         //AssertionInfo() = delete;
1386     };
1387
1388 } // end namespace Catch
1389
1390 // end catch_assertioninfo.h
1391 // start catch_decomposer.h
1392
1393 // start catch_tostring.h
1394
1395 #include <vector>
1396 #include <cstddef>
1397 #include <type_traits>
1398 #include <string>
1399 // start catch_stream.h
1400
1401 #include <iosfwd>
1402 #include <cstddef>
1403 #include <ostream>
1404
1405 namespace Catch {
1406
1407     std::ostream& cout();
1408     std::ostream& cerr();
1409     std::ostream& clog();
1410
1411     class StringRef;
1412
1413     struct IStream {
1414         virtual ~IStream();
1415         virtual std::ostream& stream() const = 0;
1416     };
1417
1418     auto makeStream( StringRef const &filename ) -> IStream const*;
1419
1420     class ReusableStringStream : NonCopyable {
1421         std::size_t m_index;
1422         std::ostream* m_oss;
1423     public:
1424         ReusableStringStream();
1425         ~ReusableStringStream();
1426
1427         auto str() const -> std::string;
1428
1429         template<typename T>
1430         auto operator << ( T const& value ) -> ReusableStringStream& {
1431             *m_oss << value;
1432             return *this;
1433         }
1434         auto get() -> std::ostream& { return *m_oss; }
1435     };
1436 }
1437
1438 // end catch_stream.h
1439 // start catch_interfaces_enum_values_registry.h
1440
1441 #include <vector>
1442
1443 namespace Catch {
1444
1445     namespace Detail {
1446         struct EnumInfo {
1447             StringRef m_name;
1448             std::vector<std::pair<int, StringRef>> m_values;
1449
1450             ~EnumInfo();
1451
1452             StringRef lookup( int value ) const;
1453         };
1454     } // namespace Detail
1455
1456     struct IMutableEnumValuesRegistry {
1457         virtual ~IMutableEnumValuesRegistry();
1458
1459         virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
1460
1461         template<typename E>
1462         Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
1463             static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1464             std::vector<int> intValues;
1465             intValues.reserve( values.size() );
1466             for( auto enumValue : values )
1467                 intValues.push_back( static_cast<int>( enumValue ) );
1468             return registerEnum( enumName, allEnums, intValues );
1469         }
1470     };
1471
1472 } // Catch
1473
1474 // end catch_interfaces_enum_values_registry.h
1475
1476 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1477 #include <string_view>
1478 #endif
1479
1480 #ifdef __OBJC__
1481 // start catch_objc_arc.hpp
1482
1483 #import <Foundation/Foundation.h>
1484
1485 #ifdef __has_feature
1486 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1487 #else
1488 #define CATCH_ARC_ENABLED 0
1489 #endif
1490
1491 void arcSafeRelease( NSObject* obj );
1492 id performOptionalSelector( id obj, SEL sel );
1493
1494 #if !CATCH_ARC_ENABLED
1495 inline void arcSafeRelease( NSObject* obj ) {
1496     [obj release];
1497 }
1498 inline id performOptionalSelector( id obj, SEL sel ) {
1499     if( [obj respondsToSelector: sel] )
1500         return [obj performSelector: sel];
1501     return nil;
1502 }
1503 #define CATCH_UNSAFE_UNRETAINED
1504 #define CATCH_ARC_STRONG
1505 #else
1506 inline void arcSafeRelease( NSObject* ){}
1507 inline id performOptionalSelector( id obj, SEL sel ) {
1508 #ifdef __clang__
1509 #pragma clang diagnostic push
1510 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1511 #endif
1512     if( [obj respondsToSelector: sel] )
1513         return [obj performSelector: sel];
1514 #ifdef __clang__
1515 #pragma clang diagnostic pop
1516 #endif
1517     return nil;
1518 }
1519 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1520 #define CATCH_ARC_STRONG __strong
1521 #endif
1522
1523 // end catch_objc_arc.hpp
1524 #endif
1525
1526 #ifdef _MSC_VER
1527 #pragma warning(push)
1528 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1529 #endif
1530
1531 namespace Catch {
1532     namespace Detail {
1533
1534         extern const std::string unprintableString;
1535
1536         std::string rawMemoryToString( const void *object, std::size_t size );
1537
1538         template<typename T>
1539         std::string rawMemoryToString( const T& object ) {
1540           return rawMemoryToString( &object, sizeof(object) );
1541         }
1542
1543         template<typename T>
1544         class IsStreamInsertable {
1545             template<typename Stream, typename U>
1546             static auto test(int)
1547                 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
1548
1549             template<typename, typename>
1550             static auto test(...)->std::false_type;
1551
1552         public:
1553             static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1554         };
1555
1556         template<typename E>
1557         std::string convertUnknownEnumToString( E e );
1558
1559         template<typename T>
1560         typename std::enable_if<
1561             !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
1562         std::string>::type convertUnstreamable( T const& ) {
1563             return Detail::unprintableString;
1564         }
1565         template<typename T>
1566         typename std::enable_if<
1567             !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
1568          std::string>::type convertUnstreamable(T const& ex) {
1569             return ex.what();
1570         }
1571
1572         template<typename T>
1573         typename std::enable_if<
1574             std::is_enum<T>::value
1575         , std::string>::type convertUnstreamable( T const& value ) {
1576             return convertUnknownEnumToString( value );
1577         }
1578
1579 #if defined(_MANAGED)
1580         //! Convert a CLR string to a utf8 std::string
1581         template<typename T>
1582         std::string clrReferenceToString( T^ ref ) {
1583             if (ref == nullptr)
1584                 return std::string("null");
1585             auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1586             cli::pin_ptr<System::Byte> p = &bytes[0];
1587             return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1588         }
1589 #endif
1590
1591     } // namespace Detail
1592
1593     // If we decide for C++14, change these to enable_if_ts
1594     template <typename T, typename = void>
1595     struct StringMaker {
1596         template <typename Fake = T>
1597         static
1598         typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1599             convert(const Fake& value) {
1600                 ReusableStringStream rss;
1601                 // NB: call using the function-like syntax to avoid ambiguity with
1602                 // user-defined templated operator<< under clang.
1603                 rss.operator<<(value);
1604                 return rss.str();
1605         }
1606
1607         template <typename Fake = T>
1608         static
1609         typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1610             convert( const Fake& value ) {
1611 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1612             return Detail::convertUnstreamable(value);
1613 #else
1614             return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1615 #endif
1616         }
1617     };
1618
1619     namespace Detail {
1620
1621         // This function dispatches all stringification requests inside of Catch.
1622         // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1623         template <typename T>
1624         std::string stringify(const T& e) {
1625             return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1626         }
1627
1628         template<typename E>
1629         std::string convertUnknownEnumToString( E e ) {
1630             return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1631         }
1632
1633 #if defined(_MANAGED)
1634         template <typename T>
1635         std::string stringify( T^ e ) {
1636             return ::Catch::StringMaker<T^>::convert(e);
1637         }
1638 #endif
1639
1640     } // namespace Detail
1641
1642     // Some predefined specializations
1643
1644     template<>
1645     struct StringMaker<std::string> {
1646         static std::string convert(const std::string& str);
1647     };
1648
1649 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1650     template<>
1651     struct StringMaker<std::string_view> {
1652         static std::string convert(std::string_view str);
1653     };
1654 #endif
1655
1656     template<>
1657     struct StringMaker<char const *> {
1658         static std::string convert(char const * str);
1659     };
1660     template<>
1661     struct StringMaker<char *> {
1662         static std::string convert(char * str);
1663     };
1664
1665 #ifdef CATCH_CONFIG_WCHAR
1666     template<>
1667     struct StringMaker<std::wstring> {
1668         static std::string convert(const std::wstring& wstr);
1669     };
1670
1671 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1672     template<>
1673     struct StringMaker<std::wstring_view> {
1674         static std::string convert(std::wstring_view str);
1675     };
1676 # endif
1677
1678     template<>
1679     struct StringMaker<wchar_t const *> {
1680         static std::string convert(wchar_t const * str);
1681     };
1682     template<>
1683     struct StringMaker<wchar_t *> {
1684         static std::string convert(wchar_t * str);
1685     };
1686 #endif
1687
1688     // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1689     //      while keeping string semantics?
1690     template<int SZ>
1691     struct StringMaker<char[SZ]> {
1692         static std::string convert(char const* str) {
1693             return ::Catch::Detail::stringify(std::string{ str });
1694         }
1695     };
1696     template<int SZ>
1697     struct StringMaker<signed char[SZ]> {
1698         static std::string convert(signed char const* str) {
1699             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1700         }
1701     };
1702     template<int SZ>
1703     struct StringMaker<unsigned char[SZ]> {
1704         static std::string convert(unsigned char const* str) {
1705             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1706         }
1707     };
1708
1709 #if defined(CATCH_CONFIG_CPP17_BYTE)
1710     template<>
1711     struct StringMaker<std::byte> {
1712         static std::string convert(std::byte value);
1713     };
1714 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
1715     template<>
1716     struct StringMaker<int> {
1717         static std::string convert(int value);
1718     };
1719     template<>
1720     struct StringMaker<long> {
1721         static std::string convert(long value);
1722     };
1723     template<>
1724     struct StringMaker<long long> {
1725         static std::string convert(long long value);
1726     };
1727     template<>
1728     struct StringMaker<unsigned int> {
1729         static std::string convert(unsigned int value);
1730     };
1731     template<>
1732     struct StringMaker<unsigned long> {
1733         static std::string convert(unsigned long value);
1734     };
1735     template<>
1736     struct StringMaker<unsigned long long> {
1737         static std::string convert(unsigned long long value);
1738     };
1739
1740     template<>
1741     struct StringMaker<bool> {
1742         static std::string convert(bool b);
1743     };
1744
1745     template<>
1746     struct StringMaker<char> {
1747         static std::string convert(char c);
1748     };
1749     template<>
1750     struct StringMaker<signed char> {
1751         static std::string convert(signed char c);
1752     };
1753     template<>
1754     struct StringMaker<unsigned char> {
1755         static std::string convert(unsigned char c);
1756     };
1757
1758     template<>
1759     struct StringMaker<std::nullptr_t> {
1760         static std::string convert(std::nullptr_t);
1761     };
1762
1763     template<>
1764     struct StringMaker<float> {
1765         static std::string convert(float value);
1766         static int precision;
1767     };
1768
1769     template<>
1770     struct StringMaker<double> {
1771         static std::string convert(double value);
1772         static int precision;
1773     };
1774
1775     template <typename T>
1776     struct StringMaker<T*> {
1777         template <typename U>
1778         static std::string convert(U* p) {
1779             if (p) {
1780                 return ::Catch::Detail::rawMemoryToString(p);
1781             } else {
1782                 return "nullptr";
1783             }
1784         }
1785     };
1786
1787     template <typename R, typename C>
1788     struct StringMaker<R C::*> {
1789         static std::string convert(R C::* p) {
1790             if (p) {
1791                 return ::Catch::Detail::rawMemoryToString(p);
1792             } else {
1793                 return "nullptr";
1794             }
1795         }
1796     };
1797
1798 #if defined(_MANAGED)
1799     template <typename T>
1800     struct StringMaker<T^> {
1801         static std::string convert( T^ ref ) {
1802             return ::Catch::Detail::clrReferenceToString(ref);
1803         }
1804     };
1805 #endif
1806
1807     namespace Detail {
1808         template<typename InputIterator>
1809         std::string rangeToString(InputIterator first, InputIterator last) {
1810             ReusableStringStream rss;
1811             rss << "{ ";
1812             if (first != last) {
1813                 rss << ::Catch::Detail::stringify(*first);
1814                 for (++first; first != last; ++first)
1815                     rss << ", " << ::Catch::Detail::stringify(*first);
1816             }
1817             rss << " }";
1818             return rss.str();
1819         }
1820     }
1821
1822 #ifdef __OBJC__
1823     template<>
1824     struct StringMaker<NSString*> {
1825         static std::string convert(NSString * nsstring) {
1826             if (!nsstring)
1827                 return "nil";
1828             return std::string("@") + [nsstring UTF8String];
1829         }
1830     };
1831     template<>
1832     struct StringMaker<NSObject*> {
1833         static std::string convert(NSObject* nsObject) {
1834             return ::Catch::Detail::stringify([nsObject description]);
1835         }
1836
1837     };
1838     namespace Detail {
1839         inline std::string stringify( NSString* nsstring ) {
1840             return StringMaker<NSString*>::convert( nsstring );
1841         }
1842
1843     } // namespace Detail
1844 #endif // __OBJC__
1845
1846 } // namespace Catch
1847
1848 //////////////////////////////////////////////////////
1849 // Separate std-lib types stringification, so it can be selectively enabled
1850 // This means that we do not bring in
1851
1852 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1853 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1854 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1855 #  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1856 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1857 #  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1858 #endif
1859
1860 // Separate std::pair specialization
1861 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1862 #include <utility>
1863 namespace Catch {
1864     template<typename T1, typename T2>
1865     struct StringMaker<std::pair<T1, T2> > {
1866         static std::string convert(const std::pair<T1, T2>& pair) {
1867             ReusableStringStream rss;
1868             rss << "{ "
1869                 << ::Catch::Detail::stringify(pair.first)
1870                 << ", "
1871                 << ::Catch::Detail::stringify(pair.second)
1872                 << " }";
1873             return rss.str();
1874         }
1875     };
1876 }
1877 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1878
1879 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
1880 #include <optional>
1881 namespace Catch {
1882     template<typename T>
1883     struct StringMaker<std::optional<T> > {
1884         static std::string convert(const std::optional<T>& optional) {
1885             ReusableStringStream rss;
1886             if (optional.has_value()) {
1887                 rss << ::Catch::Detail::stringify(*optional);
1888             } else {
1889                 rss << "{ }";
1890             }
1891             return rss.str();
1892         }
1893     };
1894 }
1895 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1896
1897 // Separate std::tuple specialization
1898 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1899 #include <tuple>
1900 namespace Catch {
1901     namespace Detail {
1902         template<
1903             typename Tuple,
1904             std::size_t N = 0,
1905             bool = (N < std::tuple_size<Tuple>::value)
1906             >
1907             struct TupleElementPrinter {
1908             static void print(const Tuple& tuple, std::ostream& os) {
1909                 os << (N ? ", " : " ")
1910                     << ::Catch::Detail::stringify(std::get<N>(tuple));
1911                 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1912             }
1913         };
1914
1915         template<
1916             typename Tuple,
1917             std::size_t N
1918         >
1919             struct TupleElementPrinter<Tuple, N, false> {
1920             static void print(const Tuple&, std::ostream&) {}
1921         };
1922
1923     }
1924
1925     template<typename ...Types>
1926     struct StringMaker<std::tuple<Types...>> {
1927         static std::string convert(const std::tuple<Types...>& tuple) {
1928             ReusableStringStream rss;
1929             rss << '{';
1930             Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1931             rss << " }";
1932             return rss.str();
1933         }
1934     };
1935 }
1936 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1937
1938 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1939 #include <variant>
1940 namespace Catch {
1941     template<>
1942     struct StringMaker<std::monostate> {
1943         static std::string convert(const std::monostate&) {
1944             return "{ }";
1945         }
1946     };
1947
1948     template<typename... Elements>
1949     struct StringMaker<std::variant<Elements...>> {
1950         static std::string convert(const std::variant<Elements...>& variant) {
1951             if (variant.valueless_by_exception()) {
1952                 return "{valueless variant}";
1953             } else {
1954                 return std::visit(
1955                     [](const auto& value) {
1956                         return ::Catch::Detail::stringify(value);
1957                     },
1958                     variant
1959                 );
1960             }
1961         }
1962     };
1963 }
1964 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1965
1966 namespace Catch {
1967     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
1968
1969     // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
1970     using std::begin;
1971     using std::end;
1972
1973     not_this_one begin( ... );
1974     not_this_one end( ... );
1975
1976     template <typename T>
1977     struct is_range {
1978         static const bool value =
1979             !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
1980             !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
1981     };
1982
1983 #if defined(_MANAGED) // Managed types are never ranges
1984     template <typename T>
1985     struct is_range<T^> {
1986         static const bool value = false;
1987     };
1988 #endif
1989
1990     template<typename Range>
1991     std::string rangeToString( Range const& range ) {
1992         return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
1993     }
1994
1995     // Handle vector<bool> specially
1996     template<typename Allocator>
1997     std::string rangeToString( std::vector<bool, Allocator> const& v ) {
1998         ReusableStringStream rss;
1999         rss << "{ ";
2000         bool first = true;
2001         for( bool b : v ) {
2002             if( first )
2003                 first = false;
2004             else
2005                 rss << ", ";
2006             rss << ::Catch::Detail::stringify( b );
2007         }
2008         rss << " }";
2009         return rss.str();
2010     }
2011
2012     template<typename R>
2013     struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
2014         static std::string convert( R const& range ) {
2015             return rangeToString( range );
2016         }
2017     };
2018
2019     template <typename T, int SZ>
2020     struct StringMaker<T[SZ]> {
2021         static std::string convert(T const(&arr)[SZ]) {
2022             return rangeToString(arr);
2023         }
2024     };
2025
2026 } // namespace Catch
2027
2028 // Separate std::chrono::duration specialization
2029 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2030 #include <ctime>
2031 #include <ratio>
2032 #include <chrono>
2033
2034 namespace Catch {
2035
2036 template <class Ratio>
2037 struct ratio_string {
2038     static std::string symbol();
2039 };
2040
2041 template <class Ratio>
2042 std::string ratio_string<Ratio>::symbol() {
2043     Catch::ReusableStringStream rss;
2044     rss << '[' << Ratio::num << '/'
2045         << Ratio::den << ']';
2046     return rss.str();
2047 }
2048 template <>
2049 struct ratio_string<std::atto> {
2050     static std::string symbol();
2051 };
2052 template <>
2053 struct ratio_string<std::femto> {
2054     static std::string symbol();
2055 };
2056 template <>
2057 struct ratio_string<std::pico> {
2058     static std::string symbol();
2059 };
2060 template <>
2061 struct ratio_string<std::nano> {
2062     static std::string symbol();
2063 };
2064 template <>
2065 struct ratio_string<std::micro> {
2066     static std::string symbol();
2067 };
2068 template <>
2069 struct ratio_string<std::milli> {
2070     static std::string symbol();
2071 };
2072
2073     ////////////
2074     // std::chrono::duration specializations
2075     template<typename Value, typename Ratio>
2076     struct StringMaker<std::chrono::duration<Value, Ratio>> {
2077         static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
2078             ReusableStringStream rss;
2079             rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2080             return rss.str();
2081         }
2082     };
2083     template<typename Value>
2084     struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2085         static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
2086             ReusableStringStream rss;
2087             rss << duration.count() << " s";
2088             return rss.str();
2089         }
2090     };
2091     template<typename Value>
2092     struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2093         static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
2094             ReusableStringStream rss;
2095             rss << duration.count() << " m";
2096             return rss.str();
2097         }
2098     };
2099     template<typename Value>
2100     struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2101         static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
2102             ReusableStringStream rss;
2103             rss << duration.count() << " h";
2104             return rss.str();
2105         }
2106     };
2107
2108     ////////////
2109     // std::chrono::time_point specialization
2110     // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2111     template<typename Clock, typename Duration>
2112     struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2113         static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
2114             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2115         }
2116     };
2117     // std::chrono::time_point<system_clock> specialization
2118     template<typename Duration>
2119     struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
2120         static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
2121             auto converted = std::chrono::system_clock::to_time_t(time_point);
2122
2123 #ifdef _MSC_VER
2124             std::tm timeInfo = {};
2125             gmtime_s(&timeInfo, &converted);
2126 #else
2127             std::tm* timeInfo = std::gmtime(&converted);
2128 #endif
2129
2130             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2131             char timeStamp[timeStampSize];
2132             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
2133
2134 #ifdef _MSC_VER
2135             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2136 #else
2137             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2138 #endif
2139             return std::string(timeStamp);
2140         }
2141     };
2142 }
2143 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2144
2145 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
2146 namespace Catch { \
2147     template<> struct StringMaker<enumName> { \
2148         static std::string convert( enumName value ) { \
2149             static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
2150             return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
2151         } \
2152     }; \
2153 }
2154
2155 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
2156
2157 #ifdef _MSC_VER
2158 #pragma warning(pop)
2159 #endif
2160
2161 // end catch_tostring.h
2162 #include <iosfwd>
2163
2164 #ifdef _MSC_VER
2165 #pragma warning(push)
2166 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
2167 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
2168 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2169 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
2170 #pragma warning(disable:4800) // Forcing result to true or false
2171 #endif
2172
2173 namespace Catch {
2174
2175     struct ITransientExpression {
2176         auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
2177         auto getResult() const -> bool { return m_result; }
2178         virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
2179
2180         ITransientExpression( bool isBinaryExpression, bool result )
2181         :   m_isBinaryExpression( isBinaryExpression ),
2182             m_result( result )
2183         {}
2184
2185         // We don't actually need a virtual destructor, but many static analysers
2186         // complain if it's not here :-(
2187         virtual ~ITransientExpression();
2188
2189         bool m_isBinaryExpression;
2190         bool m_result;
2191
2192     };
2193
2194     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
2195
2196     template<typename LhsT, typename RhsT>
2197     class BinaryExpr  : public ITransientExpression {
2198         LhsT m_lhs;
2199         StringRef m_op;
2200         RhsT m_rhs;
2201
2202         void streamReconstructedExpression( std::ostream &os ) const override {
2203             formatReconstructedExpression
2204                     ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
2205         }
2206
2207     public:
2208         BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
2209         :   ITransientExpression{ true, comparisonResult },
2210             m_lhs( lhs ),
2211             m_op( op ),
2212             m_rhs( rhs )
2213         {}
2214
2215         template<typename T>
2216         auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2217             static_assert(always_false<T>::value,
2218             "chained comparisons are not supported inside assertions, "
2219             "wrap the expression inside parentheses, or decompose it");
2220         }
2221
2222         template<typename T>
2223         auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2224             static_assert(always_false<T>::value,
2225             "chained comparisons are not supported inside assertions, "
2226             "wrap the expression inside parentheses, or decompose it");
2227         }
2228
2229         template<typename T>
2230         auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2231             static_assert(always_false<T>::value,
2232             "chained comparisons are not supported inside assertions, "
2233             "wrap the expression inside parentheses, or decompose it");
2234         }
2235
2236         template<typename T>
2237         auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2238             static_assert(always_false<T>::value,
2239             "chained comparisons are not supported inside assertions, "
2240             "wrap the expression inside parentheses, or decompose it");
2241         }
2242
2243         template<typename T>
2244         auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2245             static_assert(always_false<T>::value,
2246             "chained comparisons are not supported inside assertions, "
2247             "wrap the expression inside parentheses, or decompose it");
2248         }
2249
2250         template<typename T>
2251         auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2252             static_assert(always_false<T>::value,
2253             "chained comparisons are not supported inside assertions, "
2254             "wrap the expression inside parentheses, or decompose it");
2255         }
2256
2257         template<typename T>
2258         auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2259             static_assert(always_false<T>::value,
2260             "chained comparisons are not supported inside assertions, "
2261             "wrap the expression inside parentheses, or decompose it");
2262         }
2263
2264         template<typename T>
2265         auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2266             static_assert(always_false<T>::value,
2267             "chained comparisons are not supported inside assertions, "
2268             "wrap the expression inside parentheses, or decompose it");
2269         }
2270     };
2271
2272     template<typename LhsT>
2273     class UnaryExpr : public ITransientExpression {
2274         LhsT m_lhs;
2275
2276         void streamReconstructedExpression( std::ostream &os ) const override {
2277             os << Catch::Detail::stringify( m_lhs );
2278         }
2279
2280     public:
2281         explicit UnaryExpr( LhsT lhs )
2282         :   ITransientExpression{ false, static_cast<bool>(lhs) },
2283             m_lhs( lhs )
2284         {}
2285     };
2286
2287     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2288     template<typename LhsT, typename RhsT>
2289     auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
2290     template<typename T>
2291     auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2292     template<typename T>
2293     auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2294     template<typename T>
2295     auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2296     template<typename T>
2297     auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2298
2299     template<typename LhsT, typename RhsT>
2300     auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
2301     template<typename T>
2302     auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2303     template<typename T>
2304     auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2305     template<typename T>
2306     auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2307     template<typename T>
2308     auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2309
2310     template<typename LhsT>
2311     class ExprLhs {
2312         LhsT m_lhs;
2313     public:
2314         explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
2315
2316         template<typename RhsT>
2317         auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2318             return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
2319         }
2320         auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2321             return { m_lhs == rhs, m_lhs, "==", rhs };
2322         }
2323
2324         template<typename RhsT>
2325         auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2326             return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
2327         }
2328         auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2329             return { m_lhs != rhs, m_lhs, "!=", rhs };
2330         }
2331
2332         template<typename RhsT>
2333         auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2334             return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
2335         }
2336         template<typename RhsT>
2337         auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2338             return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
2339         }
2340         template<typename RhsT>
2341         auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2342             return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
2343         }
2344         template<typename RhsT>
2345         auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2346             return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
2347         }
2348
2349         template<typename RhsT>
2350         auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2351             static_assert(always_false<RhsT>::value,
2352             "operator&& is not supported inside assertions, "
2353             "wrap the expression inside parentheses, or decompose it");
2354         }
2355
2356         template<typename RhsT>
2357         auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2358             static_assert(always_false<RhsT>::value,
2359             "operator|| is not supported inside assertions, "
2360             "wrap the expression inside parentheses, or decompose it");
2361         }
2362
2363         auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
2364             return UnaryExpr<LhsT>{ m_lhs };
2365         }
2366     };
2367
2368     void handleExpression( ITransientExpression const& expr );
2369
2370     template<typename T>
2371     void handleExpression( ExprLhs<T> const& expr ) {
2372         handleExpression( expr.makeUnaryExpr() );
2373     }
2374
2375     struct Decomposer {
2376         template<typename T>
2377         auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
2378             return ExprLhs<T const&>{ lhs };
2379         }
2380
2381         auto operator <=( bool value ) -> ExprLhs<bool> {
2382             return ExprLhs<bool>{ value };
2383         }
2384     };
2385
2386 } // end namespace Catch
2387
2388 #ifdef _MSC_VER
2389 #pragma warning(pop)
2390 #endif
2391
2392 // end catch_decomposer.h
2393 // start catch_interfaces_capture.h
2394
2395 #include <string>
2396 #include <chrono>
2397
2398 namespace Catch {
2399
2400     class AssertionResult;
2401     struct AssertionInfo;
2402     struct SectionInfo;
2403     struct SectionEndInfo;
2404     struct MessageInfo;
2405     struct MessageBuilder;
2406     struct Counts;
2407     struct AssertionReaction;
2408     struct SourceLineInfo;
2409
2410     struct ITransientExpression;
2411     struct IGeneratorTracker;
2412
2413 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2414     struct BenchmarkInfo;
2415     template <typename Duration = std::chrono::duration<double, std::nano>>
2416     struct BenchmarkStats;
2417 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2418
2419     struct IResultCapture {
2420
2421         virtual ~IResultCapture();
2422
2423         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
2424                                         Counts& assertions ) = 0;
2425         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2426         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2427
2428         virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
2429
2430 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2431         virtual void benchmarkPreparing( std::string const& name ) = 0;
2432         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
2433         virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
2434         virtual void benchmarkFailed( std::string const& error ) = 0;
2435 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2436
2437         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2438         virtual void popScopedMessage( MessageInfo const& message ) = 0;
2439
2440         virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
2441
2442         virtual void handleFatalErrorCondition( StringRef message ) = 0;
2443
2444         virtual void handleExpr
2445                 (   AssertionInfo const& info,
2446                     ITransientExpression const& expr,
2447                     AssertionReaction& reaction ) = 0;
2448         virtual void handleMessage
2449                 (   AssertionInfo const& info,
2450                     ResultWas::OfType resultType,
2451                     StringRef const& message,
2452                     AssertionReaction& reaction ) = 0;
2453         virtual void handleUnexpectedExceptionNotThrown
2454                 (   AssertionInfo const& info,
2455                     AssertionReaction& reaction ) = 0;
2456         virtual void handleUnexpectedInflightException
2457                 (   AssertionInfo const& info,
2458                     std::string const& message,
2459                     AssertionReaction& reaction ) = 0;
2460         virtual void handleIncomplete
2461                 (   AssertionInfo const& info ) = 0;
2462         virtual void handleNonExpr
2463                 (   AssertionInfo const &info,
2464                     ResultWas::OfType resultType,
2465                     AssertionReaction &reaction ) = 0;
2466
2467         virtual bool lastAssertionPassed() = 0;
2468         virtual void assertionPassed() = 0;
2469
2470         // Deprecated, do not use:
2471         virtual std::string getCurrentTestName() const = 0;
2472         virtual const AssertionResult* getLastResult() const = 0;
2473         virtual void exceptionEarlyReported() = 0;
2474     };
2475
2476     IResultCapture& getResultCapture();
2477 }
2478
2479 // end catch_interfaces_capture.h
2480 namespace Catch {
2481
2482     struct TestFailureException{};
2483     struct AssertionResultData;
2484     struct IResultCapture;
2485     class RunContext;
2486
2487     class LazyExpression {
2488         friend class AssertionHandler;
2489         friend struct AssertionStats;
2490         friend class RunContext;
2491
2492         ITransientExpression const* m_transientExpression = nullptr;
2493         bool m_isNegated;
2494     public:
2495         LazyExpression( bool isNegated );
2496         LazyExpression( LazyExpression const& other );
2497         LazyExpression& operator = ( LazyExpression const& ) = delete;
2498
2499         explicit operator bool() const;
2500
2501         friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
2502     };
2503
2504     struct AssertionReaction {
2505         bool shouldDebugBreak = false;
2506         bool shouldThrow = false;
2507     };
2508
2509     class AssertionHandler {
2510         AssertionInfo m_assertionInfo;
2511         AssertionReaction m_reaction;
2512         bool m_completed = false;
2513         IResultCapture& m_resultCapture;
2514
2515     public:
2516         AssertionHandler
2517             (   StringRef const& macroName,
2518                 SourceLineInfo const& lineInfo,
2519                 StringRef capturedExpression,
2520                 ResultDisposition::Flags resultDisposition );
2521         ~AssertionHandler() {
2522             if ( !m_completed ) {
2523                 m_resultCapture.handleIncomplete( m_assertionInfo );
2524             }
2525         }
2526
2527         template<typename T>
2528         void handleExpr( ExprLhs<T> const& expr ) {
2529             handleExpr( expr.makeUnaryExpr() );
2530         }
2531         void handleExpr( ITransientExpression const& expr );
2532
2533         void handleMessage(ResultWas::OfType resultType, StringRef const& message);
2534
2535         void handleExceptionThrownAsExpected();
2536         void handleUnexpectedExceptionNotThrown();
2537         void handleExceptionNotThrownAsExpected();
2538         void handleThrowingCallSkipped();
2539         void handleUnexpectedInflightException();
2540
2541         void complete();
2542         void setCompleted();
2543
2544         // query
2545         auto allowThrows() const -> bool;
2546     };
2547
2548     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
2549
2550 } // namespace Catch
2551
2552 // end catch_assertionhandler.h
2553 // start catch_message.h
2554
2555 #include <string>
2556 #include <vector>
2557
2558 namespace Catch {
2559
2560     struct MessageInfo {
2561         MessageInfo(    StringRef const& _macroName,
2562                         SourceLineInfo const& _lineInfo,
2563                         ResultWas::OfType _type );
2564
2565         StringRef macroName;
2566         std::string message;
2567         SourceLineInfo lineInfo;
2568         ResultWas::OfType type;
2569         unsigned int sequence;
2570
2571         bool operator == ( MessageInfo const& other ) const;
2572         bool operator < ( MessageInfo const& other ) const;
2573     private:
2574         static unsigned int globalCount;
2575     };
2576
2577     struct MessageStream {
2578
2579         template<typename T>
2580         MessageStream& operator << ( T const& value ) {
2581             m_stream << value;
2582             return *this;
2583         }
2584
2585         ReusableStringStream m_stream;
2586     };
2587
2588     struct MessageBuilder : MessageStream {
2589         MessageBuilder( StringRef const& macroName,
2590                         SourceLineInfo const& lineInfo,
2591                         ResultWas::OfType type );
2592
2593         template<typename T>
2594         MessageBuilder& operator << ( T const& value ) {
2595             m_stream << value;
2596             return *this;
2597         }
2598
2599         MessageInfo m_info;
2600     };
2601
2602     class ScopedMessage {
2603     public:
2604         explicit ScopedMessage( MessageBuilder const& builder );
2605         ScopedMessage( ScopedMessage& duplicate ) = delete;
2606         ScopedMessage( ScopedMessage&& old );
2607         ~ScopedMessage();
2608
2609         MessageInfo m_info;
2610         bool m_moved;
2611     };
2612
2613     class Capturer {
2614         std::vector<MessageInfo> m_messages;
2615         IResultCapture& m_resultCapture = getResultCapture();
2616         size_t m_captured = 0;
2617     public:
2618         Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
2619         ~Capturer();
2620
2621         void captureValue( size_t index, std::string const& value );
2622
2623         template<typename T>
2624         void captureValues( size_t index, T const& value ) {
2625             captureValue( index, Catch::Detail::stringify( value ) );
2626         }
2627
2628         template<typename T, typename... Ts>
2629         void captureValues( size_t index, T const& value, Ts const&... values ) {
2630             captureValue( index, Catch::Detail::stringify(value) );
2631             captureValues( index+1, values... );
2632         }
2633     };
2634
2635 } // end namespace Catch
2636
2637 // end catch_message.h
2638 #if !defined(CATCH_CONFIG_DISABLE)
2639
2640 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2641   #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2642 #else
2643   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2644 #endif
2645
2646 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2647
2648 ///////////////////////////////////////////////////////////////////////////////
2649 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2650 // macros.
2651 #define INTERNAL_CATCH_TRY
2652 #define INTERNAL_CATCH_CATCH( capturer )
2653
2654 #else // CATCH_CONFIG_FAST_COMPILE
2655
2656 #define INTERNAL_CATCH_TRY try
2657 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
2658
2659 #endif
2660
2661 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
2662
2663 ///////////////////////////////////////////////////////////////////////////////
2664 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2665     do { \
2666         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2667         INTERNAL_CATCH_TRY { \
2668             CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2669             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2670             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
2671             CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
2672         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2673         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2674     } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
2675     // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2676
2677 ///////////////////////////////////////////////////////////////////////////////
2678 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
2679     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2680     if( Catch::getResultCapture().lastAssertionPassed() )
2681
2682 ///////////////////////////////////////////////////////////////////////////////
2683 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
2684     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2685     if( !Catch::getResultCapture().lastAssertionPassed() )
2686
2687 ///////////////////////////////////////////////////////////////////////////////
2688 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2689     do { \
2690         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2691         try { \
2692             static_cast<void>(__VA_ARGS__); \
2693             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
2694         } \
2695         catch( ... ) { \
2696             catchAssertionHandler.handleUnexpectedInflightException(); \
2697         } \
2698         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2699     } while( false )
2700
2701 ///////////////////////////////////////////////////////////////////////////////
2702 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2703     do { \
2704         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
2705         if( catchAssertionHandler.allowThrows() ) \
2706             try { \
2707                 static_cast<void>(__VA_ARGS__); \
2708                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2709             } \
2710             catch( ... ) { \
2711                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
2712             } \
2713         else \
2714             catchAssertionHandler.handleThrowingCallSkipped(); \
2715         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2716     } while( false )
2717
2718 ///////////////////////////////////////////////////////////////////////////////
2719 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2720     do { \
2721         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2722         if( catchAssertionHandler.allowThrows() ) \
2723             try { \
2724                 static_cast<void>(expr); \
2725                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2726             } \
2727             catch( exceptionType const& ) { \
2728                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
2729             } \
2730             catch( ... ) { \
2731                 catchAssertionHandler.handleUnexpectedInflightException(); \
2732             } \
2733         else \
2734             catchAssertionHandler.handleThrowingCallSkipped(); \
2735         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2736     } while( false )
2737
2738 ///////////////////////////////////////////////////////////////////////////////
2739 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2740     do { \
2741         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
2742         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
2743         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2744     } while( false )
2745
2746 ///////////////////////////////////////////////////////////////////////////////
2747 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
2748     auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
2749     varName.captureValues( 0, __VA_ARGS__ )
2750
2751 ///////////////////////////////////////////////////////////////////////////////
2752 #define INTERNAL_CATCH_INFO( macroName, log ) \
2753     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
2754
2755 ///////////////////////////////////////////////////////////////////////////////
2756 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
2757     Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
2758
2759 ///////////////////////////////////////////////////////////////////////////////
2760 // Although this is matcher-based, it can be used with just a string
2761 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
2762     do { \
2763         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2764         if( catchAssertionHandler.allowThrows() ) \
2765             try { \
2766                 static_cast<void>(__VA_ARGS__); \
2767                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2768             } \
2769             catch( ... ) { \
2770                 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
2771             } \
2772         else \
2773             catchAssertionHandler.handleThrowingCallSkipped(); \
2774         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2775     } while( false )
2776
2777 #endif // CATCH_CONFIG_DISABLE
2778
2779 // end catch_capture.hpp
2780 // start catch_section.h
2781
2782 // start catch_section_info.h
2783
2784 // start catch_totals.h
2785
2786 #include <cstddef>
2787
2788 namespace Catch {
2789
2790     struct Counts {
2791         Counts operator - ( Counts const& other ) const;
2792         Counts& operator += ( Counts const& other );
2793
2794         std::size_t total() const;
2795         bool allPassed() const;
2796         bool allOk() const;
2797
2798         std::size_t passed = 0;
2799         std::size_t failed = 0;
2800         std::size_t failedButOk = 0;
2801     };
2802
2803     struct Totals {
2804
2805         Totals operator - ( Totals const& other ) const;
2806         Totals& operator += ( Totals const& other );
2807
2808         Totals delta( Totals const& prevTotals ) const;
2809
2810         int error = 0;
2811         Counts assertions;
2812         Counts testCases;
2813     };
2814 }
2815
2816 // end catch_totals.h
2817 #include <string>
2818
2819 namespace Catch {
2820
2821     struct SectionInfo {
2822         SectionInfo
2823             (   SourceLineInfo const& _lineInfo,
2824                 std::string const& _name );
2825
2826         // Deprecated
2827         SectionInfo
2828             (   SourceLineInfo const& _lineInfo,
2829                 std::string const& _name,
2830                 std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2831
2832         std::string name;
2833         std::string description; // !Deprecated: this will always be empty
2834         SourceLineInfo lineInfo;
2835     };
2836
2837     struct SectionEndInfo {
2838         SectionInfo sectionInfo;
2839         Counts prevAssertions;
2840         double durationInSeconds;
2841     };
2842
2843 } // end namespace Catch
2844
2845 // end catch_section_info.h
2846 // start catch_timer.h
2847
2848 #include <cstdint>
2849
2850 namespace Catch {
2851
2852     auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
2853     auto getEstimatedClockResolution() -> uint64_t;
2854
2855     class Timer {
2856         uint64_t m_nanoseconds = 0;
2857     public:
2858         void start();
2859         auto getElapsedNanoseconds() const -> uint64_t;
2860         auto getElapsedMicroseconds() const -> uint64_t;
2861         auto getElapsedMilliseconds() const -> unsigned int;
2862         auto getElapsedSeconds() const -> double;
2863     };
2864
2865 } // namespace Catch
2866
2867 // end catch_timer.h
2868 #include <string>
2869
2870 namespace Catch {
2871
2872     class Section : NonCopyable {
2873     public:
2874         Section( SectionInfo const& info );
2875         ~Section();
2876
2877         // This indicates whether the section should be executed or not
2878         explicit operator bool() const;
2879
2880     private:
2881         SectionInfo m_info;
2882
2883         std::string m_name;
2884         Counts m_assertions;
2885         bool m_sectionIncluded;
2886         Timer m_timer;
2887     };
2888
2889 } // end namespace Catch
2890
2891 #define INTERNAL_CATCH_SECTION( ... ) \
2892     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2893     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2894     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2895     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2896
2897 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2898     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2899     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2900     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2901     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2902
2903 // end catch_section.h
2904 // start catch_interfaces_exception.h
2905
2906 // start catch_interfaces_registry_hub.h
2907
2908 #include <string>
2909 #include <memory>
2910
2911 namespace Catch {
2912
2913     class TestCase;
2914     struct ITestCaseRegistry;
2915     struct IExceptionTranslatorRegistry;
2916     struct IExceptionTranslator;
2917     struct IReporterRegistry;
2918     struct IReporterFactory;
2919     struct ITagAliasRegistry;
2920     struct IMutableEnumValuesRegistry;
2921
2922     class StartupExceptionRegistry;
2923
2924     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2925
2926     struct IRegistryHub {
2927         virtual ~IRegistryHub();
2928
2929         virtual IReporterRegistry const& getReporterRegistry() const = 0;
2930         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2931         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2932         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2933
2934         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2935     };
2936
2937     struct IMutableRegistryHub {
2938         virtual ~IMutableRegistryHub();
2939         virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2940         virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2941         virtual void registerTest( TestCase const& testInfo ) = 0;
2942         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2943         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2944         virtual void registerStartupException() noexcept = 0;
2945         virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
2946     };
2947
2948     IRegistryHub const& getRegistryHub();
2949     IMutableRegistryHub& getMutableRegistryHub();
2950     void cleanUp();
2951     std::string translateActiveException();
2952
2953 }
2954
2955 // end catch_interfaces_registry_hub.h
2956 #if defined(CATCH_CONFIG_DISABLE)
2957     #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
2958         static std::string translatorName( signature )
2959 #endif
2960
2961 #include <exception>
2962 #include <string>
2963 #include <vector>
2964
2965 namespace Catch {
2966     using exceptionTranslateFunction = std::string(*)();
2967
2968     struct IExceptionTranslator;
2969     using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
2970
2971     struct IExceptionTranslator {
2972         virtual ~IExceptionTranslator();
2973         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2974     };
2975
2976     struct IExceptionTranslatorRegistry {
2977         virtual ~IExceptionTranslatorRegistry();
2978
2979         virtual std::string translateActiveException() const = 0;
2980     };
2981
2982     class ExceptionTranslatorRegistrar {
2983         template<typename T>
2984         class ExceptionTranslator : public IExceptionTranslator {
2985         public:
2986
2987             ExceptionTranslator( std::string(*translateFunction)( T& ) )
2988             : m_translateFunction( translateFunction )
2989             {}
2990
2991             std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
2992                 try {
2993                     if( it == itEnd )
2994                         std::rethrow_exception(std::current_exception());
2995                     else
2996                         return (*it)->translate( it+1, itEnd );
2997                 }
2998                 catch( T& ex ) {
2999                     return m_translateFunction( ex );
3000                 }
3001             }
3002
3003         protected:
3004             std::string(*m_translateFunction)( T& );
3005         };
3006
3007     public:
3008         template<typename T>
3009         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
3010             getMutableRegistryHub().registerTranslator
3011                 ( new ExceptionTranslator<T>( translateFunction ) );
3012         }
3013     };
3014 }
3015
3016 ///////////////////////////////////////////////////////////////////////////////
3017 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
3018     static std::string translatorName( signature ); \
3019     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3020     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
3021     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
3022     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
3023     static std::string translatorName( signature )
3024
3025 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
3026
3027 // end catch_interfaces_exception.h
3028 // start catch_approx.h
3029
3030 #include <type_traits>
3031
3032 namespace Catch {
3033 namespace Detail {
3034
3035     class Approx {
3036     private:
3037         bool equalityComparisonImpl(double other) const;
3038         // Validates the new margin (margin >= 0)
3039         // out-of-line to avoid including stdexcept in the header
3040         void setMargin(double margin);
3041         // Validates the new epsilon (0 < epsilon < 1)
3042         // out-of-line to avoid including stdexcept in the header
3043         void setEpsilon(double epsilon);
3044
3045     public:
3046         explicit Approx ( double value );
3047
3048         static Approx custom();
3049
3050         Approx operator-() const;
3051
3052         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3053         Approx operator()( T const& value ) {
3054             Approx approx( static_cast<double>(value) );
3055             approx.m_epsilon = m_epsilon;
3056             approx.m_margin = m_margin;
3057             approx.m_scale = m_scale;
3058             return approx;
3059         }
3060
3061         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3062         explicit Approx( T const& value ): Approx(static_cast<double>(value))
3063         {}
3064
3065         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3066         friend bool operator == ( const T& lhs, Approx const& rhs ) {
3067             auto lhs_v = static_cast<double>(lhs);
3068             return rhs.equalityComparisonImpl(lhs_v);
3069         }
3070
3071         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3072         friend bool operator == ( Approx const& lhs, const T& rhs ) {
3073             return operator==( rhs, lhs );
3074         }
3075
3076         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3077         friend bool operator != ( T const& lhs, Approx const& rhs ) {
3078             return !operator==( lhs, rhs );
3079         }
3080
3081         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3082         friend bool operator != ( Approx const& lhs, T const& rhs ) {
3083             return !operator==( rhs, lhs );
3084         }
3085
3086         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3087         friend bool operator <= ( T const& lhs, Approx const& rhs ) {
3088             return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3089         }
3090
3091         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3092         friend bool operator <= ( Approx const& lhs, T const& rhs ) {
3093             return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3094         }
3095
3096         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3097         friend bool operator >= ( T const& lhs, Approx const& rhs ) {
3098             return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3099         }
3100
3101         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3102         friend bool operator >= ( Approx const& lhs, T const& rhs ) {
3103             return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3104         }
3105
3106         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3107         Approx& epsilon( T const& newEpsilon ) {
3108             double epsilonAsDouble = static_cast<double>(newEpsilon);
3109             setEpsilon(epsilonAsDouble);
3110             return *this;
3111         }
3112
3113         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3114         Approx& margin( T const& newMargin ) {
3115             double marginAsDouble = static_cast<double>(newMargin);
3116             setMargin(marginAsDouble);
3117             return *this;
3118         }
3119
3120         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3121         Approx& scale( T const& newScale ) {
3122             m_scale = static_cast<double>(newScale);
3123             return *this;
3124         }
3125
3126         std::string toString() const;
3127
3128     private:
3129         double m_epsilon;
3130         double m_margin;
3131         double m_scale;
3132         double m_value;
3133     };
3134 } // end namespace Detail
3135
3136 namespace literals {
3137     Detail::Approx operator "" _a(long double val);
3138     Detail::Approx operator "" _a(unsigned long long val);
3139 } // end namespace literals
3140
3141 template<>
3142 struct StringMaker<Catch::Detail::Approx> {
3143     static std::string convert(Catch::Detail::Approx const& value);
3144 };
3145
3146 } // end namespace Catch
3147
3148 // end catch_approx.h
3149 // start catch_string_manip.h
3150
3151 #include <string>
3152 #include <iosfwd>
3153 #include <vector>
3154
3155 namespace Catch {
3156
3157     bool startsWith( std::string const& s, std::string const& prefix );
3158     bool startsWith( std::string const& s, char prefix );
3159     bool endsWith( std::string const& s, std::string const& suffix );
3160     bool endsWith( std::string const& s, char suffix );
3161     bool contains( std::string const& s, std::string const& infix );
3162     void toLowerInPlace( std::string& s );
3163     std::string toLower( std::string const& s );
3164     //! Returns a new string without whitespace at the start/end
3165     std::string trim( std::string const& str );
3166     //! Returns a substring of the original ref without whitespace. Beware lifetimes!
3167     StringRef trim(StringRef ref);
3168
3169     // !!! Be aware, returns refs into original string - make sure original string outlives them
3170     std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
3171     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
3172
3173     struct pluralise {
3174         pluralise( std::size_t count, std::string const& label );
3175
3176         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
3177
3178         std::size_t m_count;
3179         std::string m_label;
3180     };
3181 }
3182
3183 // end catch_string_manip.h
3184 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
3185 // start catch_capture_matchers.h
3186
3187 // start catch_matchers.h
3188
3189 #include <string>
3190 #include <vector>
3191
3192 namespace Catch {
3193 namespace Matchers {
3194     namespace Impl {
3195
3196         template<typename ArgT> struct MatchAllOf;
3197         template<typename ArgT> struct MatchAnyOf;
3198         template<typename ArgT> struct MatchNotOf;
3199
3200         class MatcherUntypedBase {
3201         public:
3202             MatcherUntypedBase() = default;
3203             MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
3204             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
3205             std::string toString() const;
3206
3207         protected:
3208             virtual ~MatcherUntypedBase();
3209             virtual std::string describe() const = 0;
3210             mutable std::string m_cachedToString;
3211         };
3212
3213 #ifdef __clang__
3214 #    pragma clang diagnostic push
3215 #    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
3216 #endif
3217
3218         template<typename ObjectT>
3219         struct MatcherMethod {
3220             virtual bool match( ObjectT const& arg ) const = 0;
3221         };
3222
3223 #if defined(__OBJC__)
3224         // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
3225         // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
3226         template<>
3227         struct MatcherMethod<NSString*> {
3228             virtual bool match( NSString* arg ) const = 0;
3229         };
3230 #endif
3231
3232 #ifdef __clang__
3233 #    pragma clang diagnostic pop
3234 #endif
3235
3236         template<typename T>
3237         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
3238
3239             MatchAllOf<T> operator && ( MatcherBase const& other ) const;
3240             MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
3241             MatchNotOf<T> operator ! () const;
3242         };
3243
3244         template<typename ArgT>
3245         struct MatchAllOf : MatcherBase<ArgT> {
3246             bool match( ArgT const& arg ) const override {
3247                 for( auto matcher : m_matchers ) {
3248                     if (!matcher->match(arg))
3249                         return false;
3250                 }
3251                 return true;
3252             }
3253             std::string describe() const override {
3254                 std::string description;
3255                 description.reserve( 4 + m_matchers.size()*32 );
3256                 description += "( ";
3257                 bool first = true;
3258                 for( auto matcher : m_matchers ) {
3259                     if( first )
3260                         first = false;
3261                     else
3262                         description += " and ";
3263                     description += matcher->toString();
3264                 }
3265                 description += " )";
3266                 return description;
3267             }
3268
3269             MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
3270                 m_matchers.push_back( &other );
3271                 return *this;
3272             }
3273
3274             std::vector<MatcherBase<ArgT> const*> m_matchers;
3275         };
3276         template<typename ArgT>
3277         struct MatchAnyOf : MatcherBase<ArgT> {
3278
3279             bool match( ArgT const& arg ) const override {
3280                 for( auto matcher : m_matchers ) {
3281                     if (matcher->match(arg))
3282                         return true;
3283                 }
3284                 return false;
3285             }
3286             std::string describe() const override {
3287                 std::string description;
3288                 description.reserve( 4 + m_matchers.size()*32 );
3289                 description += "( ";
3290                 bool first = true;
3291                 for( auto matcher : m_matchers ) {
3292                     if( first )
3293                         first = false;
3294                     else
3295                         description += " or ";
3296                     description += matcher->toString();
3297                 }
3298                 description += " )";
3299                 return description;
3300             }
3301
3302             MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
3303                 m_matchers.push_back( &other );
3304                 return *this;
3305             }
3306
3307             std::vector<MatcherBase<ArgT> const*> m_matchers;
3308         };
3309
3310         template<typename ArgT>
3311         struct MatchNotOf : MatcherBase<ArgT> {
3312
3313             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
3314
3315             bool match( ArgT const& arg ) const override {
3316                 return !m_underlyingMatcher.match( arg );
3317             }
3318
3319             std::string describe() const override {
3320                 return "not " + m_underlyingMatcher.toString();
3321             }
3322             MatcherBase<ArgT> const& m_underlyingMatcher;
3323         };
3324
3325         template<typename T>
3326         MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
3327             return MatchAllOf<T>() && *this && other;
3328         }
3329         template<typename T>
3330         MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
3331             return MatchAnyOf<T>() || *this || other;
3332         }
3333         template<typename T>
3334         MatchNotOf<T> MatcherBase<T>::operator ! () const {
3335             return MatchNotOf<T>( *this );
3336         }
3337
3338     } // namespace Impl
3339
3340 } // namespace Matchers
3341
3342 using namespace Matchers;
3343 using Matchers::Impl::MatcherBase;
3344
3345 } // namespace Catch
3346
3347 // end catch_matchers.h
3348 // start catch_matchers_exception.hpp
3349
3350 namespace Catch {
3351 namespace Matchers {
3352 namespace Exception {
3353
3354 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
3355     std::string m_message;
3356 public:
3357
3358     ExceptionMessageMatcher(std::string const& message):
3359         m_message(message)
3360     {}
3361
3362     bool match(std::exception const& ex) const override;
3363
3364     std::string describe() const override;
3365 };
3366
3367 } // namespace Exception
3368
3369 Exception::ExceptionMessageMatcher Message(std::string const& message);
3370
3371 } // namespace Matchers
3372 } // namespace Catch
3373
3374 // end catch_matchers_exception.hpp
3375 // start catch_matchers_floating.h
3376
3377 namespace Catch {
3378 namespace Matchers {
3379
3380     namespace Floating {
3381
3382         enum class FloatingPointKind : uint8_t;
3383
3384         struct WithinAbsMatcher : MatcherBase<double> {
3385             WithinAbsMatcher(double target, double margin);
3386             bool match(double const& matchee) const override;
3387             std::string describe() const override;
3388         private:
3389             double m_target;
3390             double m_margin;
3391         };
3392
3393         struct WithinUlpsMatcher : MatcherBase<double> {
3394             WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
3395             bool match(double const& matchee) const override;
3396             std::string describe() const override;
3397         private:
3398             double m_target;
3399             uint64_t m_ulps;
3400             FloatingPointKind m_type;
3401         };
3402
3403         // Given IEEE-754 format for floats and doubles, we can assume
3404         // that float -> double promotion is lossless. Given this, we can
3405         // assume that if we do the standard relative comparison of
3406         // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
3407         // the same result if we do this for floats, as if we do this for
3408         // doubles that were promoted from floats.
3409         struct WithinRelMatcher : MatcherBase<double> {
3410             WithinRelMatcher(double target, double epsilon);
3411             bool match(double const& matchee) const override;
3412             std::string describe() const override;
3413         private:
3414             double m_target;
3415             double m_epsilon;
3416         };
3417
3418     } // namespace Floating
3419
3420     // The following functions create the actual matcher objects.
3421     // This allows the types to be inferred
3422     Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
3423     Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
3424     Floating::WithinAbsMatcher WithinAbs(double target, double margin);
3425     Floating::WithinRelMatcher WithinRel(double target, double eps);
3426     // defaults epsilon to 100*numeric_limits<double>::epsilon()
3427     Floating::WithinRelMatcher WithinRel(double target);
3428     Floating::WithinRelMatcher WithinRel(float target, float eps);
3429     // defaults epsilon to 100*numeric_limits<float>::epsilon()
3430     Floating::WithinRelMatcher WithinRel(float target);
3431
3432 } // namespace Matchers
3433 } // namespace Catch
3434
3435 // end catch_matchers_floating.h
3436 // start catch_matchers_generic.hpp
3437
3438 #include <functional>
3439 #include <string>
3440
3441 namespace Catch {
3442 namespace Matchers {
3443 namespace Generic {
3444
3445 namespace Detail {
3446     std::string finalizeDescription(const std::string& desc);
3447 }
3448
3449 template <typename T>
3450 class PredicateMatcher : public MatcherBase<T> {
3451     std::function<bool(T const&)> m_predicate;
3452     std::string m_description;
3453 public:
3454
3455     PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
3456         :m_predicate(std::move(elem)),
3457         m_description(Detail::finalizeDescription(descr))
3458     {}
3459
3460     bool match( T const& item ) const override {
3461         return m_predicate(item);
3462     }
3463
3464     std::string describe() const override {
3465         return m_description;
3466     }
3467 };
3468
3469 } // namespace Generic
3470
3471     // The following functions create the actual matcher objects.
3472     // The user has to explicitly specify type to the function, because
3473     // inferring std::function<bool(T const&)> is hard (but possible) and
3474     // requires a lot of TMP.
3475     template<typename T>
3476     Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
3477         return Generic::PredicateMatcher<T>(predicate, description);
3478     }
3479
3480 } // namespace Matchers
3481 } // namespace Catch
3482
3483 // end catch_matchers_generic.hpp
3484 // start catch_matchers_string.h
3485
3486 #include <string>
3487
3488 namespace Catch {
3489 namespace Matchers {
3490
3491     namespace StdString {
3492
3493         struct CasedString
3494         {
3495             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
3496             std::string adjustString( std::string const& str ) const;
3497             std::string caseSensitivitySuffix() const;
3498
3499             CaseSensitive::Choice m_caseSensitivity;
3500             std::string m_str;
3501         };
3502
3503         struct StringMatcherBase : MatcherBase<std::string> {
3504             StringMatcherBase( std::string const& operation, CasedString const& comparator );
3505             std::string describe() const override;
3506
3507             CasedString m_comparator;
3508             std::string m_operation;
3509         };
3510
3511         struct EqualsMatcher : StringMatcherBase {
3512             EqualsMatcher( CasedString const& comparator );
3513             bool match( std::string const& source ) const override;
3514         };
3515         struct ContainsMatcher : StringMatcherBase {
3516             ContainsMatcher( CasedString const& comparator );
3517             bool match( std::string const& source ) const override;
3518         };
3519         struct StartsWithMatcher : StringMatcherBase {
3520             StartsWithMatcher( CasedString const& comparator );
3521             bool match( std::string const& source ) const override;
3522         };
3523         struct EndsWithMatcher : StringMatcherBase {
3524             EndsWithMatcher( CasedString const& comparator );
3525             bool match( std::string const& source ) const override;
3526         };
3527
3528         struct RegexMatcher : MatcherBase<std::string> {
3529             RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
3530             bool match( std::string const& matchee ) const override;
3531             std::string describe() const override;
3532
3533         private:
3534             std::string m_regex;
3535             CaseSensitive::Choice m_caseSensitivity;
3536         };
3537
3538     } // namespace StdString
3539
3540     // The following functions create the actual matcher objects.
3541     // This allows the types to be inferred
3542
3543     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3544     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3545     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3546     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3547     StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3548
3549 } // namespace Matchers
3550 } // namespace Catch
3551
3552 // end catch_matchers_string.h
3553 // start catch_matchers_vector.h
3554
3555 #include <algorithm>
3556
3557 namespace Catch {
3558 namespace Matchers {
3559
3560     namespace Vector {
3561         template<typename T>
3562         struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
3563
3564             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3565
3566             bool match(std::vector<T> const &v) const override {
3567                 for (auto const& el : v) {
3568                     if (el == m_comparator) {
3569                         return true;
3570                     }
3571                 }
3572                 return false;
3573             }
3574
3575             std::string describe() const override {
3576                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3577             }
3578
3579             T const& m_comparator;
3580         };
3581
3582         template<typename T>
3583         struct ContainsMatcher : MatcherBase<std::vector<T>> {
3584
3585             ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3586
3587             bool match(std::vector<T> const &v) const override {
3588                 // !TBD: see note in EqualsMatcher
3589                 if (m_comparator.size() > v.size())
3590                     return false;
3591                 for (auto const& comparator : m_comparator) {
3592                     auto present = false;
3593                     for (const auto& el : v) {
3594                         if (el == comparator) {
3595                             present = true;
3596                             break;
3597                         }
3598                     }
3599                     if (!present) {
3600                         return false;
3601                     }
3602                 }
3603                 return true;
3604             }
3605             std::string describe() const override {
3606                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3607             }
3608
3609             std::vector<T> const& m_comparator;
3610         };
3611
3612         template<typename T>
3613         struct EqualsMatcher : MatcherBase<std::vector<T>> {
3614
3615             EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3616
3617             bool match(std::vector<T> const &v) const override {
3618                 // !TBD: This currently works if all elements can be compared using !=
3619                 // - a more general approach would be via a compare template that defaults
3620                 // to using !=. but could be specialised for, e.g. std::vector<T> etc
3621                 // - then just call that directly
3622                 if (m_comparator.size() != v.size())
3623                     return false;
3624                 for (std::size_t i = 0; i < v.size(); ++i)
3625                     if (m_comparator[i] != v[i])
3626                         return false;
3627                 return true;
3628             }
3629             std::string describe() const override {
3630                 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
3631             }
3632             std::vector<T> const& m_comparator;
3633         };
3634
3635         template<typename T>
3636         struct ApproxMatcher : MatcherBase<std::vector<T>> {
3637
3638             ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
3639
3640             bool match(std::vector<T> const &v) const override {
3641                 if (m_comparator.size() != v.size())
3642                     return false;
3643                 for (std::size_t i = 0; i < v.size(); ++i)
3644                     if (m_comparator[i] != approx(v[i]))
3645                         return false;
3646                 return true;
3647             }
3648             std::string describe() const override {
3649                 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
3650             }
3651             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3652             ApproxMatcher& epsilon( T const& newEpsilon ) {
3653                 approx.epsilon(newEpsilon);
3654                 return *this;
3655             }
3656             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3657             ApproxMatcher& margin( T const& newMargin ) {
3658                 approx.margin(newMargin);
3659                 return *this;
3660             }
3661             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3662             ApproxMatcher& scale( T const& newScale ) {
3663                 approx.scale(newScale);
3664                 return *this;
3665             }
3666
3667             std::vector<T> const& m_comparator;
3668             mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
3669         };
3670
3671         template<typename T>
3672         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
3673             UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
3674             bool match(std::vector<T> const& vec) const override {
3675                 // Note: This is a reimplementation of std::is_permutation,
3676                 //       because I don't want to include <algorithm> inside the common path
3677                 if (m_target.size() != vec.size()) {
3678                     return false;
3679                 }
3680                 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
3681             }
3682
3683             std::string describe() const override {
3684                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
3685             }
3686         private:
3687             std::vector<T> const& m_target;
3688         };
3689
3690     } // namespace Vector
3691
3692     // The following functions create the actual matcher objects.
3693     // This allows the types to be inferred
3694
3695     template<typename T>
3696     Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
3697         return Vector::ContainsMatcher<T>( comparator );
3698     }
3699
3700     template<typename T>
3701     Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
3702         return Vector::ContainsElementMatcher<T>( comparator );
3703     }
3704
3705     template<typename T>
3706     Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
3707         return Vector::EqualsMatcher<T>( comparator );
3708     }
3709
3710     template<typename T>
3711     Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
3712         return Vector::ApproxMatcher<T>( comparator );
3713     }
3714
3715     template<typename T>
3716     Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
3717         return Vector::UnorderedEqualsMatcher<T>(target);
3718     }
3719
3720 } // namespace Matchers
3721 } // namespace Catch
3722
3723 // end catch_matchers_vector.h
3724 namespace Catch {
3725
3726     template<typename ArgT, typename MatcherT>
3727     class MatchExpr : public ITransientExpression {
3728         ArgT const& m_arg;
3729         MatcherT m_matcher;
3730         StringRef m_matcherString;
3731     public:
3732         MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
3733         :   ITransientExpression{ true, matcher.match( arg ) },
3734             m_arg( arg ),
3735             m_matcher( matcher ),
3736             m_matcherString( matcherString )
3737         {}
3738
3739         void streamReconstructedExpression( std::ostream &os ) const override {
3740             auto matcherAsString = m_matcher.toString();
3741             os << Catch::Detail::stringify( m_arg ) << ' ';
3742             if( matcherAsString == Detail::unprintableString )
3743                 os << m_matcherString;
3744             else
3745                 os << matcherAsString;
3746         }
3747     };
3748
3749     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
3750
3751     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
3752
3753     template<typename ArgT, typename MatcherT>
3754     auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
3755         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
3756     }
3757
3758 } // namespace Catch
3759
3760 ///////////////////////////////////////////////////////////////////////////////
3761 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
3762     do { \
3763         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3764         INTERNAL_CATCH_TRY { \
3765             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
3766         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
3767         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3768     } while( false )
3769
3770 ///////////////////////////////////////////////////////////////////////////////
3771 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
3772     do { \
3773         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3774         if( catchAssertionHandler.allowThrows() ) \
3775             try { \
3776                 static_cast<void>(__VA_ARGS__ ); \
3777                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3778             } \
3779             catch( exceptionType const& ex ) { \
3780                 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
3781             } \
3782             catch( ... ) { \
3783                 catchAssertionHandler.handleUnexpectedInflightException(); \
3784             } \
3785         else \
3786             catchAssertionHandler.handleThrowingCallSkipped(); \
3787         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3788     } while( false )
3789
3790 // end catch_capture_matchers.h
3791 #endif
3792 // start catch_generators.hpp
3793
3794 // start catch_interfaces_generatortracker.h
3795
3796
3797 #include <memory>
3798
3799 namespace Catch {
3800
3801     namespace Generators {
3802         class GeneratorUntypedBase {
3803         public:
3804             GeneratorUntypedBase() = default;
3805             virtual ~GeneratorUntypedBase();
3806             // Attempts to move the generator to the next element
3807              //
3808              // Returns true iff the move succeeded (and a valid element
3809              // can be retrieved).
3810             virtual bool next() = 0;
3811         };
3812         using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
3813
3814     } // namespace Generators
3815
3816     struct IGeneratorTracker {
3817         virtual ~IGeneratorTracker();
3818         virtual auto hasGenerator() const -> bool = 0;
3819         virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3820         virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3821     };
3822
3823 } // namespace Catch
3824
3825 // end catch_interfaces_generatortracker.h
3826 // start catch_enforce.h
3827
3828 #include <exception>
3829
3830 namespace Catch {
3831 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3832     template <typename Ex>
3833     [[noreturn]]
3834     void throw_exception(Ex const& e) {
3835         throw e;
3836     }
3837 #else // ^^ Exceptions are enabled //  Exceptions are disabled vv
3838     [[noreturn]]
3839     void throw_exception(std::exception const& e);
3840 #endif
3841
3842     [[noreturn]]
3843     void throw_logic_error(std::string const& msg);
3844     [[noreturn]]
3845     void throw_domain_error(std::string const& msg);
3846     [[noreturn]]
3847     void throw_runtime_error(std::string const& msg);
3848
3849 } // namespace Catch;
3850
3851 #define CATCH_MAKE_MSG(...) \
3852     (Catch::ReusableStringStream() << __VA_ARGS__).str()
3853
3854 #define CATCH_INTERNAL_ERROR(...) \
3855     Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
3856
3857 #define CATCH_ERROR(...) \
3858     Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3859
3860 #define CATCH_RUNTIME_ERROR(...) \
3861     Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3862
3863 #define CATCH_ENFORCE( condition, ... ) \
3864     do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
3865
3866 // end catch_enforce.h
3867 #include <memory>
3868 #include <vector>
3869 #include <cassert>
3870
3871 #include <utility>
3872 #include <exception>
3873
3874 namespace Catch {
3875
3876 class GeneratorException : public std::exception {
3877     const char* const m_msg = "";
3878
3879 public:
3880     GeneratorException(const char* msg):
3881         m_msg(msg)
3882     {}
3883
3884     const char* what() const noexcept override final;
3885 };
3886
3887 namespace Generators {
3888
3889     // !TBD move this into its own location?
3890     namespace pf{
3891         template<typename T, typename... Args>
3892         std::unique_ptr<T> make_unique( Args&&... args ) {
3893             return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3894         }
3895     }
3896
3897     template<typename T>
3898     struct IGenerator : GeneratorUntypedBase {
3899         virtual ~IGenerator() = default;
3900
3901         // Returns the current element of the generator
3902         //
3903         // \Precondition The generator is either freshly constructed,
3904         // or the last call to `next()` returned true
3905         virtual T const& get() const = 0;
3906         using type = T;
3907     };
3908
3909     template<typename T>
3910     class SingleValueGenerator final : public IGenerator<T> {
3911         T m_value;
3912     public:
3913         SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
3914
3915         T const& get() const override {
3916             return m_value;
3917         }
3918         bool next() override {
3919             return false;
3920         }
3921     };
3922
3923     template<typename T>
3924     class FixedValuesGenerator final : public IGenerator<T> {
3925         static_assert(!std::is_same<T, bool>::value,
3926             "FixedValuesGenerator does not support bools because of std::vector<bool>"
3927             "specialization, use SingleValue Generator instead.");
3928         std::vector<T> m_values;
3929         size_t m_idx = 0;
3930     public:
3931         FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3932
3933         T const& get() const override {
3934             return m_values[m_idx];
3935         }
3936         bool next() override {
3937             ++m_idx;
3938             return m_idx < m_values.size();
3939         }
3940     };
3941
3942     template <typename T>
3943     class GeneratorWrapper final {
3944         std::unique_ptr<IGenerator<T>> m_generator;
3945     public:
3946         GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
3947             m_generator(std::move(generator))
3948         {}
3949         T const& get() const {
3950             return m_generator->get();
3951         }
3952         bool next() {
3953             return m_generator->next();
3954         }
3955     };
3956
3957     template <typename T>
3958     GeneratorWrapper<T> value(T&& value) {
3959         return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
3960     }
3961     template <typename T>
3962     GeneratorWrapper<T> values(std::initializer_list<T> values) {
3963         return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
3964     }
3965
3966     template<typename T>
3967     class Generators : public IGenerator<T> {
3968         std::vector<GeneratorWrapper<T>> m_generators;
3969         size_t m_current = 0;
3970
3971         void populate(GeneratorWrapper<T>&& generator) {
3972             m_generators.emplace_back(std::move(generator));
3973         }
3974         void populate(T&& val) {
3975             m_generators.emplace_back(value(std::forward<T>(val)));
3976         }
3977         template<typename U>
3978         void populate(U&& val) {
3979             populate(T(std::forward<U>(val)));
3980         }
3981         template<typename U, typename... Gs>
3982         void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
3983             populate(std::forward<U>(valueOrGenerator));
3984             populate(std::forward<Gs>(moreGenerators)...);
3985         }
3986
3987     public:
3988         template <typename... Gs>
3989         Generators(Gs &&... moreGenerators) {
3990             m_generators.reserve(sizeof...(Gs));
3991             populate(std::forward<Gs>(moreGenerators)...);
3992         }
3993
3994         T const& get() const override {
3995             return m_generators[m_current].get();
3996         }
3997
3998         bool next() override {
3999             if (m_current >= m_generators.size()) {
4000                 return false;
4001             }
4002             const bool current_status = m_generators[m_current].next();
4003             if (!current_status) {
4004                 ++m_current;
4005             }
4006             return m_current < m_generators.size();
4007         }
4008     };
4009
4010     template<typename... Ts>
4011     GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
4012         return values<std::tuple<Ts...>>( tuples );
4013     }
4014
4015     // Tag type to signal that a generator sequence should convert arguments to a specific type
4016     template <typename T>
4017     struct as {};
4018
4019     template<typename T, typename... Gs>
4020     auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
4021         return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
4022     }
4023     template<typename T>
4024     auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
4025         return Generators<T>(std::move(generator));
4026     }
4027     template<typename T, typename... Gs>
4028     auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
4029         return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
4030     }
4031     template<typename T, typename U, typename... Gs>
4032     auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
4033         return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
4034     }
4035
4036     auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
4037
4038     template<typename L>
4039     // Note: The type after -> is weird, because VS2015 cannot parse
4040     //       the expression used in the typedef inside, when it is in
4041     //       return type. Yeah.
4042     auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
4043         using UnderlyingType = typename decltype(generatorExpression())::type;
4044
4045         IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
4046         if (!tracker.hasGenerator()) {
4047             tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
4048         }
4049
4050         auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
4051         return generator.get();
4052     }
4053
4054 } // namespace Generators
4055 } // namespace Catch
4056
4057 #define GENERATE( ... ) \
4058     Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4059 #define GENERATE_COPY( ... ) \
4060     Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4061 #define GENERATE_REF( ... ) \
4062     Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4063
4064 // end catch_generators.hpp
4065 // start catch_generators_generic.hpp
4066
4067 namespace Catch {
4068 namespace Generators {
4069
4070     template <typename T>
4071     class TakeGenerator : public IGenerator<T> {
4072         GeneratorWrapper<T> m_generator;
4073         size_t m_returned = 0;
4074         size_t m_target;
4075     public:
4076         TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
4077             m_generator(std::move(generator)),
4078             m_target(target)
4079         {
4080             assert(target != 0 && "Empty generators are not allowed");
4081         }
4082         T const& get() const override {
4083             return m_generator.get();
4084         }
4085         bool next() override {
4086             ++m_returned;
4087             if (m_returned >= m_target) {
4088                 return false;
4089             }
4090
4091             const auto success = m_generator.next();
4092             // If the underlying generator does not contain enough values
4093             // then we cut short as well
4094             if (!success) {
4095                 m_returned = m_target;
4096             }
4097             return success;
4098         }
4099     };
4100
4101     template <typename T>
4102     GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
4103         return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
4104     }
4105
4106     template <typename T, typename Predicate>
4107     class FilterGenerator : public IGenerator<T> {
4108         GeneratorWrapper<T> m_generator;
4109         Predicate m_predicate;
4110     public:
4111         template <typename P = Predicate>
4112         FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
4113             m_generator(std::move(generator)),
4114             m_predicate(std::forward<P>(pred))
4115         {
4116             if (!m_predicate(m_generator.get())) {
4117                 // It might happen that there are no values that pass the
4118                 // filter. In that case we throw an exception.
4119                 auto has_initial_value = next();
4120                 if (!has_initial_value) {
4121                     Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
4122                 }
4123             }
4124         }
4125
4126         T const& get() const override {
4127             return m_generator.get();
4128         }
4129
4130         bool next() override {
4131             bool success = m_generator.next();
4132             if (!success) {
4133                 return false;
4134             }
4135             while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
4136             return success;
4137         }
4138     };
4139
4140     template <typename T, typename Predicate>
4141     GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
4142         return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
4143     }
4144
4145     template <typename T>
4146     class RepeatGenerator : public IGenerator<T> {
4147         static_assert(!std::is_same<T, bool>::value,
4148             "RepeatGenerator currently does not support bools"
4149             "because of std::vector<bool> specialization");
4150         GeneratorWrapper<T> m_generator;
4151         mutable std::vector<T> m_returned;
4152         size_t m_target_repeats;
4153         size_t m_current_repeat = 0;
4154         size_t m_repeat_index = 0;
4155     public:
4156         RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
4157             m_generator(std::move(generator)),
4158             m_target_repeats(repeats)
4159         {
4160             assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
4161         }
4162
4163         T const& get() const override {
4164             if (m_current_repeat == 0) {
4165                 m_returned.push_back(m_generator.get());
4166                 return m_returned.back();
4167             }
4168             return m_returned[m_repeat_index];
4169         }
4170
4171         bool next() override {
4172             // There are 2 basic cases:
4173             // 1) We are still reading the generator
4174             // 2) We are reading our own cache
4175
4176             // In the first case, we need to poke the underlying generator.
4177             // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
4178             if (m_current_repeat == 0) {
4179                 const auto success = m_generator.next();
4180                 if (!success) {
4181                     ++m_current_repeat;
4182                 }
4183                 return m_current_repeat < m_target_repeats;
4184             }
4185
4186             // In the second case, we need to move indices forward and check that we haven't run up against the end
4187             ++m_repeat_index;
4188             if (m_repeat_index == m_returned.size()) {
4189                 m_repeat_index = 0;
4190                 ++m_current_repeat;
4191             }
4192             return m_current_repeat < m_target_repeats;
4193         }
4194     };
4195
4196     template <typename T>
4197     GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
4198         return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
4199     }
4200
4201     template <typename T, typename U, typename Func>
4202     class MapGenerator : public IGenerator<T> {
4203         // TBD: provide static assert for mapping function, for friendly error message
4204         GeneratorWrapper<U> m_generator;
4205         Func m_function;
4206         // To avoid returning dangling reference, we have to save the values
4207         T m_cache;
4208     public:
4209         template <typename F2 = Func>
4210         MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
4211             m_generator(std::move(generator)),
4212             m_function(std::forward<F2>(function)),
4213             m_cache(m_function(m_generator.get()))
4214         {}
4215
4216         T const& get() const override {
4217             return m_cache;
4218         }
4219         bool next() override {
4220             const auto success = m_generator.next();
4221             if (success) {
4222                 m_cache = m_function(m_generator.get());
4223             }
4224             return success;
4225         }
4226     };
4227
4228     template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
4229     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4230         return GeneratorWrapper<T>(
4231             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4232         );
4233     }
4234
4235     template <typename T, typename U, typename Func>
4236     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4237         return GeneratorWrapper<T>(
4238             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4239         );
4240     }
4241
4242     template <typename T>
4243     class ChunkGenerator final : public IGenerator<std::vector<T>> {
4244         std::vector<T> m_chunk;
4245         size_t m_chunk_size;
4246         GeneratorWrapper<T> m_generator;
4247         bool m_used_up = false;
4248     public:
4249         ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
4250             m_chunk_size(size), m_generator(std::move(generator))
4251         {
4252             m_chunk.reserve(m_chunk_size);
4253             if (m_chunk_size != 0) {
4254                 m_chunk.push_back(m_generator.get());
4255                 for (size_t i = 1; i < m_chunk_size; ++i) {
4256                     if (!m_generator.next()) {
4257                         Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
4258                     }
4259                     m_chunk.push_back(m_generator.get());
4260                 }
4261             }
4262         }
4263         std::vector<T> const& get() const override {
4264             return m_chunk;
4265         }
4266         bool next() override {
4267             m_chunk.clear();
4268             for (size_t idx = 0; idx < m_chunk_size; ++idx) {
4269                 if (!m_generator.next()) {
4270                     return false;
4271                 }
4272                 m_chunk.push_back(m_generator.get());
4273             }
4274             return true;
4275         }
4276     };
4277
4278     template <typename T>
4279     GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
4280         return GeneratorWrapper<std::vector<T>>(
4281             pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
4282         );
4283     }
4284
4285 } // namespace Generators
4286 } // namespace Catch
4287
4288 // end catch_generators_generic.hpp
4289 // start catch_generators_specific.hpp
4290
4291 // start catch_context.h
4292
4293 #include <memory>
4294
4295 namespace Catch {
4296
4297     struct IResultCapture;
4298     struct IRunner;
4299     struct IConfig;
4300     struct IMutableContext;
4301
4302     using IConfigPtr = std::shared_ptr<IConfig const>;
4303
4304     struct IContext
4305     {
4306         virtual ~IContext();
4307
4308         virtual IResultCapture* getResultCapture() = 0;
4309         virtual IRunner* getRunner() = 0;
4310         virtual IConfigPtr const& getConfig() const = 0;
4311     };
4312
4313     struct IMutableContext : IContext
4314     {
4315         virtual ~IMutableContext();
4316         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
4317         virtual void setRunner( IRunner* runner ) = 0;
4318         virtual void setConfig( IConfigPtr const& config ) = 0;
4319
4320     private:
4321         static IMutableContext *currentContext;
4322         friend IMutableContext& getCurrentMutableContext();
4323         friend void cleanUpContext();
4324         static void createContext();
4325     };
4326
4327     inline IMutableContext& getCurrentMutableContext()
4328     {
4329         if( !IMutableContext::currentContext )
4330             IMutableContext::createContext();
4331         // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
4332         return *IMutableContext::currentContext;
4333     }
4334
4335     inline IContext& getCurrentContext()
4336     {
4337         return getCurrentMutableContext();
4338     }
4339
4340     void cleanUpContext();
4341
4342     class SimplePcg32;
4343     SimplePcg32& rng();
4344 }
4345
4346 // end catch_context.h
4347 // start catch_interfaces_config.h
4348
4349 // start catch_option.hpp
4350
4351 namespace Catch {
4352
4353     // An optional type
4354     template<typename T>
4355     class Option {
4356     public:
4357         Option() : nullableValue( nullptr ) {}
4358         Option( T const& _value )
4359         : nullableValue( new( storage ) T( _value ) )
4360         {}
4361         Option( Option const& _other )
4362         : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4363         {}
4364
4365         ~Option() {
4366             reset();
4367         }
4368
4369         Option& operator= ( Option const& _other ) {
4370             if( &_other != this ) {
4371                 reset();
4372                 if( _other )
4373                     nullableValue = new( storage ) T( *_other );
4374             }
4375             return *this;
4376         }
4377         Option& operator = ( T const& _value ) {
4378             reset();
4379             nullableValue = new( storage ) T( _value );
4380             return *this;
4381         }
4382
4383         void reset() {
4384             if( nullableValue )
4385                 nullableValue->~T();
4386             nullableValue = nullptr;
4387         }
4388
4389         T& operator*() { return *nullableValue; }
4390         T const& operator*() const { return *nullableValue; }
4391         T* operator->() { return nullableValue; }
4392         const T* operator->() const { return nullableValue; }
4393
4394         T valueOr( T const& defaultValue ) const {
4395             return nullableValue ? *nullableValue : defaultValue;
4396         }
4397
4398         bool some() const { return nullableValue != nullptr; }
4399         bool none() const { return nullableValue == nullptr; }
4400
4401         bool operator !() const { return nullableValue == nullptr; }
4402         explicit operator bool() const {
4403             return some();
4404         }
4405
4406     private:
4407         T *nullableValue;
4408         alignas(alignof(T)) char storage[sizeof(T)];
4409     };
4410
4411 } // end namespace Catch
4412
4413 // end catch_option.hpp
4414 #include <iosfwd>
4415 #include <string>
4416 #include <vector>
4417 #include <memory>
4418
4419 namespace Catch {
4420
4421     enum class Verbosity {
4422         Quiet = 0,
4423         Normal,
4424         High
4425     };
4426
4427     struct WarnAbout { enum What {
4428         Nothing = 0x00,
4429         NoAssertions = 0x01,
4430         NoTests = 0x02
4431     }; };
4432
4433     struct ShowDurations { enum OrNot {
4434         DefaultForReporter,
4435         Always,
4436         Never
4437     }; };
4438     struct RunTests { enum InWhatOrder {
4439         InDeclarationOrder,
4440         InLexicographicalOrder,
4441         InRandomOrder
4442     }; };
4443     struct UseColour { enum YesOrNo {
4444         Auto,
4445         Yes,
4446         No
4447     }; };
4448     struct WaitForKeypress { enum When {
4449         Never,
4450         BeforeStart = 1,
4451         BeforeExit = 2,
4452         BeforeStartAndExit = BeforeStart | BeforeExit
4453     }; };
4454
4455     class TestSpec;
4456
4457     struct IConfig : NonCopyable {
4458
4459         virtual ~IConfig();
4460
4461         virtual bool allowThrows() const = 0;
4462         virtual std::ostream& stream() const = 0;
4463         virtual std::string name() const = 0;
4464         virtual bool includeSuccessfulResults() const = 0;
4465         virtual bool shouldDebugBreak() const = 0;
4466         virtual bool warnAboutMissingAssertions() const = 0;
4467         virtual bool warnAboutNoTests() const = 0;
4468         virtual int abortAfter() const = 0;
4469         virtual bool showInvisibles() const = 0;
4470         virtual ShowDurations::OrNot showDurations() const = 0;
4471         virtual TestSpec const& testSpec() const = 0;
4472         virtual bool hasTestFilters() const = 0;
4473         virtual std::vector<std::string> const& getTestsOrTags() const = 0;
4474         virtual RunTests::InWhatOrder runOrder() const = 0;
4475         virtual unsigned int rngSeed() const = 0;
4476         virtual UseColour::YesOrNo useColour() const = 0;
4477         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4478         virtual Verbosity verbosity() const = 0;
4479
4480         virtual bool benchmarkNoAnalysis() const = 0;
4481         virtual int benchmarkSamples() const = 0;
4482         virtual double benchmarkConfidenceInterval() const = 0;
4483         virtual unsigned int benchmarkResamples() const = 0;
4484     };
4485
4486     using IConfigPtr = std::shared_ptr<IConfig const>;
4487 }
4488
4489 // end catch_interfaces_config.h
4490 // start catch_random_number_generator.h
4491
4492 #include <cstdint>
4493
4494 namespace Catch {
4495
4496     // This is a simple implementation of C++11 Uniform Random Number
4497     // Generator. It does not provide all operators, because Catch2
4498     // does not use it, but it should behave as expected inside stdlib's
4499     // distributions.
4500     // The implementation is based on the PCG family (http://pcg-random.org)
4501     class SimplePcg32 {
4502         using state_type = std::uint64_t;
4503     public:
4504         using result_type = std::uint32_t;
4505         static constexpr result_type (min)() {
4506             return 0;
4507         }
4508         static constexpr result_type (max)() {
4509             return static_cast<result_type>(-1);
4510         }
4511
4512         // Provide some default initial state for the default constructor
4513         SimplePcg32():SimplePcg32(0xed743cc4U) {}
4514
4515         explicit SimplePcg32(result_type seed_);
4516
4517         void seed(result_type seed_);
4518         void discard(uint64_t skip);
4519
4520         result_type operator()();
4521
4522     private:
4523         friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4524         friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4525
4526         // In theory we also need operator<< and operator>>
4527         // In practice we do not use them, so we will skip them for now
4528
4529         std::uint64_t m_state;
4530         // This part of the state determines which "stream" of the numbers
4531         // is chosen -- we take it as a constant for Catch2, so we only
4532         // need to deal with seeding the main state.
4533         // Picked by reading 8 bytes from `/dev/random` :-)
4534         static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
4535     };
4536
4537 } // end namespace Catch
4538
4539 // end catch_random_number_generator.h
4540 #include <random>
4541
4542 namespace Catch {
4543 namespace Generators {
4544
4545 template <typename Float>
4546 class RandomFloatingGenerator final : public IGenerator<Float> {
4547     Catch::SimplePcg32& m_rng;
4548     std::uniform_real_distribution<Float> m_dist;
4549     Float m_current_number;
4550 public:
4551
4552     RandomFloatingGenerator(Float a, Float b):
4553         m_rng(rng()),
4554         m_dist(a, b) {
4555         static_cast<void>(next());
4556     }
4557
4558     Float const& get() const override {
4559         return m_current_number;
4560     }
4561     bool next() override {
4562         m_current_number = m_dist(m_rng);
4563         return true;
4564     }
4565 };
4566
4567 template <typename Integer>
4568 class RandomIntegerGenerator final : public IGenerator<Integer> {
4569     Catch::SimplePcg32& m_rng;
4570     std::uniform_int_distribution<Integer> m_dist;
4571     Integer m_current_number;
4572 public:
4573
4574     RandomIntegerGenerator(Integer a, Integer b):
4575         m_rng(rng()),
4576         m_dist(a, b) {
4577         static_cast<void>(next());
4578     }
4579
4580     Integer const& get() const override {
4581         return m_current_number;
4582     }
4583     bool next() override {
4584         m_current_number = m_dist(m_rng);
4585         return true;
4586     }
4587 };
4588
4589 // TODO: Ideally this would be also constrained against the various char types,
4590 //       but I don't expect users to run into that in practice.
4591 template <typename T>
4592 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
4593 GeneratorWrapper<T>>::type
4594 random(T a, T b) {
4595     return GeneratorWrapper<T>(
4596         pf::make_unique<RandomIntegerGenerator<T>>(a, b)
4597     );
4598 }
4599
4600 template <typename T>
4601 typename std::enable_if<std::is_floating_point<T>::value,
4602 GeneratorWrapper<T>>::type
4603 random(T a, T b) {
4604     return GeneratorWrapper<T>(
4605         pf::make_unique<RandomFloatingGenerator<T>>(a, b)
4606     );
4607 }
4608
4609 template <typename T>
4610 class RangeGenerator final : public IGenerator<T> {
4611     T m_current;
4612     T m_end;
4613     T m_step;
4614     bool m_positive;
4615
4616 public:
4617     RangeGenerator(T const& start, T const& end, T const& step):
4618         m_current(start),
4619         m_end(end),
4620         m_step(step),
4621         m_positive(m_step > T(0))
4622     {
4623         assert(m_current != m_end && "Range start and end cannot be equal");
4624         assert(m_step != T(0) && "Step size cannot be zero");
4625         assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
4626     }
4627
4628     RangeGenerator(T const& start, T const& end):
4629         RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
4630     {}
4631
4632     T const& get() const override {
4633         return m_current;
4634     }
4635
4636     bool next() override {
4637         m_current += m_step;
4638         return (m_positive) ? (m_current < m_end) : (m_current > m_end);
4639     }
4640 };
4641
4642 template <typename T>
4643 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
4644     static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
4645     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
4646 }
4647
4648 template <typename T>
4649 GeneratorWrapper<T> range(T const& start, T const& end) {
4650     static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4651     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
4652 }
4653
4654 template <typename T>
4655 class IteratorGenerator final : public IGenerator<T> {
4656     static_assert(!std::is_same<T, bool>::value,
4657         "IteratorGenerator currently does not support bools"
4658         "because of std::vector<bool> specialization");
4659
4660     std::vector<T> m_elems;
4661     size_t m_current = 0;
4662 public:
4663     template <typename InputIterator, typename InputSentinel>
4664     IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
4665         if (m_elems.empty()) {
4666             Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
4667         }
4668     }
4669
4670     T const& get() const override {
4671         return m_elems[m_current];
4672     }
4673
4674     bool next() override {
4675         ++m_current;
4676         return m_current != m_elems.size();
4677     }
4678 };
4679
4680 template <typename InputIterator,
4681           typename InputSentinel,
4682           typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
4683 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
4684     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
4685 }
4686
4687 template <typename Container,
4688           typename ResultType = typename Container::value_type>
4689 GeneratorWrapper<ResultType> from_range(Container const& cnt) {
4690     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
4691 }
4692
4693 } // namespace Generators
4694 } // namespace Catch
4695
4696 // end catch_generators_specific.hpp
4697
4698 // These files are included here so the single_include script doesn't put them
4699 // in the conditionally compiled sections
4700 // start catch_test_case_info.h
4701
4702 #include <string>
4703 #include <vector>
4704 #include <memory>
4705
4706 #ifdef __clang__
4707 #pragma clang diagnostic push
4708 #pragma clang diagnostic ignored "-Wpadded"
4709 #endif
4710
4711 namespace Catch {
4712
4713     struct ITestInvoker;
4714
4715     struct TestCaseInfo {
4716         enum SpecialProperties{
4717             None = 0,
4718             IsHidden = 1 << 1,
4719             ShouldFail = 1 << 2,
4720             MayFail = 1 << 3,
4721             Throws = 1 << 4,
4722             NonPortable = 1 << 5,
4723             Benchmark = 1 << 6
4724         };
4725
4726         TestCaseInfo(   std::string const& _name,
4727                         std::string const& _className,
4728                         std::string const& _description,
4729                         std::vector<std::string> const& _tags,
4730                         SourceLineInfo const& _lineInfo );
4731
4732         friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
4733
4734         bool isHidden() const;
4735         bool throws() const;
4736         bool okToFail() const;
4737         bool expectedToFail() const;
4738
4739         std::string tagsAsString() const;
4740
4741         std::string name;
4742         std::string className;
4743         std::string description;
4744         std::vector<std::string> tags;
4745         std::vector<std::string> lcaseTags;
4746         SourceLineInfo lineInfo;
4747         SpecialProperties properties;
4748     };
4749
4750     class TestCase : public TestCaseInfo {
4751     public:
4752
4753         TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
4754
4755         TestCase withName( std::string const& _newName ) const;
4756
4757         void invoke() const;
4758
4759         TestCaseInfo const& getTestCaseInfo() const;
4760
4761         bool operator == ( TestCase const& other ) const;
4762         bool operator < ( TestCase const& other ) const;
4763
4764     private:
4765         std::shared_ptr<ITestInvoker> test;
4766     };
4767
4768     TestCase makeTestCase(  ITestInvoker* testCase,
4769                             std::string const& className,
4770                             NameAndTags const& nameAndTags,
4771                             SourceLineInfo const& lineInfo );
4772 }
4773
4774 #ifdef __clang__
4775 #pragma clang diagnostic pop
4776 #endif
4777
4778 // end catch_test_case_info.h
4779 // start catch_interfaces_runner.h
4780
4781 namespace Catch {
4782
4783     struct IRunner {
4784         virtual ~IRunner();
4785         virtual bool aborting() const = 0;
4786     };
4787 }
4788
4789 // end catch_interfaces_runner.h
4790
4791 #ifdef __OBJC__
4792 // start catch_objc.hpp
4793
4794 #import <objc/runtime.h>
4795
4796 #include <string>
4797
4798 // NB. Any general catch headers included here must be included
4799 // in catch.hpp first to make sure they are included by the single
4800 // header for non obj-usage
4801
4802 ///////////////////////////////////////////////////////////////////////////////
4803 // This protocol is really only here for (self) documenting purposes, since
4804 // all its methods are optional.
4805 @protocol OcFixture
4806
4807 @optional
4808
4809 -(void) setUp;
4810 -(void) tearDown;
4811
4812 @end
4813
4814 namespace Catch {
4815
4816     class OcMethod : public ITestInvoker {
4817
4818     public:
4819         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
4820
4821         virtual void invoke() const {
4822             id obj = [[m_cls alloc] init];
4823
4824             performOptionalSelector( obj, @selector(setUp)  );
4825             performOptionalSelector( obj, m_sel );
4826             performOptionalSelector( obj, @selector(tearDown)  );
4827
4828             arcSafeRelease( obj );
4829         }
4830     private:
4831         virtual ~OcMethod() {}
4832
4833         Class m_cls;
4834         SEL m_sel;
4835     };
4836
4837     namespace Detail{
4838
4839         inline std::string getAnnotation(   Class cls,
4840                                             std::string const& annotationName,
4841                                             std::string const& testCaseName ) {
4842             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
4843             SEL sel = NSSelectorFromString( selStr );
4844             arcSafeRelease( selStr );
4845             id value = performOptionalSelector( cls, sel );
4846             if( value )
4847                 return [(NSString*)value UTF8String];
4848             return "";
4849         }
4850     }
4851
4852     inline std::size_t registerTestMethods() {
4853         std::size_t noTestMethods = 0;
4854         int noClasses = objc_getClassList( nullptr, 0 );
4855
4856         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
4857         objc_getClassList( classes, noClasses );
4858
4859         for( int c = 0; c < noClasses; c++ ) {
4860             Class cls = classes[c];
4861             {
4862                 u_int count;
4863                 Method* methods = class_copyMethodList( cls, &count );
4864                 for( u_int m = 0; m < count ; m++ ) {
4865                     SEL selector = method_getName(methods[m]);
4866                     std::string methodName = sel_getName(selector);
4867                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
4868                         std::string testCaseName = methodName.substr( 15 );
4869                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
4870                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
4871                         const char* className = class_getName( cls );
4872
4873                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
4874                         noTestMethods++;
4875                     }
4876                 }
4877                 free(methods);
4878             }
4879         }
4880         return noTestMethods;
4881     }
4882
4883 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
4884
4885     namespace Matchers {
4886         namespace Impl {
4887         namespace NSStringMatchers {
4888
4889             struct StringHolder : MatcherBase<NSString*>{
4890                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
4891                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
4892                 StringHolder() {
4893                     arcSafeRelease( m_substr );
4894                 }
4895
4896                 bool match( NSString* str ) const override {
4897                     return false;
4898                 }
4899
4900                 NSString* CATCH_ARC_STRONG m_substr;
4901             };
4902
4903             struct Equals : StringHolder {
4904                 Equals( NSString* substr ) : StringHolder( substr ){}
4905
4906                 bool match( NSString* str ) const override {
4907                     return  (str != nil || m_substr == nil ) &&
4908                             [str isEqualToString:m_substr];
4909                 }
4910
4911                 std::string describe() const override {
4912                     return "equals string: " + Catch::Detail::stringify( m_substr );
4913                 }
4914             };
4915
4916             struct Contains : StringHolder {
4917                 Contains( NSString* substr ) : StringHolder( substr ){}
4918
4919                 bool match( NSString* str ) const override {
4920                     return  (str != nil || m_substr == nil ) &&
4921                             [str rangeOfString:m_substr].location != NSNotFound;
4922                 }
4923
4924                 std::string describe() const override {
4925                     return "contains string: " + Catch::Detail::stringify( m_substr );
4926                 }
4927             };
4928
4929             struct StartsWith : StringHolder {
4930                 StartsWith( NSString* substr ) : StringHolder( substr ){}
4931
4932                 bool match( NSString* str ) const override {
4933                     return  (str != nil || m_substr == nil ) &&
4934                             [str rangeOfString:m_substr].location == 0;
4935                 }
4936
4937                 std::string describe() const override {
4938                     return "starts with: " + Catch::Detail::stringify( m_substr );
4939                 }
4940             };
4941             struct EndsWith : StringHolder {
4942                 EndsWith( NSString* substr ) : StringHolder( substr ){}
4943
4944                 bool match( NSString* str ) const override {
4945                     return  (str != nil || m_substr == nil ) &&
4946                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
4947                 }
4948
4949                 std::string describe() const override {
4950                     return "ends with: " + Catch::Detail::stringify( m_substr );
4951                 }
4952             };
4953
4954         } // namespace NSStringMatchers
4955         } // namespace Impl
4956
4957         inline Impl::NSStringMatchers::Equals
4958             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
4959
4960         inline Impl::NSStringMatchers::Contains
4961             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
4962
4963         inline Impl::NSStringMatchers::StartsWith
4964             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
4965
4966         inline Impl::NSStringMatchers::EndsWith
4967             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
4968
4969     } // namespace Matchers
4970
4971     using namespace Matchers;
4972
4973 #endif // CATCH_CONFIG_DISABLE_MATCHERS
4974
4975 } // namespace Catch
4976
4977 ///////////////////////////////////////////////////////////////////////////////
4978 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
4979 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
4980 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
4981 { \
4982 return @ name; \
4983 } \
4984 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
4985 { \
4986 return @ desc; \
4987 } \
4988 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
4989
4990 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
4991
4992 // end catch_objc.hpp
4993 #endif
4994
4995 // Benchmarking needs the externally-facing parts of reporters to work
4996 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
4997 // start catch_external_interfaces.h
4998
4999 // start catch_reporter_bases.hpp
5000
5001 // start catch_interfaces_reporter.h
5002
5003 // start catch_config.hpp
5004
5005 // start catch_test_spec_parser.h
5006
5007 #ifdef __clang__
5008 #pragma clang diagnostic push
5009 #pragma clang diagnostic ignored "-Wpadded"
5010 #endif
5011
5012 // start catch_test_spec.h
5013
5014 #ifdef __clang__
5015 #pragma clang diagnostic push
5016 #pragma clang diagnostic ignored "-Wpadded"
5017 #endif
5018
5019 // start catch_wildcard_pattern.h
5020
5021 namespace Catch
5022 {
5023     class WildcardPattern {
5024         enum WildcardPosition {
5025             NoWildcard = 0,
5026             WildcardAtStart = 1,
5027             WildcardAtEnd = 2,
5028             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
5029         };
5030
5031     public:
5032
5033         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
5034         virtual ~WildcardPattern() = default;
5035         virtual bool matches( std::string const& str ) const;
5036
5037     private:
5038         std::string normaliseString( std::string const& str ) const;
5039         CaseSensitive::Choice m_caseSensitivity;
5040         WildcardPosition m_wildcard = NoWildcard;
5041         std::string m_pattern;
5042     };
5043 }
5044
5045 // end catch_wildcard_pattern.h
5046 #include <string>
5047 #include <vector>
5048 #include <memory>
5049
5050 namespace Catch {
5051
5052     struct IConfig;
5053
5054     class TestSpec {
5055         class Pattern {
5056         public:
5057             explicit Pattern( std::string const& name );
5058             virtual ~Pattern();
5059             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
5060             std::string const& name() const;
5061         private:
5062             std::string const m_name;
5063         };
5064         using PatternPtr = std::shared_ptr<Pattern>;
5065
5066         class NamePattern : public Pattern {
5067         public:
5068             explicit NamePattern( std::string const& name, std::string const& filterString );
5069             bool matches( TestCaseInfo const& testCase ) const override;
5070         private:
5071             WildcardPattern m_wildcardPattern;
5072         };
5073
5074         class TagPattern : public Pattern {
5075         public:
5076             explicit TagPattern( std::string const& tag, std::string const& filterString );
5077             bool matches( TestCaseInfo const& testCase ) const override;
5078         private:
5079             std::string m_tag;
5080         };
5081
5082         class ExcludedPattern : public Pattern {
5083         public:
5084             explicit ExcludedPattern( PatternPtr const& underlyingPattern );
5085             bool matches( TestCaseInfo const& testCase ) const override;
5086         private:
5087             PatternPtr m_underlyingPattern;
5088         };
5089
5090         struct Filter {
5091             std::vector<PatternPtr> m_patterns;
5092
5093             bool matches( TestCaseInfo const& testCase ) const;
5094             std::string name() const;
5095         };
5096
5097     public:
5098         struct FilterMatch {
5099             std::string name;
5100             std::vector<TestCase const*> tests;
5101         };
5102         using Matches = std::vector<FilterMatch>;
5103         using vectorStrings = std::vector<std::string>;
5104
5105         bool hasFilters() const;
5106         bool matches( TestCaseInfo const& testCase ) const;
5107         Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
5108         const vectorStrings & getInvalidArgs() const;
5109
5110     private:
5111         std::vector<Filter> m_filters;
5112         std::vector<std::string> m_invalidArgs;
5113         friend class TestSpecParser;
5114     };
5115 }
5116
5117 #ifdef __clang__
5118 #pragma clang diagnostic pop
5119 #endif
5120
5121 // end catch_test_spec.h
5122 // start catch_interfaces_tag_alias_registry.h
5123
5124 #include <string>
5125
5126 namespace Catch {
5127
5128     struct TagAlias;
5129
5130     struct ITagAliasRegistry {
5131         virtual ~ITagAliasRegistry();
5132         // Nullptr if not present
5133         virtual TagAlias const* find( std::string const& alias ) const = 0;
5134         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
5135
5136         static ITagAliasRegistry const& get();
5137     };
5138
5139 } // end namespace Catch
5140
5141 // end catch_interfaces_tag_alias_registry.h
5142 namespace Catch {
5143
5144     class TestSpecParser {
5145         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
5146         Mode m_mode = None;
5147         Mode lastMode = None;
5148         bool m_exclusion = false;
5149         std::size_t m_pos = 0;
5150         std::size_t m_realPatternPos = 0;
5151         std::string m_arg;
5152         std::string m_substring;
5153         std::string m_patternName;
5154         std::vector<std::size_t> m_escapeChars;
5155         TestSpec::Filter m_currentFilter;
5156         TestSpec m_testSpec;
5157         ITagAliasRegistry const* m_tagAliases = nullptr;
5158
5159     public:
5160         TestSpecParser( ITagAliasRegistry const& tagAliases );
5161
5162         TestSpecParser& parse( std::string const& arg );
5163         TestSpec testSpec();
5164
5165     private:
5166         bool visitChar( char c );
5167         void startNewMode( Mode mode );
5168         bool processNoneChar( char c );
5169         void processNameChar( char c );
5170         bool processOtherChar( char c );
5171         void endMode();
5172         void escape();
5173         bool isControlChar( char c ) const;
5174         void saveLastMode();
5175         void revertBackToLastMode();
5176         void addFilter();
5177         bool separate();
5178
5179         // Handles common preprocessing of the pattern for name/tag patterns
5180         std::string preprocessPattern();
5181         // Adds the current pattern as a test name
5182         void addNamePattern();
5183         // Adds the current pattern as a tag
5184         void addTagPattern();
5185
5186         inline void addCharToPattern(char c) {
5187             m_substring += c;
5188             m_patternName += c;
5189             m_realPatternPos++;
5190         }
5191
5192     };
5193     TestSpec parseTestSpec( std::string const& arg );
5194
5195 } // namespace Catch
5196
5197 #ifdef __clang__
5198 #pragma clang diagnostic pop
5199 #endif
5200
5201 // end catch_test_spec_parser.h
5202 // Libstdc++ doesn't like incomplete classes for unique_ptr
5203
5204 #include <memory>
5205 #include <vector>
5206 #include <string>
5207
5208 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
5209 #define CATCH_CONFIG_CONSOLE_WIDTH 80
5210 #endif
5211
5212 namespace Catch {
5213
5214     struct IStream;
5215
5216     struct ConfigData {
5217         bool listTests = false;
5218         bool listTags = false;
5219         bool listReporters = false;
5220         bool listTestNamesOnly = false;
5221
5222         bool showSuccessfulTests = false;
5223         bool shouldDebugBreak = false;
5224         bool noThrow = false;
5225         bool showHelp = false;
5226         bool showInvisibles = false;
5227         bool filenamesAsTags = false;
5228         bool libIdentify = false;
5229
5230         int abortAfter = -1;
5231         unsigned int rngSeed = 0;
5232
5233         bool benchmarkNoAnalysis = false;
5234         unsigned int benchmarkSamples = 100;
5235         double benchmarkConfidenceInterval = 0.95;
5236         unsigned int benchmarkResamples = 100000;
5237
5238         Verbosity verbosity = Verbosity::Normal;
5239         WarnAbout::What warnings = WarnAbout::Nothing;
5240         ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
5241         RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
5242         UseColour::YesOrNo useColour = UseColour::Auto;
5243         WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
5244
5245         std::string outputFilename;
5246         std::string name;
5247         std::string processName;
5248 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
5249 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
5250 #endif
5251         std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
5252 #undef CATCH_CONFIG_DEFAULT_REPORTER
5253
5254         std::vector<std::string> testsOrTags;
5255         std::vector<std::string> sectionsToRun;
5256     };
5257
5258     class Config : public IConfig {
5259     public:
5260
5261         Config() = default;
5262         Config( ConfigData const& data );
5263         virtual ~Config() = default;
5264
5265         std::string const& getFilename() const;
5266
5267         bool listTests() const;
5268         bool listTestNamesOnly() const;
5269         bool listTags() const;
5270         bool listReporters() const;
5271
5272         std::string getProcessName() const;
5273         std::string const& getReporterName() const;
5274
5275         std::vector<std::string> const& getTestsOrTags() const override;
5276         std::vector<std::string> const& getSectionsToRun() const override;
5277
5278         TestSpec const& testSpec() const override;
5279         bool hasTestFilters() const override;
5280
5281         bool showHelp() const;
5282
5283         // IConfig interface
5284         bool allowThrows() const override;
5285         std::ostream& stream() const override;
5286         std::string name() const override;
5287         bool includeSuccessfulResults() const override;
5288         bool warnAboutMissingAssertions() const override;
5289         bool warnAboutNoTests() const override;
5290         ShowDurations::OrNot showDurations() const override;
5291         RunTests::InWhatOrder runOrder() const override;
5292         unsigned int rngSeed() const override;
5293         UseColour::YesOrNo useColour() const override;
5294         bool shouldDebugBreak() const override;
5295         int abortAfter() const override;
5296         bool showInvisibles() const override;
5297         Verbosity verbosity() const override;
5298         bool benchmarkNoAnalysis() const override;
5299         int benchmarkSamples() const override;
5300         double benchmarkConfidenceInterval() const override;
5301         unsigned int benchmarkResamples() const override;
5302
5303     private:
5304
5305         IStream const* openStream();
5306         ConfigData m_data;
5307
5308         std::unique_ptr<IStream const> m_stream;
5309         TestSpec m_testSpec;
5310         bool m_hasTestFilters = false;
5311     };
5312
5313 } // end namespace Catch
5314
5315 // end catch_config.hpp
5316 // start catch_assertionresult.h
5317
5318 #include <string>
5319
5320 namespace Catch {
5321
5322     struct AssertionResultData
5323     {
5324         AssertionResultData() = delete;
5325
5326         AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
5327
5328         std::string message;
5329         mutable std::string reconstructedExpression;
5330         LazyExpression lazyExpression;
5331         ResultWas::OfType resultType;
5332
5333         std::string reconstructExpression() const;
5334     };
5335
5336     class AssertionResult {
5337     public:
5338         AssertionResult() = delete;
5339         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
5340
5341         bool isOk() const;
5342         bool succeeded() const;
5343         ResultWas::OfType getResultType() const;
5344         bool hasExpression() const;
5345         bool hasMessage() const;
5346         std::string getExpression() const;
5347         std::string getExpressionInMacro() const;
5348         bool hasExpandedExpression() const;
5349         std::string getExpandedExpression() const;
5350         std::string getMessage() const;
5351         SourceLineInfo getSourceInfo() const;
5352         StringRef getTestMacroName() const;
5353
5354     //protected:
5355         AssertionInfo m_info;
5356         AssertionResultData m_resultData;
5357     };
5358
5359 } // end namespace Catch
5360
5361 // end catch_assertionresult.h
5362 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5363 // start catch_estimate.hpp
5364
5365  // Statistics estimates
5366
5367
5368 namespace Catch {
5369     namespace Benchmark {
5370         template <typename Duration>
5371         struct Estimate {
5372             Duration point;
5373             Duration lower_bound;
5374             Duration upper_bound;
5375             double confidence_interval;
5376
5377             template <typename Duration2>
5378             operator Estimate<Duration2>() const {
5379                 return { point, lower_bound, upper_bound, confidence_interval };
5380             }
5381         };
5382     } // namespace Benchmark
5383 } // namespace Catch
5384
5385 // end catch_estimate.hpp
5386 // start catch_outlier_classification.hpp
5387
5388 // Outlier information
5389
5390 namespace Catch {
5391     namespace Benchmark {
5392         struct OutlierClassification {
5393             int samples_seen = 0;
5394             int low_severe = 0;     // more than 3 times IQR below Q1
5395             int low_mild = 0;       // 1.5 to 3 times IQR below Q1
5396             int high_mild = 0;      // 1.5 to 3 times IQR above Q3
5397             int high_severe = 0;    // more than 3 times IQR above Q3
5398
5399             int total() const {
5400                 return low_severe + low_mild + high_mild + high_severe;
5401             }
5402         };
5403     } // namespace Benchmark
5404 } // namespace Catch
5405
5406 // end catch_outlier_classification.hpp
5407 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5408
5409 #include <string>
5410 #include <iosfwd>
5411 #include <map>
5412 #include <set>
5413 #include <memory>
5414 #include <algorithm>
5415
5416 namespace Catch {
5417
5418     struct ReporterConfig {
5419         explicit ReporterConfig( IConfigPtr const& _fullConfig );
5420
5421         ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
5422
5423         std::ostream& stream() const;
5424         IConfigPtr fullConfig() const;
5425
5426     private:
5427         std::ostream* m_stream;
5428         IConfigPtr m_fullConfig;
5429     };
5430
5431     struct ReporterPreferences {
5432         bool shouldRedirectStdOut = false;
5433         bool shouldReportAllAssertions = false;
5434     };
5435
5436     template<typename T>
5437     struct LazyStat : Option<T> {
5438         LazyStat& operator=( T const& _value ) {
5439             Option<T>::operator=( _value );
5440             used = false;
5441             return *this;
5442         }
5443         void reset() {
5444             Option<T>::reset();
5445             used = false;
5446         }
5447         bool used = false;
5448     };
5449
5450     struct TestRunInfo {
5451         TestRunInfo( std::string const& _name );
5452         std::string name;
5453     };
5454     struct GroupInfo {
5455         GroupInfo(  std::string const& _name,
5456                     std::size_t _groupIndex,
5457                     std::size_t _groupsCount );
5458
5459         std::string name;
5460         std::size_t groupIndex;
5461         std::size_t groupsCounts;
5462     };
5463
5464     struct AssertionStats {
5465         AssertionStats( AssertionResult const& _assertionResult,
5466                         std::vector<MessageInfo> const& _infoMessages,
5467                         Totals const& _totals );
5468
5469         AssertionStats( AssertionStats const& )              = default;
5470         AssertionStats( AssertionStats && )                  = default;
5471         AssertionStats& operator = ( AssertionStats const& ) = delete;
5472         AssertionStats& operator = ( AssertionStats && )     = delete;
5473         virtual ~AssertionStats();
5474
5475         AssertionResult assertionResult;
5476         std::vector<MessageInfo> infoMessages;
5477         Totals totals;
5478     };
5479
5480     struct SectionStats {
5481         SectionStats(   SectionInfo const& _sectionInfo,
5482                         Counts const& _assertions,
5483                         double _durationInSeconds,
5484                         bool _missingAssertions );
5485         SectionStats( SectionStats const& )              = default;
5486         SectionStats( SectionStats && )                  = default;
5487         SectionStats& operator = ( SectionStats const& ) = default;
5488         SectionStats& operator = ( SectionStats && )     = default;
5489         virtual ~SectionStats();
5490
5491         SectionInfo sectionInfo;
5492         Counts assertions;
5493         double durationInSeconds;
5494         bool missingAssertions;
5495     };
5496
5497     struct TestCaseStats {
5498         TestCaseStats(  TestCaseInfo const& _testInfo,
5499                         Totals const& _totals,
5500                         std::string const& _stdOut,
5501                         std::string const& _stdErr,
5502                         bool _aborting );
5503
5504         TestCaseStats( TestCaseStats const& )              = default;
5505         TestCaseStats( TestCaseStats && )                  = default;
5506         TestCaseStats& operator = ( TestCaseStats const& ) = default;
5507         TestCaseStats& operator = ( TestCaseStats && )     = default;
5508         virtual ~TestCaseStats();
5509
5510         TestCaseInfo testInfo;
5511         Totals totals;
5512         std::string stdOut;
5513         std::string stdErr;
5514         bool aborting;
5515     };
5516
5517     struct TestGroupStats {
5518         TestGroupStats( GroupInfo const& _groupInfo,
5519                         Totals const& _totals,
5520                         bool _aborting );
5521         TestGroupStats( GroupInfo const& _groupInfo );
5522
5523         TestGroupStats( TestGroupStats const& )              = default;
5524         TestGroupStats( TestGroupStats && )                  = default;
5525         TestGroupStats& operator = ( TestGroupStats const& ) = default;
5526         TestGroupStats& operator = ( TestGroupStats && )     = default;
5527         virtual ~TestGroupStats();
5528
5529         GroupInfo groupInfo;
5530         Totals totals;
5531         bool aborting;
5532     };
5533
5534     struct TestRunStats {
5535         TestRunStats(   TestRunInfo const& _runInfo,
5536                         Totals const& _totals,
5537                         bool _aborting );
5538
5539         TestRunStats( TestRunStats const& )              = default;
5540         TestRunStats( TestRunStats && )                  = default;
5541         TestRunStats& operator = ( TestRunStats const& ) = default;
5542         TestRunStats& operator = ( TestRunStats && )     = default;
5543         virtual ~TestRunStats();
5544
5545         TestRunInfo runInfo;
5546         Totals totals;
5547         bool aborting;
5548     };
5549
5550 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5551     struct BenchmarkInfo {
5552         std::string name;
5553         double estimatedDuration;
5554         int iterations;
5555         int samples;
5556         unsigned int resamples;
5557         double clockResolution;
5558         double clockCost;
5559     };
5560
5561     template <class Duration>
5562     struct BenchmarkStats {
5563         BenchmarkInfo info;
5564
5565         std::vector<Duration> samples;
5566         Benchmark::Estimate<Duration> mean;
5567         Benchmark::Estimate<Duration> standardDeviation;
5568         Benchmark::OutlierClassification outliers;
5569         double outlierVariance;
5570
5571         template <typename Duration2>
5572         operator BenchmarkStats<Duration2>() const {
5573             std::vector<Duration2> samples2;
5574             samples2.reserve(samples.size());
5575             std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
5576             return {
5577                 info,
5578                 std::move(samples2),
5579                 mean,
5580                 standardDeviation,
5581                 outliers,
5582                 outlierVariance,
5583             };
5584         }
5585     };
5586 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5587
5588     struct IStreamingReporter {
5589         virtual ~IStreamingReporter() = default;
5590
5591         // Implementing class must also provide the following static methods:
5592         // static std::string getDescription();
5593         // static std::set<Verbosity> getSupportedVerbosities()
5594
5595         virtual ReporterPreferences getPreferences() const = 0;
5596
5597         virtual void noMatchingTestCases( std::string const& spec ) = 0;
5598
5599         virtual void reportInvalidArguments(std::string const&) {}
5600
5601         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5602         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5603
5604         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5605         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5606
5607 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5608         virtual void benchmarkPreparing( std::string const& ) {}
5609         virtual void benchmarkStarting( BenchmarkInfo const& ) {}
5610         virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
5611         virtual void benchmarkFailed( std::string const& ) {}
5612 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5613
5614         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5615
5616         // The return value indicates if the messages buffer should be cleared:
5617         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5618
5619         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5620         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5621         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5622         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5623
5624         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5625
5626         // Default empty implementation provided
5627         virtual void fatalErrorEncountered( StringRef name );
5628
5629         virtual bool isMulti() const;
5630     };
5631     using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
5632
5633     struct IReporterFactory {
5634         virtual ~IReporterFactory();
5635         virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
5636         virtual std::string getDescription() const = 0;
5637     };
5638     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
5639
5640     struct IReporterRegistry {
5641         using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
5642         using Listeners = std::vector<IReporterFactoryPtr>;
5643
5644         virtual ~IReporterRegistry();
5645         virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
5646         virtual FactoryMap const& getFactories() const = 0;
5647         virtual Listeners const& getListeners() const = 0;
5648     };
5649
5650 } // end namespace Catch
5651
5652 // end catch_interfaces_reporter.h
5653 #include <algorithm>
5654 #include <cstring>
5655 #include <cfloat>
5656 #include <cstdio>
5657 #include <cassert>
5658 #include <memory>
5659 #include <ostream>
5660
5661 namespace Catch {
5662     void prepareExpandedExpression(AssertionResult& result);
5663
5664     // Returns double formatted as %.3f (format expected on output)
5665     std::string getFormattedDuration( double duration );
5666
5667     std::string serializeFilters( std::vector<std::string> const& container );
5668
5669     template<typename DerivedT>
5670     struct StreamingReporterBase : IStreamingReporter {
5671
5672         StreamingReporterBase( ReporterConfig const& _config )
5673         :   m_config( _config.fullConfig() ),
5674             stream( _config.stream() )
5675         {
5676             m_reporterPrefs.shouldRedirectStdOut = false;
5677             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5678                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
5679         }
5680
5681         ReporterPreferences getPreferences() const override {
5682             return m_reporterPrefs;
5683         }
5684
5685         static std::set<Verbosity> getSupportedVerbosities() {
5686             return { Verbosity::Normal };
5687         }
5688
5689         ~StreamingReporterBase() override = default;
5690
5691         void noMatchingTestCases(std::string const&) override {}
5692
5693         void reportInvalidArguments(std::string const&) override {}
5694
5695         void testRunStarting(TestRunInfo const& _testRunInfo) override {
5696             currentTestRunInfo = _testRunInfo;
5697         }
5698
5699         void testGroupStarting(GroupInfo const& _groupInfo) override {
5700             currentGroupInfo = _groupInfo;
5701         }
5702
5703         void testCaseStarting(TestCaseInfo const& _testInfo) override  {
5704             currentTestCaseInfo = _testInfo;
5705         }
5706         void sectionStarting(SectionInfo const& _sectionInfo) override {
5707             m_sectionStack.push_back(_sectionInfo);
5708         }
5709
5710         void sectionEnded(SectionStats const& /* _sectionStats */) override {
5711             m_sectionStack.pop_back();
5712         }
5713         void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
5714             currentTestCaseInfo.reset();
5715         }
5716         void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
5717             currentGroupInfo.reset();
5718         }
5719         void testRunEnded(TestRunStats const& /* _testRunStats */) override {
5720             currentTestCaseInfo.reset();
5721             currentGroupInfo.reset();
5722             currentTestRunInfo.reset();
5723         }
5724
5725         void skipTest(TestCaseInfo const&) override {
5726             // Don't do anything with this by default.
5727             // It can optionally be overridden in the derived class.
5728         }
5729
5730         IConfigPtr m_config;
5731         std::ostream& stream;
5732
5733         LazyStat<TestRunInfo> currentTestRunInfo;
5734         LazyStat<GroupInfo> currentGroupInfo;
5735         LazyStat<TestCaseInfo> currentTestCaseInfo;
5736
5737         std::vector<SectionInfo> m_sectionStack;
5738         ReporterPreferences m_reporterPrefs;
5739     };
5740
5741     template<typename DerivedT>
5742     struct CumulativeReporterBase : IStreamingReporter {
5743         template<typename T, typename ChildNodeT>
5744         struct Node {
5745             explicit Node( T const& _value ) : value( _value ) {}
5746             virtual ~Node() {}
5747
5748             using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
5749             T value;
5750             ChildNodes children;
5751         };
5752         struct SectionNode {
5753             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
5754             virtual ~SectionNode() = default;
5755
5756             bool operator == (SectionNode const& other) const {
5757                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
5758             }
5759             bool operator == (std::shared_ptr<SectionNode> const& other) const {
5760                 return operator==(*other);
5761             }
5762
5763             SectionStats stats;
5764             using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
5765             using Assertions = std::vector<AssertionStats>;
5766             ChildSections childSections;
5767             Assertions assertions;
5768             std::string stdOut;
5769             std::string stdErr;
5770         };
5771
5772         struct BySectionInfo {
5773             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
5774             BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
5775             bool operator() (std::shared_ptr<SectionNode> const& node) const {
5776                 return ((node->stats.sectionInfo.name == m_other.name) &&
5777                         (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
5778             }
5779             void operator=(BySectionInfo const&) = delete;
5780
5781         private:
5782             SectionInfo const& m_other;
5783         };
5784
5785         using TestCaseNode = Node<TestCaseStats, SectionNode>;
5786         using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
5787         using TestRunNode = Node<TestRunStats, TestGroupNode>;
5788
5789         CumulativeReporterBase( ReporterConfig const& _config )
5790         :   m_config( _config.fullConfig() ),
5791             stream( _config.stream() )
5792         {
5793             m_reporterPrefs.shouldRedirectStdOut = false;
5794             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5795                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
5796         }
5797         ~CumulativeReporterBase() override = default;
5798
5799         ReporterPreferences getPreferences() const override {
5800             return m_reporterPrefs;
5801         }
5802
5803         static std::set<Verbosity> getSupportedVerbosities() {
5804             return { Verbosity::Normal };
5805         }
5806
5807         void testRunStarting( TestRunInfo const& ) override {}
5808         void testGroupStarting( GroupInfo const& ) override {}
5809
5810         void testCaseStarting( TestCaseInfo const& ) override {}
5811
5812         void sectionStarting( SectionInfo const& sectionInfo ) override {
5813             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
5814             std::shared_ptr<SectionNode> node;
5815             if( m_sectionStack.empty() ) {
5816                 if( !m_rootSection )
5817                     m_rootSection = std::make_shared<SectionNode>( incompleteStats );
5818                 node = m_rootSection;
5819             }
5820             else {
5821                 SectionNode& parentNode = *m_sectionStack.back();
5822                 auto it =
5823                     std::find_if(   parentNode.childSections.begin(),
5824                                     parentNode.childSections.end(),
5825                                     BySectionInfo( sectionInfo ) );
5826                 if( it == parentNode.childSections.end() ) {
5827                     node = std::make_shared<SectionNode>( incompleteStats );
5828                     parentNode.childSections.push_back( node );
5829                 }
5830                 else
5831                     node = *it;
5832             }
5833             m_sectionStack.push_back( node );
5834             m_deepestSection = std::move(node);
5835         }
5836
5837         void assertionStarting(AssertionInfo const&) override {}
5838
5839         bool assertionEnded(AssertionStats const& assertionStats) override {
5840             assert(!m_sectionStack.empty());
5841             // AssertionResult holds a pointer to a temporary DecomposedExpression,
5842             // which getExpandedExpression() calls to build the expression string.
5843             // Our section stack copy of the assertionResult will likely outlive the
5844             // temporary, so it must be expanded or discarded now to avoid calling
5845             // a destroyed object later.
5846             prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
5847             SectionNode& sectionNode = *m_sectionStack.back();
5848             sectionNode.assertions.push_back(assertionStats);
5849             return true;
5850         }
5851         void sectionEnded(SectionStats const& sectionStats) override {
5852             assert(!m_sectionStack.empty());
5853             SectionNode& node = *m_sectionStack.back();
5854             node.stats = sectionStats;
5855             m_sectionStack.pop_back();
5856         }
5857         void testCaseEnded(TestCaseStats const& testCaseStats) override {
5858             auto node = std::make_shared<TestCaseNode>(testCaseStats);
5859             assert(m_sectionStack.size() == 0);
5860             node->children.push_back(m_rootSection);
5861             m_testCases.push_back(node);
5862             m_rootSection.reset();
5863
5864             assert(m_deepestSection);
5865             m_deepestSection->stdOut = testCaseStats.stdOut;
5866             m_deepestSection->stdErr = testCaseStats.stdErr;
5867         }
5868         void testGroupEnded(TestGroupStats const& testGroupStats) override {
5869             auto node = std::make_shared<TestGroupNode>(testGroupStats);
5870             node->children.swap(m_testCases);
5871             m_testGroups.push_back(node);
5872         }
5873         void testRunEnded(TestRunStats const& testRunStats) override {
5874             auto node = std::make_shared<TestRunNode>(testRunStats);
5875             node->children.swap(m_testGroups);
5876             m_testRuns.push_back(node);
5877             testRunEndedCumulative();
5878         }
5879         virtual void testRunEndedCumulative() = 0;
5880
5881         void skipTest(TestCaseInfo const&) override {}
5882
5883         IConfigPtr m_config;
5884         std::ostream& stream;
5885         std::vector<AssertionStats> m_assertions;
5886         std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
5887         std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
5888         std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
5889
5890         std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
5891
5892         std::shared_ptr<SectionNode> m_rootSection;
5893         std::shared_ptr<SectionNode> m_deepestSection;
5894         std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
5895         ReporterPreferences m_reporterPrefs;
5896     };
5897
5898     template<char C>
5899     char const* getLineOfChars() {
5900         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
5901         if( !*line ) {
5902             std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
5903             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
5904         }
5905         return line;
5906     }
5907
5908     struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
5909         TestEventListenerBase( ReporterConfig const& _config );
5910
5911         static std::set<Verbosity> getSupportedVerbosities();
5912
5913         void assertionStarting(AssertionInfo const&) override;
5914         bool assertionEnded(AssertionStats const&) override;
5915     };
5916
5917 } // end namespace Catch
5918
5919 // end catch_reporter_bases.hpp
5920 // start catch_console_colour.h
5921
5922 namespace Catch {
5923
5924     struct Colour {
5925         enum Code {
5926             None = 0,
5927
5928             White,
5929             Red,
5930             Green,
5931             Blue,
5932             Cyan,
5933             Yellow,
5934             Grey,
5935
5936             Bright = 0x10,
5937
5938             BrightRed = Bright | Red,
5939             BrightGreen = Bright | Green,
5940             LightGrey = Bright | Grey,
5941             BrightWhite = Bright | White,
5942             BrightYellow = Bright | Yellow,
5943
5944             // By intention
5945             FileName = LightGrey,
5946             Warning = BrightYellow,
5947             ResultError = BrightRed,
5948             ResultSuccess = BrightGreen,
5949             ResultExpectedFailure = Warning,
5950
5951             Error = BrightRed,
5952             Success = Green,
5953
5954             OriginalExpression = Cyan,
5955             ReconstructedExpression = BrightYellow,
5956
5957             SecondaryText = LightGrey,
5958             Headers = White
5959         };
5960
5961         // Use constructed object for RAII guard
5962         Colour( Code _colourCode );
5963         Colour( Colour&& other ) noexcept;
5964         Colour& operator=( Colour&& other ) noexcept;
5965         ~Colour();
5966
5967         // Use static method for one-shot changes
5968         static void use( Code _colourCode );
5969
5970     private:
5971         bool m_moved = false;
5972     };
5973
5974     std::ostream& operator << ( std::ostream& os, Colour const& );
5975
5976 } // end namespace Catch
5977
5978 // end catch_console_colour.h
5979 // start catch_reporter_registrars.hpp
5980
5981
5982 namespace Catch {
5983
5984     template<typename T>
5985     class ReporterRegistrar {
5986
5987         class ReporterFactory : public IReporterFactory {
5988
5989             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
5990                 return std::unique_ptr<T>( new T( config ) );
5991             }
5992
5993             std::string getDescription() const override {
5994                 return T::getDescription();
5995             }
5996         };
5997
5998     public:
5999
6000         explicit ReporterRegistrar( std::string const& name ) {
6001             getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
6002         }
6003     };
6004
6005     template<typename T>
6006     class ListenerRegistrar {
6007
6008         class ListenerFactory : public IReporterFactory {
6009
6010             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
6011                 return std::unique_ptr<T>( new T( config ) );
6012             }
6013             std::string getDescription() const override {
6014                 return std::string();
6015             }
6016         };
6017
6018     public:
6019
6020         ListenerRegistrar() {
6021             getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
6022         }
6023     };
6024 }
6025
6026 #if !defined(CATCH_CONFIG_DISABLE)
6027
6028 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
6029     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
6030     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
6031     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
6032     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6033
6034 #define CATCH_REGISTER_LISTENER( listenerType ) \
6035     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
6036     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
6037     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
6038     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6039 #else // CATCH_CONFIG_DISABLE
6040
6041 #define CATCH_REGISTER_REPORTER(name, reporterType)
6042 #define CATCH_REGISTER_LISTENER(listenerType)
6043
6044 #endif // CATCH_CONFIG_DISABLE
6045
6046 // end catch_reporter_registrars.hpp
6047 // Allow users to base their work off existing reporters
6048 // start catch_reporter_compact.h
6049
6050 namespace Catch {
6051
6052     struct CompactReporter : StreamingReporterBase<CompactReporter> {
6053
6054         using StreamingReporterBase::StreamingReporterBase;
6055
6056         ~CompactReporter() override;
6057
6058         static std::string getDescription();
6059
6060         ReporterPreferences getPreferences() const override;
6061
6062         void noMatchingTestCases(std::string const& spec) override;
6063
6064         void assertionStarting(AssertionInfo const&) override;
6065
6066         bool assertionEnded(AssertionStats const& _assertionStats) override;
6067
6068         void sectionEnded(SectionStats const& _sectionStats) override;
6069
6070         void testRunEnded(TestRunStats const& _testRunStats) override;
6071
6072     };
6073
6074 } // end namespace Catch
6075
6076 // end catch_reporter_compact.h
6077 // start catch_reporter_console.h
6078
6079 #if defined(_MSC_VER)
6080 #pragma warning(push)
6081 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
6082                               // Note that 4062 (not all labels are handled
6083                               // and default is missing) is enabled
6084 #endif
6085
6086 namespace Catch {
6087     // Fwd decls
6088     struct SummaryColumn;
6089     class TablePrinter;
6090
6091     struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
6092         std::unique_ptr<TablePrinter> m_tablePrinter;
6093
6094         ConsoleReporter(ReporterConfig const& config);
6095         ~ConsoleReporter() override;
6096         static std::string getDescription();
6097
6098         void noMatchingTestCases(std::string const& spec) override;
6099
6100         void reportInvalidArguments(std::string const&arg) override;
6101
6102         void assertionStarting(AssertionInfo const&) override;
6103
6104         bool assertionEnded(AssertionStats const& _assertionStats) override;
6105
6106         void sectionStarting(SectionInfo const& _sectionInfo) override;
6107         void sectionEnded(SectionStats const& _sectionStats) override;
6108
6109 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6110         void benchmarkPreparing(std::string const& name) override;
6111         void benchmarkStarting(BenchmarkInfo const& info) override;
6112         void benchmarkEnded(BenchmarkStats<> const& stats) override;
6113         void benchmarkFailed(std::string const& error) override;
6114 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6115
6116         void testCaseEnded(TestCaseStats const& _testCaseStats) override;
6117         void testGroupEnded(TestGroupStats const& _testGroupStats) override;
6118         void testRunEnded(TestRunStats const& _testRunStats) override;
6119         void testRunStarting(TestRunInfo const& _testRunInfo) override;
6120     private:
6121
6122         void lazyPrint();
6123
6124         void lazyPrintWithoutClosingBenchmarkTable();
6125         void lazyPrintRunInfo();
6126         void lazyPrintGroupInfo();
6127         void printTestCaseAndSectionHeader();
6128
6129         void printClosedHeader(std::string const& _name);
6130         void printOpenHeader(std::string const& _name);
6131
6132         // if string has a : in first line will set indent to follow it on
6133         // subsequent lines
6134         void printHeaderString(std::string const& _string, std::size_t indent = 0);
6135
6136         void printTotals(Totals const& totals);
6137         void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
6138
6139         void printTotalsDivider(Totals const& totals);
6140         void printSummaryDivider();
6141         void printTestFilters();
6142
6143     private:
6144         bool m_headerPrinted = false;
6145     };
6146
6147 } // end namespace Catch
6148
6149 #if defined(_MSC_VER)
6150 #pragma warning(pop)
6151 #endif
6152
6153 // end catch_reporter_console.h
6154 // start catch_reporter_junit.h
6155
6156 // start catch_xmlwriter.h
6157
6158 #include <vector>
6159
6160 namespace Catch {
6161     enum class XmlFormatting {
6162         None = 0x00,
6163         Indent = 0x01,
6164         Newline = 0x02,
6165     };
6166
6167     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
6168     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
6169
6170     class XmlEncode {
6171     public:
6172         enum ForWhat { ForTextNodes, ForAttributes };
6173
6174         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
6175
6176         void encodeTo( std::ostream& os ) const;
6177
6178         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
6179
6180     private:
6181         std::string m_str;
6182         ForWhat m_forWhat;
6183     };
6184
6185     class XmlWriter {
6186     public:
6187
6188         class ScopedElement {
6189         public:
6190             ScopedElement( XmlWriter* writer, XmlFormatting fmt );
6191
6192             ScopedElement( ScopedElement&& other ) noexcept;
6193             ScopedElement& operator=( ScopedElement&& other ) noexcept;
6194
6195             ~ScopedElement();
6196
6197             ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
6198
6199             template<typename T>
6200             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
6201                 m_writer->writeAttribute( name, attribute );
6202                 return *this;
6203             }
6204
6205         private:
6206             mutable XmlWriter* m_writer = nullptr;
6207             XmlFormatting m_fmt;
6208         };
6209
6210         XmlWriter( std::ostream& os = Catch::cout() );
6211         ~XmlWriter();
6212
6213         XmlWriter( XmlWriter const& ) = delete;
6214         XmlWriter& operator=( XmlWriter const& ) = delete;
6215
6216         XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6217
6218         ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6219
6220         XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6221
6222         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
6223
6224         XmlWriter& writeAttribute( std::string const& name, bool attribute );
6225
6226         template<typename T>
6227         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
6228             ReusableStringStream rss;
6229             rss << attribute;
6230             return writeAttribute( name, rss.str() );
6231         }
6232
6233         XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6234
6235         XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6236
6237         void writeStylesheetRef( std::string const& url );
6238
6239         XmlWriter& writeBlankLine();
6240
6241         void ensureTagClosed();
6242
6243     private:
6244
6245         void applyFormatting(XmlFormatting fmt);
6246
6247         void writeDeclaration();
6248
6249         void newlineIfNecessary();
6250
6251         bool m_tagIsOpen = false;
6252         bool m_needsNewline = false;
6253         std::vector<std::string> m_tags;
6254         std::string m_indent;
6255         std::ostream& m_os;
6256     };
6257
6258 }
6259
6260 // end catch_xmlwriter.h
6261 namespace Catch {
6262
6263     class JunitReporter : public CumulativeReporterBase<JunitReporter> {
6264     public:
6265         JunitReporter(ReporterConfig const& _config);
6266
6267         ~JunitReporter() override;
6268
6269         static std::string getDescription();
6270
6271         void noMatchingTestCases(std::string const& /*spec*/) override;
6272
6273         void testRunStarting(TestRunInfo const& runInfo) override;
6274
6275         void testGroupStarting(GroupInfo const& groupInfo) override;
6276
6277         void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
6278         bool assertionEnded(AssertionStats const& assertionStats) override;
6279
6280         void testCaseEnded(TestCaseStats const& testCaseStats) override;
6281
6282         void testGroupEnded(TestGroupStats const& testGroupStats) override;
6283
6284         void testRunEndedCumulative() override;
6285
6286         void writeGroup(TestGroupNode const& groupNode, double suiteTime);
6287
6288         void writeTestCase(TestCaseNode const& testCaseNode);
6289
6290         void writeSection(std::string const& className,
6291                           std::string const& rootName,
6292                           SectionNode const& sectionNode);
6293
6294         void writeAssertions(SectionNode const& sectionNode);
6295         void writeAssertion(AssertionStats const& stats);
6296
6297         XmlWriter xml;
6298         Timer suiteTimer;
6299         std::string stdOutForSuite;
6300         std::string stdErrForSuite;
6301         unsigned int unexpectedExceptions = 0;
6302         bool m_okToFail = false;
6303     };
6304
6305 } // end namespace Catch
6306
6307 // end catch_reporter_junit.h
6308 // start catch_reporter_xml.h
6309
6310 namespace Catch {
6311     class XmlReporter : public StreamingReporterBase<XmlReporter> {
6312     public:
6313         XmlReporter(ReporterConfig const& _config);
6314
6315         ~XmlReporter() override;
6316
6317         static std::string getDescription();
6318
6319         virtual std::string getStylesheetRef() const;
6320
6321         void writeSourceInfo(SourceLineInfo const& sourceInfo);
6322
6323     public: // StreamingReporterBase
6324
6325         void noMatchingTestCases(std::string const& s) override;
6326
6327         void testRunStarting(TestRunInfo const& testInfo) override;
6328
6329         void testGroupStarting(GroupInfo const& groupInfo) override;
6330
6331         void testCaseStarting(TestCaseInfo const& testInfo) override;
6332
6333         void sectionStarting(SectionInfo const& sectionInfo) override;
6334
6335         void assertionStarting(AssertionInfo const&) override;
6336
6337         bool assertionEnded(AssertionStats const& assertionStats) override;
6338
6339         void sectionEnded(SectionStats const& sectionStats) override;
6340
6341         void testCaseEnded(TestCaseStats const& testCaseStats) override;
6342
6343         void testGroupEnded(TestGroupStats const& testGroupStats) override;
6344
6345         void testRunEnded(TestRunStats const& testRunStats) override;
6346
6347 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6348         void benchmarkPreparing(std::string const& name) override;
6349         void benchmarkStarting(BenchmarkInfo const&) override;
6350         void benchmarkEnded(BenchmarkStats<> const&) override;
6351         void benchmarkFailed(std::string const&) override;
6352 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6353
6354     private:
6355         Timer m_testCaseTimer;
6356         XmlWriter m_xml;
6357         int m_sectionDepth = 0;
6358     };
6359
6360 } // end namespace Catch
6361
6362 // end catch_reporter_xml.h
6363
6364 // end catch_external_interfaces.h
6365 #endif
6366
6367 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6368 // start catch_benchmarking_all.hpp
6369
6370 // A proxy header that includes all of the benchmarking headers to allow
6371 // concise include of the benchmarking features. You should prefer the
6372 // individual includes in standard use.
6373
6374 // start catch_benchmark.hpp
6375
6376  // Benchmark
6377
6378 // start catch_chronometer.hpp
6379
6380 // User-facing chronometer
6381
6382
6383 // start catch_clock.hpp
6384
6385 // Clocks
6386
6387
6388 #include <chrono>
6389 #include <ratio>
6390
6391 namespace Catch {
6392     namespace Benchmark {
6393         template <typename Clock>
6394         using ClockDuration = typename Clock::duration;
6395         template <typename Clock>
6396         using FloatDuration = std::chrono::duration<double, typename Clock::period>;
6397
6398         template <typename Clock>
6399         using TimePoint = typename Clock::time_point;
6400
6401         using default_clock = std::chrono::steady_clock;
6402
6403         template <typename Clock>
6404         struct now {
6405             TimePoint<Clock> operator()() const {
6406                 return Clock::now();
6407             }
6408         };
6409
6410         using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
6411     } // namespace Benchmark
6412 } // namespace Catch
6413
6414 // end catch_clock.hpp
6415 // start catch_optimizer.hpp
6416
6417  // Hinting the optimizer
6418
6419
6420 #if defined(_MSC_VER)
6421 #   include <atomic> // atomic_thread_fence
6422 #endif
6423
6424 namespace Catch {
6425     namespace Benchmark {
6426 #if defined(__GNUC__) || defined(__clang__)
6427         template <typename T>
6428         inline void keep_memory(T* p) {
6429             asm volatile("" : : "g"(p) : "memory");
6430         }
6431         inline void keep_memory() {
6432             asm volatile("" : : : "memory");
6433         }
6434
6435         namespace Detail {
6436             inline void optimizer_barrier() { keep_memory(); }
6437         } // namespace Detail
6438 #elif defined(_MSC_VER)
6439
6440 #pragma optimize("", off)
6441         template <typename T>
6442         inline void keep_memory(T* p) {
6443             // thanks @milleniumbug
6444             *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
6445         }
6446         // TODO equivalent keep_memory()
6447 #pragma optimize("", on)
6448
6449         namespace Detail {
6450             inline void optimizer_barrier() {
6451                 std::atomic_thread_fence(std::memory_order_seq_cst);
6452             }
6453         } // namespace Detail
6454
6455 #endif
6456
6457         template <typename T>
6458         inline void deoptimize_value(T&& x) {
6459             keep_memory(&x);
6460         }
6461
6462         template <typename Fn, typename... Args>
6463         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
6464             deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
6465         }
6466
6467         template <typename Fn, typename... Args>
6468         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
6469             std::forward<Fn>(fn) (std::forward<Args...>(args...));
6470         }
6471     } // namespace Benchmark
6472 } // namespace Catch
6473
6474 // end catch_optimizer.hpp
6475 // start catch_complete_invoke.hpp
6476
6477 // Invoke with a special case for void
6478
6479
6480 #include <type_traits>
6481 #include <utility>
6482
6483 namespace Catch {
6484     namespace Benchmark {
6485         namespace Detail {
6486             template <typename T>
6487             struct CompleteType { using type = T; };
6488             template <>
6489             struct CompleteType<void> { struct type {}; };
6490
6491             template <typename T>
6492             using CompleteType_t = typename CompleteType<T>::type;
6493
6494             template <typename Result>
6495             struct CompleteInvoker {
6496                 template <typename Fun, typename... Args>
6497                 static Result invoke(Fun&& fun, Args&&... args) {
6498                     return std::forward<Fun>(fun)(std::forward<Args>(args)...);
6499                 }
6500             };
6501             template <>
6502             struct CompleteInvoker<void> {
6503                 template <typename Fun, typename... Args>
6504                 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
6505                     std::forward<Fun>(fun)(std::forward<Args>(args)...);
6506                     return {};
6507                 }
6508             };
6509             template <typename Sig>
6510             using ResultOf_t = typename std::result_of<Sig>::type;
6511
6512             // invoke and not return void :(
6513             template <typename Fun, typename... Args>
6514             CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
6515                 return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
6516             }
6517
6518             const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
6519         } // namespace Detail
6520
6521         template <typename Fun>
6522         Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
6523             CATCH_TRY{
6524                 return Detail::complete_invoke(std::forward<Fun>(fun));
6525             } CATCH_CATCH_ALL{
6526                 getResultCapture().benchmarkFailed(translateActiveException());
6527                 CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
6528             }
6529         }
6530     } // namespace Benchmark
6531 } // namespace Catch
6532
6533 // end catch_complete_invoke.hpp
6534 namespace Catch {
6535     namespace Benchmark {
6536         namespace Detail {
6537             struct ChronometerConcept {
6538                 virtual void start() = 0;
6539                 virtual void finish() = 0;
6540                 virtual ~ChronometerConcept() = default;
6541             };
6542             template <typename Clock>
6543             struct ChronometerModel final : public ChronometerConcept {
6544                 void start() override { started = Clock::now(); }
6545                 void finish() override { finished = Clock::now(); }
6546
6547                 ClockDuration<Clock> elapsed() const { return finished - started; }
6548
6549                 TimePoint<Clock> started;
6550                 TimePoint<Clock> finished;
6551             };
6552         } // namespace Detail
6553
6554         struct Chronometer {
6555         public:
6556             template <typename Fun>
6557             void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
6558
6559             int runs() const { return k; }
6560
6561             Chronometer(Detail::ChronometerConcept& meter, int k)
6562                 : impl(&meter)
6563                 , k(k) {}
6564
6565         private:
6566             template <typename Fun>
6567             void measure(Fun&& fun, std::false_type) {
6568                 measure([&fun](int) { return fun(); }, std::true_type());
6569             }
6570
6571             template <typename Fun>
6572             void measure(Fun&& fun, std::true_type) {
6573                 Detail::optimizer_barrier();
6574                 impl->start();
6575                 for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
6576                 impl->finish();
6577                 Detail::optimizer_barrier();
6578             }
6579
6580             Detail::ChronometerConcept* impl;
6581             int k;
6582         };
6583     } // namespace Benchmark
6584 } // namespace Catch
6585
6586 // end catch_chronometer.hpp
6587 // start catch_environment.hpp
6588
6589 // Environment information
6590
6591
6592 namespace Catch {
6593     namespace Benchmark {
6594         template <typename Duration>
6595         struct EnvironmentEstimate {
6596             Duration mean;
6597             OutlierClassification outliers;
6598
6599             template <typename Duration2>
6600             operator EnvironmentEstimate<Duration2>() const {
6601                 return { mean, outliers };
6602             }
6603         };
6604         template <typename Clock>
6605         struct Environment {
6606             using clock_type = Clock;
6607             EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
6608             EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
6609         };
6610     } // namespace Benchmark
6611 } // namespace Catch
6612
6613 // end catch_environment.hpp
6614 // start catch_execution_plan.hpp
6615
6616  // Execution plan
6617
6618
6619 // start catch_benchmark_function.hpp
6620
6621  // Dumb std::function implementation for consistent call overhead
6622
6623
6624 #include <cassert>
6625 #include <type_traits>
6626 #include <utility>
6627 #include <memory>
6628
6629 namespace Catch {
6630     namespace Benchmark {
6631         namespace Detail {
6632             template <typename T>
6633             using Decay = typename std::decay<T>::type;
6634             template <typename T, typename U>
6635             struct is_related
6636                 : std::is_same<Decay<T>, Decay<U>> {};
6637
6638             /// We need to reinvent std::function because every piece of code that might add overhead
6639             /// in a measurement context needs to have consistent performance characteristics so that we
6640             /// can account for it in the measurement.
6641             /// Implementations of std::function with optimizations that aren't always applicable, like
6642             /// small buffer optimizations, are not uncommon.
6643             /// This is effectively an implementation of std::function without any such optimizations;
6644             /// it may be slow, but it is consistently slow.
6645             struct BenchmarkFunction {
6646             private:
6647                 struct callable {
6648                     virtual void call(Chronometer meter) const = 0;
6649                     virtual callable* clone() const = 0;
6650                     virtual ~callable() = default;
6651                 };
6652                 template <typename Fun>
6653                 struct model : public callable {
6654                     model(Fun&& fun) : fun(std::move(fun)) {}
6655                     model(Fun const& fun) : fun(fun) {}
6656
6657                     model<Fun>* clone() const override { return new model<Fun>(*this); }
6658
6659                     void call(Chronometer meter) const override {
6660                         call(meter, is_callable<Fun(Chronometer)>());
6661                     }
6662                     void call(Chronometer meter, std::true_type) const {
6663                         fun(meter);
6664                     }
6665                     void call(Chronometer meter, std::false_type) const {
6666                         meter.measure(fun);
6667                     }
6668
6669                     Fun fun;
6670                 };
6671
6672                 struct do_nothing { void operator()() const {} };
6673
6674                 template <typename T>
6675                 BenchmarkFunction(model<T>* c) : f(c) {}
6676
6677             public:
6678                 BenchmarkFunction()
6679                     : f(new model<do_nothing>{ {} }) {}
6680
6681                 template <typename Fun,
6682                     typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
6683                     BenchmarkFunction(Fun&& fun)
6684                     : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
6685
6686                 BenchmarkFunction(BenchmarkFunction&& that)
6687                     : f(std::move(that.f)) {}
6688
6689                 BenchmarkFunction(BenchmarkFunction const& that)
6690                     : f(that.f->clone()) {}
6691
6692                 BenchmarkFunction& operator=(BenchmarkFunction&& that) {
6693                     f = std::move(that.f);
6694                     return *this;
6695                 }
6696
6697                 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
6698                     f.reset(that.f->clone());
6699                     return *this;
6700                 }
6701
6702                 void operator()(Chronometer meter) const { f->call(meter); }
6703
6704             private:
6705                 std::unique_ptr<callable> f;
6706             };
6707         } // namespace Detail
6708     } // namespace Benchmark
6709 } // namespace Catch
6710
6711 // end catch_benchmark_function.hpp
6712 // start catch_repeat.hpp
6713
6714 // repeat algorithm
6715
6716
6717 #include <type_traits>
6718 #include <utility>
6719
6720 namespace Catch {
6721     namespace Benchmark {
6722         namespace Detail {
6723             template <typename Fun>
6724             struct repeater {
6725                 void operator()(int k) const {
6726                     for (int i = 0; i < k; ++i) {
6727                         fun();
6728                     }
6729                 }
6730                 Fun fun;
6731             };
6732             template <typename Fun>
6733             repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
6734                 return { std::forward<Fun>(fun) };
6735             }
6736         } // namespace Detail
6737     } // namespace Benchmark
6738 } // namespace Catch
6739
6740 // end catch_repeat.hpp
6741 // start catch_run_for_at_least.hpp
6742
6743 // Run a function for a minimum amount of time
6744
6745
6746 // start catch_measure.hpp
6747
6748 // Measure
6749
6750
6751 // start catch_timing.hpp
6752
6753 // Timing
6754
6755
6756 #include <tuple>
6757 #include <type_traits>
6758
6759 namespace Catch {
6760     namespace Benchmark {
6761         template <typename Duration, typename Result>
6762         struct Timing {
6763             Duration elapsed;
6764             Result result;
6765             int iterations;
6766         };
6767         template <typename Clock, typename Sig>
6768         using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
6769     } // namespace Benchmark
6770 } // namespace Catch
6771
6772 // end catch_timing.hpp
6773 #include <utility>
6774
6775 namespace Catch {
6776     namespace Benchmark {
6777         namespace Detail {
6778             template <typename Clock, typename Fun, typename... Args>
6779             TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
6780                 auto start = Clock::now();
6781                 auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
6782                 auto end = Clock::now();
6783                 auto delta = end - start;
6784                 return { delta, std::forward<decltype(r)>(r), 1 };
6785             }
6786         } // namespace Detail
6787     } // namespace Benchmark
6788 } // namespace Catch
6789
6790 // end catch_measure.hpp
6791 #include <utility>
6792 #include <type_traits>
6793
6794 namespace Catch {
6795     namespace Benchmark {
6796         namespace Detail {
6797             template <typename Clock, typename Fun>
6798             TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
6799                 return Detail::measure<Clock>(fun, iters);
6800             }
6801             template <typename Clock, typename Fun>
6802             TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
6803                 Detail::ChronometerModel<Clock> meter;
6804                 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
6805
6806                 return { meter.elapsed(), std::move(result), iters };
6807             }
6808
6809             template <typename Clock, typename Fun>
6810             using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
6811
6812             struct optimized_away_error : std::exception {
6813                 const char* what() const noexcept override {
6814                     return "could not measure benchmark, maybe it was optimized away";
6815                 }
6816             };
6817
6818             template <typename Clock, typename Fun>
6819             TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
6820                 auto iters = seed;
6821                 while (iters < (1 << 30)) {
6822                     auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
6823
6824                     if (Timing.elapsed >= how_long) {
6825                         return { Timing.elapsed, std::move(Timing.result), iters };
6826                     }
6827                     iters *= 2;
6828                 }
6829                 throw optimized_away_error{};
6830             }
6831         } // namespace Detail
6832     } // namespace Benchmark
6833 } // namespace Catch
6834
6835 // end catch_run_for_at_least.hpp
6836 #include <algorithm>
6837
6838 namespace Catch {
6839     namespace Benchmark {
6840         template <typename Duration>
6841         struct ExecutionPlan {
6842             int iterations_per_sample;
6843             Duration estimated_duration;
6844             Detail::BenchmarkFunction benchmark;
6845             Duration warmup_time;
6846             int warmup_iterations;
6847
6848             template <typename Duration2>
6849             operator ExecutionPlan<Duration2>() const {
6850                 return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
6851             }
6852
6853             template <typename Clock>
6854             std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
6855                 // warmup a bit
6856                 Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
6857
6858                 std::vector<FloatDuration<Clock>> times;
6859                 times.reserve(cfg.benchmarkSamples());
6860                 std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
6861                     Detail::ChronometerModel<Clock> model;
6862                     this->benchmark(Chronometer(model, iterations_per_sample));
6863                     auto sample_time = model.elapsed() - env.clock_cost.mean;
6864                     if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
6865                     return sample_time / iterations_per_sample;
6866                 });
6867                 return times;
6868             }
6869         };
6870     } // namespace Benchmark
6871 } // namespace Catch
6872
6873 // end catch_execution_plan.hpp
6874 // start catch_estimate_clock.hpp
6875
6876  // Environment measurement
6877
6878
6879 // start catch_stats.hpp
6880
6881 // Statistical analysis tools
6882
6883
6884 #include <algorithm>
6885 #include <functional>
6886 #include <vector>
6887 #include <numeric>
6888 #include <tuple>
6889 #include <cmath>
6890 #include <utility>
6891 #include <cstddef>
6892
6893 namespace Catch {
6894     namespace Benchmark {
6895         namespace Detail {
6896             using sample = std::vector<double>;
6897
6898             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
6899
6900             template <typename Iterator>
6901             OutlierClassification classify_outliers(Iterator first, Iterator last) {
6902                 std::vector<double> copy(first, last);
6903
6904                 auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
6905                 auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
6906                 auto iqr = q3 - q1;
6907                 auto los = q1 - (iqr * 3.);
6908                 auto lom = q1 - (iqr * 1.5);
6909                 auto him = q3 + (iqr * 1.5);
6910                 auto his = q3 + (iqr * 3.);
6911
6912                 OutlierClassification o;
6913                 for (; first != last; ++first) {
6914                     auto&& t = *first;
6915                     if (t < los) ++o.low_severe;
6916                     else if (t < lom) ++o.low_mild;
6917                     else if (t > his) ++o.high_severe;
6918                     else if (t > him) ++o.high_mild;
6919                     ++o.samples_seen;
6920                 }
6921                 return o;
6922             }
6923
6924             template <typename Iterator>
6925             double mean(Iterator first, Iterator last) {
6926                 auto count = last - first;
6927                 double sum = std::accumulate(first, last, 0.);
6928                 return sum / count;
6929             }
6930
6931             template <typename URng, typename Iterator, typename Estimator>
6932             sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
6933                 auto n = last - first;
6934                 std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
6935
6936                 sample out;
6937                 out.reserve(resamples);
6938                 std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
6939                     std::vector<double> resampled;
6940                     resampled.reserve(n);
6941                     std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
6942                     return estimator(resampled.begin(), resampled.end());
6943                 });
6944                 std::sort(out.begin(), out.end());
6945                 return out;
6946             }
6947
6948             template <typename Estimator, typename Iterator>
6949             sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
6950                 auto n = last - first;
6951                 auto second = std::next(first);
6952                 sample results;
6953                 results.reserve(n);
6954
6955                 for (auto it = first; it != last; ++it) {
6956                     std::iter_swap(it, first);
6957                     results.push_back(estimator(second, last));
6958                 }
6959
6960                 return results;
6961             }
6962
6963             inline double normal_cdf(double x) {
6964                 return std::erfc(-x / std::sqrt(2.0)) / 2.0;
6965             }
6966
6967             double erfc_inv(double x);
6968
6969             double normal_quantile(double p);
6970
6971             template <typename Iterator, typename Estimator>
6972             Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
6973                 auto n_samples = last - first;
6974
6975                 double point = estimator(first, last);
6976                 // Degenerate case with a single sample
6977                 if (n_samples == 1) return { point, point, point, confidence_level };
6978
6979                 sample jack = jackknife(estimator, first, last);
6980                 double jack_mean = mean(jack.begin(), jack.end());
6981                 double sum_squares, sum_cubes;
6982                 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> {
6983                     auto d = jack_mean - x;
6984                     auto d2 = d * d;
6985                     auto d3 = d2 * d;
6986                     return { sqcb.first + d2, sqcb.second + d3 };
6987                 });
6988
6989                 double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
6990                 int n = static_cast<int>(resample.size());
6991                 double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
6992                 // degenerate case with uniform samples
6993                 if (prob_n == 0) return { point, point, point, confidence_level };
6994
6995                 double bias = normal_quantile(prob_n);
6996                 double z1 = normal_quantile((1. - confidence_level) / 2.);
6997
6998                 auto cumn = [n](double x) -> int {
6999                     return std::lround(normal_cdf(x) * n); };
7000                 auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
7001                 double b1 = bias + z1;
7002                 double b2 = bias - z1;
7003                 double a1 = a(b1);
7004                 double a2 = a(b2);
7005                 auto lo = std::max(cumn(a1), 0);
7006                 auto hi = std::min(cumn(a2), n - 1);
7007
7008                 return { point, resample[lo], resample[hi], confidence_level };
7009             }
7010
7011             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
7012
7013             struct bootstrap_analysis {
7014                 Estimate<double> mean;
7015                 Estimate<double> standard_deviation;
7016                 double outlier_variance;
7017             };
7018
7019             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
7020         } // namespace Detail
7021     } // namespace Benchmark
7022 } // namespace Catch
7023
7024 // end catch_stats.hpp
7025 #include <algorithm>
7026 #include <iterator>
7027 #include <tuple>
7028 #include <vector>
7029 #include <cmath>
7030
7031 namespace Catch {
7032     namespace Benchmark {
7033         namespace Detail {
7034             template <typename Clock>
7035             std::vector<double> resolution(int k) {
7036                 std::vector<TimePoint<Clock>> times;
7037                 times.reserve(k + 1);
7038                 std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
7039
7040                 std::vector<double> deltas;
7041                 deltas.reserve(k);
7042                 std::transform(std::next(times.begin()), times.end(), times.begin(),
7043                     std::back_inserter(deltas),
7044                     [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
7045
7046                 return deltas;
7047             }
7048
7049             const auto warmup_iterations = 10000;
7050             const auto warmup_time = std::chrono::milliseconds(100);
7051             const auto minimum_ticks = 1000;
7052             const auto warmup_seed = 10000;
7053             const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
7054             const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
7055             const auto clock_cost_estimation_tick_limit = 100000;
7056             const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
7057             const auto clock_cost_estimation_iterations = 10000;
7058
7059             template <typename Clock>
7060             int warmup() {
7061                 return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
7062                     .iterations;
7063             }
7064             template <typename Clock>
7065             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
7066                 auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
7067                     .result;
7068                 return {
7069                     FloatDuration<Clock>(mean(r.begin(), r.end())),
7070                     classify_outliers(r.begin(), r.end()),
7071                 };
7072             }
7073             template <typename Clock>
7074             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
7075                 auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
7076                 auto time_clock = [](int k) {
7077                     return Detail::measure<Clock>([k] {
7078                         for (int i = 0; i < k; ++i) {
7079                             volatile auto ignored = Clock::now();
7080                             (void)ignored;
7081                         }
7082                     }).elapsed;
7083                 };
7084                 time_clock(1);
7085                 int iters = clock_cost_estimation_iterations;
7086                 auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
7087                 std::vector<double> times;
7088                 int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
7089                 times.reserve(nsamples);
7090                 std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
7091                     return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
7092                 });
7093                 return {
7094                     FloatDuration<Clock>(mean(times.begin(), times.end())),
7095                     classify_outliers(times.begin(), times.end()),
7096                 };
7097             }
7098
7099             template <typename Clock>
7100             Environment<FloatDuration<Clock>> measure_environment() {
7101                 static Environment<FloatDuration<Clock>>* env = nullptr;
7102                 if (env) {
7103                     return *env;
7104                 }
7105
7106                 auto iters = Detail::warmup<Clock>();
7107                 auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
7108                 auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
7109
7110                 env = new Environment<FloatDuration<Clock>>{ resolution, cost };
7111                 return *env;
7112             }
7113         } // namespace Detail
7114     } // namespace Benchmark
7115 } // namespace Catch
7116
7117 // end catch_estimate_clock.hpp
7118 // start catch_analyse.hpp
7119
7120  // Run and analyse one benchmark
7121
7122
7123 // start catch_sample_analysis.hpp
7124
7125 // Benchmark results
7126
7127
7128 #include <algorithm>
7129 #include <vector>
7130 #include <string>
7131 #include <iterator>
7132
7133 namespace Catch {
7134     namespace Benchmark {
7135         template <typename Duration>
7136         struct SampleAnalysis {
7137             std::vector<Duration> samples;
7138             Estimate<Duration> mean;
7139             Estimate<Duration> standard_deviation;
7140             OutlierClassification outliers;
7141             double outlier_variance;
7142
7143             template <typename Duration2>
7144             operator SampleAnalysis<Duration2>() const {
7145                 std::vector<Duration2> samples2;
7146                 samples2.reserve(samples.size());
7147                 std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
7148                 return {
7149                     std::move(samples2),
7150                     mean,
7151                     standard_deviation,
7152                     outliers,
7153                     outlier_variance,
7154                 };
7155             }
7156         };
7157     } // namespace Benchmark
7158 } // namespace Catch
7159
7160 // end catch_sample_analysis.hpp
7161 #include <algorithm>
7162 #include <iterator>
7163 #include <vector>
7164
7165 namespace Catch {
7166     namespace Benchmark {
7167         namespace Detail {
7168             template <typename Duration, typename Iterator>
7169             SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
7170                 if (!cfg.benchmarkNoAnalysis()) {
7171                     std::vector<double> samples;
7172                     samples.reserve(last - first);
7173                     std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
7174
7175                     auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
7176                     auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
7177
7178                     auto wrap_estimate = [](Estimate<double> e) {
7179                         return Estimate<Duration> {
7180                             Duration(e.point),
7181                                 Duration(e.lower_bound),
7182                                 Duration(e.upper_bound),
7183                                 e.confidence_interval,
7184                         };
7185                     };
7186                     std::vector<Duration> samples2;
7187                     samples2.reserve(samples.size());
7188                     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
7189                     return {
7190                         std::move(samples2),
7191                         wrap_estimate(analysis.mean),
7192                         wrap_estimate(analysis.standard_deviation),
7193                         outliers,
7194                         analysis.outlier_variance,
7195                     };
7196                 } else {
7197                     std::vector<Duration> samples;
7198                     samples.reserve(last - first);
7199
7200                     Duration mean = Duration(0);
7201                     int i = 0;
7202                     for (auto it = first; it < last; ++it, ++i) {
7203                         samples.push_back(Duration(*it));
7204                         mean += Duration(*it);
7205                     }
7206                     mean /= i;
7207
7208                     return {
7209                         std::move(samples),
7210                         Estimate<Duration>{mean, mean, mean, 0.0},
7211                         Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
7212                         OutlierClassification{},
7213                         0.0
7214                     };
7215                 }
7216             }
7217         } // namespace Detail
7218     } // namespace Benchmark
7219 } // namespace Catch
7220
7221 // end catch_analyse.hpp
7222 #include <algorithm>
7223 #include <functional>
7224 #include <string>
7225 #include <vector>
7226 #include <cmath>
7227
7228 namespace Catch {
7229     namespace Benchmark {
7230         struct Benchmark {
7231             Benchmark(std::string &&name)
7232                 : name(std::move(name)) {}
7233
7234             template <class FUN>
7235             Benchmark(std::string &&name, FUN &&func)
7236                 : fun(std::move(func)), name(std::move(name)) {}
7237
7238             template <typename Clock>
7239             ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
7240                 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
7241                 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
7242                 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
7243                 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
7244                 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
7245             }
7246
7247             template <typename Clock = default_clock>
7248             void run() {
7249                 IConfigPtr cfg = getCurrentContext().getConfig();
7250
7251                 auto env = Detail::measure_environment<Clock>();
7252
7253                 getResultCapture().benchmarkPreparing(name);
7254                 CATCH_TRY{
7255                     auto plan = user_code([&] {
7256                         return prepare<Clock>(*cfg, env);
7257                     });
7258
7259                     BenchmarkInfo info {
7260                         name,
7261                         plan.estimated_duration.count(),
7262                         plan.iterations_per_sample,
7263                         cfg->benchmarkSamples(),
7264                         cfg->benchmarkResamples(),
7265                         env.clock_resolution.mean.count(),
7266                         env.clock_cost.mean.count()
7267                     };
7268
7269                     getResultCapture().benchmarkStarting(info);
7270
7271                     auto samples = user_code([&] {
7272                         return plan.template run<Clock>(*cfg, env);
7273                     });
7274
7275                     auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
7276                     BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
7277                     getResultCapture().benchmarkEnded(stats);
7278
7279                 } CATCH_CATCH_ALL{
7280                     if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
7281                         std::rethrow_exception(std::current_exception());
7282                 }
7283             }
7284
7285             // sets lambda to be used in fun *and* executes benchmark!
7286             template <typename Fun,
7287                 typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
7288                 Benchmark & operator=(Fun func) {
7289                 fun = Detail::BenchmarkFunction(func);
7290                 run();
7291                 return *this;
7292             }
7293
7294             explicit operator bool() {
7295                 return true;
7296             }
7297
7298         private:
7299             Detail::BenchmarkFunction fun;
7300             std::string name;
7301         };
7302     }
7303 } // namespace Catch
7304
7305 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
7306 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
7307
7308 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
7309     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7310         BenchmarkName = [&](int benchmarkIndex)
7311
7312 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
7313     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7314         BenchmarkName = [&]
7315
7316 // end catch_benchmark.hpp
7317 // start catch_constructor.hpp
7318
7319 // Constructor and destructor helpers
7320
7321
7322 #include <type_traits>
7323
7324 namespace Catch {
7325     namespace Benchmark {
7326         namespace Detail {
7327             template <typename T, bool Destruct>
7328             struct ObjectStorage
7329             {
7330                 using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
7331
7332                 ObjectStorage() : data() {}
7333
7334                 ObjectStorage(const ObjectStorage& other)
7335                 {
7336                     new(&data) T(other.stored_object());
7337                 }
7338
7339                 ObjectStorage(ObjectStorage&& other)
7340                 {
7341                     new(&data) T(std::move(other.stored_object()));
7342                 }
7343
7344                 ~ObjectStorage() { destruct_on_exit<T>(); }
7345
7346                 template <typename... Args>
7347                 void construct(Args&&... args)
7348                 {
7349                     new (&data) T(std::forward<Args>(args)...);
7350                 }
7351
7352                 template <bool AllowManualDestruction = !Destruct>
7353                 typename std::enable_if<AllowManualDestruction>::type destruct()
7354                 {
7355                     stored_object().~T();
7356                 }
7357
7358             private:
7359                 // If this is a constructor benchmark, destruct the underlying object
7360                 template <typename U>
7361                 void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
7362                 // Otherwise, don't
7363                 template <typename U>
7364                 void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
7365
7366                 T& stored_object() {
7367                     return *static_cast<T*>(static_cast<void*>(&data));
7368                 }
7369
7370                 T const& stored_object() const {
7371                     return *static_cast<T*>(static_cast<void*>(&data));
7372                 }
7373
7374                 TStorage data;
7375             };
7376         }
7377
7378         template <typename T>
7379         using storage_for = Detail::ObjectStorage<T, true>;
7380
7381         template <typename T>
7382         using destructable_object = Detail::ObjectStorage<T, false>;
7383     }
7384 }
7385
7386 // end catch_constructor.hpp
7387 // end catch_benchmarking_all.hpp
7388 #endif
7389
7390 #endif // ! CATCH_CONFIG_IMPL_ONLY
7391
7392 #ifdef CATCH_IMPL
7393 // start catch_impl.hpp
7394
7395 #ifdef __clang__
7396 #pragma clang diagnostic push
7397 #pragma clang diagnostic ignored "-Wweak-vtables"
7398 #endif
7399
7400 // Keep these here for external reporters
7401 // start catch_test_case_tracker.h
7402
7403 #include <string>
7404 #include <vector>
7405 #include <memory>
7406
7407 namespace Catch {
7408 namespace TestCaseTracking {
7409
7410     struct NameAndLocation {
7411         std::string name;
7412         SourceLineInfo location;
7413
7414         NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
7415     };
7416
7417     struct ITracker;
7418
7419     using ITrackerPtr = std::shared_ptr<ITracker>;
7420
7421     struct ITracker {
7422         virtual ~ITracker();
7423
7424         // static queries
7425         virtual NameAndLocation const& nameAndLocation() const = 0;
7426
7427         // dynamic queries
7428         virtual bool isComplete() const = 0; // Successfully completed or failed
7429         virtual bool isSuccessfullyCompleted() const = 0;
7430         virtual bool isOpen() const = 0; // Started but not complete
7431         virtual bool hasChildren() const = 0;
7432
7433         virtual ITracker& parent() = 0;
7434
7435         // actions
7436         virtual void close() = 0; // Successfully complete
7437         virtual void fail() = 0;
7438         virtual void markAsNeedingAnotherRun() = 0;
7439
7440         virtual void addChild( ITrackerPtr const& child ) = 0;
7441         virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
7442         virtual void openChild() = 0;
7443
7444         // Debug/ checking
7445         virtual bool isSectionTracker() const = 0;
7446         virtual bool isGeneratorTracker() const = 0;
7447     };
7448
7449     class TrackerContext {
7450
7451         enum RunState {
7452             NotStarted,
7453             Executing,
7454             CompletedCycle
7455         };
7456
7457         ITrackerPtr m_rootTracker;
7458         ITracker* m_currentTracker = nullptr;
7459         RunState m_runState = NotStarted;
7460
7461     public:
7462
7463         ITracker& startRun();
7464         void endRun();
7465
7466         void startCycle();
7467         void completeCycle();
7468
7469         bool completedCycle() const;
7470         ITracker& currentTracker();
7471         void setCurrentTracker( ITracker* tracker );
7472     };
7473
7474     class TrackerBase : public ITracker {
7475     protected:
7476         enum CycleState {
7477             NotStarted,
7478             Executing,
7479             ExecutingChildren,
7480             NeedsAnotherRun,
7481             CompletedSuccessfully,
7482             Failed
7483         };
7484
7485         using Children = std::vector<ITrackerPtr>;
7486         NameAndLocation m_nameAndLocation;
7487         TrackerContext& m_ctx;
7488         ITracker* m_parent;
7489         Children m_children;
7490         CycleState m_runState = NotStarted;
7491
7492     public:
7493         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7494
7495         NameAndLocation const& nameAndLocation() const override;
7496         bool isComplete() const override;
7497         bool isSuccessfullyCompleted() const override;
7498         bool isOpen() const override;
7499         bool hasChildren() const override;
7500
7501         void addChild( ITrackerPtr const& child ) override;
7502
7503         ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
7504         ITracker& parent() override;
7505
7506         void openChild() override;
7507
7508         bool isSectionTracker() const override;
7509         bool isGeneratorTracker() const override;
7510
7511         void open();
7512
7513         void close() override;
7514         void fail() override;
7515         void markAsNeedingAnotherRun() override;
7516
7517     private:
7518         void moveToParent();
7519         void moveToThis();
7520     };
7521
7522     class SectionTracker : public TrackerBase {
7523         std::vector<std::string> m_filters;
7524         std::string m_trimmed_name;
7525     public:
7526         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7527
7528         bool isSectionTracker() const override;
7529
7530         bool isComplete() const override;
7531
7532         static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
7533
7534         void tryOpen();
7535
7536         void addInitialFilters( std::vector<std::string> const& filters );
7537         void addNextFilters( std::vector<std::string> const& filters );
7538     };
7539
7540 } // namespace TestCaseTracking
7541
7542 using TestCaseTracking::ITracker;
7543 using TestCaseTracking::TrackerContext;
7544 using TestCaseTracking::SectionTracker;
7545
7546 } // namespace Catch
7547
7548 // end catch_test_case_tracker.h
7549
7550 // start catch_leak_detector.h
7551
7552 namespace Catch {
7553
7554     struct LeakDetector {
7555         LeakDetector();
7556         ~LeakDetector();
7557     };
7558
7559 }
7560 // end catch_leak_detector.h
7561 // Cpp files will be included in the single-header file here
7562 // start catch_stats.cpp
7563
7564 // Statistical analysis tools
7565
7566 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
7567
7568 #include <cassert>
7569 #include <random>
7570
7571 #if defined(CATCH_CONFIG_USE_ASYNC)
7572 #include <future>
7573 #endif
7574
7575 namespace {
7576     double erf_inv(double x) {
7577         // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
7578         double w, p;
7579
7580         w = -log((1.0 - x) * (1.0 + x));
7581
7582         if (w < 6.250000) {
7583             w = w - 3.125000;
7584             p = -3.6444120640178196996e-21;
7585             p = -1.685059138182016589e-19 + p * w;
7586             p = 1.2858480715256400167e-18 + p * w;
7587             p = 1.115787767802518096e-17 + p * w;
7588             p = -1.333171662854620906e-16 + p * w;
7589             p = 2.0972767875968561637e-17 + p * w;
7590             p = 6.6376381343583238325e-15 + p * w;
7591             p = -4.0545662729752068639e-14 + p * w;
7592             p = -8.1519341976054721522e-14 + p * w;
7593             p = 2.6335093153082322977e-12 + p * w;
7594             p = -1.2975133253453532498e-11 + p * w;
7595             p = -5.4154120542946279317e-11 + p * w;
7596             p = 1.051212273321532285e-09 + p * w;
7597             p = -4.1126339803469836976e-09 + p * w;
7598             p = -2.9070369957882005086e-08 + p * w;
7599             p = 4.2347877827932403518e-07 + p * w;
7600             p = -1.3654692000834678645e-06 + p * w;
7601             p = -1.3882523362786468719e-05 + p * w;
7602             p = 0.0001867342080340571352 + p * w;
7603             p = -0.00074070253416626697512 + p * w;
7604             p = -0.0060336708714301490533 + p * w;
7605             p = 0.24015818242558961693 + p * w;
7606             p = 1.6536545626831027356 + p * w;
7607         } else if (w < 16.000000) {
7608             w = sqrt(w) - 3.250000;
7609             p = 2.2137376921775787049e-09;
7610             p = 9.0756561938885390979e-08 + p * w;
7611             p = -2.7517406297064545428e-07 + p * w;
7612             p = 1.8239629214389227755e-08 + p * w;
7613             p = 1.5027403968909827627e-06 + p * w;
7614             p = -4.013867526981545969e-06 + p * w;
7615             p = 2.9234449089955446044e-06 + p * w;
7616             p = 1.2475304481671778723e-05 + p * w;
7617             p = -4.7318229009055733981e-05 + p * w;
7618             p = 6.8284851459573175448e-05 + p * w;
7619             p = 2.4031110387097893999e-05 + p * w;
7620             p = -0.0003550375203628474796 + p * w;
7621             p = 0.00095328937973738049703 + p * w;
7622             p = -0.0016882755560235047313 + p * w;
7623             p = 0.0024914420961078508066 + p * w;
7624             p = -0.0037512085075692412107 + p * w;
7625             p = 0.005370914553590063617 + p * w;
7626             p = 1.0052589676941592334 + p * w;
7627             p = 3.0838856104922207635 + p * w;
7628         } else {
7629             w = sqrt(w) - 5.000000;
7630             p = -2.7109920616438573243e-11;
7631             p = -2.5556418169965252055e-10 + p * w;
7632             p = 1.5076572693500548083e-09 + p * w;
7633             p = -3.7894654401267369937e-09 + p * w;
7634             p = 7.6157012080783393804e-09 + p * w;
7635             p = -1.4960026627149240478e-08 + p * w;
7636             p = 2.9147953450901080826e-08 + p * w;
7637             p = -6.7711997758452339498e-08 + p * w;
7638             p = 2.2900482228026654717e-07 + p * w;
7639             p = -9.9298272942317002539e-07 + p * w;
7640             p = 4.5260625972231537039e-06 + p * w;
7641             p = -1.9681778105531670567e-05 + p * w;
7642             p = 7.5995277030017761139e-05 + p * w;
7643             p = -0.00021503011930044477347 + p * w;
7644             p = -0.00013871931833623122026 + p * w;
7645             p = 1.0103004648645343977 + p * w;
7646             p = 4.8499064014085844221 + p * w;
7647         }
7648         return p * x;
7649     }
7650
7651     double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
7652         auto m = Catch::Benchmark::Detail::mean(first, last);
7653         double variance = std::accumulate(first, last, 0., [m](double a, double b) {
7654             double diff = b - m;
7655             return a + diff * diff;
7656             }) / (last - first);
7657             return std::sqrt(variance);
7658     }
7659
7660 }
7661
7662 namespace Catch {
7663     namespace Benchmark {
7664         namespace Detail {
7665
7666             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7667                 auto count = last - first;
7668                 double idx = (count - 1) * k / static_cast<double>(q);
7669                 int j = static_cast<int>(idx);
7670                 double g = idx - j;
7671                 std::nth_element(first, first + j, last);
7672                 auto xj = first[j];
7673                 if (g == 0) return xj;
7674
7675                 auto xj1 = *std::min_element(first + (j + 1), last);
7676                 return xj + g * (xj1 - xj);
7677             }
7678
7679             double erfc_inv(double x) {
7680                 return erf_inv(1.0 - x);
7681             }
7682
7683             double normal_quantile(double p) {
7684                 static const double ROOT_TWO = std::sqrt(2.0);
7685
7686                 double result = 0.0;
7687                 assert(p >= 0 && p <= 1);
7688                 if (p < 0 || p > 1) {
7689                     return result;
7690                 }
7691
7692                 result = -erfc_inv(2.0 * p);
7693                 // result *= normal distribution standard deviation (1.0) * sqrt(2)
7694                 result *= /*sd * */ ROOT_TWO;
7695                 // result += normal disttribution mean (0)
7696                 return result;
7697             }
7698
7699             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
7700                 double sb = stddev.point;
7701                 double mn = mean.point / n;
7702                 double mg_min = mn / 2.;
7703                 double sg = std::min(mg_min / 4., sb / std::sqrt(n));
7704                 double sg2 = sg * sg;
7705                 double sb2 = sb * sb;
7706
7707                 auto c_max = [n, mn, sb2, sg2](double x) -> double {
7708                     double k = mn - x;
7709                     double d = k * k;
7710                     double nd = n * d;
7711                     double k0 = -n * nd;
7712                     double k1 = sb2 - n * sg2 + nd;
7713                     double det = k1 * k1 - 4 * sg2 * k0;
7714                     return (int)(-2. * k0 / (k1 + std::sqrt(det)));
7715                 };
7716
7717                 auto var_out = [n, sb2, sg2](double c) {
7718                     double nc = n - c;
7719                     return (nc / n) * (sb2 - nc * sg2);
7720                 };
7721
7722                 return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
7723             }
7724
7725             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7726                 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
7727                 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
7728                 static std::random_device entropy;
7729                 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
7730
7731                 auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
7732
7733                 auto mean = &Detail::mean<std::vector<double>::iterator>;
7734                 auto stddev = &standard_deviation;
7735
7736 #if defined(CATCH_CONFIG_USE_ASYNC)
7737                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7738                     auto seed = entropy();
7739                     return std::async(std::launch::async, [=] {
7740                         std::mt19937 rng(seed);
7741                         auto resampled = resample(rng, n_resamples, first, last, f);
7742                         return bootstrap(confidence_level, first, last, resampled, f);
7743                     });
7744                 };
7745
7746                 auto mean_future = Estimate(mean);
7747                 auto stddev_future = Estimate(stddev);
7748
7749                 auto mean_estimate = mean_future.get();
7750                 auto stddev_estimate = stddev_future.get();
7751 #else
7752                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7753                     auto seed = entropy();
7754                     std::mt19937 rng(seed);
7755                     auto resampled = resample(rng, n_resamples, first, last, f);
7756                     return bootstrap(confidence_level, first, last, resampled, f);
7757                 };
7758
7759                 auto mean_estimate = Estimate(mean);
7760                 auto stddev_estimate = Estimate(stddev);
7761 #endif // CATCH_USE_ASYNC
7762
7763                 double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
7764
7765                 return { mean_estimate, stddev_estimate, outlier_variance };
7766             }
7767         } // namespace Detail
7768     } // namespace Benchmark
7769 } // namespace Catch
7770
7771 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
7772 // end catch_stats.cpp
7773 // start catch_approx.cpp
7774
7775 #include <cmath>
7776 #include <limits>
7777
7778 namespace {
7779
7780 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
7781 // But without the subtraction to allow for INFINITY in comparison
7782 bool marginComparison(double lhs, double rhs, double margin) {
7783     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
7784 }
7785
7786 }
7787
7788 namespace Catch {
7789 namespace Detail {
7790
7791     Approx::Approx ( double value )
7792     :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
7793         m_margin( 0.0 ),
7794         m_scale( 0.0 ),
7795         m_value( value )
7796     {}
7797
7798     Approx Approx::custom() {
7799         return Approx( 0 );
7800     }
7801
7802     Approx Approx::operator-() const {
7803         auto temp(*this);
7804         temp.m_value = -temp.m_value;
7805         return temp;
7806     }
7807
7808     std::string Approx::toString() const {
7809         ReusableStringStream rss;
7810         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
7811         return rss.str();
7812     }
7813
7814     bool Approx::equalityComparisonImpl(const double other) const {
7815         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
7816         // Thanks to Richard Harris for his help refining the scaled margin value
7817         return marginComparison(m_value, other, m_margin)
7818             || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
7819     }
7820
7821     void Approx::setMargin(double newMargin) {
7822         CATCH_ENFORCE(newMargin >= 0,
7823             "Invalid Approx::margin: " << newMargin << '.'
7824             << " Approx::Margin has to be non-negative.");
7825         m_margin = newMargin;
7826     }
7827
7828     void Approx::setEpsilon(double newEpsilon) {
7829         CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
7830             "Invalid Approx::epsilon: " << newEpsilon << '.'
7831             << " Approx::epsilon has to be in [0, 1]");
7832         m_epsilon = newEpsilon;
7833     }
7834
7835 } // end namespace Detail
7836
7837 namespace literals {
7838     Detail::Approx operator "" _a(long double val) {
7839         return Detail::Approx(val);
7840     }
7841     Detail::Approx operator "" _a(unsigned long long val) {
7842         return Detail::Approx(val);
7843     }
7844 } // end namespace literals
7845
7846 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
7847     return value.toString();
7848 }
7849
7850 } // end namespace Catch
7851 // end catch_approx.cpp
7852 // start catch_assertionhandler.cpp
7853
7854 // start catch_debugger.h
7855
7856 namespace Catch {
7857     bool isDebuggerActive();
7858 }
7859
7860 #ifdef CATCH_PLATFORM_MAC
7861
7862     #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
7863
7864 #elif defined(CATCH_PLATFORM_IPHONE)
7865
7866     // use inline assembler
7867     #if defined(__i386__) || defined(__x86_64__)
7868         #define CATCH_TRAP()  __asm__("int $3")
7869     #elif defined(__aarch64__)
7870         #define CATCH_TRAP()  __asm__(".inst 0xd4200000")
7871     #elif defined(__arm__)
7872         #define CATCH_TRAP()  __asm__(".inst 0xe7f001f0")
7873     #endif
7874
7875 #elif defined(CATCH_PLATFORM_LINUX)
7876     // If we can use inline assembler, do it because this allows us to break
7877     // directly at the location of the failing check instead of breaking inside
7878     // raise() called from it, i.e. one stack frame below.
7879     #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
7880         #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
7881     #else // Fall back to the generic way.
7882         #include <signal.h>
7883
7884         #define CATCH_TRAP() raise(SIGTRAP)
7885     #endif
7886 #elif defined(_MSC_VER)
7887     #define CATCH_TRAP() __debugbreak()
7888 #elif defined(__MINGW32__)
7889     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
7890     #define CATCH_TRAP() DebugBreak()
7891 #endif
7892
7893 #ifdef CATCH_TRAP
7894     #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
7895 #else
7896     #define CATCH_BREAK_INTO_DEBUGGER() []{}()
7897 #endif
7898
7899 // end catch_debugger.h
7900 // start catch_run_context.h
7901
7902 // start catch_fatal_condition.h
7903
7904 // start catch_windows_h_proxy.h
7905
7906
7907 #if defined(CATCH_PLATFORM_WINDOWS)
7908
7909 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
7910 #  define CATCH_DEFINED_NOMINMAX
7911 #  define NOMINMAX
7912 #endif
7913 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
7914 #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
7915 #  define WIN32_LEAN_AND_MEAN
7916 #endif
7917
7918 #ifdef __AFXDLL
7919 #include <AfxWin.h>
7920 #else
7921 #include <windows.h>
7922 #endif
7923
7924 #ifdef CATCH_DEFINED_NOMINMAX
7925 #  undef NOMINMAX
7926 #endif
7927 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
7928 #  undef WIN32_LEAN_AND_MEAN
7929 #endif
7930
7931 #endif // defined(CATCH_PLATFORM_WINDOWS)
7932
7933 // end catch_windows_h_proxy.h
7934 #if defined( CATCH_CONFIG_WINDOWS_SEH )
7935
7936 namespace Catch {
7937
7938     struct FatalConditionHandler {
7939
7940         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
7941         FatalConditionHandler();
7942         static void reset();
7943         ~FatalConditionHandler();
7944
7945     private:
7946         static bool isSet;
7947         static ULONG guaranteeSize;
7948         static PVOID exceptionHandlerHandle;
7949     };
7950
7951 } // namespace Catch
7952
7953 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
7954
7955 #include <signal.h>
7956
7957 namespace Catch {
7958
7959     struct FatalConditionHandler {
7960
7961         static bool isSet;
7962         static struct sigaction oldSigActions[];
7963         static stack_t oldSigStack;
7964         static char altStackMem[];
7965
7966         static void handleSignal( int sig );
7967
7968         FatalConditionHandler();
7969         ~FatalConditionHandler();
7970         static void reset();
7971     };
7972
7973 } // namespace Catch
7974
7975 #else
7976
7977 namespace Catch {
7978     struct FatalConditionHandler {
7979         void reset();
7980     };
7981 }
7982
7983 #endif
7984
7985 // end catch_fatal_condition.h
7986 #include <string>
7987
7988 namespace Catch {
7989
7990     struct IMutableContext;
7991
7992     ///////////////////////////////////////////////////////////////////////////
7993
7994     class RunContext : public IResultCapture, public IRunner {
7995
7996     public:
7997         RunContext( RunContext const& ) = delete;
7998         RunContext& operator =( RunContext const& ) = delete;
7999
8000         explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
8001
8002         ~RunContext() override;
8003
8004         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
8005         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
8006
8007         Totals runTest(TestCase const& testCase);
8008
8009         IConfigPtr config() const;
8010         IStreamingReporter& reporter() const;
8011
8012     public: // IResultCapture
8013
8014         // Assertion handlers
8015         void handleExpr
8016                 (   AssertionInfo const& info,
8017                     ITransientExpression const& expr,
8018                     AssertionReaction& reaction ) override;
8019         void handleMessage
8020                 (   AssertionInfo const& info,
8021                     ResultWas::OfType resultType,
8022                     StringRef const& message,
8023                     AssertionReaction& reaction ) override;
8024         void handleUnexpectedExceptionNotThrown
8025                 (   AssertionInfo const& info,
8026                     AssertionReaction& reaction ) override;
8027         void handleUnexpectedInflightException
8028                 (   AssertionInfo const& info,
8029                     std::string const& message,
8030                     AssertionReaction& reaction ) override;
8031         void handleIncomplete
8032                 (   AssertionInfo const& info ) override;
8033         void handleNonExpr
8034                 (   AssertionInfo const &info,
8035                     ResultWas::OfType resultType,
8036                     AssertionReaction &reaction ) override;
8037
8038         bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
8039
8040         void sectionEnded( SectionEndInfo const& endInfo ) override;
8041         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
8042
8043         auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
8044
8045 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
8046         void benchmarkPreparing( std::string const& name ) override;
8047         void benchmarkStarting( BenchmarkInfo const& info ) override;
8048         void benchmarkEnded( BenchmarkStats<> const& stats ) override;
8049         void benchmarkFailed( std::string const& error ) override;
8050 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
8051
8052         void pushScopedMessage( MessageInfo const& message ) override;
8053         void popScopedMessage( MessageInfo const& message ) override;
8054
8055         void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
8056
8057         std::string getCurrentTestName() const override;
8058
8059         const AssertionResult* getLastResult() const override;
8060
8061         void exceptionEarlyReported() override;
8062
8063         void handleFatalErrorCondition( StringRef message ) override;
8064
8065         bool lastAssertionPassed() override;
8066
8067         void assertionPassed() override;
8068
8069     public:
8070         // !TBD We need to do this another way!
8071         bool aborting() const final;
8072
8073     private:
8074
8075         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
8076         void invokeActiveTestCase();
8077
8078         void resetAssertionInfo();
8079         bool testForMissingAssertions( Counts& assertions );
8080
8081         void assertionEnded( AssertionResult const& result );
8082         void reportExpr
8083                 (   AssertionInfo const &info,
8084                     ResultWas::OfType resultType,
8085                     ITransientExpression const *expr,
8086                     bool negated );
8087
8088         void populateReaction( AssertionReaction& reaction );
8089
8090     private:
8091
8092         void handleUnfinishedSections();
8093
8094         TestRunInfo m_runInfo;
8095         IMutableContext& m_context;
8096         TestCase const* m_activeTestCase = nullptr;
8097         ITracker* m_testCaseTracker = nullptr;
8098         Option<AssertionResult> m_lastResult;
8099
8100         IConfigPtr m_config;
8101         Totals m_totals;
8102         IStreamingReporterPtr m_reporter;
8103         std::vector<MessageInfo> m_messages;
8104         std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
8105         AssertionInfo m_lastAssertionInfo;
8106         std::vector<SectionEndInfo> m_unfinishedSections;
8107         std::vector<ITracker*> m_activeSections;
8108         TrackerContext m_trackerContext;
8109         bool m_lastAssertionPassed = false;
8110         bool m_shouldReportUnexpected = true;
8111         bool m_includeSuccessfulResults;
8112     };
8113
8114     void seedRng(IConfig const& config);
8115     unsigned int rngSeed();
8116 } // end namespace Catch
8117
8118 // end catch_run_context.h
8119 namespace Catch {
8120
8121     namespace {
8122         auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
8123             expr.streamReconstructedExpression( os );
8124             return os;
8125         }
8126     }
8127
8128     LazyExpression::LazyExpression( bool isNegated )
8129     :   m_isNegated( isNegated )
8130     {}
8131
8132     LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
8133
8134     LazyExpression::operator bool() const {
8135         return m_transientExpression != nullptr;
8136     }
8137
8138     auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
8139         if( lazyExpr.m_isNegated )
8140             os << "!";
8141
8142         if( lazyExpr ) {
8143             if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
8144                 os << "(" << *lazyExpr.m_transientExpression << ")";
8145             else
8146                 os << *lazyExpr.m_transientExpression;
8147         }
8148         else {
8149             os << "{** error - unchecked empty expression requested **}";
8150         }
8151         return os;
8152     }
8153
8154     AssertionHandler::AssertionHandler
8155         (   StringRef const& macroName,
8156             SourceLineInfo const& lineInfo,
8157             StringRef capturedExpression,
8158             ResultDisposition::Flags resultDisposition )
8159     :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
8160         m_resultCapture( getResultCapture() )
8161     {}
8162
8163     void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
8164         m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
8165     }
8166     void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
8167         m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
8168     }
8169
8170     auto AssertionHandler::allowThrows() const -> bool {
8171         return getCurrentContext().getConfig()->allowThrows();
8172     }
8173
8174     void AssertionHandler::complete() {
8175         setCompleted();
8176         if( m_reaction.shouldDebugBreak ) {
8177
8178             // If you find your debugger stopping you here then go one level up on the
8179             // call-stack for the code that caused it (typically a failed assertion)
8180
8181             // (To go back to the test and change execution, jump over the throw, next)
8182             CATCH_BREAK_INTO_DEBUGGER();
8183         }
8184         if (m_reaction.shouldThrow) {
8185 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8186             throw Catch::TestFailureException();
8187 #else
8188             CATCH_ERROR( "Test failure requires aborting test!" );
8189 #endif
8190         }
8191     }
8192     void AssertionHandler::setCompleted() {
8193         m_completed = true;
8194     }
8195
8196     void AssertionHandler::handleUnexpectedInflightException() {
8197         m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
8198     }
8199
8200     void AssertionHandler::handleExceptionThrownAsExpected() {
8201         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8202     }
8203     void AssertionHandler::handleExceptionNotThrownAsExpected() {
8204         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8205     }
8206
8207     void AssertionHandler::handleUnexpectedExceptionNotThrown() {
8208         m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
8209     }
8210
8211     void AssertionHandler::handleThrowingCallSkipped() {
8212         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8213     }
8214
8215     // This is the overload that takes a string and infers the Equals matcher from it
8216     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
8217     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
8218         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
8219     }
8220
8221 } // namespace Catch
8222 // end catch_assertionhandler.cpp
8223 // start catch_assertionresult.cpp
8224
8225 namespace Catch {
8226     AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
8227         lazyExpression(_lazyExpression),
8228         resultType(_resultType) {}
8229
8230     std::string AssertionResultData::reconstructExpression() const {
8231
8232         if( reconstructedExpression.empty() ) {
8233             if( lazyExpression ) {
8234                 ReusableStringStream rss;
8235                 rss << lazyExpression;
8236                 reconstructedExpression = rss.str();
8237             }
8238         }
8239         return reconstructedExpression;
8240     }
8241
8242     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
8243     :   m_info( info ),
8244         m_resultData( data )
8245     {}
8246
8247     // Result was a success
8248     bool AssertionResult::succeeded() const {
8249         return Catch::isOk( m_resultData.resultType );
8250     }
8251
8252     // Result was a success, or failure is suppressed
8253     bool AssertionResult::isOk() const {
8254         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
8255     }
8256
8257     ResultWas::OfType AssertionResult::getResultType() const {
8258         return m_resultData.resultType;
8259     }
8260
8261     bool AssertionResult::hasExpression() const {
8262         return !m_info.capturedExpression.empty();
8263     }
8264
8265     bool AssertionResult::hasMessage() const {
8266         return !m_resultData.message.empty();
8267     }
8268
8269     std::string AssertionResult::getExpression() const {
8270         // Possibly overallocating by 3 characters should be basically free
8271         std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
8272         if (isFalseTest(m_info.resultDisposition)) {
8273             expr += "!(";
8274         }
8275         expr += m_info.capturedExpression;
8276         if (isFalseTest(m_info.resultDisposition)) {
8277             expr += ')';
8278         }
8279         return expr;
8280     }
8281
8282     std::string AssertionResult::getExpressionInMacro() const {
8283         std::string expr;
8284         if( m_info.macroName.empty() )
8285             expr = static_cast<std::string>(m_info.capturedExpression);
8286         else {
8287             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
8288             expr += m_info.macroName;
8289             expr += "( ";
8290             expr += m_info.capturedExpression;
8291             expr += " )";
8292         }
8293         return expr;
8294     }
8295
8296     bool AssertionResult::hasExpandedExpression() const {
8297         return hasExpression() && getExpandedExpression() != getExpression();
8298     }
8299
8300     std::string AssertionResult::getExpandedExpression() const {
8301         std::string expr = m_resultData.reconstructExpression();
8302         return expr.empty()
8303                 ? getExpression()
8304                 : expr;
8305     }
8306
8307     std::string AssertionResult::getMessage() const {
8308         return m_resultData.message;
8309     }
8310     SourceLineInfo AssertionResult::getSourceInfo() const {
8311         return m_info.lineInfo;
8312     }
8313
8314     StringRef AssertionResult::getTestMacroName() const {
8315         return m_info.macroName;
8316     }
8317
8318 } // end namespace Catch
8319 // end catch_assertionresult.cpp
8320 // start catch_capture_matchers.cpp
8321
8322 namespace Catch {
8323
8324     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
8325
8326     // This is the general overload that takes a any string matcher
8327     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
8328     // the Equals matcher (so the header does not mention matchers)
8329     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
8330         std::string exceptionMessage = Catch::translateActiveException();
8331         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
8332         handler.handleExpr( expr );
8333     }
8334
8335 } // namespace Catch
8336 // end catch_capture_matchers.cpp
8337 // start catch_commandline.cpp
8338
8339 // start catch_commandline.h
8340
8341 // start catch_clara.h
8342
8343 // Use Catch's value for console width (store Clara's off to the side, if present)
8344 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
8345 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8346 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8347 #endif
8348 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
8349
8350 #ifdef __clang__
8351 #pragma clang diagnostic push
8352 #pragma clang diagnostic ignored "-Wweak-vtables"
8353 #pragma clang diagnostic ignored "-Wexit-time-destructors"
8354 #pragma clang diagnostic ignored "-Wshadow"
8355 #endif
8356
8357 // start clara.hpp
8358 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
8359 //
8360 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8361 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8362 //
8363 // See https://github.com/philsquared/Clara for more details
8364
8365 // Clara v1.1.5
8366
8367
8368 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8369 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
8370 #endif
8371
8372 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8373 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8374 #endif
8375
8376 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
8377 #ifdef __has_include
8378 #if __has_include(<optional>) && __cplusplus >= 201703L
8379 #include <optional>
8380 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
8381 #endif
8382 #endif
8383 #endif
8384
8385 // ----------- #included from clara_textflow.hpp -----------
8386
8387 // TextFlowCpp
8388 //
8389 // A single-header library for wrapping and laying out basic text, by Phil Nash
8390 //
8391 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8392 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8393 //
8394 // This project is hosted at https://github.com/philsquared/textflowcpp
8395
8396
8397 #include <cassert>
8398 #include <ostream>
8399 #include <sstream>
8400 #include <vector>
8401
8402 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8403 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
8404 #endif
8405
8406 namespace Catch {
8407 namespace clara {
8408 namespace TextFlow {
8409
8410 inline auto isWhitespace(char c) -> bool {
8411         static std::string chars = " \t\n\r";
8412         return chars.find(c) != std::string::npos;
8413 }
8414 inline auto isBreakableBefore(char c) -> bool {
8415         static std::string chars = "[({<|";
8416         return chars.find(c) != std::string::npos;
8417 }
8418 inline auto isBreakableAfter(char c) -> bool {
8419         static std::string chars = "])}>.,:;*+-=&/\\";
8420         return chars.find(c) != std::string::npos;
8421 }
8422
8423 class Columns;
8424
8425 class Column {
8426         std::vector<std::string> m_strings;
8427         size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
8428         size_t m_indent = 0;
8429         size_t m_initialIndent = std::string::npos;
8430
8431 public:
8432         class iterator {
8433                 friend Column;
8434
8435                 Column const& m_column;
8436                 size_t m_stringIndex = 0;
8437                 size_t m_pos = 0;
8438
8439                 size_t m_len = 0;
8440                 size_t m_end = 0;
8441                 bool m_suffix = false;
8442
8443                 iterator(Column const& column, size_t stringIndex)
8444                         : m_column(column),
8445                         m_stringIndex(stringIndex) {}
8446
8447                 auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
8448
8449                 auto isBoundary(size_t at) const -> bool {
8450                         assert(at > 0);
8451                         assert(at <= line().size());
8452
8453                         return at == line().size() ||
8454                                 (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
8455                                 isBreakableBefore(line()[at]) ||
8456                                 isBreakableAfter(line()[at - 1]);
8457                 }
8458
8459                 void calcLength() {
8460                         assert(m_stringIndex < m_column.m_strings.size());
8461
8462                         m_suffix = false;
8463                         auto width = m_column.m_width - indent();
8464                         m_end = m_pos;
8465                         if (line()[m_pos] == '\n') {
8466                                 ++m_end;
8467                         }
8468                         while (m_end < line().size() && line()[m_end] != '\n')
8469                                 ++m_end;
8470
8471                         if (m_end < m_pos + width) {
8472                                 m_len = m_end - m_pos;
8473                         } else {
8474                                 size_t len = width;
8475                                 while (len > 0 && !isBoundary(m_pos + len))
8476                                         --len;
8477                                 while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
8478                                         --len;
8479
8480                                 if (len > 0) {
8481                                         m_len = len;
8482                                 } else {
8483                                         m_suffix = true;
8484                                         m_len = width - 1;
8485                                 }
8486                         }
8487                 }
8488
8489                 auto indent() const -> size_t {
8490                         auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
8491                         return initial == std::string::npos ? m_column.m_indent : initial;
8492                 }
8493
8494                 auto addIndentAndSuffix(std::string const &plain) const -> std::string {
8495                         return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
8496                 }
8497
8498         public:
8499                 using difference_type = std::ptrdiff_t;
8500                 using value_type = std::string;
8501                 using pointer = value_type * ;
8502                 using reference = value_type & ;
8503                 using iterator_category = std::forward_iterator_tag;
8504
8505                 explicit iterator(Column const& column) : m_column(column) {
8506                         assert(m_column.m_width > m_column.m_indent);
8507                         assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
8508                         calcLength();
8509                         if (m_len == 0)
8510                                 m_stringIndex++; // Empty string
8511                 }
8512
8513                 auto operator *() const -> std::string {
8514                         assert(m_stringIndex < m_column.m_strings.size());
8515                         assert(m_pos <= m_end);
8516                         return addIndentAndSuffix(line().substr(m_pos, m_len));
8517                 }
8518
8519                 auto operator ++() -> iterator& {
8520                         m_pos += m_len;
8521                         if (m_pos < line().size() && line()[m_pos] == '\n')
8522                                 m_pos += 1;
8523                         else
8524                                 while (m_pos < line().size() && isWhitespace(line()[m_pos]))
8525                                         ++m_pos;
8526
8527                         if (m_pos == line().size()) {
8528                                 m_pos = 0;
8529                                 ++m_stringIndex;
8530                         }
8531                         if (m_stringIndex < m_column.m_strings.size())
8532                                 calcLength();
8533                         return *this;
8534                 }
8535                 auto operator ++(int) -> iterator {
8536                         iterator prev(*this);
8537                         operator++();
8538                         return prev;
8539                 }
8540
8541                 auto operator ==(iterator const& other) const -> bool {
8542                         return
8543                                 m_pos == other.m_pos &&
8544                                 m_stringIndex == other.m_stringIndex &&
8545                                 &m_column == &other.m_column;
8546                 }
8547                 auto operator !=(iterator const& other) const -> bool {
8548                         return !operator==(other);
8549                 }
8550         };
8551         using const_iterator = iterator;
8552
8553         explicit Column(std::string const& text) { m_strings.push_back(text); }
8554
8555         auto width(size_t newWidth) -> Column& {
8556                 assert(newWidth > 0);
8557                 m_width = newWidth;
8558                 return *this;
8559         }
8560         auto indent(size_t newIndent) -> Column& {
8561                 m_indent = newIndent;
8562                 return *this;
8563         }
8564         auto initialIndent(size_t newIndent) -> Column& {
8565                 m_initialIndent = newIndent;
8566                 return *this;
8567         }
8568
8569         auto width() const -> size_t { return m_width; }
8570         auto begin() const -> iterator { return iterator(*this); }
8571         auto end() const -> iterator { return { *this, m_strings.size() }; }
8572
8573         inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
8574                 bool first = true;
8575                 for (auto line : col) {
8576                         if (first)
8577                                 first = false;
8578                         else
8579                                 os << "\n";
8580                         os << line;
8581                 }
8582                 return os;
8583         }
8584
8585         auto operator + (Column const& other)->Columns;
8586
8587         auto toString() const -> std::string {
8588                 std::ostringstream oss;
8589                 oss << *this;
8590                 return oss.str();
8591         }
8592 };
8593
8594 class Spacer : public Column {
8595
8596 public:
8597         explicit Spacer(size_t spaceWidth) : Column("") {
8598                 width(spaceWidth);
8599         }
8600 };
8601
8602 class Columns {
8603         std::vector<Column> m_columns;
8604
8605 public:
8606
8607         class iterator {
8608                 friend Columns;
8609                 struct EndTag {};
8610
8611                 std::vector<Column> const& m_columns;
8612                 std::vector<Column::iterator> m_iterators;
8613                 size_t m_activeIterators;
8614
8615                 iterator(Columns const& columns, EndTag)
8616                         : m_columns(columns.m_columns),
8617                         m_activeIterators(0) {
8618                         m_iterators.reserve(m_columns.size());
8619
8620                         for (auto const& col : m_columns)
8621                                 m_iterators.push_back(col.end());
8622                 }
8623
8624         public:
8625                 using difference_type = std::ptrdiff_t;
8626                 using value_type = std::string;
8627                 using pointer = value_type * ;
8628                 using reference = value_type & ;
8629                 using iterator_category = std::forward_iterator_tag;
8630
8631                 explicit iterator(Columns const& columns)
8632                         : m_columns(columns.m_columns),
8633                         m_activeIterators(m_columns.size()) {
8634                         m_iterators.reserve(m_columns.size());
8635
8636                         for (auto const& col : m_columns)
8637                                 m_iterators.push_back(col.begin());
8638                 }
8639
8640                 auto operator ==(iterator const& other) const -> bool {
8641                         return m_iterators == other.m_iterators;
8642                 }
8643                 auto operator !=(iterator const& other) const -> bool {
8644                         return m_iterators != other.m_iterators;
8645                 }
8646                 auto operator *() const -> std::string {
8647                         std::string row, padding;
8648
8649                         for (size_t i = 0; i < m_columns.size(); ++i) {
8650                                 auto width = m_columns[i].width();
8651                                 if (m_iterators[i] != m_columns[i].end()) {
8652                                         std::string col = *m_iterators[i];
8653                                         row += padding + col;
8654                                         if (col.size() < width)
8655                                                 padding = std::string(width - col.size(), ' ');
8656                                         else
8657                                                 padding = "";
8658                                 } else {
8659                                         padding += std::string(width, ' ');
8660                                 }
8661                         }
8662                         return row;
8663                 }
8664                 auto operator ++() -> iterator& {
8665                         for (size_t i = 0; i < m_columns.size(); ++i) {
8666                                 if (m_iterators[i] != m_columns[i].end())
8667                                         ++m_iterators[i];
8668                         }
8669                         return *this;
8670                 }
8671                 auto operator ++(int) -> iterator {
8672                         iterator prev(*this);
8673                         operator++();
8674                         return prev;
8675                 }
8676         };
8677         using const_iterator = iterator;
8678
8679         auto begin() const -> iterator { return iterator(*this); }
8680         auto end() const -> iterator { return { *this, iterator::EndTag() }; }
8681
8682         auto operator += (Column const& col) -> Columns& {
8683                 m_columns.push_back(col);
8684                 return *this;
8685         }
8686         auto operator + (Column const& col) -> Columns {
8687                 Columns combined = *this;
8688                 combined += col;
8689                 return combined;
8690         }
8691
8692         inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
8693
8694                 bool first = true;
8695                 for (auto line : cols) {
8696                         if (first)
8697                                 first = false;
8698                         else
8699                                 os << "\n";
8700                         os << line;
8701                 }
8702                 return os;
8703         }
8704
8705         auto toString() const -> std::string {
8706                 std::ostringstream oss;
8707                 oss << *this;
8708                 return oss.str();
8709         }
8710 };
8711
8712 inline auto Column::operator + (Column const& other) -> Columns {
8713         Columns cols;
8714         cols += *this;
8715         cols += other;
8716         return cols;
8717 }
8718 }
8719
8720 }
8721 }
8722
8723 // ----------- end of #include from clara_textflow.hpp -----------
8724 // ........... back in clara.hpp
8725
8726 #include <cctype>
8727 #include <string>
8728 #include <memory>
8729 #include <set>
8730 #include <algorithm>
8731
8732 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
8733 #define CATCH_PLATFORM_WINDOWS
8734 #endif
8735
8736 namespace Catch { namespace clara {
8737 namespace detail {
8738
8739     // Traits for extracting arg and return type of lambdas (for single argument lambdas)
8740     template<typename L>
8741     struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
8742
8743     template<typename ClassT, typename ReturnT, typename... Args>
8744     struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
8745         static const bool isValid = false;
8746     };
8747
8748     template<typename ClassT, typename ReturnT, typename ArgT>
8749     struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
8750         static const bool isValid = true;
8751         using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
8752         using ReturnType = ReturnT;
8753     };
8754
8755     class TokenStream;
8756
8757     // Transport for raw args (copied from main args, or supplied via init list for testing)
8758     class Args {
8759         friend TokenStream;
8760         std::string m_exeName;
8761         std::vector<std::string> m_args;
8762
8763     public:
8764         Args( int argc, char const* const* argv )
8765             : m_exeName(argv[0]),
8766               m_args(argv + 1, argv + argc) {}
8767
8768         Args( std::initializer_list<std::string> args )
8769         :   m_exeName( *args.begin() ),
8770             m_args( args.begin()+1, args.end() )
8771         {}
8772
8773         auto exeName() const -> std::string {
8774             return m_exeName;
8775         }
8776     };
8777
8778     // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
8779     // may encode an option + its argument if the : or = form is used
8780     enum class TokenType {
8781         Option, Argument
8782     };
8783     struct Token {
8784         TokenType type;
8785         std::string token;
8786     };
8787
8788     inline auto isOptPrefix( char c ) -> bool {
8789         return c == '-'
8790 #ifdef CATCH_PLATFORM_WINDOWS
8791             || c == '/'
8792 #endif
8793         ;
8794     }
8795
8796     // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
8797     class TokenStream {
8798         using Iterator = std::vector<std::string>::const_iterator;
8799         Iterator it;
8800         Iterator itEnd;
8801         std::vector<Token> m_tokenBuffer;
8802
8803         void loadBuffer() {
8804             m_tokenBuffer.resize( 0 );
8805
8806             // Skip any empty strings
8807             while( it != itEnd && it->empty() )
8808                 ++it;
8809
8810             if( it != itEnd ) {
8811                 auto const &next = *it;
8812                 if( isOptPrefix( next[0] ) ) {
8813                     auto delimiterPos = next.find_first_of( " :=" );
8814                     if( delimiterPos != std::string::npos ) {
8815                         m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
8816                         m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
8817                     } else {
8818                         if( next[1] != '-' && next.size() > 2 ) {
8819                             std::string opt = "- ";
8820                             for( size_t i = 1; i < next.size(); ++i ) {
8821                                 opt[1] = next[i];
8822                                 m_tokenBuffer.push_back( { TokenType::Option, opt } );
8823                             }
8824                         } else {
8825                             m_tokenBuffer.push_back( { TokenType::Option, next } );
8826                         }
8827                     }
8828                 } else {
8829                     m_tokenBuffer.push_back( { TokenType::Argument, next } );
8830                 }
8831             }
8832         }
8833
8834     public:
8835         explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
8836
8837         TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
8838             loadBuffer();
8839         }
8840
8841         explicit operator bool() const {
8842             return !m_tokenBuffer.empty() || it != itEnd;
8843         }
8844
8845         auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
8846
8847         auto operator*() const -> Token {
8848             assert( !m_tokenBuffer.empty() );
8849             return m_tokenBuffer.front();
8850         }
8851
8852         auto operator->() const -> Token const * {
8853             assert( !m_tokenBuffer.empty() );
8854             return &m_tokenBuffer.front();
8855         }
8856
8857         auto operator++() -> TokenStream & {
8858             if( m_tokenBuffer.size() >= 2 ) {
8859                 m_tokenBuffer.erase( m_tokenBuffer.begin() );
8860             } else {
8861                 if( it != itEnd )
8862                     ++it;
8863                 loadBuffer();
8864             }
8865             return *this;
8866         }
8867     };
8868
8869     class ResultBase {
8870     public:
8871         enum Type {
8872             Ok, LogicError, RuntimeError
8873         };
8874
8875     protected:
8876         ResultBase( Type type ) : m_type( type ) {}
8877         virtual ~ResultBase() = default;
8878
8879         virtual void enforceOk() const = 0;
8880
8881         Type m_type;
8882     };
8883
8884     template<typename T>
8885     class ResultValueBase : public ResultBase {
8886     public:
8887         auto value() const -> T const & {
8888             enforceOk();
8889             return m_value;
8890         }
8891
8892     protected:
8893         ResultValueBase( Type type ) : ResultBase( type ) {}
8894
8895         ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
8896             if( m_type == ResultBase::Ok )
8897                 new( &m_value ) T( other.m_value );
8898         }
8899
8900         ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
8901             new( &m_value ) T( value );
8902         }
8903
8904         auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
8905             if( m_type == ResultBase::Ok )
8906                 m_value.~T();
8907             ResultBase::operator=(other);
8908             if( m_type == ResultBase::Ok )
8909                 new( &m_value ) T( other.m_value );
8910             return *this;
8911         }
8912
8913         ~ResultValueBase() override {
8914             if( m_type == Ok )
8915                 m_value.~T();
8916         }
8917
8918         union {
8919             T m_value;
8920         };
8921     };
8922
8923     template<>
8924     class ResultValueBase<void> : public ResultBase {
8925     protected:
8926         using ResultBase::ResultBase;
8927     };
8928
8929     template<typename T = void>
8930     class BasicResult : public ResultValueBase<T> {
8931     public:
8932         template<typename U>
8933         explicit BasicResult( BasicResult<U> const &other )
8934         :   ResultValueBase<T>( other.type() ),
8935             m_errorMessage( other.errorMessage() )
8936         {
8937             assert( type() != ResultBase::Ok );
8938         }
8939
8940         template<typename U>
8941         static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
8942         static auto ok() -> BasicResult { return { ResultBase::Ok }; }
8943         static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
8944         static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
8945
8946         explicit operator bool() const { return m_type == ResultBase::Ok; }
8947         auto type() const -> ResultBase::Type { return m_type; }
8948         auto errorMessage() const -> std::string { return m_errorMessage; }
8949
8950     protected:
8951         void enforceOk() const override {
8952
8953             // Errors shouldn't reach this point, but if they do
8954             // the actual error message will be in m_errorMessage
8955             assert( m_type != ResultBase::LogicError );
8956             assert( m_type != ResultBase::RuntimeError );
8957             if( m_type != ResultBase::Ok )
8958                 std::abort();
8959         }
8960
8961         std::string m_errorMessage; // Only populated if resultType is an error
8962
8963         BasicResult( ResultBase::Type type, std::string const &message )
8964         :   ResultValueBase<T>(type),
8965             m_errorMessage(message)
8966         {
8967             assert( m_type != ResultBase::Ok );
8968         }
8969
8970         using ResultValueBase<T>::ResultValueBase;
8971         using ResultBase::m_type;
8972     };
8973
8974     enum class ParseResultType {
8975         Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
8976     };
8977
8978     class ParseState {
8979     public:
8980
8981         ParseState( ParseResultType type, TokenStream const &remainingTokens )
8982         : m_type(type),
8983           m_remainingTokens( remainingTokens )
8984         {}
8985
8986         auto type() const -> ParseResultType { return m_type; }
8987         auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
8988
8989     private:
8990         ParseResultType m_type;
8991         TokenStream m_remainingTokens;
8992     };
8993
8994     using Result = BasicResult<void>;
8995     using ParserResult = BasicResult<ParseResultType>;
8996     using InternalParseResult = BasicResult<ParseState>;
8997
8998     struct HelpColumns {
8999         std::string left;
9000         std::string right;
9001     };
9002
9003     template<typename T>
9004     inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
9005         std::stringstream ss;
9006         ss << source;
9007         ss >> target;
9008         if( ss.fail() )
9009             return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
9010         else
9011             return ParserResult::ok( ParseResultType::Matched );
9012     }
9013     inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
9014         target = source;
9015         return ParserResult::ok( ParseResultType::Matched );
9016     }
9017     inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
9018         std::string srcLC = source;
9019         std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
9020         if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
9021             target = true;
9022         else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
9023             target = false;
9024         else
9025             return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
9026         return ParserResult::ok( ParseResultType::Matched );
9027     }
9028 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
9029     template<typename T>
9030     inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
9031         T temp;
9032         auto result = convertInto( source, temp );
9033         if( result )
9034             target = std::move(temp);
9035         return result;
9036     }
9037 #endif // CLARA_CONFIG_OPTIONAL_TYPE
9038
9039     struct NonCopyable {
9040         NonCopyable() = default;
9041         NonCopyable( NonCopyable const & ) = delete;
9042         NonCopyable( NonCopyable && ) = delete;
9043         NonCopyable &operator=( NonCopyable const & ) = delete;
9044         NonCopyable &operator=( NonCopyable && ) = delete;
9045     };
9046
9047     struct BoundRef : NonCopyable {
9048         virtual ~BoundRef() = default;
9049         virtual auto isContainer() const -> bool { return false; }
9050         virtual auto isFlag() const -> bool { return false; }
9051     };
9052     struct BoundValueRefBase : BoundRef {
9053         virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
9054     };
9055     struct BoundFlagRefBase : BoundRef {
9056         virtual auto setFlag( bool flag ) -> ParserResult = 0;
9057         virtual auto isFlag() const -> bool { return true; }
9058     };
9059
9060     template<typename T>
9061     struct BoundValueRef : BoundValueRefBase {
9062         T &m_ref;
9063
9064         explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
9065
9066         auto setValue( std::string const &arg ) -> ParserResult override {
9067             return convertInto( arg, m_ref );
9068         }
9069     };
9070
9071     template<typename T>
9072     struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
9073         std::vector<T> &m_ref;
9074
9075         explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
9076
9077         auto isContainer() const -> bool override { return true; }
9078
9079         auto setValue( std::string const &arg ) -> ParserResult override {
9080             T temp;
9081             auto result = convertInto( arg, temp );
9082             if( result )
9083                 m_ref.push_back( temp );
9084             return result;
9085         }
9086     };
9087
9088     struct BoundFlagRef : BoundFlagRefBase {
9089         bool &m_ref;
9090
9091         explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
9092
9093         auto setFlag( bool flag ) -> ParserResult override {
9094             m_ref = flag;
9095             return ParserResult::ok( ParseResultType::Matched );
9096         }
9097     };
9098
9099     template<typename ReturnType>
9100     struct LambdaInvoker {
9101         static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
9102
9103         template<typename L, typename ArgType>
9104         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9105             return lambda( arg );
9106         }
9107     };
9108
9109     template<>
9110     struct LambdaInvoker<void> {
9111         template<typename L, typename ArgType>
9112         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9113             lambda( arg );
9114             return ParserResult::ok( ParseResultType::Matched );
9115         }
9116     };
9117
9118     template<typename ArgType, typename L>
9119     inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
9120         ArgType temp{};
9121         auto result = convertInto( arg, temp );
9122         return !result
9123            ? result
9124            : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
9125     }
9126
9127     template<typename L>
9128     struct BoundLambda : BoundValueRefBase {
9129         L m_lambda;
9130
9131         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9132         explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
9133
9134         auto setValue( std::string const &arg ) -> ParserResult override {
9135             return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
9136         }
9137     };
9138
9139     template<typename L>
9140     struct BoundFlagLambda : BoundFlagRefBase {
9141         L m_lambda;
9142
9143         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9144         static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
9145
9146         explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
9147
9148         auto setFlag( bool flag ) -> ParserResult override {
9149             return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
9150         }
9151     };
9152
9153     enum class Optionality { Optional, Required };
9154
9155     struct Parser;
9156
9157     class ParserBase {
9158     public:
9159         virtual ~ParserBase() = default;
9160         virtual auto validate() const -> Result { return Result::ok(); }
9161         virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
9162         virtual auto cardinality() const -> size_t { return 1; }
9163
9164         auto parse( Args const &args ) const -> InternalParseResult {
9165             return parse( args.exeName(), TokenStream( args ) );
9166         }
9167     };
9168
9169     template<typename DerivedT>
9170     class ComposableParserImpl : public ParserBase {
9171     public:
9172         template<typename T>
9173         auto operator|( T const &other ) const -> Parser;
9174
9175                 template<typename T>
9176         auto operator+( T const &other ) const -> Parser;
9177     };
9178
9179     // Common code and state for Args and Opts
9180     template<typename DerivedT>
9181     class ParserRefImpl : public ComposableParserImpl<DerivedT> {
9182     protected:
9183         Optionality m_optionality = Optionality::Optional;
9184         std::shared_ptr<BoundRef> m_ref;
9185         std::string m_hint;
9186         std::string m_description;
9187
9188         explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
9189
9190     public:
9191         template<typename T>
9192         ParserRefImpl( T &ref, std::string const &hint )
9193         :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
9194             m_hint( hint )
9195         {}
9196
9197         template<typename LambdaT>
9198         ParserRefImpl( LambdaT const &ref, std::string const &hint )
9199         :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
9200             m_hint(hint)
9201         {}
9202
9203         auto operator()( std::string const &description ) -> DerivedT & {
9204             m_description = description;
9205             return static_cast<DerivedT &>( *this );
9206         }
9207
9208         auto optional() -> DerivedT & {
9209             m_optionality = Optionality::Optional;
9210             return static_cast<DerivedT &>( *this );
9211         };
9212
9213         auto required() -> DerivedT & {
9214             m_optionality = Optionality::Required;
9215             return static_cast<DerivedT &>( *this );
9216         };
9217
9218         auto isOptional() const -> bool {
9219             return m_optionality == Optionality::Optional;
9220         }
9221
9222         auto cardinality() const -> size_t override {
9223             if( m_ref->isContainer() )
9224                 return 0;
9225             else
9226                 return 1;
9227         }
9228
9229         auto hint() const -> std::string { return m_hint; }
9230     };
9231
9232     class ExeName : public ComposableParserImpl<ExeName> {
9233         std::shared_ptr<std::string> m_name;
9234         std::shared_ptr<BoundValueRefBase> m_ref;
9235
9236         template<typename LambdaT>
9237         static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
9238             return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
9239         }
9240
9241     public:
9242         ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
9243
9244         explicit ExeName( std::string &ref ) : ExeName() {
9245             m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
9246         }
9247
9248         template<typename LambdaT>
9249         explicit ExeName( LambdaT const& lambda ) : ExeName() {
9250             m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
9251         }
9252
9253         // The exe name is not parsed out of the normal tokens, but is handled specially
9254         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9255             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9256         }
9257
9258         auto name() const -> std::string { return *m_name; }
9259         auto set( std::string const& newName ) -> ParserResult {
9260
9261             auto lastSlash = newName.find_last_of( "\\/" );
9262             auto filename = ( lastSlash == std::string::npos )
9263                     ? newName
9264                     : newName.substr( lastSlash+1 );
9265
9266             *m_name = filename;
9267             if( m_ref )
9268                 return m_ref->setValue( filename );
9269             else
9270                 return ParserResult::ok( ParseResultType::Matched );
9271         }
9272     };
9273
9274     class Arg : public ParserRefImpl<Arg> {
9275     public:
9276         using ParserRefImpl::ParserRefImpl;
9277
9278         auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
9279             auto validationResult = validate();
9280             if( !validationResult )
9281                 return InternalParseResult( validationResult );
9282
9283             auto remainingTokens = tokens;
9284             auto const &token = *remainingTokens;
9285             if( token.type != TokenType::Argument )
9286                 return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9287
9288             assert( !m_ref->isFlag() );
9289             auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9290
9291             auto result = valueRef->setValue( remainingTokens->token );
9292             if( !result )
9293                 return InternalParseResult( result );
9294             else
9295                 return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9296         }
9297     };
9298
9299     inline auto normaliseOpt( std::string const &optName ) -> std::string {
9300 #ifdef CATCH_PLATFORM_WINDOWS
9301         if( optName[0] == '/' )
9302             return "-" + optName.substr( 1 );
9303         else
9304 #endif
9305             return optName;
9306     }
9307
9308     class Opt : public ParserRefImpl<Opt> {
9309     protected:
9310         std::vector<std::string> m_optNames;
9311
9312     public:
9313         template<typename LambdaT>
9314         explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
9315
9316         explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
9317
9318         template<typename LambdaT>
9319         Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9320
9321         template<typename T>
9322         Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9323
9324         auto operator[]( std::string const &optName ) -> Opt & {
9325             m_optNames.push_back( optName );
9326             return *this;
9327         }
9328
9329         auto getHelpColumns() const -> std::vector<HelpColumns> {
9330             std::ostringstream oss;
9331             bool first = true;
9332             for( auto const &opt : m_optNames ) {
9333                 if (first)
9334                     first = false;
9335                 else
9336                     oss << ", ";
9337                 oss << opt;
9338             }
9339             if( !m_hint.empty() )
9340                 oss << " <" << m_hint << ">";
9341             return { { oss.str(), m_description } };
9342         }
9343
9344         auto isMatch( std::string const &optToken ) const -> bool {
9345             auto normalisedToken = normaliseOpt( optToken );
9346             for( auto const &name : m_optNames ) {
9347                 if( normaliseOpt( name ) == normalisedToken )
9348                     return true;
9349             }
9350             return false;
9351         }
9352
9353         using ParserBase::parse;
9354
9355         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9356             auto validationResult = validate();
9357             if( !validationResult )
9358                 return InternalParseResult( validationResult );
9359
9360             auto remainingTokens = tokens;
9361             if( remainingTokens && remainingTokens->type == TokenType::Option ) {
9362                 auto const &token = *remainingTokens;
9363                 if( isMatch(token.token ) ) {
9364                     if( m_ref->isFlag() ) {
9365                         auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
9366                         auto result = flagRef->setFlag( true );
9367                         if( !result )
9368                             return InternalParseResult( result );
9369                         if( result.value() == ParseResultType::ShortCircuitAll )
9370                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9371                     } else {
9372                         auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9373                         ++remainingTokens;
9374                         if( !remainingTokens )
9375                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9376                         auto const &argToken = *remainingTokens;
9377                         if( argToken.type != TokenType::Argument )
9378                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9379                         auto result = valueRef->setValue( argToken.token );
9380                         if( !result )
9381                             return InternalParseResult( result );
9382                         if( result.value() == ParseResultType::ShortCircuitAll )
9383                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9384                     }
9385                     return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9386                 }
9387             }
9388             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9389         }
9390
9391         auto validate() const -> Result override {
9392             if( m_optNames.empty() )
9393                 return Result::logicError( "No options supplied to Opt" );
9394             for( auto const &name : m_optNames ) {
9395                 if( name.empty() )
9396                     return Result::logicError( "Option name cannot be empty" );
9397 #ifdef CATCH_PLATFORM_WINDOWS
9398                 if( name[0] != '-' && name[0] != '/' )
9399                     return Result::logicError( "Option name must begin with '-' or '/'" );
9400 #else
9401                 if( name[0] != '-' )
9402                     return Result::logicError( "Option name must begin with '-'" );
9403 #endif
9404             }
9405             return ParserRefImpl::validate();
9406         }
9407     };
9408
9409     struct Help : Opt {
9410         Help( bool &showHelpFlag )
9411         :   Opt([&]( bool flag ) {
9412                 showHelpFlag = flag;
9413                 return ParserResult::ok( ParseResultType::ShortCircuitAll );
9414             })
9415         {
9416             static_cast<Opt &>( *this )
9417                     ("display usage information")
9418                     ["-?"]["-h"]["--help"]
9419                     .optional();
9420         }
9421     };
9422
9423     struct Parser : ParserBase {
9424
9425         mutable ExeName m_exeName;
9426         std::vector<Opt> m_options;
9427         std::vector<Arg> m_args;
9428
9429         auto operator|=( ExeName const &exeName ) -> Parser & {
9430             m_exeName = exeName;
9431             return *this;
9432         }
9433
9434         auto operator|=( Arg const &arg ) -> Parser & {
9435             m_args.push_back(arg);
9436             return *this;
9437         }
9438
9439         auto operator|=( Opt const &opt ) -> Parser & {
9440             m_options.push_back(opt);
9441             return *this;
9442         }
9443
9444         auto operator|=( Parser const &other ) -> Parser & {
9445             m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
9446             m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
9447             return *this;
9448         }
9449
9450         template<typename T>
9451         auto operator|( T const &other ) const -> Parser {
9452             return Parser( *this ) |= other;
9453         }
9454
9455         // Forward deprecated interface with '+' instead of '|'
9456         template<typename T>
9457         auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
9458         template<typename T>
9459         auto operator+( T const &other ) const -> Parser { return operator|( other ); }
9460
9461         auto getHelpColumns() const -> std::vector<HelpColumns> {
9462             std::vector<HelpColumns> cols;
9463             for (auto const &o : m_options) {
9464                 auto childCols = o.getHelpColumns();
9465                 cols.insert( cols.end(), childCols.begin(), childCols.end() );
9466             }
9467             return cols;
9468         }
9469
9470         void writeToStream( std::ostream &os ) const {
9471             if (!m_exeName.name().empty()) {
9472                 os << "usage:\n" << "  " << m_exeName.name() << " ";
9473                 bool required = true, first = true;
9474                 for( auto const &arg : m_args ) {
9475                     if (first)
9476                         first = false;
9477                     else
9478                         os << " ";
9479                     if( arg.isOptional() && required ) {
9480                         os << "[";
9481                         required = false;
9482                     }
9483                     os << "<" << arg.hint() << ">";
9484                     if( arg.cardinality() == 0 )
9485                         os << " ... ";
9486                 }
9487                 if( !required )
9488                     os << "]";
9489                 if( !m_options.empty() )
9490                     os << " options";
9491                 os << "\n\nwhere options are:" << std::endl;
9492             }
9493
9494             auto rows = getHelpColumns();
9495             size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
9496             size_t optWidth = 0;
9497             for( auto const &cols : rows )
9498                 optWidth = (std::max)(optWidth, cols.left.size() + 2);
9499
9500             optWidth = (std::min)(optWidth, consoleWidth/2);
9501
9502             for( auto const &cols : rows ) {
9503                 auto row =
9504                         TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
9505                         TextFlow::Spacer(4) +
9506                         TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
9507                 os << row << std::endl;
9508             }
9509         }
9510
9511         friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
9512             parser.writeToStream( os );
9513             return os;
9514         }
9515
9516         auto validate() const -> Result override {
9517             for( auto const &opt : m_options ) {
9518                 auto result = opt.validate();
9519                 if( !result )
9520                     return result;
9521             }
9522             for( auto const &arg : m_args ) {
9523                 auto result = arg.validate();
9524                 if( !result )
9525                     return result;
9526             }
9527             return Result::ok();
9528         }
9529
9530         using ParserBase::parse;
9531
9532         auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
9533
9534             struct ParserInfo {
9535                 ParserBase const* parser = nullptr;
9536                 size_t count = 0;
9537             };
9538             const size_t totalParsers = m_options.size() + m_args.size();
9539             assert( totalParsers < 512 );
9540             // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
9541             ParserInfo parseInfos[512];
9542
9543             {
9544                 size_t i = 0;
9545                 for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
9546                 for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
9547             }
9548
9549             m_exeName.set( exeName );
9550
9551             auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9552             while( result.value().remainingTokens() ) {
9553                 bool tokenParsed = false;
9554
9555                 for( size_t i = 0; i < totalParsers; ++i ) {
9556                     auto&  parseInfo = parseInfos[i];
9557                     if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
9558                         result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
9559                         if (!result)
9560                             return result;
9561                         if (result.value().type() != ParseResultType::NoMatch) {
9562                             tokenParsed = true;
9563                             ++parseInfo.count;
9564                             break;
9565                         }
9566                     }
9567                 }
9568
9569                 if( result.value().type() == ParseResultType::ShortCircuitAll )
9570                     return result;
9571                 if( !tokenParsed )
9572                     return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
9573             }
9574             // !TBD Check missing required options
9575             return result;
9576         }
9577     };
9578
9579     template<typename DerivedT>
9580     template<typename T>
9581     auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
9582         return Parser() | static_cast<DerivedT const &>( *this ) | other;
9583     }
9584 } // namespace detail
9585
9586 // A Combined parser
9587 using detail::Parser;
9588
9589 // A parser for options
9590 using detail::Opt;
9591
9592 // A parser for arguments
9593 using detail::Arg;
9594
9595 // Wrapper for argc, argv from main()
9596 using detail::Args;
9597
9598 // Specifies the name of the executable
9599 using detail::ExeName;
9600
9601 // Convenience wrapper for option parser that specifies the help option
9602 using detail::Help;
9603
9604 // enum of result types from a parse
9605 using detail::ParseResultType;
9606
9607 // Result type for parser operation
9608 using detail::ParserResult;
9609
9610 }} // namespace Catch::clara
9611
9612 // end clara.hpp
9613 #ifdef __clang__
9614 #pragma clang diagnostic pop
9615 #endif
9616
9617 // Restore Clara's value for console width, if present
9618 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9619 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9620 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9621 #endif
9622
9623 // end catch_clara.h
9624 namespace Catch {
9625
9626     clara::Parser makeCommandLineParser( ConfigData& config );
9627
9628 } // end namespace Catch
9629
9630 // end catch_commandline.h
9631 #include <fstream>
9632 #include <ctime>
9633
9634 namespace Catch {
9635
9636     clara::Parser makeCommandLineParser( ConfigData& config ) {
9637
9638         using namespace clara;
9639
9640         auto const setWarning = [&]( std::string const& warning ) {
9641                 auto warningSet = [&]() {
9642                     if( warning == "NoAssertions" )
9643                         return WarnAbout::NoAssertions;
9644
9645                     if ( warning == "NoTests" )
9646                         return WarnAbout::NoTests;
9647
9648                     return WarnAbout::Nothing;
9649                 }();
9650
9651                 if (warningSet == WarnAbout::Nothing)
9652                     return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
9653                 config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
9654                 return ParserResult::ok( ParseResultType::Matched );
9655             };
9656         auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
9657                 std::ifstream f( filename.c_str() );
9658                 if( !f.is_open() )
9659                     return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
9660
9661                 std::string line;
9662                 while( std::getline( f, line ) ) {
9663                     line = trim(line);
9664                     if( !line.empty() && !startsWith( line, '#' ) ) {
9665                         if( !startsWith( line, '"' ) )
9666                             line = '"' + line + '"';
9667                         config.testsOrTags.push_back( line );
9668                         config.testsOrTags.push_back( "," );
9669
9670                     }
9671                 }
9672                 //Remove comma in the end
9673                 if(!config.testsOrTags.empty())
9674                     config.testsOrTags.erase( config.testsOrTags.end()-1 );
9675
9676                 return ParserResult::ok( ParseResultType::Matched );
9677             };
9678         auto const setTestOrder = [&]( std::string const& order ) {
9679                 if( startsWith( "declared", order ) )
9680                     config.runOrder = RunTests::InDeclarationOrder;
9681                 else if( startsWith( "lexical", order ) )
9682                     config.runOrder = RunTests::InLexicographicalOrder;
9683                 else if( startsWith( "random", order ) )
9684                     config.runOrder = RunTests::InRandomOrder;
9685                 else
9686                     return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
9687                 return ParserResult::ok( ParseResultType::Matched );
9688             };
9689         auto const setRngSeed = [&]( std::string const& seed ) {
9690                 if( seed != "time" )
9691                     return clara::detail::convertInto( seed, config.rngSeed );
9692                 config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
9693                 return ParserResult::ok( ParseResultType::Matched );
9694             };
9695         auto const setColourUsage = [&]( std::string const& useColour ) {
9696                     auto mode = toLower( useColour );
9697
9698                     if( mode == "yes" )
9699                         config.useColour = UseColour::Yes;
9700                     else if( mode == "no" )
9701                         config.useColour = UseColour::No;
9702                     else if( mode == "auto" )
9703                         config.useColour = UseColour::Auto;
9704                     else
9705                         return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
9706                 return ParserResult::ok( ParseResultType::Matched );
9707             };
9708         auto const setWaitForKeypress = [&]( std::string const& keypress ) {
9709                 auto keypressLc = toLower( keypress );
9710                 if( keypressLc == "start" )
9711                     config.waitForKeypress = WaitForKeypress::BeforeStart;
9712                 else if( keypressLc == "exit" )
9713                     config.waitForKeypress = WaitForKeypress::BeforeExit;
9714                 else if( keypressLc == "both" )
9715                     config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
9716                 else
9717                     return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
9718             return ParserResult::ok( ParseResultType::Matched );
9719             };
9720         auto const setVerbosity = [&]( std::string const& verbosity ) {
9721             auto lcVerbosity = toLower( verbosity );
9722             if( lcVerbosity == "quiet" )
9723                 config.verbosity = Verbosity::Quiet;
9724             else if( lcVerbosity == "normal" )
9725                 config.verbosity = Verbosity::Normal;
9726             else if( lcVerbosity == "high" )
9727                 config.verbosity = Verbosity::High;
9728             else
9729                 return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
9730             return ParserResult::ok( ParseResultType::Matched );
9731         };
9732         auto const setReporter = [&]( std::string const& reporter ) {
9733             IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
9734
9735             auto lcReporter = toLower( reporter );
9736             auto result = factories.find( lcReporter );
9737
9738             if( factories.end() != result )
9739                 config.reporterName = lcReporter;
9740             else
9741                 return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
9742             return ParserResult::ok( ParseResultType::Matched );
9743         };
9744
9745         auto cli
9746             = ExeName( config.processName )
9747             | Help( config.showHelp )
9748             | Opt( config.listTests )
9749                 ["-l"]["--list-tests"]
9750                 ( "list all/matching test cases" )
9751             | Opt( config.listTags )
9752                 ["-t"]["--list-tags"]
9753                 ( "list all/matching tags" )
9754             | Opt( config.showSuccessfulTests )
9755                 ["-s"]["--success"]
9756                 ( "include successful tests in output" )
9757             | Opt( config.shouldDebugBreak )
9758                 ["-b"]["--break"]
9759                 ( "break into debugger on failure" )
9760             | Opt( config.noThrow )
9761                 ["-e"]["--nothrow"]
9762                 ( "skip exception tests" )
9763             | Opt( config.showInvisibles )
9764                 ["-i"]["--invisibles"]
9765                 ( "show invisibles (tabs, newlines)" )
9766             | Opt( config.outputFilename, "filename" )
9767                 ["-o"]["--out"]
9768                 ( "output filename" )
9769             | Opt( setReporter, "name" )
9770                 ["-r"]["--reporter"]
9771                 ( "reporter to use (defaults to console)" )
9772             | Opt( config.name, "name" )
9773                 ["-n"]["--name"]
9774                 ( "suite name" )
9775             | Opt( [&]( bool ){ config.abortAfter = 1; } )
9776                 ["-a"]["--abort"]
9777                 ( "abort at first failure" )
9778             | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
9779                 ["-x"]["--abortx"]
9780                 ( "abort after x failures" )
9781             | Opt( setWarning, "warning name" )
9782                 ["-w"]["--warn"]
9783                 ( "enable warnings" )
9784             | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
9785                 ["-d"]["--durations"]
9786                 ( "show test durations" )
9787             | Opt( loadTestNamesFromFile, "filename" )
9788                 ["-f"]["--input-file"]
9789                 ( "load test names to run from a file" )
9790             | Opt( config.filenamesAsTags )
9791                 ["-#"]["--filenames-as-tags"]
9792                 ( "adds a tag for the filename" )
9793             | Opt( config.sectionsToRun, "section name" )
9794                 ["-c"]["--section"]
9795                 ( "specify section to run" )
9796             | Opt( setVerbosity, "quiet|normal|high" )
9797                 ["-v"]["--verbosity"]
9798                 ( "set output verbosity" )
9799             | Opt( config.listTestNamesOnly )
9800                 ["--list-test-names-only"]
9801                 ( "list all/matching test cases names only" )
9802             | Opt( config.listReporters )
9803                 ["--list-reporters"]
9804                 ( "list all reporters" )
9805             | Opt( setTestOrder, "decl|lex|rand" )
9806                 ["--order"]
9807                 ( "test case order (defaults to decl)" )
9808             | Opt( setRngSeed, "'time'|number" )
9809                 ["--rng-seed"]
9810                 ( "set a specific seed for random numbers" )
9811             | Opt( setColourUsage, "yes|no" )
9812                 ["--use-colour"]
9813                 ( "should output be colourised" )
9814             | Opt( config.libIdentify )
9815                 ["--libidentify"]
9816                 ( "report name and version according to libidentify standard" )
9817             | Opt( setWaitForKeypress, "start|exit|both" )
9818                 ["--wait-for-keypress"]
9819                 ( "waits for a keypress before exiting" )
9820             | Opt( config.benchmarkSamples, "samples" )
9821                 ["--benchmark-samples"]
9822                 ( "number of samples to collect (default: 100)" )
9823             | Opt( config.benchmarkResamples, "resamples" )
9824                 ["--benchmark-resamples"]
9825                 ( "number of resamples for the bootstrap (default: 100000)" )
9826             | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
9827                 ["--benchmark-confidence-interval"]
9828                 ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
9829             | Opt( config.benchmarkNoAnalysis )
9830                 ["--benchmark-no-analysis"]
9831                 ( "perform only measurements; do not perform any analysis" )
9832                         | Arg( config.testsOrTags, "test name|pattern|tags" )
9833                 ( "which test or tests to use" );
9834
9835         return cli;
9836     }
9837
9838 } // end namespace Catch
9839 // end catch_commandline.cpp
9840 // start catch_common.cpp
9841
9842 #include <cstring>
9843 #include <ostream>
9844
9845 namespace Catch {
9846
9847     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
9848         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
9849     }
9850     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
9851         // We can assume that the same file will usually have the same pointer.
9852         // Thus, if the pointers are the same, there is no point in calling the strcmp
9853         return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
9854     }
9855
9856     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
9857 #ifndef __GNUG__
9858         os << info.file << '(' << info.line << ')';
9859 #else
9860         os << info.file << ':' << info.line;
9861 #endif
9862         return os;
9863     }
9864
9865     std::string StreamEndStop::operator+() const {
9866         return std::string();
9867     }
9868
9869     NonCopyable::NonCopyable() = default;
9870     NonCopyable::~NonCopyable() = default;
9871
9872 }
9873 // end catch_common.cpp
9874 // start catch_config.cpp
9875
9876 namespace Catch {
9877
9878     Config::Config( ConfigData const& data )
9879     :   m_data( data ),
9880         m_stream( openStream() )
9881     {
9882         // We need to trim filter specs to avoid trouble with superfluous
9883         // whitespace (esp. important for bdd macros, as those are manually
9884         // aligned with whitespace).
9885
9886         for (auto& elem : m_data.testsOrTags) {
9887             elem = trim(elem);
9888         }
9889         for (auto& elem : m_data.sectionsToRun) {
9890             elem = trim(elem);
9891         }
9892
9893         TestSpecParser parser(ITagAliasRegistry::get());
9894         if (!m_data.testsOrTags.empty()) {
9895             m_hasTestFilters = true;
9896             for (auto const& testOrTags : m_data.testsOrTags) {
9897                 parser.parse(testOrTags);
9898             }
9899         }
9900         m_testSpec = parser.testSpec();
9901     }
9902
9903     std::string const& Config::getFilename() const {
9904         return m_data.outputFilename ;
9905     }
9906
9907     bool Config::listTests() const          { return m_data.listTests; }
9908     bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }
9909     bool Config::listTags() const           { return m_data.listTags; }
9910     bool Config::listReporters() const      { return m_data.listReporters; }
9911
9912     std::string Config::getProcessName() const { return m_data.processName; }
9913     std::string const& Config::getReporterName() const { return m_data.reporterName; }
9914
9915     std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
9916     std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
9917
9918     TestSpec const& Config::testSpec() const { return m_testSpec; }
9919     bool Config::hasTestFilters() const { return m_hasTestFilters; }
9920
9921     bool Config::showHelp() const { return m_data.showHelp; }
9922
9923     // IConfig interface
9924     bool Config::allowThrows() const                   { return !m_data.noThrow; }
9925     std::ostream& Config::stream() const               { return m_stream->stream(); }
9926     std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }
9927     bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }
9928     bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }
9929     bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }
9930     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
9931     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
9932     unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
9933     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
9934     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
9935     int Config::abortAfter() const                     { return m_data.abortAfter; }
9936     bool Config::showInvisibles() const                { return m_data.showInvisibles; }
9937     Verbosity Config::verbosity() const                { return m_data.verbosity; }
9938
9939     bool Config::benchmarkNoAnalysis() const           { return m_data.benchmarkNoAnalysis; }
9940     int Config::benchmarkSamples() const               { return m_data.benchmarkSamples; }
9941     double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
9942     unsigned int Config::benchmarkResamples() const    { return m_data.benchmarkResamples; }
9943
9944     IStream const* Config::openStream() {
9945         return Catch::makeStream(m_data.outputFilename);
9946     }
9947
9948 } // end namespace Catch
9949 // end catch_config.cpp
9950 // start catch_console_colour.cpp
9951
9952 #if defined(__clang__)
9953 #    pragma clang diagnostic push
9954 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
9955 #endif
9956
9957 // start catch_errno_guard.h
9958
9959 namespace Catch {
9960
9961     class ErrnoGuard {
9962     public:
9963         ErrnoGuard();
9964         ~ErrnoGuard();
9965     private:
9966         int m_oldErrno;
9967     };
9968
9969 }
9970
9971 // end catch_errno_guard.h
9972 #include <sstream>
9973
9974 namespace Catch {
9975     namespace {
9976
9977         struct IColourImpl {
9978             virtual ~IColourImpl() = default;
9979             virtual void use( Colour::Code _colourCode ) = 0;
9980         };
9981
9982         struct NoColourImpl : IColourImpl {
9983             void use( Colour::Code ) {}
9984
9985             static IColourImpl* instance() {
9986                 static NoColourImpl s_instance;
9987                 return &s_instance;
9988             }
9989         };
9990
9991     } // anon namespace
9992 } // namespace Catch
9993
9994 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
9995 #   ifdef CATCH_PLATFORM_WINDOWS
9996 #       define CATCH_CONFIG_COLOUR_WINDOWS
9997 #   else
9998 #       define CATCH_CONFIG_COLOUR_ANSI
9999 #   endif
10000 #endif
10001
10002 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
10003
10004 namespace Catch {
10005 namespace {
10006
10007     class Win32ColourImpl : public IColourImpl {
10008     public:
10009         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
10010         {
10011             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
10012             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
10013             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
10014             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
10015         }
10016
10017         void use( Colour::Code _colourCode ) override {
10018             switch( _colourCode ) {
10019                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
10020                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10021                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
10022                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
10023                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
10024                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
10025                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
10026                 case Colour::Grey:      return setTextAttribute( 0 );
10027
10028                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
10029                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
10030                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
10031                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10032                 case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
10033
10034                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10035
10036                 default:
10037                     CATCH_ERROR( "Unknown colour requested" );
10038             }
10039         }
10040
10041     private:
10042         void setTextAttribute( WORD _textAttribute ) {
10043             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
10044         }
10045         HANDLE stdoutHandle;
10046         WORD originalForegroundAttributes;
10047         WORD originalBackgroundAttributes;
10048     };
10049
10050     IColourImpl* platformColourInstance() {
10051         static Win32ColourImpl s_instance;
10052
10053         IConfigPtr config = getCurrentContext().getConfig();
10054         UseColour::YesOrNo colourMode = config
10055             ? config->useColour()
10056             : UseColour::Auto;
10057         if( colourMode == UseColour::Auto )
10058             colourMode = UseColour::Yes;
10059         return colourMode == UseColour::Yes
10060             ? &s_instance
10061             : NoColourImpl::instance();
10062     }
10063
10064 } // end anon namespace
10065 } // end namespace Catch
10066
10067 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
10068
10069 #include <unistd.h>
10070
10071 namespace Catch {
10072 namespace {
10073
10074     // use POSIX/ ANSI console terminal codes
10075     // Thanks to Adam Strzelecki for original contribution
10076     // (http://github.com/nanoant)
10077     // https://github.com/philsquared/Catch/pull/131
10078     class PosixColourImpl : public IColourImpl {
10079     public:
10080         void use( Colour::Code _colourCode ) override {
10081             switch( _colourCode ) {
10082                 case Colour::None:
10083                 case Colour::White:     return setColour( "[0m" );
10084                 case Colour::Red:       return setColour( "[0;31m" );
10085                 case Colour::Green:     return setColour( "[0;32m" );
10086                 case Colour::Blue:      return setColour( "[0;34m" );
10087                 case Colour::Cyan:      return setColour( "[0;36m" );
10088                 case Colour::Yellow:    return setColour( "[0;33m" );
10089                 case Colour::Grey:      return setColour( "[1;30m" );
10090
10091                 case Colour::LightGrey:     return setColour( "[0;37m" );
10092                 case Colour::BrightRed:     return setColour( "[1;31m" );
10093                 case Colour::BrightGreen:   return setColour( "[1;32m" );
10094                 case Colour::BrightWhite:   return setColour( "[1;37m" );
10095                 case Colour::BrightYellow:  return setColour( "[1;33m" );
10096
10097                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10098                 default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
10099             }
10100         }
10101         static IColourImpl* instance() {
10102             static PosixColourImpl s_instance;
10103             return &s_instance;
10104         }
10105
10106     private:
10107         void setColour( const char* _escapeCode ) {
10108             getCurrentContext().getConfig()->stream()
10109                 << '\033' << _escapeCode;
10110         }
10111     };
10112
10113     bool useColourOnPlatform() {
10114         return
10115 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10116             !isDebuggerActive() &&
10117 #endif
10118 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
10119             isatty(STDOUT_FILENO)
10120 #else
10121             false
10122 #endif
10123             ;
10124     }
10125     IColourImpl* platformColourInstance() {
10126         ErrnoGuard guard;
10127         IConfigPtr config = getCurrentContext().getConfig();
10128         UseColour::YesOrNo colourMode = config
10129             ? config->useColour()
10130             : UseColour::Auto;
10131         if( colourMode == UseColour::Auto )
10132             colourMode = useColourOnPlatform()
10133                 ? UseColour::Yes
10134                 : UseColour::No;
10135         return colourMode == UseColour::Yes
10136             ? PosixColourImpl::instance()
10137             : NoColourImpl::instance();
10138     }
10139
10140 } // end anon namespace
10141 } // end namespace Catch
10142
10143 #else  // not Windows or ANSI ///////////////////////////////////////////////
10144
10145 namespace Catch {
10146
10147     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
10148
10149 } // end namespace Catch
10150
10151 #endif // Windows/ ANSI/ None
10152
10153 namespace Catch {
10154
10155     Colour::Colour( Code _colourCode ) { use( _colourCode ); }
10156     Colour::Colour( Colour&& rhs ) noexcept {
10157         m_moved = rhs.m_moved;
10158         rhs.m_moved = true;
10159     }
10160     Colour& Colour::operator=( Colour&& rhs ) noexcept {
10161         m_moved = rhs.m_moved;
10162         rhs.m_moved  = true;
10163         return *this;
10164     }
10165
10166     Colour::~Colour(){ if( !m_moved ) use( None ); }
10167
10168     void Colour::use( Code _colourCode ) {
10169         static IColourImpl* impl = platformColourInstance();
10170         // Strictly speaking, this cannot possibly happen.
10171         // However, under some conditions it does happen (see #1626),
10172         // and this change is small enough that we can let practicality
10173         // triumph over purity in this case.
10174         if (impl != NULL) {
10175             impl->use( _colourCode );
10176         }
10177     }
10178
10179     std::ostream& operator << ( std::ostream& os, Colour const& ) {
10180         return os;
10181     }
10182
10183 } // end namespace Catch
10184
10185 #if defined(__clang__)
10186 #    pragma clang diagnostic pop
10187 #endif
10188
10189 // end catch_console_colour.cpp
10190 // start catch_context.cpp
10191
10192 namespace Catch {
10193
10194     class Context : public IMutableContext, NonCopyable {
10195
10196     public: // IContext
10197         IResultCapture* getResultCapture() override {
10198             return m_resultCapture;
10199         }
10200         IRunner* getRunner() override {
10201             return m_runner;
10202         }
10203
10204         IConfigPtr const& getConfig() const override {
10205             return m_config;
10206         }
10207
10208         ~Context() override;
10209
10210     public: // IMutableContext
10211         void setResultCapture( IResultCapture* resultCapture ) override {
10212             m_resultCapture = resultCapture;
10213         }
10214         void setRunner( IRunner* runner ) override {
10215             m_runner = runner;
10216         }
10217         void setConfig( IConfigPtr const& config ) override {
10218             m_config = config;
10219         }
10220
10221         friend IMutableContext& getCurrentMutableContext();
10222
10223     private:
10224         IConfigPtr m_config;
10225         IRunner* m_runner = nullptr;
10226         IResultCapture* m_resultCapture = nullptr;
10227     };
10228
10229     IMutableContext *IMutableContext::currentContext = nullptr;
10230
10231     void IMutableContext::createContext()
10232     {
10233         currentContext = new Context();
10234     }
10235
10236     void cleanUpContext() {
10237         delete IMutableContext::currentContext;
10238         IMutableContext::currentContext = nullptr;
10239     }
10240     IContext::~IContext() = default;
10241     IMutableContext::~IMutableContext() = default;
10242     Context::~Context() = default;
10243
10244     SimplePcg32& rng() {
10245         static SimplePcg32 s_rng;
10246         return s_rng;
10247     }
10248
10249 }
10250 // end catch_context.cpp
10251 // start catch_debug_console.cpp
10252
10253 // start catch_debug_console.h
10254
10255 #include <string>
10256
10257 namespace Catch {
10258     void writeToDebugConsole( std::string const& text );
10259 }
10260
10261 // end catch_debug_console.h
10262 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
10263 #include <android/log.h>
10264
10265     namespace Catch {
10266         void writeToDebugConsole( std::string const& text ) {
10267             __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
10268         }
10269     }
10270
10271 #elif defined(CATCH_PLATFORM_WINDOWS)
10272
10273     namespace Catch {
10274         void writeToDebugConsole( std::string const& text ) {
10275             ::OutputDebugStringA( text.c_str() );
10276         }
10277     }
10278
10279 #else
10280
10281     namespace Catch {
10282         void writeToDebugConsole( std::string const& text ) {
10283             // !TBD: Need a version for Mac/ XCode and other IDEs
10284             Catch::cout() << text;
10285         }
10286     }
10287
10288 #endif // Platform
10289 // end catch_debug_console.cpp
10290 // start catch_debugger.cpp
10291
10292 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10293
10294 #  include <assert.h>
10295 #  include <stdbool.h>
10296 #  include <sys/types.h>
10297 #  include <unistd.h>
10298 #  include <cstddef>
10299 #  include <ostream>
10300
10301 #ifdef __apple_build_version__
10302     // These headers will only compile with AppleClang (XCode)
10303     // For other compilers (Clang, GCC, ... ) we need to exclude them
10304 #  include <sys/sysctl.h>
10305 #endif
10306
10307     namespace Catch {
10308         #ifdef __apple_build_version__
10309         // The following function is taken directly from the following technical note:
10310         // https://developer.apple.com/library/archive/qa/qa1361/_index.html
10311
10312         // Returns true if the current process is being debugged (either
10313         // running under the debugger or has a debugger attached post facto).
10314         bool isDebuggerActive(){
10315             int                 mib[4];
10316             struct kinfo_proc   info;
10317             std::size_t         size;
10318
10319             // Initialize the flags so that, if sysctl fails for some bizarre
10320             // reason, we get a predictable result.
10321
10322             info.kp_proc.p_flag = 0;
10323
10324             // Initialize mib, which tells sysctl the info we want, in this case
10325             // we're looking for information about a specific process ID.
10326
10327             mib[0] = CTL_KERN;
10328             mib[1] = KERN_PROC;
10329             mib[2] = KERN_PROC_PID;
10330             mib[3] = getpid();
10331
10332             // Call sysctl.
10333
10334             size = sizeof(info);
10335             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
10336                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
10337                 return false;
10338             }
10339
10340             // We're being debugged if the P_TRACED flag is set.
10341
10342             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
10343         }
10344         #else
10345         bool isDebuggerActive() {
10346             // We need to find another way to determine this for non-appleclang compilers on macOS
10347             return false;
10348         }
10349         #endif
10350     } // namespace Catch
10351
10352 #elif defined(CATCH_PLATFORM_LINUX)
10353     #include <fstream>
10354     #include <string>
10355
10356     namespace Catch{
10357         // The standard POSIX way of detecting a debugger is to attempt to
10358         // ptrace() the process, but this needs to be done from a child and not
10359         // this process itself to still allow attaching to this process later
10360         // if wanted, so is rather heavy. Under Linux we have the PID of the
10361         // "debugger" (which doesn't need to be gdb, of course, it could also
10362         // be strace, for example) in /proc/$PID/status, so just get it from
10363         // there instead.
10364         bool isDebuggerActive(){
10365             // Libstdc++ has a bug, where std::ifstream sets errno to 0
10366             // This way our users can properly assert over errno values
10367             ErrnoGuard guard;
10368             std::ifstream in("/proc/self/status");
10369             for( std::string line; std::getline(in, line); ) {
10370                 static const int PREFIX_LEN = 11;
10371                 if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
10372                     // We're traced if the PID is not 0 and no other PID starts
10373                     // with 0 digit, so it's enough to check for just a single
10374                     // character.
10375                     return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
10376                 }
10377             }
10378
10379             return false;
10380         }
10381     } // namespace Catch
10382 #elif defined(_MSC_VER)
10383     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10384     namespace Catch {
10385         bool isDebuggerActive() {
10386             return IsDebuggerPresent() != 0;
10387         }
10388     }
10389 #elif defined(__MINGW32__)
10390     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10391     namespace Catch {
10392         bool isDebuggerActive() {
10393             return IsDebuggerPresent() != 0;
10394         }
10395     }
10396 #else
10397     namespace Catch {
10398        bool isDebuggerActive() { return false; }
10399     }
10400 #endif // Platform
10401 // end catch_debugger.cpp
10402 // start catch_decomposer.cpp
10403
10404 namespace Catch {
10405
10406     ITransientExpression::~ITransientExpression() = default;
10407
10408     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
10409         if( lhs.size() + rhs.size() < 40 &&
10410                 lhs.find('\n') == std::string::npos &&
10411                 rhs.find('\n') == std::string::npos )
10412             os << lhs << " " << op << " " << rhs;
10413         else
10414             os << lhs << "\n" << op << "\n" << rhs;
10415     }
10416 }
10417 // end catch_decomposer.cpp
10418 // start catch_enforce.cpp
10419
10420 #include <stdexcept>
10421
10422 namespace Catch {
10423 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
10424     [[noreturn]]
10425     void throw_exception(std::exception const& e) {
10426         Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
10427                       << "The message was: " << e.what() << '\n';
10428         std::terminate();
10429     }
10430 #endif
10431
10432     [[noreturn]]
10433     void throw_logic_error(std::string const& msg) {
10434         throw_exception(std::logic_error(msg));
10435     }
10436
10437     [[noreturn]]
10438     void throw_domain_error(std::string const& msg) {
10439         throw_exception(std::domain_error(msg));
10440     }
10441
10442     [[noreturn]]
10443     void throw_runtime_error(std::string const& msg) {
10444         throw_exception(std::runtime_error(msg));
10445     }
10446
10447 } // namespace Catch;
10448 // end catch_enforce.cpp
10449 // start catch_enum_values_registry.cpp
10450 // start catch_enum_values_registry.h
10451
10452 #include <vector>
10453 #include <memory>
10454
10455 namespace Catch {
10456
10457     namespace Detail {
10458
10459         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
10460
10461         class EnumValuesRegistry : public IMutableEnumValuesRegistry {
10462
10463             std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
10464
10465             EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
10466         };
10467
10468         std::vector<StringRef> parseEnums( StringRef enums );
10469
10470     } // Detail
10471
10472 } // Catch
10473
10474 // end catch_enum_values_registry.h
10475
10476 #include <map>
10477 #include <cassert>
10478
10479 namespace Catch {
10480
10481     IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
10482
10483     namespace Detail {
10484
10485         namespace {
10486             // Extracts the actual name part of an enum instance
10487             // In other words, it returns the Blue part of Bikeshed::Colour::Blue
10488             StringRef extractInstanceName(StringRef enumInstance) {
10489                 // Find last occurence of ":"
10490                 size_t name_start = enumInstance.size();
10491                 while (name_start > 0 && enumInstance[name_start - 1] != ':') {
10492                     --name_start;
10493                 }
10494                 return enumInstance.substr(name_start, enumInstance.size() - name_start);
10495             }
10496         }
10497
10498         std::vector<StringRef> parseEnums( StringRef enums ) {
10499             auto enumValues = splitStringRef( enums, ',' );
10500             std::vector<StringRef> parsed;
10501             parsed.reserve( enumValues.size() );
10502             for( auto const& enumValue : enumValues ) {
10503                 parsed.push_back(trim(extractInstanceName(enumValue)));
10504             }
10505             return parsed;
10506         }
10507
10508         EnumInfo::~EnumInfo() {}
10509
10510         StringRef EnumInfo::lookup( int value ) const {
10511             for( auto const& valueToName : m_values ) {
10512                 if( valueToName.first == value )
10513                     return valueToName.second;
10514             }
10515             return "{** unexpected enum value **}"_sr;
10516         }
10517
10518         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10519             std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
10520             enumInfo->m_name = enumName;
10521             enumInfo->m_values.reserve( values.size() );
10522
10523             const auto valueNames = Catch::Detail::parseEnums( allValueNames );
10524             assert( valueNames.size() == values.size() );
10525             std::size_t i = 0;
10526             for( auto value : values )
10527                 enumInfo->m_values.push_back({ value, valueNames[i++] });
10528
10529             return enumInfo;
10530         }
10531
10532         EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10533             m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
10534             return *m_enumInfos.back();
10535         }
10536
10537     } // Detail
10538 } // Catch
10539
10540 // end catch_enum_values_registry.cpp
10541 // start catch_errno_guard.cpp
10542
10543 #include <cerrno>
10544
10545 namespace Catch {
10546         ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
10547         ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
10548 }
10549 // end catch_errno_guard.cpp
10550 // start catch_exception_translator_registry.cpp
10551
10552 // start catch_exception_translator_registry.h
10553
10554 #include <vector>
10555 #include <string>
10556 #include <memory>
10557
10558 namespace Catch {
10559
10560     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
10561     public:
10562         ~ExceptionTranslatorRegistry();
10563         virtual void registerTranslator( const IExceptionTranslator* translator );
10564         std::string translateActiveException() const override;
10565         std::string tryTranslators() const;
10566
10567     private:
10568         std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
10569     };
10570 }
10571
10572 // end catch_exception_translator_registry.h
10573 #ifdef __OBJC__
10574 #import "Foundation/Foundation.h"
10575 #endif
10576
10577 namespace Catch {
10578
10579     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
10580     }
10581
10582     void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
10583         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
10584     }
10585
10586 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10587     std::string ExceptionTranslatorRegistry::translateActiveException() const {
10588         try {
10589 #ifdef __OBJC__
10590             // In Objective-C try objective-c exceptions first
10591             @try {
10592                 return tryTranslators();
10593             }
10594             @catch (NSException *exception) {
10595                 return Catch::Detail::stringify( [exception description] );
10596             }
10597 #else
10598             // Compiling a mixed mode project with MSVC means that CLR
10599             // exceptions will be caught in (...) as well. However, these
10600             // do not fill-in std::current_exception and thus lead to crash
10601             // when attempting rethrow.
10602             // /EHa switch also causes structured exceptions to be caught
10603             // here, but they fill-in current_exception properly, so
10604             // at worst the output should be a little weird, instead of
10605             // causing a crash.
10606             if (std::current_exception() == nullptr) {
10607                 return "Non C++ exception. Possibly a CLR exception.";
10608             }
10609             return tryTranslators();
10610 #endif
10611         }
10612         catch( TestFailureException& ) {
10613             std::rethrow_exception(std::current_exception());
10614         }
10615         catch( std::exception& ex ) {
10616             return ex.what();
10617         }
10618         catch( std::string& msg ) {
10619             return msg;
10620         }
10621         catch( const char* msg ) {
10622             return msg;
10623         }
10624         catch(...) {
10625             return "Unknown exception";
10626         }
10627     }
10628
10629     std::string ExceptionTranslatorRegistry::tryTranslators() const {
10630         if (m_translators.empty()) {
10631             std::rethrow_exception(std::current_exception());
10632         } else {
10633             return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
10634         }
10635     }
10636
10637 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
10638     std::string ExceptionTranslatorRegistry::translateActiveException() const {
10639         CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10640     }
10641
10642     std::string ExceptionTranslatorRegistry::tryTranslators() const {
10643         CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10644     }
10645 #endif
10646
10647 }
10648 // end catch_exception_translator_registry.cpp
10649 // start catch_fatal_condition.cpp
10650
10651 #if defined(__GNUC__)
10652 #    pragma GCC diagnostic push
10653 #    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
10654 #endif
10655
10656 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
10657
10658 namespace {
10659     // Report the error condition
10660     void reportFatal( char const * const message ) {
10661         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
10662     }
10663 }
10664
10665 #endif // signals/SEH handling
10666
10667 #if defined( CATCH_CONFIG_WINDOWS_SEH )
10668
10669 namespace Catch {
10670     struct SignalDefs { DWORD id; const char* name; };
10671
10672     // There is no 1-1 mapping between signals and windows exceptions.
10673     // Windows can easily distinguish between SO and SigSegV,
10674     // but SigInt, SigTerm, etc are handled differently.
10675     static SignalDefs signalDefs[] = {
10676         { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  "SIGILL - Illegal instruction signal" },
10677         { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
10678         { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
10679         { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
10680     };
10681
10682     LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
10683         for (auto const& def : signalDefs) {
10684             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
10685                 reportFatal(def.name);
10686             }
10687         }
10688         // If its not an exception we care about, pass it along.
10689         // This stops us from eating debugger breaks etc.
10690         return EXCEPTION_CONTINUE_SEARCH;
10691     }
10692
10693     FatalConditionHandler::FatalConditionHandler() {
10694         isSet = true;
10695         // 32k seems enough for Catch to handle stack overflow,
10696         // but the value was found experimentally, so there is no strong guarantee
10697         guaranteeSize = 32 * 1024;
10698         exceptionHandlerHandle = nullptr;
10699         // Register as first handler in current chain
10700         exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
10701         // Pass in guarantee size to be filled
10702         SetThreadStackGuarantee(&guaranteeSize);
10703     }
10704
10705     void FatalConditionHandler::reset() {
10706         if (isSet) {
10707             RemoveVectoredExceptionHandler(exceptionHandlerHandle);
10708             SetThreadStackGuarantee(&guaranteeSize);
10709             exceptionHandlerHandle = nullptr;
10710             isSet = false;
10711         }
10712     }
10713
10714     FatalConditionHandler::~FatalConditionHandler() {
10715         reset();
10716     }
10717
10718 bool FatalConditionHandler::isSet = false;
10719 ULONG FatalConditionHandler::guaranteeSize = 0;
10720 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
10721
10722 } // namespace Catch
10723
10724 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
10725
10726 namespace Catch {
10727
10728     struct SignalDefs {
10729         int id;
10730         const char* name;
10731     };
10732
10733     // 32kb for the alternate stack seems to be sufficient. However, this value
10734     // is experimentally determined, so that's not guaranteed.
10735     // Update: MINSIGSTKSZ is not const anymore with recent glibc
10736     static constexpr std::size_t sigStackSize = 32768;
10737
10738     static SignalDefs signalDefs[] = {
10739         { SIGINT,  "SIGINT - Terminal interrupt signal" },
10740         { SIGILL,  "SIGILL - Illegal instruction signal" },
10741         { SIGFPE,  "SIGFPE - Floating point error signal" },
10742         { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
10743         { SIGTERM, "SIGTERM - Termination request signal" },
10744         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
10745     };
10746
10747     void FatalConditionHandler::handleSignal( int sig ) {
10748         char const * name = "<unknown signal>";
10749         for (auto const& def : signalDefs) {
10750             if (sig == def.id) {
10751                 name = def.name;
10752                 break;
10753             }
10754         }
10755         reset();
10756         reportFatal(name);
10757         raise( sig );
10758     }
10759
10760     FatalConditionHandler::FatalConditionHandler() {
10761         isSet = true;
10762         stack_t sigStack;
10763         sigStack.ss_sp = altStackMem;
10764         sigStack.ss_size = sigStackSize;
10765         sigStack.ss_flags = 0;
10766         sigaltstack(&sigStack, &oldSigStack);
10767         struct sigaction sa = { };
10768
10769         sa.sa_handler = handleSignal;
10770         sa.sa_flags = SA_ONSTACK;
10771         for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
10772             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
10773         }
10774     }
10775
10776     FatalConditionHandler::~FatalConditionHandler() {
10777         reset();
10778     }
10779
10780     void FatalConditionHandler::reset() {
10781         if( isSet ) {
10782             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
10783             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
10784                 sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
10785             }
10786             // Return the old stack
10787             sigaltstack(&oldSigStack, nullptr);
10788             isSet = false;
10789         }
10790     }
10791
10792     bool FatalConditionHandler::isSet = false;
10793     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
10794     stack_t FatalConditionHandler::oldSigStack = {};
10795     char FatalConditionHandler::altStackMem[sigStackSize] = {};
10796
10797 } // namespace Catch
10798
10799 #else
10800
10801 namespace Catch {
10802     void FatalConditionHandler::reset() {}
10803 }
10804
10805 #endif // signals/SEH handling
10806
10807 #if defined(__GNUC__)
10808 #    pragma GCC diagnostic pop
10809 #endif
10810 // end catch_fatal_condition.cpp
10811 // start catch_generators.cpp
10812
10813 #include <limits>
10814 #include <set>
10815
10816 namespace Catch {
10817
10818 IGeneratorTracker::~IGeneratorTracker() {}
10819
10820 const char* GeneratorException::what() const noexcept {
10821     return m_msg;
10822 }
10823
10824 namespace Generators {
10825
10826     GeneratorUntypedBase::~GeneratorUntypedBase() {}
10827
10828     auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
10829         return getResultCapture().acquireGeneratorTracker( lineInfo );
10830     }
10831
10832 } // namespace Generators
10833 } // namespace Catch
10834 // end catch_generators.cpp
10835 // start catch_interfaces_capture.cpp
10836
10837 namespace Catch {
10838     IResultCapture::~IResultCapture() = default;
10839 }
10840 // end catch_interfaces_capture.cpp
10841 // start catch_interfaces_config.cpp
10842
10843 namespace Catch {
10844     IConfig::~IConfig() = default;
10845 }
10846 // end catch_interfaces_config.cpp
10847 // start catch_interfaces_exception.cpp
10848
10849 namespace Catch {
10850     IExceptionTranslator::~IExceptionTranslator() = default;
10851     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
10852 }
10853 // end catch_interfaces_exception.cpp
10854 // start catch_interfaces_registry_hub.cpp
10855
10856 namespace Catch {
10857     IRegistryHub::~IRegistryHub() = default;
10858     IMutableRegistryHub::~IMutableRegistryHub() = default;
10859 }
10860 // end catch_interfaces_registry_hub.cpp
10861 // start catch_interfaces_reporter.cpp
10862
10863 // start catch_reporter_listening.h
10864
10865 namespace Catch {
10866
10867     class ListeningReporter : public IStreamingReporter {
10868         using Reporters = std::vector<IStreamingReporterPtr>;
10869         Reporters m_listeners;
10870         IStreamingReporterPtr m_reporter = nullptr;
10871         ReporterPreferences m_preferences;
10872
10873     public:
10874         ListeningReporter();
10875
10876         void addListener( IStreamingReporterPtr&& listener );
10877         void addReporter( IStreamingReporterPtr&& reporter );
10878
10879     public: // IStreamingReporter
10880
10881         ReporterPreferences getPreferences() const override;
10882
10883         void noMatchingTestCases( std::string const& spec ) override;
10884
10885         void reportInvalidArguments(std::string const&arg) override;
10886
10887         static std::set<Verbosity> getSupportedVerbosities();
10888
10889 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
10890         void benchmarkPreparing(std::string const& name) override;
10891         void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
10892         void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
10893         void benchmarkFailed(std::string const&) override;
10894 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
10895
10896         void testRunStarting( TestRunInfo const& testRunInfo ) override;
10897         void testGroupStarting( GroupInfo const& groupInfo ) override;
10898         void testCaseStarting( TestCaseInfo const& testInfo ) override;
10899         void sectionStarting( SectionInfo const& sectionInfo ) override;
10900         void assertionStarting( AssertionInfo const& assertionInfo ) override;
10901
10902         // The return value indicates if the messages buffer should be cleared:
10903         bool assertionEnded( AssertionStats const& assertionStats ) override;
10904         void sectionEnded( SectionStats const& sectionStats ) override;
10905         void testCaseEnded( TestCaseStats const& testCaseStats ) override;
10906         void testGroupEnded( TestGroupStats const& testGroupStats ) override;
10907         void testRunEnded( TestRunStats const& testRunStats ) override;
10908
10909         void skipTest( TestCaseInfo const& testInfo ) override;
10910         bool isMulti() const override;
10911
10912     };
10913
10914 } // end namespace Catch
10915
10916 // end catch_reporter_listening.h
10917 namespace Catch {
10918
10919     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
10920     :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
10921
10922     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
10923     :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
10924
10925     std::ostream& ReporterConfig::stream() const { return *m_stream; }
10926     IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
10927
10928     TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
10929
10930     GroupInfo::GroupInfo(  std::string const& _name,
10931                            std::size_t _groupIndex,
10932                            std::size_t _groupsCount )
10933     :   name( _name ),
10934         groupIndex( _groupIndex ),
10935         groupsCounts( _groupsCount )
10936     {}
10937
10938      AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
10939                                      std::vector<MessageInfo> const& _infoMessages,
10940                                      Totals const& _totals )
10941     :   assertionResult( _assertionResult ),
10942         infoMessages( _infoMessages ),
10943         totals( _totals )
10944     {
10945         assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
10946
10947         if( assertionResult.hasMessage() ) {
10948             // Copy message into messages list.
10949             // !TBD This should have been done earlier, somewhere
10950             MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
10951             builder << assertionResult.getMessage();
10952             builder.m_info.message = builder.m_stream.str();
10953
10954             infoMessages.push_back( builder.m_info );
10955         }
10956     }
10957
10958      AssertionStats::~AssertionStats() = default;
10959
10960     SectionStats::SectionStats(  SectionInfo const& _sectionInfo,
10961                                  Counts const& _assertions,
10962                                  double _durationInSeconds,
10963                                  bool _missingAssertions )
10964     :   sectionInfo( _sectionInfo ),
10965         assertions( _assertions ),
10966         durationInSeconds( _durationInSeconds ),
10967         missingAssertions( _missingAssertions )
10968     {}
10969
10970     SectionStats::~SectionStats() = default;
10971
10972     TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,
10973                                    Totals const& _totals,
10974                                    std::string const& _stdOut,
10975                                    std::string const& _stdErr,
10976                                    bool _aborting )
10977     : testInfo( _testInfo ),
10978         totals( _totals ),
10979         stdOut( _stdOut ),
10980         stdErr( _stdErr ),
10981         aborting( _aborting )
10982     {}
10983
10984     TestCaseStats::~TestCaseStats() = default;
10985
10986     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
10987                                     Totals const& _totals,
10988                                     bool _aborting )
10989     :   groupInfo( _groupInfo ),
10990         totals( _totals ),
10991         aborting( _aborting )
10992     {}
10993
10994     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
10995     :   groupInfo( _groupInfo ),
10996         aborting( false )
10997     {}
10998
10999     TestGroupStats::~TestGroupStats() = default;
11000
11001     TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,
11002                     Totals const& _totals,
11003                     bool _aborting )
11004     :   runInfo( _runInfo ),
11005         totals( _totals ),
11006         aborting( _aborting )
11007     {}
11008
11009     TestRunStats::~TestRunStats() = default;
11010
11011     void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
11012     bool IStreamingReporter::isMulti() const { return false; }
11013
11014     IReporterFactory::~IReporterFactory() = default;
11015     IReporterRegistry::~IReporterRegistry() = default;
11016
11017 } // end namespace Catch
11018 // end catch_interfaces_reporter.cpp
11019 // start catch_interfaces_runner.cpp
11020
11021 namespace Catch {
11022     IRunner::~IRunner() = default;
11023 }
11024 // end catch_interfaces_runner.cpp
11025 // start catch_interfaces_testcase.cpp
11026
11027 namespace Catch {
11028     ITestInvoker::~ITestInvoker() = default;
11029     ITestCaseRegistry::~ITestCaseRegistry() = default;
11030 }
11031 // end catch_interfaces_testcase.cpp
11032 // start catch_leak_detector.cpp
11033
11034 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
11035 #include <crtdbg.h>
11036
11037 namespace Catch {
11038
11039     LeakDetector::LeakDetector() {
11040         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
11041         flag |= _CRTDBG_LEAK_CHECK_DF;
11042         flag |= _CRTDBG_ALLOC_MEM_DF;
11043         _CrtSetDbgFlag(flag);
11044         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
11045         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
11046         // Change this to leaking allocation's number to break there
11047         _CrtSetBreakAlloc(-1);
11048     }
11049 }
11050
11051 #else
11052
11053     Catch::LeakDetector::LeakDetector() {}
11054
11055 #endif
11056
11057 Catch::LeakDetector::~LeakDetector() {
11058     Catch::cleanUp();
11059 }
11060 // end catch_leak_detector.cpp
11061 // start catch_list.cpp
11062
11063 // start catch_list.h
11064
11065 #include <set>
11066
11067 namespace Catch {
11068
11069     std::size_t listTests( Config const& config );
11070
11071     std::size_t listTestsNamesOnly( Config const& config );
11072
11073     struct TagInfo {
11074         void add( std::string const& spelling );
11075         std::string all() const;
11076
11077         std::set<std::string> spellings;
11078         std::size_t count = 0;
11079     };
11080
11081     std::size_t listTags( Config const& config );
11082
11083     std::size_t listReporters();
11084
11085     Option<std::size_t> list( std::shared_ptr<Config> const& config );
11086
11087 } // end namespace Catch
11088
11089 // end catch_list.h
11090 // start catch_text.h
11091
11092 namespace Catch {
11093     using namespace clara::TextFlow;
11094 }
11095
11096 // end catch_text.h
11097 #include <limits>
11098 #include <algorithm>
11099 #include <iomanip>
11100
11101 namespace Catch {
11102
11103     std::size_t listTests( Config const& config ) {
11104         TestSpec testSpec = config.testSpec();
11105         if( config.hasTestFilters() )
11106             Catch::cout() << "Matching test cases:\n";
11107         else {
11108             Catch::cout() << "All available test cases:\n";
11109         }
11110
11111         auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11112         for( auto const& testCaseInfo : matchedTestCases ) {
11113             Colour::Code colour = testCaseInfo.isHidden()
11114                 ? Colour::SecondaryText
11115                 : Colour::None;
11116             Colour colourGuard( colour );
11117
11118             Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
11119             if( config.verbosity() >= Verbosity::High ) {
11120                 Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
11121                 std::string description = testCaseInfo.description;
11122                 if( description.empty() )
11123                     description = "(NO DESCRIPTION)";
11124                 Catch::cout() << Column( description ).indent(4) << std::endl;
11125             }
11126             if( !testCaseInfo.tags.empty() )
11127                 Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
11128         }
11129
11130         if( !config.hasTestFilters() )
11131             Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
11132         else
11133             Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
11134         return matchedTestCases.size();
11135     }
11136
11137     std::size_t listTestsNamesOnly( Config const& config ) {
11138         TestSpec testSpec = config.testSpec();
11139         std::size_t matchedTests = 0;
11140         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11141         for( auto const& testCaseInfo : matchedTestCases ) {
11142             matchedTests++;
11143             if( startsWith( testCaseInfo.name, '#' ) )
11144                Catch::cout() << '"' << testCaseInfo.name << '"';
11145             else
11146                Catch::cout() << testCaseInfo.name;
11147             if ( config.verbosity() >= Verbosity::High )
11148                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
11149             Catch::cout() << std::endl;
11150         }
11151         return matchedTests;
11152     }
11153
11154     void TagInfo::add( std::string const& spelling ) {
11155         ++count;
11156         spellings.insert( spelling );
11157     }
11158
11159     std::string TagInfo::all() const {
11160         size_t size = 0;
11161         for (auto const& spelling : spellings) {
11162             // Add 2 for the brackes
11163             size += spelling.size() + 2;
11164         }
11165
11166         std::string out; out.reserve(size);
11167         for (auto const& spelling : spellings) {
11168             out += '[';
11169             out += spelling;
11170             out += ']';
11171         }
11172         return out;
11173     }
11174
11175     std::size_t listTags( Config const& config ) {
11176         TestSpec testSpec = config.testSpec();
11177         if( config.hasTestFilters() )
11178             Catch::cout() << "Tags for matching test cases:\n";
11179         else {
11180             Catch::cout() << "All available tags:\n";
11181         }
11182
11183         std::map<std::string, TagInfo> tagCounts;
11184
11185         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11186         for( auto const& testCase : matchedTestCases ) {
11187             for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
11188                 std::string lcaseTagName = toLower( tagName );
11189                 auto countIt = tagCounts.find( lcaseTagName );
11190                 if( countIt == tagCounts.end() )
11191                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
11192                 countIt->second.add( tagName );
11193             }
11194         }
11195
11196         for( auto const& tagCount : tagCounts ) {
11197             ReusableStringStream rss;
11198             rss << "  " << std::setw(2) << tagCount.second.count << "  ";
11199             auto str = rss.str();
11200             auto wrapper = Column( tagCount.second.all() )
11201                                                     .initialIndent( 0 )
11202                                                     .indent( str.size() )
11203                                                     .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
11204             Catch::cout() << str << wrapper << '\n';
11205         }
11206         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
11207         return tagCounts.size();
11208     }
11209
11210     std::size_t listReporters() {
11211         Catch::cout() << "Available reporters:\n";
11212         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
11213         std::size_t maxNameLen = 0;
11214         for( auto const& factoryKvp : factories )
11215             maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
11216
11217         for( auto const& factoryKvp : factories ) {
11218             Catch::cout()
11219                     << Column( factoryKvp.first + ":" )
11220                             .indent(2)
11221                             .width( 5+maxNameLen )
11222                     +  Column( factoryKvp.second->getDescription() )
11223                             .initialIndent(0)
11224                             .indent(2)
11225                             .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
11226                     << "\n";
11227         }
11228         Catch::cout() << std::endl;
11229         return factories.size();
11230     }
11231
11232     Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
11233         Option<std::size_t> listedCount;
11234         getCurrentMutableContext().setConfig( config );
11235         if( config->listTests() )
11236             listedCount = listedCount.valueOr(0) + listTests( *config );
11237         if( config->listTestNamesOnly() )
11238             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
11239         if( config->listTags() )
11240             listedCount = listedCount.valueOr(0) + listTags( *config );
11241         if( config->listReporters() )
11242             listedCount = listedCount.valueOr(0) + listReporters();
11243         return listedCount;
11244     }
11245
11246 } // end namespace Catch
11247 // end catch_list.cpp
11248 // start catch_matchers.cpp
11249
11250 namespace Catch {
11251 namespace Matchers {
11252     namespace Impl {
11253
11254         std::string MatcherUntypedBase::toString() const {
11255             if( m_cachedToString.empty() )
11256                 m_cachedToString = describe();
11257             return m_cachedToString;
11258         }
11259
11260         MatcherUntypedBase::~MatcherUntypedBase() = default;
11261
11262     } // namespace Impl
11263 } // namespace Matchers
11264
11265 using namespace Matchers;
11266 using Matchers::Impl::MatcherBase;
11267
11268 } // namespace Catch
11269 // end catch_matchers.cpp
11270 // start catch_matchers_exception.cpp
11271
11272 namespace Catch {
11273 namespace Matchers {
11274 namespace Exception {
11275
11276 bool ExceptionMessageMatcher::match(std::exception const& ex) const {
11277     return ex.what() == m_message;
11278 }
11279
11280 std::string ExceptionMessageMatcher::describe() const {
11281     return "exception message matches \"" + m_message + "\"";
11282 }
11283
11284 }
11285 Exception::ExceptionMessageMatcher Message(std::string const& message) {
11286     return Exception::ExceptionMessageMatcher(message);
11287 }
11288
11289 // namespace Exception
11290 } // namespace Matchers
11291 } // namespace Catch
11292 // end catch_matchers_exception.cpp
11293 // start catch_matchers_floating.cpp
11294
11295 // start catch_polyfills.hpp
11296
11297 namespace Catch {
11298     bool isnan(float f);
11299     bool isnan(double d);
11300 }
11301
11302 // end catch_polyfills.hpp
11303 // start catch_to_string.hpp
11304
11305 #include <string>
11306
11307 namespace Catch {
11308     template <typename T>
11309     std::string to_string(T const& t) {
11310 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11311         return std::to_string(t);
11312 #else
11313         ReusableStringStream rss;
11314         rss << t;
11315         return rss.str();
11316 #endif
11317     }
11318 } // end namespace Catch
11319
11320 // end catch_to_string.hpp
11321 #include <algorithm>
11322 #include <cmath>
11323 #include <cstdlib>
11324 #include <cstdint>
11325 #include <cstring>
11326 #include <sstream>
11327 #include <type_traits>
11328 #include <iomanip>
11329 #include <limits>
11330
11331 namespace Catch {
11332 namespace {
11333
11334     int32_t convert(float f) {
11335         static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
11336         int32_t i;
11337         std::memcpy(&i, &f, sizeof(f));
11338         return i;
11339     }
11340
11341     int64_t convert(double d) {
11342         static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
11343         int64_t i;
11344         std::memcpy(&i, &d, sizeof(d));
11345         return i;
11346     }
11347
11348     template <typename FP>
11349     bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
11350         // Comparison with NaN should always be false.
11351         // This way we can rule it out before getting into the ugly details
11352         if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
11353             return false;
11354         }
11355
11356         auto lc = convert(lhs);
11357         auto rc = convert(rhs);
11358
11359         if ((lc < 0) != (rc < 0)) {
11360             // Potentially we can have +0 and -0
11361             return lhs == rhs;
11362         }
11363
11364         auto ulpDiff = std::abs(lc - rc);
11365         return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
11366     }
11367
11368 } //end anonymous namespace
11369
11370 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11371
11372 #if defined(__clang__)
11373 #pragma clang diagnostic push
11374 // The long double overload is currently unused
11375 #pragma clang diagnostic ignored "-Wunused-function"
11376 #endif
11377
11378     float nextafter(float x, float y) {
11379         return ::nextafterf(x, y);
11380     }
11381
11382     double nextafter(double x, double y) {
11383         return ::nextafter(x, y);
11384     }
11385
11386     long double nextafter(long double x, long double y) {
11387         return ::nextafterl(x, y);
11388     }
11389
11390 #if defined(__clang__)
11391 #pragma clang diagnostic pop
11392 #endif
11393
11394 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
11395
11396 namespace {
11397
11398 template <typename FP>
11399 FP step(FP start, FP direction, uint64_t steps) {
11400     for (uint64_t i = 0; i < steps; ++i) {
11401 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11402         start = Catch::nextafter(start, direction);
11403 #else
11404         start = std::nextafter(start, direction);
11405 #endif
11406     }
11407     return start;
11408 }
11409
11410 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11411 // But without the subtraction to allow for INFINITY in comparison
11412 bool marginComparison(double lhs, double rhs, double margin) {
11413     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
11414 }
11415
11416 template <typename FloatingPoint>
11417 void write(std::ostream& out, FloatingPoint num) {
11418     out << std::scientific
11419         << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
11420         << num;
11421 }
11422
11423 } // end anonymous namespace
11424
11425 namespace Matchers {
11426 namespace Floating {
11427
11428     enum class FloatingPointKind : uint8_t {
11429         Float,
11430         Double
11431     };
11432
11433     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
11434         :m_target{ target }, m_margin{ margin } {
11435         CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
11436             << " Margin has to be non-negative.");
11437     }
11438
11439     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11440     // But without the subtraction to allow for INFINITY in comparison
11441     bool WithinAbsMatcher::match(double const& matchee) const {
11442         return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
11443     }
11444
11445     std::string WithinAbsMatcher::describe() const {
11446         return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
11447     }
11448
11449     WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
11450         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
11451         CATCH_ENFORCE(m_type == FloatingPointKind::Double
11452                    || m_ulps < (std::numeric_limits<uint32_t>::max)(),
11453             "Provided ULP is impossibly large for a float comparison.");
11454     }
11455
11456 #if defined(__clang__)
11457 #pragma clang diagnostic push
11458 // Clang <3.5 reports on the default branch in the switch below
11459 #pragma clang diagnostic ignored "-Wunreachable-code"
11460 #endif
11461
11462     bool WithinUlpsMatcher::match(double const& matchee) const {
11463         switch (m_type) {
11464         case FloatingPointKind::Float:
11465             return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
11466         case FloatingPointKind::Double:
11467             return almostEqualUlps<double>(matchee, m_target, m_ulps);
11468         default:
11469             CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
11470         }
11471     }
11472
11473 #if defined(__clang__)
11474 #pragma clang diagnostic pop
11475 #endif
11476
11477     std::string WithinUlpsMatcher::describe() const {
11478         std::stringstream ret;
11479
11480         ret << "is within " << m_ulps << " ULPs of ";
11481
11482         if (m_type == FloatingPointKind::Float) {
11483             write(ret, static_cast<float>(m_target));
11484             ret << 'f';
11485         } else {
11486             write(ret, m_target);
11487         }
11488
11489         ret << " ([";
11490         if (m_type == FloatingPointKind::Double) {
11491             write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
11492             ret << ", ";
11493             write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
11494         } else {
11495             // We have to cast INFINITY to float because of MinGW, see #1782
11496             write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
11497             ret << ", ";
11498             write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
11499         }
11500         ret << "])";
11501
11502         return ret.str();
11503     }
11504
11505     WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
11506         m_target(target),
11507         m_epsilon(epsilon){
11508         CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
11509         CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
11510     }
11511
11512     bool WithinRelMatcher::match(double const& matchee) const {
11513         const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
11514         return marginComparison(matchee, m_target,
11515                                 std::isinf(relMargin)? 0 : relMargin);
11516     }
11517
11518     std::string WithinRelMatcher::describe() const {
11519         Catch::ReusableStringStream sstr;
11520         sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
11521         return sstr.str();
11522     }
11523
11524 }// namespace Floating
11525
11526 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
11527     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
11528 }
11529
11530 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
11531     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
11532 }
11533
11534 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
11535     return Floating::WithinAbsMatcher(target, margin);
11536 }
11537
11538 Floating::WithinRelMatcher WithinRel(double target, double eps) {
11539     return Floating::WithinRelMatcher(target, eps);
11540 }
11541
11542 Floating::WithinRelMatcher WithinRel(double target) {
11543     return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
11544 }
11545
11546 Floating::WithinRelMatcher WithinRel(float target, float eps) {
11547     return Floating::WithinRelMatcher(target, eps);
11548 }
11549
11550 Floating::WithinRelMatcher WithinRel(float target) {
11551     return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
11552 }
11553
11554 } // namespace Matchers
11555 } // namespace Catch
11556
11557 // end catch_matchers_floating.cpp
11558 // start catch_matchers_generic.cpp
11559
11560 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
11561     if (desc.empty()) {
11562         return "matches undescribed predicate";
11563     } else {
11564         return "matches predicate: \"" + desc + '"';
11565     }
11566 }
11567 // end catch_matchers_generic.cpp
11568 // start catch_matchers_string.cpp
11569
11570 #include <regex>
11571
11572 namespace Catch {
11573 namespace Matchers {
11574
11575     namespace StdString {
11576
11577         CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
11578         :   m_caseSensitivity( caseSensitivity ),
11579             m_str( adjustString( str ) )
11580         {}
11581         std::string CasedString::adjustString( std::string const& str ) const {
11582             return m_caseSensitivity == CaseSensitive::No
11583                    ? toLower( str )
11584                    : str;
11585         }
11586         std::string CasedString::caseSensitivitySuffix() const {
11587             return m_caseSensitivity == CaseSensitive::No
11588                    ? " (case insensitive)"
11589                    : std::string();
11590         }
11591
11592         StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
11593         : m_comparator( comparator ),
11594           m_operation( operation ) {
11595         }
11596
11597         std::string StringMatcherBase::describe() const {
11598             std::string description;
11599             description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
11600                                         m_comparator.caseSensitivitySuffix().size());
11601             description += m_operation;
11602             description += ": \"";
11603             description += m_comparator.m_str;
11604             description += "\"";
11605             description += m_comparator.caseSensitivitySuffix();
11606             return description;
11607         }
11608
11609         EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
11610
11611         bool EqualsMatcher::match( std::string const& source ) const {
11612             return m_comparator.adjustString( source ) == m_comparator.m_str;
11613         }
11614
11615         ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
11616
11617         bool ContainsMatcher::match( std::string const& source ) const {
11618             return contains( m_comparator.adjustString( source ), m_comparator.m_str );
11619         }
11620
11621         StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
11622
11623         bool StartsWithMatcher::match( std::string const& source ) const {
11624             return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11625         }
11626
11627         EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
11628
11629         bool EndsWithMatcher::match( std::string const& source ) const {
11630             return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11631         }
11632
11633         RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
11634
11635         bool RegexMatcher::match(std::string const& matchee) const {
11636             auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
11637             if (m_caseSensitivity == CaseSensitive::Choice::No) {
11638                 flags |= std::regex::icase;
11639             }
11640             auto reg = std::regex(m_regex, flags);
11641             return std::regex_match(matchee, reg);
11642         }
11643
11644         std::string RegexMatcher::describe() const {
11645             return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
11646         }
11647
11648     } // namespace StdString
11649
11650     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11651         return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
11652     }
11653     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11654         return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
11655     }
11656     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11657         return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11658     }
11659     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11660         return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11661     }
11662
11663     StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
11664         return StdString::RegexMatcher(regex, caseSensitivity);
11665     }
11666
11667 } // namespace Matchers
11668 } // namespace Catch
11669 // end catch_matchers_string.cpp
11670 // start catch_message.cpp
11671
11672 // start catch_uncaught_exceptions.h
11673
11674 namespace Catch {
11675     bool uncaught_exceptions();
11676 } // end namespace Catch
11677
11678 // end catch_uncaught_exceptions.h
11679 #include <cassert>
11680 #include <stack>
11681
11682 namespace Catch {
11683
11684     MessageInfo::MessageInfo(   StringRef const& _macroName,
11685                                 SourceLineInfo const& _lineInfo,
11686                                 ResultWas::OfType _type )
11687     :   macroName( _macroName ),
11688         lineInfo( _lineInfo ),
11689         type( _type ),
11690         sequence( ++globalCount )
11691     {}
11692
11693     bool MessageInfo::operator==( MessageInfo const& other ) const {
11694         return sequence == other.sequence;
11695     }
11696
11697     bool MessageInfo::operator<( MessageInfo const& other ) const {
11698         return sequence < other.sequence;
11699     }
11700
11701     // This may need protecting if threading support is added
11702     unsigned int MessageInfo::globalCount = 0;
11703
11704     ////////////////////////////////////////////////////////////////////////////
11705
11706     Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
11707                                            SourceLineInfo const& lineInfo,
11708                                            ResultWas::OfType type )
11709         :m_info(macroName, lineInfo, type) {}
11710
11711     ////////////////////////////////////////////////////////////////////////////
11712
11713     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
11714     : m_info( builder.m_info ), m_moved()
11715     {
11716         m_info.message = builder.m_stream.str();
11717         getResultCapture().pushScopedMessage( m_info );
11718     }
11719
11720     ScopedMessage::ScopedMessage( ScopedMessage&& old )
11721     : m_info( old.m_info ), m_moved()
11722     {
11723         old.m_moved = true;
11724     }
11725
11726     ScopedMessage::~ScopedMessage() {
11727         if ( !uncaught_exceptions() && !m_moved ){
11728             getResultCapture().popScopedMessage(m_info);
11729         }
11730     }
11731
11732     Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
11733         auto trimmed = [&] (size_t start, size_t end) {
11734             while (names[start] == ',' || isspace(names[start])) {
11735                 ++start;
11736             }
11737             while (names[end] == ',' || isspace(names[end])) {
11738                 --end;
11739             }
11740             return names.substr(start, end - start + 1);
11741         };
11742         auto skipq = [&] (size_t start, char quote) {
11743             for (auto i = start + 1; i < names.size() ; ++i) {
11744                 if (names[i] == quote)
11745                     return i;
11746                 if (names[i] == '\\')
11747                     ++i;
11748             }
11749             CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
11750         };
11751
11752         size_t start = 0;
11753         std::stack<char> openings;
11754         for (size_t pos = 0; pos < names.size(); ++pos) {
11755             char c = names[pos];
11756             switch (c) {
11757             case '[':
11758             case '{':
11759             case '(':
11760             // It is basically impossible to disambiguate between
11761             // comparison and start of template args in this context
11762 //            case '<':
11763                 openings.push(c);
11764                 break;
11765             case ']':
11766             case '}':
11767             case ')':
11768 //           case '>':
11769                 openings.pop();
11770                 break;
11771             case '"':
11772             case '\'':
11773                 pos = skipq(pos, c);
11774                 break;
11775             case ',':
11776                 if (start != pos && openings.size() == 0) {
11777                     m_messages.emplace_back(macroName, lineInfo, resultType);
11778                     m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
11779                     m_messages.back().message += " := ";
11780                     start = pos;
11781                 }
11782             }
11783         }
11784         assert(openings.size() == 0 && "Mismatched openings");
11785         m_messages.emplace_back(macroName, lineInfo, resultType);
11786         m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
11787         m_messages.back().message += " := ";
11788     }
11789     Capturer::~Capturer() {
11790         if ( !uncaught_exceptions() ){
11791             assert( m_captured == m_messages.size() );
11792             for( size_t i = 0; i < m_captured; ++i  )
11793                 m_resultCapture.popScopedMessage( m_messages[i] );
11794         }
11795     }
11796
11797     void Capturer::captureValue( size_t index, std::string const& value ) {
11798         assert( index < m_messages.size() );
11799         m_messages[index].message += value;
11800         m_resultCapture.pushScopedMessage( m_messages[index] );
11801         m_captured++;
11802     }
11803
11804 } // end namespace Catch
11805 // end catch_message.cpp
11806 // start catch_output_redirect.cpp
11807
11808 // start catch_output_redirect.h
11809 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11810 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11811
11812 #include <cstdio>
11813 #include <iosfwd>
11814 #include <string>
11815
11816 namespace Catch {
11817
11818     class RedirectedStream {
11819         std::ostream& m_originalStream;
11820         std::ostream& m_redirectionStream;
11821         std::streambuf* m_prevBuf;
11822
11823     public:
11824         RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
11825         ~RedirectedStream();
11826     };
11827
11828     class RedirectedStdOut {
11829         ReusableStringStream m_rss;
11830         RedirectedStream m_cout;
11831     public:
11832         RedirectedStdOut();
11833         auto str() const -> std::string;
11834     };
11835
11836     // StdErr has two constituent streams in C++, std::cerr and std::clog
11837     // This means that we need to redirect 2 streams into 1 to keep proper
11838     // order of writes
11839     class RedirectedStdErr {
11840         ReusableStringStream m_rss;
11841         RedirectedStream m_cerr;
11842         RedirectedStream m_clog;
11843     public:
11844         RedirectedStdErr();
11845         auto str() const -> std::string;
11846     };
11847
11848     class RedirectedStreams {
11849     public:
11850         RedirectedStreams(RedirectedStreams const&) = delete;
11851         RedirectedStreams& operator=(RedirectedStreams const&) = delete;
11852         RedirectedStreams(RedirectedStreams&&) = delete;
11853         RedirectedStreams& operator=(RedirectedStreams&&) = delete;
11854
11855         RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
11856         ~RedirectedStreams();
11857     private:
11858         std::string& m_redirectedCout;
11859         std::string& m_redirectedCerr;
11860         RedirectedStdOut m_redirectedStdOut;
11861         RedirectedStdErr m_redirectedStdErr;
11862     };
11863
11864 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11865
11866     // Windows's implementation of std::tmpfile is terrible (it tries
11867     // to create a file inside system folder, thus requiring elevated
11868     // privileges for the binary), so we have to use tmpnam(_s) and
11869     // create the file ourselves there.
11870     class TempFile {
11871     public:
11872         TempFile(TempFile const&) = delete;
11873         TempFile& operator=(TempFile const&) = delete;
11874         TempFile(TempFile&&) = delete;
11875         TempFile& operator=(TempFile&&) = delete;
11876
11877         TempFile();
11878         ~TempFile();
11879
11880         std::FILE* getFile();
11881         std::string getContents();
11882
11883     private:
11884         std::FILE* m_file = nullptr;
11885     #if defined(_MSC_VER)
11886         char m_buffer[L_tmpnam] = { 0 };
11887     #endif
11888     };
11889
11890     class OutputRedirect {
11891     public:
11892         OutputRedirect(OutputRedirect const&) = delete;
11893         OutputRedirect& operator=(OutputRedirect const&) = delete;
11894         OutputRedirect(OutputRedirect&&) = delete;
11895         OutputRedirect& operator=(OutputRedirect&&) = delete;
11896
11897         OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
11898         ~OutputRedirect();
11899
11900     private:
11901         int m_originalStdout = -1;
11902         int m_originalStderr = -1;
11903         TempFile m_stdoutFile;
11904         TempFile m_stderrFile;
11905         std::string& m_stdoutDest;
11906         std::string& m_stderrDest;
11907     };
11908
11909 #endif
11910
11911 } // end namespace Catch
11912
11913 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11914 // end catch_output_redirect.h
11915 #include <cstdio>
11916 #include <cstring>
11917 #include <fstream>
11918 #include <sstream>
11919 #include <stdexcept>
11920
11921 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11922     #if defined(_MSC_VER)
11923     #include <io.h>      //_dup and _dup2
11924     #define dup _dup
11925     #define dup2 _dup2
11926     #define fileno _fileno
11927     #else
11928     #include <unistd.h>  // dup and dup2
11929     #endif
11930 #endif
11931
11932 namespace Catch {
11933
11934     RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
11935     :   m_originalStream( originalStream ),
11936         m_redirectionStream( redirectionStream ),
11937         m_prevBuf( m_originalStream.rdbuf() )
11938     {
11939         m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
11940     }
11941
11942     RedirectedStream::~RedirectedStream() {
11943         m_originalStream.rdbuf( m_prevBuf );
11944     }
11945
11946     RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
11947     auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
11948
11949     RedirectedStdErr::RedirectedStdErr()
11950     :   m_cerr( Catch::cerr(), m_rss.get() ),
11951         m_clog( Catch::clog(), m_rss.get() )
11952     {}
11953     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
11954
11955     RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
11956     :   m_redirectedCout(redirectedCout),
11957         m_redirectedCerr(redirectedCerr)
11958     {}
11959
11960     RedirectedStreams::~RedirectedStreams() {
11961         m_redirectedCout += m_redirectedStdOut.str();
11962         m_redirectedCerr += m_redirectedStdErr.str();
11963     }
11964
11965 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11966
11967 #if defined(_MSC_VER)
11968     TempFile::TempFile() {
11969         if (tmpnam_s(m_buffer)) {
11970             CATCH_RUNTIME_ERROR("Could not get a temp filename");
11971         }
11972         if (fopen_s(&m_file, m_buffer, "w")) {
11973             char buffer[100];
11974             if (strerror_s(buffer, errno)) {
11975                 CATCH_RUNTIME_ERROR("Could not translate errno to a string");
11976             }
11977             CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
11978         }
11979     }
11980 #else
11981     TempFile::TempFile() {
11982         m_file = std::tmpfile();
11983         if (!m_file) {
11984             CATCH_RUNTIME_ERROR("Could not create a temp file.");
11985         }
11986     }
11987
11988 #endif
11989
11990     TempFile::~TempFile() {
11991          // TBD: What to do about errors here?
11992          std::fclose(m_file);
11993          // We manually create the file on Windows only, on Linux
11994          // it will be autodeleted
11995 #if defined(_MSC_VER)
11996          std::remove(m_buffer);
11997 #endif
11998     }
11999
12000     FILE* TempFile::getFile() {
12001         return m_file;
12002     }
12003
12004     std::string TempFile::getContents() {
12005         std::stringstream sstr;
12006         char buffer[100] = {};
12007         std::rewind(m_file);
12008         while (std::fgets(buffer, sizeof(buffer), m_file)) {
12009             sstr << buffer;
12010         }
12011         return sstr.str();
12012     }
12013
12014     OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
12015         m_originalStdout(dup(1)),
12016         m_originalStderr(dup(2)),
12017         m_stdoutDest(stdout_dest),
12018         m_stderrDest(stderr_dest) {
12019         dup2(fileno(m_stdoutFile.getFile()), 1);
12020         dup2(fileno(m_stderrFile.getFile()), 2);
12021     }
12022
12023     OutputRedirect::~OutputRedirect() {
12024         Catch::cout() << std::flush;
12025         fflush(stdout);
12026         // Since we support overriding these streams, we flush cerr
12027         // even though std::cerr is unbuffered
12028         Catch::cerr() << std::flush;
12029         Catch::clog() << std::flush;
12030         fflush(stderr);
12031
12032         dup2(m_originalStdout, 1);
12033         dup2(m_originalStderr, 2);
12034
12035         m_stdoutDest += m_stdoutFile.getContents();
12036         m_stderrDest += m_stderrFile.getContents();
12037     }
12038
12039 #endif // CATCH_CONFIG_NEW_CAPTURE
12040
12041 } // namespace Catch
12042
12043 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12044     #if defined(_MSC_VER)
12045     #undef dup
12046     #undef dup2
12047     #undef fileno
12048     #endif
12049 #endif
12050 // end catch_output_redirect.cpp
12051 // start catch_polyfills.cpp
12052
12053 #include <cmath>
12054
12055 namespace Catch {
12056
12057 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
12058     bool isnan(float f) {
12059         return std::isnan(f);
12060     }
12061     bool isnan(double d) {
12062         return std::isnan(d);
12063     }
12064 #else
12065     // For now we only use this for embarcadero
12066     bool isnan(float f) {
12067         return std::_isnan(f);
12068     }
12069     bool isnan(double d) {
12070         return std::_isnan(d);
12071     }
12072 #endif
12073
12074 } // end namespace Catch
12075 // end catch_polyfills.cpp
12076 // start catch_random_number_generator.cpp
12077
12078 namespace Catch {
12079
12080 namespace {
12081
12082 #if defined(_MSC_VER)
12083 #pragma warning(push)
12084 #pragma warning(disable:4146) // we negate uint32 during the rotate
12085 #endif
12086         // Safe rotr implementation thanks to John Regehr
12087         uint32_t rotate_right(uint32_t val, uint32_t count) {
12088             const uint32_t mask = 31;
12089             count &= mask;
12090             return (val >> count) | (val << (-count & mask));
12091         }
12092
12093 #if defined(_MSC_VER)
12094 #pragma warning(pop)
12095 #endif
12096
12097 }
12098
12099     SimplePcg32::SimplePcg32(result_type seed_) {
12100         seed(seed_);
12101     }
12102
12103     void SimplePcg32::seed(result_type seed_) {
12104         m_state = 0;
12105         (*this)();
12106         m_state += seed_;
12107         (*this)();
12108     }
12109
12110     void SimplePcg32::discard(uint64_t skip) {
12111         // We could implement this to run in O(log n) steps, but this
12112         // should suffice for our use case.
12113         for (uint64_t s = 0; s < skip; ++s) {
12114             static_cast<void>((*this)());
12115         }
12116     }
12117
12118     SimplePcg32::result_type SimplePcg32::operator()() {
12119         // prepare the output value
12120         const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
12121         const auto output = rotate_right(xorshifted, m_state >> 59u);
12122
12123         // advance state
12124         m_state = m_state * 6364136223846793005ULL + s_inc;
12125
12126         return output;
12127     }
12128
12129     bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12130         return lhs.m_state == rhs.m_state;
12131     }
12132
12133     bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12134         return lhs.m_state != rhs.m_state;
12135     }
12136 }
12137 // end catch_random_number_generator.cpp
12138 // start catch_registry_hub.cpp
12139
12140 // start catch_test_case_registry_impl.h
12141
12142 #include <vector>
12143 #include <set>
12144 #include <algorithm>
12145 #include <ios>
12146
12147 namespace Catch {
12148
12149     class TestCase;
12150     struct IConfig;
12151
12152     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
12153
12154     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
12155     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
12156
12157     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
12158
12159     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
12160     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
12161
12162     class TestRegistry : public ITestCaseRegistry {
12163     public:
12164         virtual ~TestRegistry() = default;
12165
12166         virtual void registerTest( TestCase const& testCase );
12167
12168         std::vector<TestCase> const& getAllTests() const override;
12169         std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
12170
12171     private:
12172         std::vector<TestCase> m_functions;
12173         mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
12174         mutable std::vector<TestCase> m_sortedFunctions;
12175         std::size_t m_unnamedCount = 0;
12176         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
12177     };
12178
12179     ///////////////////////////////////////////////////////////////////////////
12180
12181     class TestInvokerAsFunction : public ITestInvoker {
12182         void(*m_testAsFunction)();
12183     public:
12184         TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
12185
12186         void invoke() const override;
12187     };
12188
12189     std::string extractClassName( StringRef const& classOrQualifiedMethodName );
12190
12191     ///////////////////////////////////////////////////////////////////////////
12192
12193 } // end namespace Catch
12194
12195 // end catch_test_case_registry_impl.h
12196 // start catch_reporter_registry.h
12197
12198 #include <map>
12199
12200 namespace Catch {
12201
12202     class ReporterRegistry : public IReporterRegistry {
12203
12204     public:
12205
12206         ~ReporterRegistry() override;
12207
12208         IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
12209
12210         void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
12211         void registerListener( IReporterFactoryPtr const& factory );
12212
12213         FactoryMap const& getFactories() const override;
12214         Listeners const& getListeners() const override;
12215
12216     private:
12217         FactoryMap m_factories;
12218         Listeners m_listeners;
12219     };
12220 }
12221
12222 // end catch_reporter_registry.h
12223 // start catch_tag_alias_registry.h
12224
12225 // start catch_tag_alias.h
12226
12227 #include <string>
12228
12229 namespace Catch {
12230
12231     struct TagAlias {
12232         TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
12233
12234         std::string tag;
12235         SourceLineInfo lineInfo;
12236     };
12237
12238 } // end namespace Catch
12239
12240 // end catch_tag_alias.h
12241 #include <map>
12242
12243 namespace Catch {
12244
12245     class TagAliasRegistry : public ITagAliasRegistry {
12246     public:
12247         ~TagAliasRegistry() override;
12248         TagAlias const* find( std::string const& alias ) const override;
12249         std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
12250         void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
12251
12252     private:
12253         std::map<std::string, TagAlias> m_registry;
12254     };
12255
12256 } // end namespace Catch
12257
12258 // end catch_tag_alias_registry.h
12259 // start catch_startup_exception_registry.h
12260
12261 #include <vector>
12262 #include <exception>
12263
12264 namespace Catch {
12265
12266     class StartupExceptionRegistry {
12267     public:
12268         void add(std::exception_ptr const& exception) noexcept;
12269         std::vector<std::exception_ptr> const& getExceptions() const noexcept;
12270     private:
12271         std::vector<std::exception_ptr> m_exceptions;
12272     };
12273
12274 } // end namespace Catch
12275
12276 // end catch_startup_exception_registry.h
12277 // start catch_singletons.hpp
12278
12279 namespace Catch {
12280
12281     struct ISingleton {
12282         virtual ~ISingleton();
12283     };
12284
12285     void addSingleton( ISingleton* singleton );
12286     void cleanupSingletons();
12287
12288     template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
12289     class Singleton : SingletonImplT, public ISingleton {
12290
12291         static auto getInternal() -> Singleton* {
12292             static Singleton* s_instance = nullptr;
12293             if( !s_instance ) {
12294                 s_instance = new Singleton;
12295                 addSingleton( s_instance );
12296             }
12297             return s_instance;
12298         }
12299
12300     public:
12301         static auto get() -> InterfaceT const& {
12302             return *getInternal();
12303         }
12304         static auto getMutable() -> MutableInterfaceT& {
12305             return *getInternal();
12306         }
12307     };
12308
12309 } // namespace Catch
12310
12311 // end catch_singletons.hpp
12312 namespace Catch {
12313
12314     namespace {
12315
12316         class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
12317                             private NonCopyable {
12318
12319         public: // IRegistryHub
12320             RegistryHub() = default;
12321             IReporterRegistry const& getReporterRegistry() const override {
12322                 return m_reporterRegistry;
12323             }
12324             ITestCaseRegistry const& getTestCaseRegistry() const override {
12325                 return m_testCaseRegistry;
12326             }
12327             IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
12328                 return m_exceptionTranslatorRegistry;
12329             }
12330             ITagAliasRegistry const& getTagAliasRegistry() const override {
12331                 return m_tagAliasRegistry;
12332             }
12333             StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
12334                 return m_exceptionRegistry;
12335             }
12336
12337         public: // IMutableRegistryHub
12338             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
12339                 m_reporterRegistry.registerReporter( name, factory );
12340             }
12341             void registerListener( IReporterFactoryPtr const& factory ) override {
12342                 m_reporterRegistry.registerListener( factory );
12343             }
12344             void registerTest( TestCase const& testInfo ) override {
12345                 m_testCaseRegistry.registerTest( testInfo );
12346             }
12347             void registerTranslator( const IExceptionTranslator* translator ) override {
12348                 m_exceptionTranslatorRegistry.registerTranslator( translator );
12349             }
12350             void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
12351                 m_tagAliasRegistry.add( alias, tag, lineInfo );
12352             }
12353             void registerStartupException() noexcept override {
12354                 m_exceptionRegistry.add(std::current_exception());
12355             }
12356             IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
12357                 return m_enumValuesRegistry;
12358             }
12359
12360         private:
12361             TestRegistry m_testCaseRegistry;
12362             ReporterRegistry m_reporterRegistry;
12363             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
12364             TagAliasRegistry m_tagAliasRegistry;
12365             StartupExceptionRegistry m_exceptionRegistry;
12366             Detail::EnumValuesRegistry m_enumValuesRegistry;
12367         };
12368     }
12369
12370     using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
12371
12372     IRegistryHub const& getRegistryHub() {
12373         return RegistryHubSingleton::get();
12374     }
12375     IMutableRegistryHub& getMutableRegistryHub() {
12376         return RegistryHubSingleton::getMutable();
12377     }
12378     void cleanUp() {
12379         cleanupSingletons();
12380         cleanUpContext();
12381     }
12382     std::string translateActiveException() {
12383         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
12384     }
12385
12386 } // end namespace Catch
12387 // end catch_registry_hub.cpp
12388 // start catch_reporter_registry.cpp
12389
12390 namespace Catch {
12391
12392     ReporterRegistry::~ReporterRegistry() = default;
12393
12394     IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
12395         auto it =  m_factories.find( name );
12396         if( it == m_factories.end() )
12397             return nullptr;
12398         return it->second->create( ReporterConfig( config ) );
12399     }
12400
12401     void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
12402         m_factories.emplace(name, factory);
12403     }
12404     void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
12405         m_listeners.push_back( factory );
12406     }
12407
12408     IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
12409         return m_factories;
12410     }
12411     IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
12412         return m_listeners;
12413     }
12414
12415 }
12416 // end catch_reporter_registry.cpp
12417 // start catch_result_type.cpp
12418
12419 namespace Catch {
12420
12421     bool isOk( ResultWas::OfType resultType ) {
12422         return ( resultType & ResultWas::FailureBit ) == 0;
12423     }
12424     bool isJustInfo( int flags ) {
12425         return flags == ResultWas::Info;
12426     }
12427
12428     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
12429         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
12430     }
12431
12432     bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
12433     bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
12434
12435 } // end namespace Catch
12436 // end catch_result_type.cpp
12437 // start catch_run_context.cpp
12438
12439 #include <cassert>
12440 #include <algorithm>
12441 #include <sstream>
12442
12443 namespace Catch {
12444
12445     namespace Generators {
12446         struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
12447             GeneratorBasePtr m_generator;
12448
12449             GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
12450             :   TrackerBase( nameAndLocation, ctx, parent )
12451             {}
12452             ~GeneratorTracker();
12453
12454             static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
12455                 std::shared_ptr<GeneratorTracker> tracker;
12456
12457                 ITracker& currentTracker = ctx.currentTracker();
12458                 if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
12459                     assert( childTracker );
12460                     assert( childTracker->isGeneratorTracker() );
12461                     tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
12462                 }
12463                 else {
12464                     tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
12465                     currentTracker.addChild( tracker );
12466                 }
12467
12468                 if( !ctx.completedCycle() && !tracker->isComplete() ) {
12469                     tracker->open();
12470                 }
12471
12472                 return *tracker;
12473             }
12474
12475             // TrackerBase interface
12476             bool isGeneratorTracker() const override { return true; }
12477             auto hasGenerator() const -> bool override {
12478                 return !!m_generator;
12479             }
12480             void close() override {
12481                 TrackerBase::close();
12482                 // Generator interface only finds out if it has another item on atual move
12483                 if (m_runState == CompletedSuccessfully && m_generator->next()) {
12484                     m_children.clear();
12485                     m_runState = Executing;
12486                 }
12487             }
12488
12489             // IGeneratorTracker interface
12490             auto getGenerator() const -> GeneratorBasePtr const& override {
12491                 return m_generator;
12492             }
12493             void setGenerator( GeneratorBasePtr&& generator ) override {
12494                 m_generator = std::move( generator );
12495             }
12496         };
12497         GeneratorTracker::~GeneratorTracker() {}
12498     }
12499
12500     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
12501     :   m_runInfo(_config->name()),
12502         m_context(getCurrentMutableContext()),
12503         m_config(_config),
12504         m_reporter(std::move(reporter)),
12505         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
12506         m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
12507     {
12508         m_context.setRunner(this);
12509         m_context.setConfig(m_config);
12510         m_context.setResultCapture(this);
12511         m_reporter->testRunStarting(m_runInfo);
12512     }
12513
12514     RunContext::~RunContext() {
12515         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
12516     }
12517
12518     void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
12519         m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
12520     }
12521
12522     void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
12523         m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
12524     }
12525
12526     Totals RunContext::runTest(TestCase const& testCase) {
12527         Totals prevTotals = m_totals;
12528
12529         std::string redirectedCout;
12530         std::string redirectedCerr;
12531
12532         auto const& testInfo = testCase.getTestCaseInfo();
12533
12534         m_reporter->testCaseStarting(testInfo);
12535
12536         m_activeTestCase = &testCase;
12537
12538         ITracker& rootTracker = m_trackerContext.startRun();
12539         assert(rootTracker.isSectionTracker());
12540         static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
12541         do {
12542             m_trackerContext.startCycle();
12543             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
12544             runCurrentTest(redirectedCout, redirectedCerr);
12545         } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
12546
12547         Totals deltaTotals = m_totals.delta(prevTotals);
12548         if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
12549             deltaTotals.assertions.failed++;
12550             deltaTotals.testCases.passed--;
12551             deltaTotals.testCases.failed++;
12552         }
12553         m_totals.testCases += deltaTotals.testCases;
12554         m_reporter->testCaseEnded(TestCaseStats(testInfo,
12555                                   deltaTotals,
12556                                   redirectedCout,
12557                                   redirectedCerr,
12558                                   aborting()));
12559
12560         m_activeTestCase = nullptr;
12561         m_testCaseTracker = nullptr;
12562
12563         return deltaTotals;
12564     }
12565
12566     IConfigPtr RunContext::config() const {
12567         return m_config;
12568     }
12569
12570     IStreamingReporter& RunContext::reporter() const {
12571         return *m_reporter;
12572     }
12573
12574     void RunContext::assertionEnded(AssertionResult const & result) {
12575         if (result.getResultType() == ResultWas::Ok) {
12576             m_totals.assertions.passed++;
12577             m_lastAssertionPassed = true;
12578         } else if (!result.isOk()) {
12579             m_lastAssertionPassed = false;
12580             if( m_activeTestCase->getTestCaseInfo().okToFail() )
12581                 m_totals.assertions.failedButOk++;
12582             else
12583                 m_totals.assertions.failed++;
12584         }
12585         else {
12586             m_lastAssertionPassed = true;
12587         }
12588
12589         // We have no use for the return value (whether messages should be cleared), because messages were made scoped
12590         // and should be let to clear themselves out.
12591         static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
12592
12593         if (result.getResultType() != ResultWas::Warning)
12594             m_messageScopes.clear();
12595
12596         // Reset working state
12597         resetAssertionInfo();
12598         m_lastResult = result;
12599     }
12600     void RunContext::resetAssertionInfo() {
12601         m_lastAssertionInfo.macroName = StringRef();
12602         m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
12603     }
12604
12605     bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
12606         ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
12607         if (!sectionTracker.isOpen())
12608             return false;
12609         m_activeSections.push_back(&sectionTracker);
12610
12611         m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
12612
12613         m_reporter->sectionStarting(sectionInfo);
12614
12615         assertions = m_totals.assertions;
12616
12617         return true;
12618     }
12619     auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
12620         using namespace Generators;
12621         GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
12622         assert( tracker.isOpen() );
12623         m_lastAssertionInfo.lineInfo = lineInfo;
12624         return tracker;
12625     }
12626
12627     bool RunContext::testForMissingAssertions(Counts& assertions) {
12628         if (assertions.total() != 0)
12629             return false;
12630         if (!m_config->warnAboutMissingAssertions())
12631             return false;
12632         if (m_trackerContext.currentTracker().hasChildren())
12633             return false;
12634         m_totals.assertions.failed++;
12635         assertions.failed++;
12636         return true;
12637     }
12638
12639     void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
12640         Counts assertions = m_totals.assertions - endInfo.prevAssertions;
12641         bool missingAssertions = testForMissingAssertions(assertions);
12642
12643         if (!m_activeSections.empty()) {
12644             m_activeSections.back()->close();
12645             m_activeSections.pop_back();
12646         }
12647
12648         m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
12649         m_messages.clear();
12650         m_messageScopes.clear();
12651     }
12652
12653     void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
12654         if (m_unfinishedSections.empty())
12655             m_activeSections.back()->fail();
12656         else
12657             m_activeSections.back()->close();
12658         m_activeSections.pop_back();
12659
12660         m_unfinishedSections.push_back(endInfo);
12661     }
12662
12663 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
12664     void RunContext::benchmarkPreparing(std::string const& name) {
12665                 m_reporter->benchmarkPreparing(name);
12666         }
12667     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
12668         m_reporter->benchmarkStarting( info );
12669     }
12670     void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
12671         m_reporter->benchmarkEnded( stats );
12672     }
12673         void RunContext::benchmarkFailed(std::string const & error) {
12674                 m_reporter->benchmarkFailed(error);
12675         }
12676 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
12677
12678     void RunContext::pushScopedMessage(MessageInfo const & message) {
12679         m_messages.push_back(message);
12680     }
12681
12682     void RunContext::popScopedMessage(MessageInfo const & message) {
12683         m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
12684     }
12685
12686     void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
12687         m_messageScopes.emplace_back( builder );
12688     }
12689
12690     std::string RunContext::getCurrentTestName() const {
12691         return m_activeTestCase
12692             ? m_activeTestCase->getTestCaseInfo().name
12693             : std::string();
12694     }
12695
12696     const AssertionResult * RunContext::getLastResult() const {
12697         return &(*m_lastResult);
12698     }
12699
12700     void RunContext::exceptionEarlyReported() {
12701         m_shouldReportUnexpected = false;
12702     }
12703
12704     void RunContext::handleFatalErrorCondition( StringRef message ) {
12705         // First notify reporter that bad things happened
12706         m_reporter->fatalErrorEncountered(message);
12707
12708         // Don't rebuild the result -- the stringification itself can cause more fatal errors
12709         // Instead, fake a result data.
12710         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
12711         tempResult.message = static_cast<std::string>(message);
12712         AssertionResult result(m_lastAssertionInfo, tempResult);
12713
12714         assertionEnded(result);
12715
12716         handleUnfinishedSections();
12717
12718         // Recreate section for test case (as we will lose the one that was in scope)
12719         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12720         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12721
12722         Counts assertions;
12723         assertions.failed = 1;
12724         SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
12725         m_reporter->sectionEnded(testCaseSectionStats);
12726
12727         auto const& testInfo = m_activeTestCase->getTestCaseInfo();
12728
12729         Totals deltaTotals;
12730         deltaTotals.testCases.failed = 1;
12731         deltaTotals.assertions.failed = 1;
12732         m_reporter->testCaseEnded(TestCaseStats(testInfo,
12733                                   deltaTotals,
12734                                   std::string(),
12735                                   std::string(),
12736                                   false));
12737         m_totals.testCases.failed++;
12738         testGroupEnded(std::string(), m_totals, 1, 1);
12739         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
12740     }
12741
12742     bool RunContext::lastAssertionPassed() {
12743          return m_lastAssertionPassed;
12744     }
12745
12746     void RunContext::assertionPassed() {
12747         m_lastAssertionPassed = true;
12748         ++m_totals.assertions.passed;
12749         resetAssertionInfo();
12750         m_messageScopes.clear();
12751     }
12752
12753     bool RunContext::aborting() const {
12754         return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
12755     }
12756
12757     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
12758         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12759         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12760         m_reporter->sectionStarting(testCaseSection);
12761         Counts prevAssertions = m_totals.assertions;
12762         double duration = 0;
12763         m_shouldReportUnexpected = true;
12764         m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
12765
12766         seedRng(*m_config);
12767
12768         Timer timer;
12769         CATCH_TRY {
12770             if (m_reporter->getPreferences().shouldRedirectStdOut) {
12771 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
12772                 RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
12773
12774                 timer.start();
12775                 invokeActiveTestCase();
12776 #else
12777                 OutputRedirect r(redirectedCout, redirectedCerr);
12778                 timer.start();
12779                 invokeActiveTestCase();
12780 #endif
12781             } else {
12782                 timer.start();
12783                 invokeActiveTestCase();
12784             }
12785             duration = timer.getElapsedSeconds();
12786         } CATCH_CATCH_ANON (TestFailureException&) {
12787             // This just means the test was aborted due to failure
12788         } CATCH_CATCH_ALL {
12789             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
12790             // are reported without translation at the point of origin.
12791             if( m_shouldReportUnexpected ) {
12792                 AssertionReaction dummyReaction;
12793                 handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
12794             }
12795         }
12796         Counts assertions = m_totals.assertions - prevAssertions;
12797         bool missingAssertions = testForMissingAssertions(assertions);
12798
12799         m_testCaseTracker->close();
12800         handleUnfinishedSections();
12801         m_messages.clear();
12802         m_messageScopes.clear();
12803
12804         SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
12805         m_reporter->sectionEnded(testCaseSectionStats);
12806     }
12807
12808     void RunContext::invokeActiveTestCase() {
12809         FatalConditionHandler fatalConditionHandler; // Handle signals
12810         m_activeTestCase->invoke();
12811         fatalConditionHandler.reset();
12812     }
12813
12814     void RunContext::handleUnfinishedSections() {
12815         // If sections ended prematurely due to an exception we stored their
12816         // infos here so we can tear them down outside the unwind process.
12817         for (auto it = m_unfinishedSections.rbegin(),
12818              itEnd = m_unfinishedSections.rend();
12819              it != itEnd;
12820              ++it)
12821             sectionEnded(*it);
12822         m_unfinishedSections.clear();
12823     }
12824
12825     void RunContext::handleExpr(
12826         AssertionInfo const& info,
12827         ITransientExpression const& expr,
12828         AssertionReaction& reaction
12829     ) {
12830         m_reporter->assertionStarting( info );
12831
12832         bool negated = isFalseTest( info.resultDisposition );
12833         bool result = expr.getResult() != negated;
12834
12835         if( result ) {
12836             if (!m_includeSuccessfulResults) {
12837                 assertionPassed();
12838             }
12839             else {
12840                 reportExpr(info, ResultWas::Ok, &expr, negated);
12841             }
12842         }
12843         else {
12844             reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
12845             populateReaction( reaction );
12846         }
12847     }
12848     void RunContext::reportExpr(
12849             AssertionInfo const &info,
12850             ResultWas::OfType resultType,
12851             ITransientExpression const *expr,
12852             bool negated ) {
12853
12854         m_lastAssertionInfo = info;
12855         AssertionResultData data( resultType, LazyExpression( negated ) );
12856
12857         AssertionResult assertionResult{ info, data };
12858         assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
12859
12860         assertionEnded( assertionResult );
12861     }
12862
12863     void RunContext::handleMessage(
12864             AssertionInfo const& info,
12865             ResultWas::OfType resultType,
12866             StringRef const& message,
12867             AssertionReaction& reaction
12868     ) {
12869         m_reporter->assertionStarting( info );
12870
12871         m_lastAssertionInfo = info;
12872
12873         AssertionResultData data( resultType, LazyExpression( false ) );
12874         data.message = static_cast<std::string>(message);
12875         AssertionResult assertionResult{ m_lastAssertionInfo, data };
12876         assertionEnded( assertionResult );
12877         if( !assertionResult.isOk() )
12878             populateReaction( reaction );
12879     }
12880     void RunContext::handleUnexpectedExceptionNotThrown(
12881             AssertionInfo const& info,
12882             AssertionReaction& reaction
12883     ) {
12884         handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
12885     }
12886
12887     void RunContext::handleUnexpectedInflightException(
12888             AssertionInfo const& info,
12889             std::string const& message,
12890             AssertionReaction& reaction
12891     ) {
12892         m_lastAssertionInfo = info;
12893
12894         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
12895         data.message = message;
12896         AssertionResult assertionResult{ info, data };
12897         assertionEnded( assertionResult );
12898         populateReaction( reaction );
12899     }
12900
12901     void RunContext::populateReaction( AssertionReaction& reaction ) {
12902         reaction.shouldDebugBreak = m_config->shouldDebugBreak();
12903         reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
12904     }
12905
12906     void RunContext::handleIncomplete(
12907             AssertionInfo const& info
12908     ) {
12909         m_lastAssertionInfo = info;
12910
12911         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
12912         data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
12913         AssertionResult assertionResult{ info, data };
12914         assertionEnded( assertionResult );
12915     }
12916     void RunContext::handleNonExpr(
12917             AssertionInfo const &info,
12918             ResultWas::OfType resultType,
12919             AssertionReaction &reaction
12920     ) {
12921         m_lastAssertionInfo = info;
12922
12923         AssertionResultData data( resultType, LazyExpression( false ) );
12924         AssertionResult assertionResult{ info, data };
12925         assertionEnded( assertionResult );
12926
12927         if( !assertionResult.isOk() )
12928             populateReaction( reaction );
12929     }
12930
12931     IResultCapture& getResultCapture() {
12932         if (auto* capture = getCurrentContext().getResultCapture())
12933             return *capture;
12934         else
12935             CATCH_INTERNAL_ERROR("No result capture instance");
12936     }
12937
12938     void seedRng(IConfig const& config) {
12939         if (config.rngSeed() != 0) {
12940             std::srand(config.rngSeed());
12941             rng().seed(config.rngSeed());
12942         }
12943     }
12944
12945     unsigned int rngSeed() {
12946         return getCurrentContext().getConfig()->rngSeed();
12947     }
12948
12949 }
12950 // end catch_run_context.cpp
12951 // start catch_section.cpp
12952
12953 namespace Catch {
12954
12955     Section::Section( SectionInfo const& info )
12956     :   m_info( info ),
12957         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
12958     {
12959         m_timer.start();
12960     }
12961
12962     Section::~Section() {
12963         if( m_sectionIncluded ) {
12964             SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
12965             if( uncaught_exceptions() )
12966                 getResultCapture().sectionEndedEarly( endInfo );
12967             else
12968                 getResultCapture().sectionEnded( endInfo );
12969         }
12970     }
12971
12972     // This indicates whether the section should be executed or not
12973     Section::operator bool() const {
12974         return m_sectionIncluded;
12975     }
12976
12977 } // end namespace Catch
12978 // end catch_section.cpp
12979 // start catch_section_info.cpp
12980
12981 namespace Catch {
12982
12983     SectionInfo::SectionInfo
12984         (   SourceLineInfo const& _lineInfo,
12985             std::string const& _name )
12986     :   name( _name ),
12987         lineInfo( _lineInfo )
12988     {}
12989
12990 } // end namespace Catch
12991 // end catch_section_info.cpp
12992 // start catch_session.cpp
12993
12994 // start catch_session.h
12995
12996 #include <memory>
12997
12998 namespace Catch {
12999
13000     class Session : NonCopyable {
13001     public:
13002
13003         Session();
13004         ~Session() override;
13005
13006         void showHelp() const;
13007         void libIdentify();
13008
13009         int applyCommandLine( int argc, char const * const * argv );
13010     #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13011         int applyCommandLine( int argc, wchar_t const * const * argv );
13012     #endif
13013
13014         void useConfigData( ConfigData const& configData );
13015
13016         template<typename CharT>
13017         int run(int argc, CharT const * const argv[]) {
13018             if (m_startupExceptions)
13019                 return 1;
13020             int returnCode = applyCommandLine(argc, argv);
13021             if (returnCode == 0)
13022                 returnCode = run();
13023             return returnCode;
13024         }
13025
13026         int run();
13027
13028         clara::Parser const& cli() const;
13029         void cli( clara::Parser const& newParser );
13030         ConfigData& configData();
13031         Config& config();
13032     private:
13033         int runInternal();
13034
13035         clara::Parser m_cli;
13036         ConfigData m_configData;
13037         std::shared_ptr<Config> m_config;
13038         bool m_startupExceptions = false;
13039     };
13040
13041 } // end namespace Catch
13042
13043 // end catch_session.h
13044 // start catch_version.h
13045
13046 #include <iosfwd>
13047
13048 namespace Catch {
13049
13050     // Versioning information
13051     struct Version {
13052         Version( Version const& ) = delete;
13053         Version& operator=( Version const& ) = delete;
13054         Version(    unsigned int _majorVersion,
13055                     unsigned int _minorVersion,
13056                     unsigned int _patchNumber,
13057                     char const * const _branchName,
13058                     unsigned int _buildNumber );
13059
13060         unsigned int const majorVersion;
13061         unsigned int const minorVersion;
13062         unsigned int const patchNumber;
13063
13064         // buildNumber is only used if branchName is not null
13065         char const * const branchName;
13066         unsigned int const buildNumber;
13067
13068         friend std::ostream& operator << ( std::ostream& os, Version const& version );
13069     };
13070
13071     Version const& libraryVersion();
13072 }
13073
13074 // end catch_version.h
13075 #include <cstdlib>
13076 #include <iomanip>
13077 #include <set>
13078 #include <iterator>
13079
13080 namespace Catch {
13081
13082     namespace {
13083         const int MaxExitCode = 255;
13084
13085         IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
13086             auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
13087             CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
13088
13089             return reporter;
13090         }
13091
13092         IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
13093             if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
13094                 return createReporter(config->getReporterName(), config);
13095             }
13096
13097             // On older platforms, returning std::unique_ptr<ListeningReporter>
13098             // when the return type is std::unique_ptr<IStreamingReporter>
13099             // doesn't compile without a std::move call. However, this causes
13100             // a warning on newer platforms. Thus, we have to work around
13101             // it a bit and downcast the pointer manually.
13102             auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
13103             auto& multi = static_cast<ListeningReporter&>(*ret);
13104             auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
13105             for (auto const& listener : listeners) {
13106                 multi.addListener(listener->create(Catch::ReporterConfig(config)));
13107             }
13108             multi.addReporter(createReporter(config->getReporterName(), config));
13109             return ret;
13110         }
13111
13112         class TestGroup {
13113         public:
13114             explicit TestGroup(std::shared_ptr<Config> const& config)
13115             : m_config{config}
13116             , m_context{config, makeReporter(config)}
13117             {
13118                 auto const& allTestCases = getAllTestCasesSorted(*m_config);
13119                 m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
13120                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13121
13122                 if (m_matches.empty() && invalidArgs.empty()) {
13123                     for (auto const& test : allTestCases)
13124                         if (!test.isHidden())
13125                             m_tests.emplace(&test);
13126                 } else {
13127                     for (auto const& match : m_matches)
13128                         m_tests.insert(match.tests.begin(), match.tests.end());
13129                 }
13130             }
13131
13132             Totals execute() {
13133                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13134                 Totals totals;
13135                 m_context.testGroupStarting(m_config->name(), 1, 1);
13136                 for (auto const& testCase : m_tests) {
13137                     if (!m_context.aborting())
13138                         totals += m_context.runTest(*testCase);
13139                     else
13140                         m_context.reporter().skipTest(*testCase);
13141                 }
13142
13143                 for (auto const& match : m_matches) {
13144                     if (match.tests.empty()) {
13145                         m_context.reporter().noMatchingTestCases(match.name);
13146                         totals.error = -1;
13147                     }
13148                 }
13149
13150                 if (!invalidArgs.empty()) {
13151                     for (auto const& invalidArg: invalidArgs)
13152                          m_context.reporter().reportInvalidArguments(invalidArg);
13153                 }
13154
13155                 m_context.testGroupEnded(m_config->name(), totals, 1, 1);
13156                 return totals;
13157             }
13158
13159         private:
13160             using Tests = std::set<TestCase const*>;
13161
13162             std::shared_ptr<Config> m_config;
13163             RunContext m_context;
13164             Tests m_tests;
13165             TestSpec::Matches m_matches;
13166         };
13167
13168         void applyFilenamesAsTags(Catch::IConfig const& config) {
13169             auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
13170             for (auto& testCase : tests) {
13171                 auto tags = testCase.tags;
13172
13173                 std::string filename = testCase.lineInfo.file;
13174                 auto lastSlash = filename.find_last_of("\\/");
13175                 if (lastSlash != std::string::npos) {
13176                     filename.erase(0, lastSlash);
13177                     filename[0] = '#';
13178                 }
13179
13180                 auto lastDot = filename.find_last_of('.');
13181                 if (lastDot != std::string::npos) {
13182                     filename.erase(lastDot);
13183                 }
13184
13185                 tags.push_back(std::move(filename));
13186                 setTags(testCase, tags);
13187             }
13188         }
13189
13190     } // anon namespace
13191
13192     Session::Session() {
13193         static bool alreadyInstantiated = false;
13194         if( alreadyInstantiated ) {
13195             CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
13196             CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
13197         }
13198
13199         // There cannot be exceptions at startup in no-exception mode.
13200 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13201         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
13202         if ( !exceptions.empty() ) {
13203             config();
13204             getCurrentMutableContext().setConfig(m_config);
13205
13206             m_startupExceptions = true;
13207             Colour colourGuard( Colour::Red );
13208             Catch::cerr() << "Errors occurred during startup!" << '\n';
13209             // iterate over all exceptions and notify user
13210             for ( const auto& ex_ptr : exceptions ) {
13211                 try {
13212                     std::rethrow_exception(ex_ptr);
13213                 } catch ( std::exception const& ex ) {
13214                     Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
13215                 }
13216             }
13217         }
13218 #endif
13219
13220         alreadyInstantiated = true;
13221         m_cli = makeCommandLineParser( m_configData );
13222     }
13223     Session::~Session() {
13224         Catch::cleanUp();
13225     }
13226
13227     void Session::showHelp() const {
13228         Catch::cout()
13229                 << "\nCatch v" << libraryVersion() << "\n"
13230                 << m_cli << std::endl
13231                 << "For more detailed usage please see the project docs\n" << std::endl;
13232     }
13233     void Session::libIdentify() {
13234         Catch::cout()
13235                 << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
13236                 << std::left << std::setw(16) << "category: " << "testframework\n"
13237                 << std::left << std::setw(16) << "framework: " << "Catch Test\n"
13238                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
13239     }
13240
13241     int Session::applyCommandLine( int argc, char const * const * argv ) {
13242         if( m_startupExceptions )
13243             return 1;
13244
13245         auto result = m_cli.parse( clara::Args( argc, argv ) );
13246         if( !result ) {
13247             config();
13248             getCurrentMutableContext().setConfig(m_config);
13249             Catch::cerr()
13250                 << Colour( Colour::Red )
13251                 << "\nError(s) in input:\n"
13252                 << Column( result.errorMessage() ).indent( 2 )
13253                 << "\n\n";
13254             Catch::cerr() << "Run with -? for usage\n" << std::endl;
13255             return MaxExitCode;
13256         }
13257
13258         if( m_configData.showHelp )
13259             showHelp();
13260         if( m_configData.libIdentify )
13261             libIdentify();
13262         m_config.reset();
13263         return 0;
13264     }
13265
13266 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13267     int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
13268
13269         char **utf8Argv = new char *[ argc ];
13270
13271         for ( int i = 0; i < argc; ++i ) {
13272             int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
13273
13274             utf8Argv[ i ] = new char[ bufSize ];
13275
13276             WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
13277         }
13278
13279         int returnCode = applyCommandLine( argc, utf8Argv );
13280
13281         for ( int i = 0; i < argc; ++i )
13282             delete [] utf8Argv[ i ];
13283
13284         delete [] utf8Argv;
13285
13286         return returnCode;
13287     }
13288 #endif
13289
13290     void Session::useConfigData( ConfigData const& configData ) {
13291         m_configData = configData;
13292         m_config.reset();
13293     }
13294
13295     int Session::run() {
13296         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
13297             Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
13298             static_cast<void>(std::getchar());
13299         }
13300         int exitCode = runInternal();
13301         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
13302             Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
13303             static_cast<void>(std::getchar());
13304         }
13305         return exitCode;
13306     }
13307
13308     clara::Parser const& Session::cli() const {
13309         return m_cli;
13310     }
13311     void Session::cli( clara::Parser const& newParser ) {
13312         m_cli = newParser;
13313     }
13314     ConfigData& Session::configData() {
13315         return m_configData;
13316     }
13317     Config& Session::config() {
13318         if( !m_config )
13319             m_config = std::make_shared<Config>( m_configData );
13320         return *m_config;
13321     }
13322
13323     int Session::runInternal() {
13324         if( m_startupExceptions )
13325             return 1;
13326
13327         if (m_configData.showHelp || m_configData.libIdentify) {
13328             return 0;
13329         }
13330
13331         CATCH_TRY {
13332             config(); // Force config to be constructed
13333
13334             seedRng( *m_config );
13335
13336             if( m_configData.filenamesAsTags )
13337                 applyFilenamesAsTags( *m_config );
13338
13339             // Handle list request
13340             if( Option<std::size_t> listed = list( m_config ) )
13341                 return static_cast<int>( *listed );
13342
13343             TestGroup tests { m_config };
13344             auto const totals = tests.execute();
13345
13346             if( m_config->warnAboutNoTests() && totals.error == -1 )
13347                 return 2;
13348
13349             // Note that on unices only the lower 8 bits are usually used, clamping
13350             // the return value to 255 prevents false negative when some multiple
13351             // of 256 tests has failed
13352             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
13353         }
13354 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13355         catch( std::exception& ex ) {
13356             Catch::cerr() << ex.what() << std::endl;
13357             return MaxExitCode;
13358         }
13359 #endif
13360     }
13361
13362 } // end namespace Catch
13363 // end catch_session.cpp
13364 // start catch_singletons.cpp
13365
13366 #include <vector>
13367
13368 namespace Catch {
13369
13370     namespace {
13371         static auto getSingletons() -> std::vector<ISingleton*>*& {
13372             static std::vector<ISingleton*>* g_singletons = nullptr;
13373             if( !g_singletons )
13374                 g_singletons = new std::vector<ISingleton*>();
13375             return g_singletons;
13376         }
13377     }
13378
13379     ISingleton::~ISingleton() {}
13380
13381     void addSingleton(ISingleton* singleton ) {
13382         getSingletons()->push_back( singleton );
13383     }
13384     void cleanupSingletons() {
13385         auto& singletons = getSingletons();
13386         for( auto singleton : *singletons )
13387             delete singleton;
13388         delete singletons;
13389         singletons = nullptr;
13390     }
13391
13392 } // namespace Catch
13393 // end catch_singletons.cpp
13394 // start catch_startup_exception_registry.cpp
13395
13396 namespace Catch {
13397 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
13398         CATCH_TRY {
13399             m_exceptions.push_back(exception);
13400         } CATCH_CATCH_ALL {
13401             // If we run out of memory during start-up there's really not a lot more we can do about it
13402             std::terminate();
13403         }
13404     }
13405
13406     std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
13407         return m_exceptions;
13408     }
13409
13410 } // end namespace Catch
13411 // end catch_startup_exception_registry.cpp
13412 // start catch_stream.cpp
13413
13414 #include <cstdio>
13415 #include <iostream>
13416 #include <fstream>
13417 #include <sstream>
13418 #include <vector>
13419 #include <memory>
13420
13421 namespace Catch {
13422
13423     Catch::IStream::~IStream() = default;
13424
13425     namespace Detail { namespace {
13426         template<typename WriterF, std::size_t bufferSize=256>
13427         class StreamBufImpl : public std::streambuf {
13428             char data[bufferSize];
13429             WriterF m_writer;
13430
13431         public:
13432             StreamBufImpl() {
13433                 setp( data, data + sizeof(data) );
13434             }
13435
13436             ~StreamBufImpl() noexcept {
13437                 StreamBufImpl::sync();
13438             }
13439
13440         private:
13441             int overflow( int c ) override {
13442                 sync();
13443
13444                 if( c != EOF ) {
13445                     if( pbase() == epptr() )
13446                         m_writer( std::string( 1, static_cast<char>( c ) ) );
13447                     else
13448                         sputc( static_cast<char>( c ) );
13449                 }
13450                 return 0;
13451             }
13452
13453             int sync() override {
13454                 if( pbase() != pptr() ) {
13455                     m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
13456                     setp( pbase(), epptr() );
13457                 }
13458                 return 0;
13459             }
13460         };
13461
13462         ///////////////////////////////////////////////////////////////////////////
13463
13464         struct OutputDebugWriter {
13465
13466             void operator()( std::string const&str ) {
13467                 writeToDebugConsole( str );
13468             }
13469         };
13470
13471         ///////////////////////////////////////////////////////////////////////////
13472
13473         class FileStream : public IStream {
13474             mutable std::ofstream m_ofs;
13475         public:
13476             FileStream( StringRef filename ) {
13477                 m_ofs.open( filename.c_str() );
13478                 CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
13479             }
13480             ~FileStream() override = default;
13481         public: // IStream
13482             std::ostream& stream() const override {
13483                 return m_ofs;
13484             }
13485         };
13486
13487         ///////////////////////////////////////////////////////////////////////////
13488
13489         class CoutStream : public IStream {
13490             mutable std::ostream m_os;
13491         public:
13492             // Store the streambuf from cout up-front because
13493             // cout may get redirected when running tests
13494             CoutStream() : m_os( Catch::cout().rdbuf() ) {}
13495             ~CoutStream() override = default;
13496
13497         public: // IStream
13498             std::ostream& stream() const override { return m_os; }
13499         };
13500
13501         ///////////////////////////////////////////////////////////////////////////
13502
13503         class DebugOutStream : public IStream {
13504             std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
13505             mutable std::ostream m_os;
13506         public:
13507             DebugOutStream()
13508             :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
13509                 m_os( m_streamBuf.get() )
13510             {}
13511
13512             ~DebugOutStream() override = default;
13513
13514         public: // IStream
13515             std::ostream& stream() const override { return m_os; }
13516         };
13517
13518     }} // namespace anon::detail
13519
13520     ///////////////////////////////////////////////////////////////////////////
13521
13522     auto makeStream( StringRef const &filename ) -> IStream const* {
13523         if( filename.empty() )
13524             return new Detail::CoutStream();
13525         else if( filename[0] == '%' ) {
13526             if( filename == "%debug" )
13527                 return new Detail::DebugOutStream();
13528             else
13529                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
13530         }
13531         else
13532             return new Detail::FileStream( filename );
13533     }
13534
13535     // This class encapsulates the idea of a pool of ostringstreams that can be reused.
13536     struct StringStreams {
13537         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
13538         std::vector<std::size_t> m_unused;
13539         std::ostringstream m_referenceStream; // Used for copy state/ flags from
13540
13541         auto add() -> std::size_t {
13542             if( m_unused.empty() ) {
13543                 m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
13544                 return m_streams.size()-1;
13545             }
13546             else {
13547                 auto index = m_unused.back();
13548                 m_unused.pop_back();
13549                 return index;
13550             }
13551         }
13552
13553         void release( std::size_t index ) {
13554             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
13555             m_unused.push_back(index);
13556         }
13557     };
13558
13559     ReusableStringStream::ReusableStringStream()
13560     :   m_index( Singleton<StringStreams>::getMutable().add() ),
13561         m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
13562     {}
13563
13564     ReusableStringStream::~ReusableStringStream() {
13565         static_cast<std::ostringstream*>( m_oss )->str("");
13566         m_oss->clear();
13567         Singleton<StringStreams>::getMutable().release( m_index );
13568     }
13569
13570     auto ReusableStringStream::str() const -> std::string {
13571         return static_cast<std::ostringstream*>( m_oss )->str();
13572     }
13573
13574     ///////////////////////////////////////////////////////////////////////////
13575
13576 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
13577     std::ostream& cout() { return std::cout; }
13578     std::ostream& cerr() { return std::cerr; }
13579     std::ostream& clog() { return std::clog; }
13580 #endif
13581 }
13582 // end catch_stream.cpp
13583 // start catch_string_manip.cpp
13584
13585 #include <algorithm>
13586 #include <ostream>
13587 #include <cstring>
13588 #include <cctype>
13589 #include <vector>
13590
13591 namespace Catch {
13592
13593     namespace {
13594         char toLowerCh(char c) {
13595             return static_cast<char>( std::tolower( c ) );
13596         }
13597     }
13598
13599     bool startsWith( std::string const& s, std::string const& prefix ) {
13600         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
13601     }
13602     bool startsWith( std::string const& s, char prefix ) {
13603         return !s.empty() && s[0] == prefix;
13604     }
13605     bool endsWith( std::string const& s, std::string const& suffix ) {
13606         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
13607     }
13608     bool endsWith( std::string const& s, char suffix ) {
13609         return !s.empty() && s[s.size()-1] == suffix;
13610     }
13611     bool contains( std::string const& s, std::string const& infix ) {
13612         return s.find( infix ) != std::string::npos;
13613     }
13614     void toLowerInPlace( std::string& s ) {
13615         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
13616     }
13617     std::string toLower( std::string const& s ) {
13618         std::string lc = s;
13619         toLowerInPlace( lc );
13620         return lc;
13621     }
13622     std::string trim( std::string const& str ) {
13623         static char const* whitespaceChars = "\n\r\t ";
13624         std::string::size_type start = str.find_first_not_of( whitespaceChars );
13625         std::string::size_type end = str.find_last_not_of( whitespaceChars );
13626
13627         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
13628     }
13629
13630     StringRef trim(StringRef ref) {
13631         const auto is_ws = [](char c) {
13632             return c == ' ' || c == '\t' || c == '\n' || c == '\r';
13633         };
13634         size_t real_begin = 0;
13635         while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
13636         size_t real_end = ref.size();
13637         while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
13638
13639         return ref.substr(real_begin, real_end - real_begin);
13640     }
13641
13642     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
13643         bool replaced = false;
13644         std::size_t i = str.find( replaceThis );
13645         while( i != std::string::npos ) {
13646             replaced = true;
13647             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
13648             if( i < str.size()-withThis.size() )
13649                 i = str.find( replaceThis, i+withThis.size() );
13650             else
13651                 i = std::string::npos;
13652         }
13653         return replaced;
13654     }
13655
13656     std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
13657         std::vector<StringRef> subStrings;
13658         std::size_t start = 0;
13659         for(std::size_t pos = 0; pos < str.size(); ++pos ) {
13660             if( str[pos] == delimiter ) {
13661                 if( pos - start > 1 )
13662                     subStrings.push_back( str.substr( start, pos-start ) );
13663                 start = pos+1;
13664             }
13665         }
13666         if( start < str.size() )
13667             subStrings.push_back( str.substr( start, str.size()-start ) );
13668         return subStrings;
13669     }
13670
13671     pluralise::pluralise( std::size_t count, std::string const& label )
13672     :   m_count( count ),
13673         m_label( label )
13674     {}
13675
13676     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
13677         os << pluraliser.m_count << ' ' << pluraliser.m_label;
13678         if( pluraliser.m_count != 1 )
13679             os << 's';
13680         return os;
13681     }
13682
13683 }
13684 // end catch_string_manip.cpp
13685 // start catch_stringref.cpp
13686
13687 #include <algorithm>
13688 #include <ostream>
13689 #include <cstring>
13690 #include <cstdint>
13691
13692 namespace Catch {
13693     StringRef::StringRef( char const* rawChars ) noexcept
13694     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
13695     {}
13696
13697     auto StringRef::c_str() const -> char const* {
13698         CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
13699         return m_start;
13700     }
13701     auto StringRef::data() const noexcept -> char const* {
13702         return m_start;
13703     }
13704
13705     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
13706         if (start < m_size) {
13707             return StringRef(m_start + start, (std::min)(m_size - start, size));
13708         } else {
13709             return StringRef();
13710         }
13711     }
13712     auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
13713         return m_size == other.m_size
13714             && (std::memcmp( m_start, other.m_start, m_size ) == 0);
13715     }
13716
13717     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
13718         return os.write(str.data(), str.size());
13719     }
13720
13721     auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
13722         lhs.append(rhs.data(), rhs.size());
13723         return lhs;
13724     }
13725
13726 } // namespace Catch
13727 // end catch_stringref.cpp
13728 // start catch_tag_alias.cpp
13729
13730 namespace Catch {
13731     TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
13732 }
13733 // end catch_tag_alias.cpp
13734 // start catch_tag_alias_autoregistrar.cpp
13735
13736 namespace Catch {
13737
13738     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
13739         CATCH_TRY {
13740             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
13741         } CATCH_CATCH_ALL {
13742             // Do not throw when constructing global objects, instead register the exception to be processed later
13743             getMutableRegistryHub().registerStartupException();
13744         }
13745     }
13746
13747 }
13748 // end catch_tag_alias_autoregistrar.cpp
13749 // start catch_tag_alias_registry.cpp
13750
13751 #include <sstream>
13752
13753 namespace Catch {
13754
13755     TagAliasRegistry::~TagAliasRegistry() {}
13756
13757     TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
13758         auto it = m_registry.find( alias );
13759         if( it != m_registry.end() )
13760             return &(it->second);
13761         else
13762             return nullptr;
13763     }
13764
13765     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
13766         std::string expandedTestSpec = unexpandedTestSpec;
13767         for( auto const& registryKvp : m_registry ) {
13768             std::size_t pos = expandedTestSpec.find( registryKvp.first );
13769             if( pos != std::string::npos ) {
13770                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
13771                                     registryKvp.second.tag +
13772                                     expandedTestSpec.substr( pos + registryKvp.first.size() );
13773             }
13774         }
13775         return expandedTestSpec;
13776     }
13777
13778     void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
13779         CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
13780                       "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
13781
13782         CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
13783                       "error: tag alias, '" << alias << "' already registered.\n"
13784                       << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
13785                       << "\tRedefined at: " << lineInfo );
13786     }
13787
13788     ITagAliasRegistry::~ITagAliasRegistry() {}
13789
13790     ITagAliasRegistry const& ITagAliasRegistry::get() {
13791         return getRegistryHub().getTagAliasRegistry();
13792     }
13793
13794 } // end namespace Catch
13795 // end catch_tag_alias_registry.cpp
13796 // start catch_test_case_info.cpp
13797
13798 #include <cctype>
13799 #include <exception>
13800 #include <algorithm>
13801 #include <sstream>
13802
13803 namespace Catch {
13804
13805     namespace {
13806         TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
13807             if( startsWith( tag, '.' ) ||
13808                 tag == "!hide" )
13809                 return TestCaseInfo::IsHidden;
13810             else if( tag == "!throws" )
13811                 return TestCaseInfo::Throws;
13812             else if( tag == "!shouldfail" )
13813                 return TestCaseInfo::ShouldFail;
13814             else if( tag == "!mayfail" )
13815                 return TestCaseInfo::MayFail;
13816             else if( tag == "!nonportable" )
13817                 return TestCaseInfo::NonPortable;
13818             else if( tag == "!benchmark" )
13819                 return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
13820             else
13821                 return TestCaseInfo::None;
13822         }
13823         bool isReservedTag( std::string const& tag ) {
13824             return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
13825         }
13826         void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
13827             CATCH_ENFORCE( !isReservedTag(tag),
13828                           "Tag name: [" << tag << "] is not allowed.\n"
13829                           << "Tag names starting with non alphanumeric characters are reserved\n"
13830                           << _lineInfo );
13831         }
13832     }
13833
13834     TestCase makeTestCase(  ITestInvoker* _testCase,
13835                             std::string const& _className,
13836                             NameAndTags const& nameAndTags,
13837                             SourceLineInfo const& _lineInfo )
13838     {
13839         bool isHidden = false;
13840
13841         // Parse out tags
13842         std::vector<std::string> tags;
13843         std::string desc, tag;
13844         bool inTag = false;
13845         for (char c : nameAndTags.tags) {
13846             if( !inTag ) {
13847                 if( c == '[' )
13848                     inTag = true;
13849                 else
13850                     desc += c;
13851             }
13852             else {
13853                 if( c == ']' ) {
13854                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
13855                     if( ( prop & TestCaseInfo::IsHidden ) != 0 )
13856                         isHidden = true;
13857                     else if( prop == TestCaseInfo::None )
13858                         enforceNotReservedTag( tag, _lineInfo );
13859
13860                     // Merged hide tags like `[.approvals]` should be added as
13861                     // `[.][approvals]`. The `[.]` is added at later point, so
13862                     // we only strip the prefix
13863                     if (startsWith(tag, '.') && tag.size() > 1) {
13864                         tag.erase(0, 1);
13865                     }
13866                     tags.push_back( tag );
13867                     tag.clear();
13868                     inTag = false;
13869                 }
13870                 else
13871                     tag += c;
13872             }
13873         }
13874         if( isHidden ) {
13875             tags.push_back( "." );
13876         }
13877
13878         TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
13879         return TestCase( _testCase, std::move(info) );
13880     }
13881
13882     void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
13883         std::sort(begin(tags), end(tags));
13884         tags.erase(std::unique(begin(tags), end(tags)), end(tags));
13885         testCaseInfo.lcaseTags.clear();
13886
13887         for( auto const& tag : tags ) {
13888             std::string lcaseTag = toLower( tag );
13889             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
13890             testCaseInfo.lcaseTags.push_back( lcaseTag );
13891         }
13892         testCaseInfo.tags = std::move(tags);
13893     }
13894
13895     TestCaseInfo::TestCaseInfo( std::string const& _name,
13896                                 std::string const& _className,
13897                                 std::string const& _description,
13898                                 std::vector<std::string> const& _tags,
13899                                 SourceLineInfo const& _lineInfo )
13900     :   name( _name ),
13901         className( _className ),
13902         description( _description ),
13903         lineInfo( _lineInfo ),
13904         properties( None )
13905     {
13906         setTags( *this, _tags );
13907     }
13908
13909     bool TestCaseInfo::isHidden() const {
13910         return ( properties & IsHidden ) != 0;
13911     }
13912     bool TestCaseInfo::throws() const {
13913         return ( properties & Throws ) != 0;
13914     }
13915     bool TestCaseInfo::okToFail() const {
13916         return ( properties & (ShouldFail | MayFail ) ) != 0;
13917     }
13918     bool TestCaseInfo::expectedToFail() const {
13919         return ( properties & (ShouldFail ) ) != 0;
13920     }
13921
13922     std::string TestCaseInfo::tagsAsString() const {
13923         std::string ret;
13924         // '[' and ']' per tag
13925         std::size_t full_size = 2 * tags.size();
13926         for (const auto& tag : tags) {
13927             full_size += tag.size();
13928         }
13929         ret.reserve(full_size);
13930         for (const auto& tag : tags) {
13931             ret.push_back('[');
13932             ret.append(tag);
13933             ret.push_back(']');
13934         }
13935
13936         return ret;
13937     }
13938
13939     TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
13940
13941     TestCase TestCase::withName( std::string const& _newName ) const {
13942         TestCase other( *this );
13943         other.name = _newName;
13944         return other;
13945     }
13946
13947     void TestCase::invoke() const {
13948         test->invoke();
13949     }
13950
13951     bool TestCase::operator == ( TestCase const& other ) const {
13952         return  test.get() == other.test.get() &&
13953                 name == other.name &&
13954                 className == other.className;
13955     }
13956
13957     bool TestCase::operator < ( TestCase const& other ) const {
13958         return name < other.name;
13959     }
13960
13961     TestCaseInfo const& TestCase::getTestCaseInfo() const
13962     {
13963         return *this;
13964     }
13965
13966 } // end namespace Catch
13967 // end catch_test_case_info.cpp
13968 // start catch_test_case_registry_impl.cpp
13969
13970 #include <sstream>
13971
13972 namespace Catch {
13973
13974     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
13975
13976         std::vector<TestCase> sorted = unsortedTestCases;
13977
13978         switch( config.runOrder() ) {
13979             case RunTests::InLexicographicalOrder:
13980                 std::sort( sorted.begin(), sorted.end() );
13981                 break;
13982             case RunTests::InRandomOrder:
13983                 seedRng( config );
13984                 std::shuffle( sorted.begin(), sorted.end(), rng() );
13985                 break;
13986             case RunTests::InDeclarationOrder:
13987                 // already in declaration order
13988                 break;
13989         }
13990         return sorted;
13991     }
13992
13993     bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
13994         return !testCase.throws() || config.allowThrows();
13995     }
13996
13997     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
13998         return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
13999     }
14000
14001     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
14002         std::set<TestCase> seenFunctions;
14003         for( auto const& function : functions ) {
14004             auto prev = seenFunctions.insert( function );
14005             CATCH_ENFORCE( prev.second,
14006                     "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
14007                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
14008                     << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
14009         }
14010     }
14011
14012     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
14013         std::vector<TestCase> filtered;
14014         filtered.reserve( testCases.size() );
14015         for (auto const& testCase : testCases) {
14016             if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
14017                 (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
14018                 filtered.push_back(testCase);
14019             }
14020         }
14021         return filtered;
14022     }
14023     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
14024         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
14025     }
14026
14027     void TestRegistry::registerTest( TestCase const& testCase ) {
14028         std::string name = testCase.getTestCaseInfo().name;
14029         if( name.empty() ) {
14030             ReusableStringStream rss;
14031             rss << "Anonymous test case " << ++m_unnamedCount;
14032             return registerTest( testCase.withName( rss.str() ) );
14033         }
14034         m_functions.push_back( testCase );
14035     }
14036
14037     std::vector<TestCase> const& TestRegistry::getAllTests() const {
14038         return m_functions;
14039     }
14040     std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
14041         if( m_sortedFunctions.empty() )
14042             enforceNoDuplicateTestCases( m_functions );
14043
14044         if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
14045             m_sortedFunctions = sortTests( config, m_functions );
14046             m_currentSortOrder = config.runOrder();
14047         }
14048         return m_sortedFunctions;
14049     }
14050
14051     ///////////////////////////////////////////////////////////////////////////
14052     TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
14053
14054     void TestInvokerAsFunction::invoke() const {
14055         m_testAsFunction();
14056     }
14057
14058     std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
14059         std::string className(classOrQualifiedMethodName);
14060         if( startsWith( className, '&' ) )
14061         {
14062             std::size_t lastColons = className.rfind( "::" );
14063             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
14064             if( penultimateColons == std::string::npos )
14065                 penultimateColons = 1;
14066             className = className.substr( penultimateColons, lastColons-penultimateColons );
14067         }
14068         return className;
14069     }
14070
14071 } // end namespace Catch
14072 // end catch_test_case_registry_impl.cpp
14073 // start catch_test_case_tracker.cpp
14074
14075 #include <algorithm>
14076 #include <cassert>
14077 #include <stdexcept>
14078 #include <memory>
14079 #include <sstream>
14080
14081 #if defined(__clang__)
14082 #    pragma clang diagnostic push
14083 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
14084 #endif
14085
14086 namespace Catch {
14087 namespace TestCaseTracking {
14088
14089     NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
14090     :   name( _name ),
14091         location( _location )
14092     {}
14093
14094     ITracker::~ITracker() = default;
14095
14096     ITracker& TrackerContext::startRun() {
14097         m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
14098         m_currentTracker = nullptr;
14099         m_runState = Executing;
14100         return *m_rootTracker;
14101     }
14102
14103     void TrackerContext::endRun() {
14104         m_rootTracker.reset();
14105         m_currentTracker = nullptr;
14106         m_runState = NotStarted;
14107     }
14108
14109     void TrackerContext::startCycle() {
14110         m_currentTracker = m_rootTracker.get();
14111         m_runState = Executing;
14112     }
14113     void TrackerContext::completeCycle() {
14114         m_runState = CompletedCycle;
14115     }
14116
14117     bool TrackerContext::completedCycle() const {
14118         return m_runState == CompletedCycle;
14119     }
14120     ITracker& TrackerContext::currentTracker() {
14121         return *m_currentTracker;
14122     }
14123     void TrackerContext::setCurrentTracker( ITracker* tracker ) {
14124         m_currentTracker = tracker;
14125     }
14126
14127     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
14128     :   m_nameAndLocation( nameAndLocation ),
14129         m_ctx( ctx ),
14130         m_parent( parent )
14131     {}
14132
14133     NameAndLocation const& TrackerBase::nameAndLocation() const {
14134         return m_nameAndLocation;
14135     }
14136     bool TrackerBase::isComplete() const {
14137         return m_runState == CompletedSuccessfully || m_runState == Failed;
14138     }
14139     bool TrackerBase::isSuccessfullyCompleted() const {
14140         return m_runState == CompletedSuccessfully;
14141     }
14142     bool TrackerBase::isOpen() const {
14143         return m_runState != NotStarted && !isComplete();
14144     }
14145     bool TrackerBase::hasChildren() const {
14146         return !m_children.empty();
14147     }
14148
14149     void TrackerBase::addChild( ITrackerPtr const& child ) {
14150         m_children.push_back( child );
14151     }
14152
14153     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
14154         auto it = std::find_if( m_children.begin(), m_children.end(),
14155             [&nameAndLocation]( ITrackerPtr const& tracker ){
14156                 return
14157                     tracker->nameAndLocation().location == nameAndLocation.location &&
14158                     tracker->nameAndLocation().name == nameAndLocation.name;
14159             } );
14160         return( it != m_children.end() )
14161             ? *it
14162             : nullptr;
14163     }
14164     ITracker& TrackerBase::parent() {
14165         assert( m_parent ); // Should always be non-null except for root
14166         return *m_parent;
14167     }
14168
14169     void TrackerBase::openChild() {
14170         if( m_runState != ExecutingChildren ) {
14171             m_runState = ExecutingChildren;
14172             if( m_parent )
14173                 m_parent->openChild();
14174         }
14175     }
14176
14177     bool TrackerBase::isSectionTracker() const { return false; }
14178     bool TrackerBase::isGeneratorTracker() const { return false; }
14179
14180     void TrackerBase::open() {
14181         m_runState = Executing;
14182         moveToThis();
14183         if( m_parent )
14184             m_parent->openChild();
14185     }
14186
14187     void TrackerBase::close() {
14188
14189         // Close any still open children (e.g. generators)
14190         while( &m_ctx.currentTracker() != this )
14191             m_ctx.currentTracker().close();
14192
14193         switch( m_runState ) {
14194             case NeedsAnotherRun:
14195                 break;
14196
14197             case Executing:
14198                 m_runState = CompletedSuccessfully;
14199                 break;
14200             case ExecutingChildren:
14201                 if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
14202                     m_runState = CompletedSuccessfully;
14203                 break;
14204
14205             case NotStarted:
14206             case CompletedSuccessfully:
14207             case Failed:
14208                 CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
14209
14210             default:
14211                 CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
14212         }
14213         moveToParent();
14214         m_ctx.completeCycle();
14215     }
14216     void TrackerBase::fail() {
14217         m_runState = Failed;
14218         if( m_parent )
14219             m_parent->markAsNeedingAnotherRun();
14220         moveToParent();
14221         m_ctx.completeCycle();
14222     }
14223     void TrackerBase::markAsNeedingAnotherRun() {
14224         m_runState = NeedsAnotherRun;
14225     }
14226
14227     void TrackerBase::moveToParent() {
14228         assert( m_parent );
14229         m_ctx.setCurrentTracker( m_parent );
14230     }
14231     void TrackerBase::moveToThis() {
14232         m_ctx.setCurrentTracker( this );
14233     }
14234
14235     SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
14236     :   TrackerBase( nameAndLocation, ctx, parent ),
14237         m_trimmed_name(trim(nameAndLocation.name))
14238     {
14239         if( parent ) {
14240             while( !parent->isSectionTracker() )
14241                 parent = &parent->parent();
14242
14243             SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
14244             addNextFilters( parentSection.m_filters );
14245         }
14246     }
14247
14248     bool SectionTracker::isComplete() const {
14249         bool complete = true;
14250
14251         if ((m_filters.empty() || m_filters[0] == "")
14252             || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
14253             complete = TrackerBase::isComplete();
14254         }
14255         return complete;
14256     }
14257
14258     bool SectionTracker::isSectionTracker() const { return true; }
14259
14260     SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
14261         std::shared_ptr<SectionTracker> section;
14262
14263         ITracker& currentTracker = ctx.currentTracker();
14264         if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
14265             assert( childTracker );
14266             assert( childTracker->isSectionTracker() );
14267             section = std::static_pointer_cast<SectionTracker>( childTracker );
14268         }
14269         else {
14270             section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
14271             currentTracker.addChild( section );
14272         }
14273         if( !ctx.completedCycle() )
14274             section->tryOpen();
14275         return *section;
14276     }
14277
14278     void SectionTracker::tryOpen() {
14279         if( !isComplete() )
14280             open();
14281     }
14282
14283     void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
14284         if( !filters.empty() ) {
14285             m_filters.reserve( m_filters.size() + filters.size() + 2 );
14286             m_filters.push_back(""); // Root - should never be consulted
14287             m_filters.push_back(""); // Test Case - not a section filter
14288             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
14289         }
14290     }
14291     void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
14292         if( filters.size() > 1 )
14293             m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
14294     }
14295
14296 } // namespace TestCaseTracking
14297
14298 using TestCaseTracking::ITracker;
14299 using TestCaseTracking::TrackerContext;
14300 using TestCaseTracking::SectionTracker;
14301
14302 } // namespace Catch
14303
14304 #if defined(__clang__)
14305 #    pragma clang diagnostic pop
14306 #endif
14307 // end catch_test_case_tracker.cpp
14308 // start catch_test_registry.cpp
14309
14310 namespace Catch {
14311
14312     auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
14313         return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
14314     }
14315
14316     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
14317
14318     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
14319         CATCH_TRY {
14320             getMutableRegistryHub()
14321                     .registerTest(
14322                         makeTestCase(
14323                             invoker,
14324                             extractClassName( classOrMethod ),
14325                             nameAndTags,
14326                             lineInfo));
14327         } CATCH_CATCH_ALL {
14328             // Do not throw when constructing global objects, instead register the exception to be processed later
14329             getMutableRegistryHub().registerStartupException();
14330         }
14331     }
14332
14333     AutoReg::~AutoReg() = default;
14334 }
14335 // end catch_test_registry.cpp
14336 // start catch_test_spec.cpp
14337
14338 #include <algorithm>
14339 #include <string>
14340 #include <vector>
14341 #include <memory>
14342
14343 namespace Catch {
14344
14345     TestSpec::Pattern::Pattern( std::string const& name )
14346     : m_name( name )
14347     {}
14348
14349     TestSpec::Pattern::~Pattern() = default;
14350
14351     std::string const& TestSpec::Pattern::name() const {
14352         return m_name;
14353     }
14354
14355     TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
14356     : Pattern( filterString )
14357     , m_wildcardPattern( toLower( name ), CaseSensitive::No )
14358     {}
14359
14360     bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
14361         return m_wildcardPattern.matches( testCase.name );
14362     }
14363
14364     TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
14365     : Pattern( filterString )
14366     , m_tag( toLower( tag ) )
14367     {}
14368
14369     bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
14370         return std::find(begin(testCase.lcaseTags),
14371                          end(testCase.lcaseTags),
14372                          m_tag) != end(testCase.lcaseTags);
14373     }
14374
14375     TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
14376     : Pattern( underlyingPattern->name() )
14377     , m_underlyingPattern( underlyingPattern )
14378     {}
14379
14380     bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
14381         return !m_underlyingPattern->matches( testCase );
14382     }
14383
14384     bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
14385         return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
14386     }
14387
14388     std::string TestSpec::Filter::name() const {
14389         std::string name;
14390         for( auto const& p : m_patterns )
14391             name += p->name();
14392         return name;
14393     }
14394
14395     bool TestSpec::hasFilters() const {
14396         return !m_filters.empty();
14397     }
14398
14399     bool TestSpec::matches( TestCaseInfo const& testCase ) const {
14400         return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
14401     }
14402
14403     TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
14404     {
14405         Matches matches( m_filters.size() );
14406         std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
14407             std::vector<TestCase const*> currentMatches;
14408             for( auto const& test : testCases )
14409                 if( isThrowSafe( test, config ) && filter.matches( test ) )
14410                     currentMatches.emplace_back( &test );
14411             return FilterMatch{ filter.name(), currentMatches };
14412         } );
14413         return matches;
14414     }
14415
14416     const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
14417         return  (m_invalidArgs);
14418     }
14419
14420 }
14421 // end catch_test_spec.cpp
14422 // start catch_test_spec_parser.cpp
14423
14424 namespace Catch {
14425
14426     TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
14427
14428     TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
14429         m_mode = None;
14430         m_exclusion = false;
14431         m_arg = m_tagAliases->expandAliases( arg );
14432         m_escapeChars.clear();
14433         m_substring.reserve(m_arg.size());
14434         m_patternName.reserve(m_arg.size());
14435         m_realPatternPos = 0;
14436
14437         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
14438           //if visitChar fails
14439            if( !visitChar( m_arg[m_pos] ) ){
14440                m_testSpec.m_invalidArgs.push_back(arg);
14441                break;
14442            }
14443         endMode();
14444         return *this;
14445     }
14446     TestSpec TestSpecParser::testSpec() {
14447         addFilter();
14448         return m_testSpec;
14449     }
14450     bool TestSpecParser::visitChar( char c ) {
14451         if( (m_mode != EscapedName) && (c == '\\') ) {
14452             escape();
14453             addCharToPattern(c);
14454             return true;
14455         }else if((m_mode != EscapedName) && (c == ',') )  {
14456             return separate();
14457         }
14458
14459         switch( m_mode ) {
14460         case None:
14461             if( processNoneChar( c ) )
14462                 return true;
14463             break;
14464         case Name:
14465             processNameChar( c );
14466             break;
14467         case EscapedName:
14468             endMode();
14469             addCharToPattern(c);
14470             return true;
14471         default:
14472         case Tag:
14473         case QuotedName:
14474             if( processOtherChar( c ) )
14475                 return true;
14476             break;
14477         }
14478
14479         m_substring += c;
14480         if( !isControlChar( c ) ) {
14481             m_patternName += c;
14482             m_realPatternPos++;
14483         }
14484         return true;
14485     }
14486     // Two of the processing methods return true to signal the caller to return
14487     // without adding the given character to the current pattern strings
14488     bool TestSpecParser::processNoneChar( char c ) {
14489         switch( c ) {
14490         case ' ':
14491             return true;
14492         case '~':
14493             m_exclusion = true;
14494             return false;
14495         case '[':
14496             startNewMode( Tag );
14497             return false;
14498         case '"':
14499             startNewMode( QuotedName );
14500             return false;
14501         default:
14502             startNewMode( Name );
14503             return false;
14504         }
14505     }
14506     void TestSpecParser::processNameChar( char c ) {
14507         if( c == '[' ) {
14508             if( m_substring == "exclude:" )
14509                 m_exclusion = true;
14510             else
14511                 endMode();
14512             startNewMode( Tag );
14513         }
14514     }
14515     bool TestSpecParser::processOtherChar( char c ) {
14516         if( !isControlChar( c ) )
14517             return false;
14518         m_substring += c;
14519         endMode();
14520         return true;
14521     }
14522     void TestSpecParser::startNewMode( Mode mode ) {
14523         m_mode = mode;
14524     }
14525     void TestSpecParser::endMode() {
14526         switch( m_mode ) {
14527         case Name:
14528         case QuotedName:
14529             return addNamePattern();
14530         case Tag:
14531             return addTagPattern();
14532         case EscapedName:
14533             revertBackToLastMode();
14534             return;
14535         case None:
14536         default:
14537             return startNewMode( None );
14538         }
14539     }
14540     void TestSpecParser::escape() {
14541         saveLastMode();
14542         m_mode = EscapedName;
14543         m_escapeChars.push_back(m_realPatternPos);
14544     }
14545     bool TestSpecParser::isControlChar( char c ) const {
14546         switch( m_mode ) {
14547             default:
14548                 return false;
14549             case None:
14550                 return c == '~';
14551             case Name:
14552                 return c == '[';
14553             case EscapedName:
14554                 return true;
14555             case QuotedName:
14556                 return c == '"';
14557             case Tag:
14558                 return c == '[' || c == ']';
14559         }
14560     }
14561
14562     void TestSpecParser::addFilter() {
14563         if( !m_currentFilter.m_patterns.empty() ) {
14564             m_testSpec.m_filters.push_back( m_currentFilter );
14565             m_currentFilter = TestSpec::Filter();
14566         }
14567     }
14568
14569     void TestSpecParser::saveLastMode() {
14570       lastMode = m_mode;
14571     }
14572
14573     void TestSpecParser::revertBackToLastMode() {
14574       m_mode = lastMode;
14575     }
14576
14577     bool TestSpecParser::separate() {
14578       if( (m_mode==QuotedName) || (m_mode==Tag) ){
14579          //invalid argument, signal failure to previous scope.
14580          m_mode = None;
14581          m_pos = m_arg.size();
14582          m_substring.clear();
14583          m_patternName.clear();
14584          return false;
14585       }
14586       endMode();
14587       addFilter();
14588       return true; //success
14589     }
14590
14591     std::string TestSpecParser::preprocessPattern() {
14592         std::string token = m_patternName;
14593         for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
14594             token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
14595         m_escapeChars.clear();
14596         if (startsWith(token, "exclude:")) {
14597             m_exclusion = true;
14598             token = token.substr(8);
14599         }
14600
14601         m_patternName.clear();
14602
14603         return token;
14604     }
14605
14606     void TestSpecParser::addNamePattern() {
14607         auto token = preprocessPattern();
14608
14609         if (!token.empty()) {
14610             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
14611             if (m_exclusion)
14612                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14613             m_currentFilter.m_patterns.push_back(pattern);
14614         }
14615         m_substring.clear();
14616         m_exclusion = false;
14617         m_mode = None;
14618     }
14619
14620     void TestSpecParser::addTagPattern() {
14621         auto token = preprocessPattern();
14622
14623         if (!token.empty()) {
14624             // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
14625             // we have to create a separate hide tag and shorten the real one
14626             if (token.size() > 1 && token[0] == '.') {
14627                 token.erase(token.begin());
14628                 TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
14629                 if (m_exclusion) {
14630                     pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14631                 }
14632                 m_currentFilter.m_patterns.push_back(pattern);
14633             }
14634
14635             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
14636
14637             if (m_exclusion) {
14638                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14639             }
14640             m_currentFilter.m_patterns.push_back(pattern);
14641         }
14642         m_substring.clear();
14643         m_exclusion = false;
14644         m_mode = None;
14645     }
14646
14647     TestSpec parseTestSpec( std::string const& arg ) {
14648         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
14649     }
14650
14651 } // namespace Catch
14652 // end catch_test_spec_parser.cpp
14653 // start catch_timer.cpp
14654
14655 #include <chrono>
14656
14657 static const uint64_t nanosecondsInSecond = 1000000000;
14658
14659 namespace Catch {
14660
14661     auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
14662         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
14663     }
14664
14665     namespace {
14666         auto estimateClockResolution() -> uint64_t {
14667             uint64_t sum = 0;
14668             static const uint64_t iterations = 1000000;
14669
14670             auto startTime = getCurrentNanosecondsSinceEpoch();
14671
14672             for( std::size_t i = 0; i < iterations; ++i ) {
14673
14674                 uint64_t ticks;
14675                 uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
14676                 do {
14677                     ticks = getCurrentNanosecondsSinceEpoch();
14678                 } while( ticks == baseTicks );
14679
14680                 auto delta = ticks - baseTicks;
14681                 sum += delta;
14682
14683                 // If we have been calibrating for over 3 seconds -- the clock
14684                 // is terrible and we should move on.
14685                 // TBD: How to signal that the measured resolution is probably wrong?
14686                 if (ticks > startTime + 3 * nanosecondsInSecond) {
14687                     return sum / ( i + 1u );
14688                 }
14689             }
14690
14691             // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
14692             // - and potentially do more iterations if there's a high variance.
14693             return sum/iterations;
14694         }
14695     }
14696     auto getEstimatedClockResolution() -> uint64_t {
14697         static auto s_resolution = estimateClockResolution();
14698         return s_resolution;
14699     }
14700
14701     void Timer::start() {
14702        m_nanoseconds = getCurrentNanosecondsSinceEpoch();
14703     }
14704     auto Timer::getElapsedNanoseconds() const -> uint64_t {
14705         return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
14706     }
14707     auto Timer::getElapsedMicroseconds() const -> uint64_t {
14708         return getElapsedNanoseconds()/1000;
14709     }
14710     auto Timer::getElapsedMilliseconds() const -> unsigned int {
14711         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
14712     }
14713     auto Timer::getElapsedSeconds() const -> double {
14714         return getElapsedMicroseconds()/1000000.0;
14715     }
14716
14717 } // namespace Catch
14718 // end catch_timer.cpp
14719 // start catch_tostring.cpp
14720
14721 #if defined(__clang__)
14722 #    pragma clang diagnostic push
14723 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
14724 #    pragma clang diagnostic ignored "-Wglobal-constructors"
14725 #endif
14726
14727 // Enable specific decls locally
14728 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
14729 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
14730 #endif
14731
14732 #include <cmath>
14733 #include <iomanip>
14734
14735 namespace Catch {
14736
14737 namespace Detail {
14738
14739     const std::string unprintableString = "{?}";
14740
14741     namespace {
14742         const int hexThreshold = 255;
14743
14744         struct Endianness {
14745             enum Arch { Big, Little };
14746
14747             static Arch which() {
14748                 int one = 1;
14749                 // If the lowest byte we read is non-zero, we can assume
14750                 // that little endian format is used.
14751                 auto value = *reinterpret_cast<char*>(&one);
14752                 return value ? Little : Big;
14753             }
14754         };
14755     }
14756
14757     std::string rawMemoryToString( const void *object, std::size_t size ) {
14758         // Reverse order for little endian architectures
14759         int i = 0, end = static_cast<int>( size ), inc = 1;
14760         if( Endianness::which() == Endianness::Little ) {
14761             i = end-1;
14762             end = inc = -1;
14763         }
14764
14765         unsigned char const *bytes = static_cast<unsigned char const *>(object);
14766         ReusableStringStream rss;
14767         rss << "0x" << std::setfill('0') << std::hex;
14768         for( ; i != end; i += inc )
14769              rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
14770        return rss.str();
14771     }
14772 }
14773
14774 template<typename T>
14775 std::string fpToString( T value, int precision ) {
14776     if (Catch::isnan(value)) {
14777         return "nan";
14778     }
14779
14780     ReusableStringStream rss;
14781     rss << std::setprecision( precision )
14782         << std::fixed
14783         << value;
14784     std::string d = rss.str();
14785     std::size_t i = d.find_last_not_of( '0' );
14786     if( i != std::string::npos && i != d.size()-1 ) {
14787         if( d[i] == '.' )
14788             i++;
14789         d = d.substr( 0, i+1 );
14790     }
14791     return d;
14792 }
14793
14794 //// ======================================================= ////
14795 //
14796 //   Out-of-line defs for full specialization of StringMaker
14797 //
14798 //// ======================================================= ////
14799
14800 std::string StringMaker<std::string>::convert(const std::string& str) {
14801     if (!getCurrentContext().getConfig()->showInvisibles()) {
14802         return '"' + str + '"';
14803     }
14804
14805     std::string s("\"");
14806     for (char c : str) {
14807         switch (c) {
14808         case '\n':
14809             s.append("\\n");
14810             break;
14811         case '\t':
14812             s.append("\\t");
14813             break;
14814         default:
14815             s.push_back(c);
14816             break;
14817         }
14818     }
14819     s.append("\"");
14820     return s;
14821 }
14822
14823 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
14824 std::string StringMaker<std::string_view>::convert(std::string_view str) {
14825     return ::Catch::Detail::stringify(std::string{ str });
14826 }
14827 #endif
14828
14829 std::string StringMaker<char const*>::convert(char const* str) {
14830     if (str) {
14831         return ::Catch::Detail::stringify(std::string{ str });
14832     } else {
14833         return{ "{null string}" };
14834     }
14835 }
14836 std::string StringMaker<char*>::convert(char* str) {
14837     if (str) {
14838         return ::Catch::Detail::stringify(std::string{ str });
14839     } else {
14840         return{ "{null string}" };
14841     }
14842 }
14843
14844 #ifdef CATCH_CONFIG_WCHAR
14845 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
14846     std::string s;
14847     s.reserve(wstr.size());
14848     for (auto c : wstr) {
14849         s += (c <= 0xff) ? static_cast<char>(c) : '?';
14850     }
14851     return ::Catch::Detail::stringify(s);
14852 }
14853
14854 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
14855 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
14856     return StringMaker<std::wstring>::convert(std::wstring(str));
14857 }
14858 # endif
14859
14860 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
14861     if (str) {
14862         return ::Catch::Detail::stringify(std::wstring{ str });
14863     } else {
14864         return{ "{null string}" };
14865     }
14866 }
14867 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
14868     if (str) {
14869         return ::Catch::Detail::stringify(std::wstring{ str });
14870     } else {
14871         return{ "{null string}" };
14872     }
14873 }
14874 #endif
14875
14876 #if defined(CATCH_CONFIG_CPP17_BYTE)
14877 #include <cstddef>
14878 std::string StringMaker<std::byte>::convert(std::byte value) {
14879     return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
14880 }
14881 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
14882
14883 std::string StringMaker<int>::convert(int value) {
14884     return ::Catch::Detail::stringify(static_cast<long long>(value));
14885 }
14886 std::string StringMaker<long>::convert(long value) {
14887     return ::Catch::Detail::stringify(static_cast<long long>(value));
14888 }
14889 std::string StringMaker<long long>::convert(long long value) {
14890     ReusableStringStream rss;
14891     rss << value;
14892     if (value > Detail::hexThreshold) {
14893         rss << " (0x" << std::hex << value << ')';
14894     }
14895     return rss.str();
14896 }
14897
14898 std::string StringMaker<unsigned int>::convert(unsigned int value) {
14899     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
14900 }
14901 std::string StringMaker<unsigned long>::convert(unsigned long value) {
14902     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
14903 }
14904 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
14905     ReusableStringStream rss;
14906     rss << value;
14907     if (value > Detail::hexThreshold) {
14908         rss << " (0x" << std::hex << value << ')';
14909     }
14910     return rss.str();
14911 }
14912
14913 std::string StringMaker<bool>::convert(bool b) {
14914     return b ? "true" : "false";
14915 }
14916
14917 std::string StringMaker<signed char>::convert(signed char value) {
14918     if (value == '\r') {
14919         return "'\\r'";
14920     } else if (value == '\f') {
14921         return "'\\f'";
14922     } else if (value == '\n') {
14923         return "'\\n'";
14924     } else if (value == '\t') {
14925         return "'\\t'";
14926     } else if ('\0' <= value && value < ' ') {
14927         return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
14928     } else {
14929         char chstr[] = "' '";
14930         chstr[1] = value;
14931         return chstr;
14932     }
14933 }
14934 std::string StringMaker<char>::convert(char c) {
14935     return ::Catch::Detail::stringify(static_cast<signed char>(c));
14936 }
14937 std::string StringMaker<unsigned char>::convert(unsigned char c) {
14938     return ::Catch::Detail::stringify(static_cast<char>(c));
14939 }
14940
14941 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
14942     return "nullptr";
14943 }
14944
14945 int StringMaker<float>::precision = 5;
14946
14947 std::string StringMaker<float>::convert(float value) {
14948     return fpToString(value, precision) + 'f';
14949 }
14950
14951 int StringMaker<double>::precision = 10;
14952
14953 std::string StringMaker<double>::convert(double value) {
14954     return fpToString(value, precision);
14955 }
14956
14957 std::string ratio_string<std::atto>::symbol() { return "a"; }
14958 std::string ratio_string<std::femto>::symbol() { return "f"; }
14959 std::string ratio_string<std::pico>::symbol() { return "p"; }
14960 std::string ratio_string<std::nano>::symbol() { return "n"; }
14961 std::string ratio_string<std::micro>::symbol() { return "u"; }
14962 std::string ratio_string<std::milli>::symbol() { return "m"; }
14963
14964 } // end namespace Catch
14965
14966 #if defined(__clang__)
14967 #    pragma clang diagnostic pop
14968 #endif
14969
14970 // end catch_tostring.cpp
14971 // start catch_totals.cpp
14972
14973 namespace Catch {
14974
14975     Counts Counts::operator - ( Counts const& other ) const {
14976         Counts diff;
14977         diff.passed = passed - other.passed;
14978         diff.failed = failed - other.failed;
14979         diff.failedButOk = failedButOk - other.failedButOk;
14980         return diff;
14981     }
14982
14983     Counts& Counts::operator += ( Counts const& other ) {
14984         passed += other.passed;
14985         failed += other.failed;
14986         failedButOk += other.failedButOk;
14987         return *this;
14988     }
14989
14990     std::size_t Counts::total() const {
14991         return passed + failed + failedButOk;
14992     }
14993     bool Counts::allPassed() const {
14994         return failed == 0 && failedButOk == 0;
14995     }
14996     bool Counts::allOk() const {
14997         return failed == 0;
14998     }
14999
15000     Totals Totals::operator - ( Totals const& other ) const {
15001         Totals diff;
15002         diff.assertions = assertions - other.assertions;
15003         diff.testCases = testCases - other.testCases;
15004         return diff;
15005     }
15006
15007     Totals& Totals::operator += ( Totals const& other ) {
15008         assertions += other.assertions;
15009         testCases += other.testCases;
15010         return *this;
15011     }
15012
15013     Totals Totals::delta( Totals const& prevTotals ) const {
15014         Totals diff = *this - prevTotals;
15015         if( diff.assertions.failed > 0 )
15016             ++diff.testCases.failed;
15017         else if( diff.assertions.failedButOk > 0 )
15018             ++diff.testCases.failedButOk;
15019         else
15020             ++diff.testCases.passed;
15021         return diff;
15022     }
15023
15024 }
15025 // end catch_totals.cpp
15026 // start catch_uncaught_exceptions.cpp
15027
15028 #include <exception>
15029
15030 namespace Catch {
15031     bool uncaught_exceptions() {
15032 #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15033         return std::uncaught_exceptions() > 0;
15034 #else
15035         return std::uncaught_exception();
15036 #endif
15037   }
15038 } // end namespace Catch
15039 // end catch_uncaught_exceptions.cpp
15040 // start catch_version.cpp
15041
15042 #include <ostream>
15043
15044 namespace Catch {
15045
15046     Version::Version
15047         (   unsigned int _majorVersion,
15048             unsigned int _minorVersion,
15049             unsigned int _patchNumber,
15050             char const * const _branchName,
15051             unsigned int _buildNumber )
15052     :   majorVersion( _majorVersion ),
15053         minorVersion( _minorVersion ),
15054         patchNumber( _patchNumber ),
15055         branchName( _branchName ),
15056         buildNumber( _buildNumber )
15057     {}
15058
15059     std::ostream& operator << ( std::ostream& os, Version const& version ) {
15060         os  << version.majorVersion << '.'
15061             << version.minorVersion << '.'
15062             << version.patchNumber;
15063         // branchName is never null -> 0th char is \0 if it is empty
15064         if (version.branchName[0]) {
15065             os << '-' << version.branchName
15066                << '.' << version.buildNumber;
15067         }
15068         return os;
15069     }
15070
15071     Version const& libraryVersion() {
15072         static Version version( 2, 11, 1, "", 0 );
15073         return version;
15074     }
15075
15076 }
15077 // end catch_version.cpp
15078 // start catch_wildcard_pattern.cpp
15079
15080 namespace Catch {
15081
15082     WildcardPattern::WildcardPattern( std::string const& pattern,
15083                                       CaseSensitive::Choice caseSensitivity )
15084     :   m_caseSensitivity( caseSensitivity ),
15085         m_pattern( normaliseString( pattern ) )
15086     {
15087         if( startsWith( m_pattern, '*' ) ) {
15088             m_pattern = m_pattern.substr( 1 );
15089             m_wildcard = WildcardAtStart;
15090         }
15091         if( endsWith( m_pattern, '*' ) ) {
15092             m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
15093             m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
15094         }
15095     }
15096
15097     bool WildcardPattern::matches( std::string const& str ) const {
15098         switch( m_wildcard ) {
15099             case NoWildcard:
15100                 return m_pattern == normaliseString( str );
15101             case WildcardAtStart:
15102                 return endsWith( normaliseString( str ), m_pattern );
15103             case WildcardAtEnd:
15104                 return startsWith( normaliseString( str ), m_pattern );
15105             case WildcardAtBothEnds:
15106                 return contains( normaliseString( str ), m_pattern );
15107             default:
15108                 CATCH_INTERNAL_ERROR( "Unknown enum" );
15109         }
15110     }
15111
15112     std::string WildcardPattern::normaliseString( std::string const& str ) const {
15113         return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
15114     }
15115 }
15116 // end catch_wildcard_pattern.cpp
15117 // start catch_xmlwriter.cpp
15118
15119 #include <iomanip>
15120 #include <type_traits>
15121
15122 using uchar = unsigned char;
15123
15124 namespace Catch {
15125
15126 namespace {
15127
15128     size_t trailingBytes(unsigned char c) {
15129         if ((c & 0xE0) == 0xC0) {
15130             return 2;
15131         }
15132         if ((c & 0xF0) == 0xE0) {
15133             return 3;
15134         }
15135         if ((c & 0xF8) == 0xF0) {
15136             return 4;
15137         }
15138         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15139     }
15140
15141     uint32_t headerValue(unsigned char c) {
15142         if ((c & 0xE0) == 0xC0) {
15143             return c & 0x1F;
15144         }
15145         if ((c & 0xF0) == 0xE0) {
15146             return c & 0x0F;
15147         }
15148         if ((c & 0xF8) == 0xF0) {
15149             return c & 0x07;
15150         }
15151         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15152     }
15153
15154     void hexEscapeChar(std::ostream& os, unsigned char c) {
15155         std::ios_base::fmtflags f(os.flags());
15156         os << "\\x"
15157             << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
15158             << static_cast<int>(c);
15159         os.flags(f);
15160     }
15161
15162     bool shouldNewline(XmlFormatting fmt) {
15163         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
15164     }
15165
15166     bool shouldIndent(XmlFormatting fmt) {
15167         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
15168     }
15169
15170 } // anonymous namespace
15171
15172     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
15173         return static_cast<XmlFormatting>(
15174             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
15175             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
15176         );
15177     }
15178
15179     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
15180         return static_cast<XmlFormatting>(
15181             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
15182             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
15183         );
15184     }
15185
15186     XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
15187     :   m_str( str ),
15188         m_forWhat( forWhat )
15189     {}
15190
15191     void XmlEncode::encodeTo( std::ostream& os ) const {
15192         // Apostrophe escaping not necessary if we always use " to write attributes
15193         // (see: http://www.w3.org/TR/xml/#syntax)
15194
15195         for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
15196             uchar c = m_str[idx];
15197             switch (c) {
15198             case '<':   os << "&lt;"; break;
15199             case '&':   os << "&amp;"; break;
15200
15201             case '>':
15202                 // See: http://www.w3.org/TR/xml/#syntax
15203                 if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
15204                     os << "&gt;";
15205                 else
15206                     os << c;
15207                 break;
15208
15209             case '\"':
15210                 if (m_forWhat == ForAttributes)
15211                     os << "&quot;";
15212                 else
15213                     os << c;
15214                 break;
15215
15216             default:
15217                 // Check for control characters and invalid utf-8
15218
15219                 // Escape control characters in standard ascii
15220                 // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
15221                 if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
15222                     hexEscapeChar(os, c);
15223                     break;
15224                 }
15225
15226                 // Plain ASCII: Write it to stream
15227                 if (c < 0x7F) {
15228                     os << c;
15229                     break;
15230                 }
15231
15232                 // UTF-8 territory
15233                 // Check if the encoding is valid and if it is not, hex escape bytes.
15234                 // Important: We do not check the exact decoded values for validity, only the encoding format
15235                 // First check that this bytes is a valid lead byte:
15236                 // This means that it is not encoded as 1111 1XXX
15237                 // Or as 10XX XXXX
15238                 if (c <  0xC0 ||
15239                     c >= 0xF8) {
15240                     hexEscapeChar(os, c);
15241                     break;
15242                 }
15243
15244                 auto encBytes = trailingBytes(c);
15245                 // Are there enough bytes left to avoid accessing out-of-bounds memory?
15246                 if (idx + encBytes - 1 >= m_str.size()) {
15247                     hexEscapeChar(os, c);
15248                     break;
15249                 }
15250                 // The header is valid, check data
15251                 // The next encBytes bytes must together be a valid utf-8
15252                 // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
15253                 bool valid = true;
15254                 uint32_t value = headerValue(c);
15255                 for (std::size_t n = 1; n < encBytes; ++n) {
15256                     uchar nc = m_str[idx + n];
15257                     valid &= ((nc & 0xC0) == 0x80);
15258                     value = (value << 6) | (nc & 0x3F);
15259                 }
15260
15261                 if (
15262                     // Wrong bit pattern of following bytes
15263                     (!valid) ||
15264                     // Overlong encodings
15265                     (value < 0x80) ||
15266                     (0x80 <= value && value < 0x800   && encBytes > 2) ||
15267                     (0x800 < value && value < 0x10000 && encBytes > 3) ||
15268                     // Encoded value out of range
15269                     (value >= 0x110000)
15270                     ) {
15271                     hexEscapeChar(os, c);
15272                     break;
15273                 }
15274
15275                 // If we got here, this is in fact a valid(ish) utf-8 sequence
15276                 for (std::size_t n = 0; n < encBytes; ++n) {
15277                     os << m_str[idx + n];
15278                 }
15279                 idx += encBytes - 1;
15280                 break;
15281             }
15282         }
15283     }
15284
15285     std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
15286         xmlEncode.encodeTo( os );
15287         return os;
15288     }
15289
15290     XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
15291     :   m_writer( writer ),
15292         m_fmt(fmt)
15293     {}
15294
15295     XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
15296     :   m_writer( other.m_writer ),
15297         m_fmt(other.m_fmt)
15298     {
15299         other.m_writer = nullptr;
15300         other.m_fmt = XmlFormatting::None;
15301     }
15302     XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
15303         if ( m_writer ) {
15304             m_writer->endElement();
15305         }
15306         m_writer = other.m_writer;
15307         other.m_writer = nullptr;
15308         m_fmt = other.m_fmt;
15309         other.m_fmt = XmlFormatting::None;
15310         return *this;
15311     }
15312
15313     XmlWriter::ScopedElement::~ScopedElement() {
15314         if (m_writer) {
15315             m_writer->endElement(m_fmt);
15316         }
15317     }
15318
15319     XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
15320         m_writer->writeText( text, fmt );
15321         return *this;
15322     }
15323
15324     XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
15325     {
15326         writeDeclaration();
15327     }
15328
15329     XmlWriter::~XmlWriter() {
15330         while (!m_tags.empty()) {
15331             endElement();
15332         }
15333         newlineIfNecessary();
15334     }
15335
15336     XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
15337         ensureTagClosed();
15338         newlineIfNecessary();
15339         if (shouldIndent(fmt)) {
15340             m_os << m_indent;
15341             m_indent += "  ";
15342         }
15343         m_os << '<' << name;
15344         m_tags.push_back( name );
15345         m_tagIsOpen = true;
15346         applyFormatting(fmt);
15347         return *this;
15348     }
15349
15350     XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
15351         ScopedElement scoped( this, fmt );
15352         startElement( name, fmt );
15353         return scoped;
15354     }
15355
15356     XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
15357         m_indent = m_indent.substr(0, m_indent.size() - 2);
15358
15359         if( m_tagIsOpen ) {
15360             m_os << "/>";
15361             m_tagIsOpen = false;
15362         } else {
15363             newlineIfNecessary();
15364             if (shouldIndent(fmt)) {
15365                 m_os << m_indent;
15366             }
15367             m_os << "</" << m_tags.back() << ">";
15368         }
15369         m_os << std::flush;
15370         applyFormatting(fmt);
15371         m_tags.pop_back();
15372         return *this;
15373     }
15374
15375     XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
15376         if( !name.empty() && !attribute.empty() )
15377             m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
15378         return *this;
15379     }
15380
15381     XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
15382         m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
15383         return *this;
15384     }
15385
15386     XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
15387         if( !text.empty() ){
15388             bool tagWasOpen = m_tagIsOpen;
15389             ensureTagClosed();
15390             if (tagWasOpen && shouldIndent(fmt)) {
15391                 m_os << m_indent;
15392             }
15393             m_os << XmlEncode( text );
15394             applyFormatting(fmt);
15395         }
15396         return *this;
15397     }
15398
15399     XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
15400         ensureTagClosed();
15401         if (shouldIndent(fmt)) {
15402             m_os << m_indent;
15403         }
15404         m_os << "<!--" << text << "-->";
15405         applyFormatting(fmt);
15406         return *this;
15407     }
15408
15409     void XmlWriter::writeStylesheetRef( std::string const& url ) {
15410         m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
15411     }
15412
15413     XmlWriter& XmlWriter::writeBlankLine() {
15414         ensureTagClosed();
15415         m_os << '\n';
15416         return *this;
15417     }
15418
15419     void XmlWriter::ensureTagClosed() {
15420         if( m_tagIsOpen ) {
15421             m_os << '>' << std::flush;
15422             newlineIfNecessary();
15423             m_tagIsOpen = false;
15424         }
15425     }
15426
15427     void XmlWriter::applyFormatting(XmlFormatting fmt) {
15428         m_needsNewline = shouldNewline(fmt);
15429     }
15430
15431     void XmlWriter::writeDeclaration() {
15432         m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
15433     }
15434
15435     void XmlWriter::newlineIfNecessary() {
15436         if( m_needsNewline ) {
15437             m_os << std::endl;
15438             m_needsNewline = false;
15439         }
15440     }
15441 }
15442 // end catch_xmlwriter.cpp
15443 // start catch_reporter_bases.cpp
15444
15445 #include <cstring>
15446 #include <cfloat>
15447 #include <cstdio>
15448 #include <cassert>
15449 #include <memory>
15450
15451 namespace Catch {
15452     void prepareExpandedExpression(AssertionResult& result) {
15453         result.getExpandedExpression();
15454     }
15455
15456     // Because formatting using c++ streams is stateful, drop down to C is required
15457     // Alternatively we could use stringstream, but its performance is... not good.
15458     std::string getFormattedDuration( double duration ) {
15459         // Max exponent + 1 is required to represent the whole part
15460         // + 1 for decimal point
15461         // + 3 for the 3 decimal places
15462         // + 1 for null terminator
15463         const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
15464         char buffer[maxDoubleSize];
15465
15466         // Save previous errno, to prevent sprintf from overwriting it
15467         ErrnoGuard guard;
15468 #ifdef _MSC_VER
15469         sprintf_s(buffer, "%.3f", duration);
15470 #else
15471         std::sprintf(buffer, "%.3f", duration);
15472 #endif
15473         return std::string(buffer);
15474     }
15475
15476     std::string serializeFilters( std::vector<std::string> const& container ) {
15477         ReusableStringStream oss;
15478         bool first = true;
15479         for (auto&& filter : container)
15480         {
15481             if (!first)
15482                 oss << ' ';
15483             else
15484                 first = false;
15485
15486             oss << filter;
15487         }
15488         return oss.str();
15489     }
15490
15491     TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
15492         :StreamingReporterBase(_config) {}
15493
15494     std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
15495         return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
15496     }
15497
15498     void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
15499
15500     bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
15501         return false;
15502     }
15503
15504 } // end namespace Catch
15505 // end catch_reporter_bases.cpp
15506 // start catch_reporter_compact.cpp
15507
15508 namespace {
15509
15510 #ifdef CATCH_PLATFORM_MAC
15511     const char* failedString() { return "FAILED"; }
15512     const char* passedString() { return "PASSED"; }
15513 #else
15514     const char* failedString() { return "failed"; }
15515     const char* passedString() { return "passed"; }
15516 #endif
15517
15518     // Colour::LightGrey
15519     Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
15520
15521     std::string bothOrAll( std::size_t count ) {
15522         return count == 1 ? std::string() :
15523                count == 2 ? "both " : "all " ;
15524     }
15525
15526 } // anon namespace
15527
15528 namespace Catch {
15529 namespace {
15530 // Colour, message variants:
15531 // - white: No tests ran.
15532 // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
15533 // - white: Passed [both/all] N test cases (no assertions).
15534 // -   red: Failed N tests cases, failed M assertions.
15535 // - green: Passed [both/all] N tests cases with M assertions.
15536 void printTotals(std::ostream& out, const Totals& totals) {
15537     if (totals.testCases.total() == 0) {
15538         out << "No tests ran.";
15539     } else if (totals.testCases.failed == totals.testCases.total()) {
15540         Colour colour(Colour::ResultError);
15541         const std::string qualify_assertions_failed =
15542             totals.assertions.failed == totals.assertions.total() ?
15543             bothOrAll(totals.assertions.failed) : std::string();
15544         out <<
15545             "Failed " << bothOrAll(totals.testCases.failed)
15546             << pluralise(totals.testCases.failed, "test case") << ", "
15547             "failed " << qualify_assertions_failed <<
15548             pluralise(totals.assertions.failed, "assertion") << '.';
15549     } else if (totals.assertions.total() == 0) {
15550         out <<
15551             "Passed " << bothOrAll(totals.testCases.total())
15552             << pluralise(totals.testCases.total(), "test case")
15553             << " (no assertions).";
15554     } else if (totals.assertions.failed) {
15555         Colour colour(Colour::ResultError);
15556         out <<
15557             "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
15558             "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
15559     } else {
15560         Colour colour(Colour::ResultSuccess);
15561         out <<
15562             "Passed " << bothOrAll(totals.testCases.passed)
15563             << pluralise(totals.testCases.passed, "test case") <<
15564             " with " << pluralise(totals.assertions.passed, "assertion") << '.';
15565     }
15566 }
15567
15568 // Implementation of CompactReporter formatting
15569 class AssertionPrinter {
15570 public:
15571     AssertionPrinter& operator= (AssertionPrinter const&) = delete;
15572     AssertionPrinter(AssertionPrinter const&) = delete;
15573     AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15574         : stream(_stream)
15575         , result(_stats.assertionResult)
15576         , messages(_stats.infoMessages)
15577         , itMessage(_stats.infoMessages.begin())
15578         , printInfoMessages(_printInfoMessages) {}
15579
15580     void print() {
15581         printSourceInfo();
15582
15583         itMessage = messages.begin();
15584
15585         switch (result.getResultType()) {
15586         case ResultWas::Ok:
15587             printResultType(Colour::ResultSuccess, passedString());
15588             printOriginalExpression();
15589             printReconstructedExpression();
15590             if (!result.hasExpression())
15591                 printRemainingMessages(Colour::None);
15592             else
15593                 printRemainingMessages();
15594             break;
15595         case ResultWas::ExpressionFailed:
15596             if (result.isOk())
15597                 printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
15598             else
15599                 printResultType(Colour::Error, failedString());
15600             printOriginalExpression();
15601             printReconstructedExpression();
15602             printRemainingMessages();
15603             break;
15604         case ResultWas::ThrewException:
15605             printResultType(Colour::Error, failedString());
15606             printIssue("unexpected exception with message:");
15607             printMessage();
15608             printExpressionWas();
15609             printRemainingMessages();
15610             break;
15611         case ResultWas::FatalErrorCondition:
15612             printResultType(Colour::Error, failedString());
15613             printIssue("fatal error condition with message:");
15614             printMessage();
15615             printExpressionWas();
15616             printRemainingMessages();
15617             break;
15618         case ResultWas::DidntThrowException:
15619             printResultType(Colour::Error, failedString());
15620             printIssue("expected exception, got none");
15621             printExpressionWas();
15622             printRemainingMessages();
15623             break;
15624         case ResultWas::Info:
15625             printResultType(Colour::None, "info");
15626             printMessage();
15627             printRemainingMessages();
15628             break;
15629         case ResultWas::Warning:
15630             printResultType(Colour::None, "warning");
15631             printMessage();
15632             printRemainingMessages();
15633             break;
15634         case ResultWas::ExplicitFailure:
15635             printResultType(Colour::Error, failedString());
15636             printIssue("explicitly");
15637             printRemainingMessages(Colour::None);
15638             break;
15639             // These cases are here to prevent compiler warnings
15640         case ResultWas::Unknown:
15641         case ResultWas::FailureBit:
15642         case ResultWas::Exception:
15643             printResultType(Colour::Error, "** internal error **");
15644             break;
15645         }
15646     }
15647
15648 private:
15649     void printSourceInfo() const {
15650         Colour colourGuard(Colour::FileName);
15651         stream << result.getSourceInfo() << ':';
15652     }
15653
15654     void printResultType(Colour::Code colour, std::string const& passOrFail) const {
15655         if (!passOrFail.empty()) {
15656             {
15657                 Colour colourGuard(colour);
15658                 stream << ' ' << passOrFail;
15659             }
15660             stream << ':';
15661         }
15662     }
15663
15664     void printIssue(std::string const& issue) const {
15665         stream << ' ' << issue;
15666     }
15667
15668     void printExpressionWas() {
15669         if (result.hasExpression()) {
15670             stream << ';';
15671             {
15672                 Colour colour(dimColour());
15673                 stream << " expression was:";
15674             }
15675             printOriginalExpression();
15676         }
15677     }
15678
15679     void printOriginalExpression() const {
15680         if (result.hasExpression()) {
15681             stream << ' ' << result.getExpression();
15682         }
15683     }
15684
15685     void printReconstructedExpression() const {
15686         if (result.hasExpandedExpression()) {
15687             {
15688                 Colour colour(dimColour());
15689                 stream << " for: ";
15690             }
15691             stream << result.getExpandedExpression();
15692         }
15693     }
15694
15695     void printMessage() {
15696         if (itMessage != messages.end()) {
15697             stream << " '" << itMessage->message << '\'';
15698             ++itMessage;
15699         }
15700     }
15701
15702     void printRemainingMessages(Colour::Code colour = dimColour()) {
15703         if (itMessage == messages.end())
15704             return;
15705
15706         const auto itEnd = messages.cend();
15707         const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
15708
15709         {
15710             Colour colourGuard(colour);
15711             stream << " with " << pluralise(N, "message") << ':';
15712         }
15713
15714         while (itMessage != itEnd) {
15715             // If this assertion is a warning ignore any INFO messages
15716             if (printInfoMessages || itMessage->type != ResultWas::Info) {
15717                 printMessage();
15718                 if (itMessage != itEnd) {
15719                     Colour colourGuard(dimColour());
15720                     stream << " and";
15721                 }
15722                 continue;
15723             }
15724             ++itMessage;
15725         }
15726     }
15727
15728 private:
15729     std::ostream& stream;
15730     AssertionResult const& result;
15731     std::vector<MessageInfo> messages;
15732     std::vector<MessageInfo>::const_iterator itMessage;
15733     bool printInfoMessages;
15734 };
15735
15736 } // anon namespace
15737
15738         std::string CompactReporter::getDescription() {
15739             return "Reports test results on a single line, suitable for IDEs";
15740         }
15741
15742         ReporterPreferences CompactReporter::getPreferences() const {
15743             return m_reporterPrefs;
15744         }
15745
15746         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
15747             stream << "No test cases matched '" << spec << '\'' << std::endl;
15748         }
15749
15750         void CompactReporter::assertionStarting( AssertionInfo const& ) {}
15751
15752         bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
15753             AssertionResult const& result = _assertionStats.assertionResult;
15754
15755             bool printInfoMessages = true;
15756
15757             // Drop out if result was successful and we're not printing those
15758             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
15759                 if( result.getResultType() != ResultWas::Warning )
15760                     return false;
15761                 printInfoMessages = false;
15762             }
15763
15764             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
15765             printer.print();
15766
15767             stream << std::endl;
15768             return true;
15769         }
15770
15771         void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
15772             if (m_config->showDurations() == ShowDurations::Always) {
15773                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
15774             }
15775         }
15776
15777         void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
15778             printTotals( stream, _testRunStats.totals );
15779             stream << '\n' << std::endl;
15780             StreamingReporterBase::testRunEnded( _testRunStats );
15781         }
15782
15783         CompactReporter::~CompactReporter() {}
15784
15785     CATCH_REGISTER_REPORTER( "compact", CompactReporter )
15786
15787 } // end namespace Catch
15788 // end catch_reporter_compact.cpp
15789 // start catch_reporter_console.cpp
15790
15791 #include <cfloat>
15792 #include <cstdio>
15793
15794 #if defined(_MSC_VER)
15795 #pragma warning(push)
15796 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
15797  // Note that 4062 (not all labels are handled and default is missing) is enabled
15798 #endif
15799
15800 #if defined(__clang__)
15801 #  pragma clang diagnostic push
15802 // For simplicity, benchmarking-only helpers are always enabled
15803 #  pragma clang diagnostic ignored "-Wunused-function"
15804 #endif
15805
15806 namespace Catch {
15807
15808 namespace {
15809
15810 // Formatter impl for ConsoleReporter
15811 class ConsoleAssertionPrinter {
15812 public:
15813     ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
15814     ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
15815     ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15816         : stream(_stream),
15817         stats(_stats),
15818         result(_stats.assertionResult),
15819         colour(Colour::None),
15820         message(result.getMessage()),
15821         messages(_stats.infoMessages),
15822         printInfoMessages(_printInfoMessages) {
15823         switch (result.getResultType()) {
15824         case ResultWas::Ok:
15825             colour = Colour::Success;
15826             passOrFail = "PASSED";
15827             //if( result.hasMessage() )
15828             if (_stats.infoMessages.size() == 1)
15829                 messageLabel = "with message";
15830             if (_stats.infoMessages.size() > 1)
15831                 messageLabel = "with messages";
15832             break;
15833         case ResultWas::ExpressionFailed:
15834             if (result.isOk()) {
15835                 colour = Colour::Success;
15836                 passOrFail = "FAILED - but was ok";
15837             } else {
15838                 colour = Colour::Error;
15839                 passOrFail = "FAILED";
15840             }
15841             if (_stats.infoMessages.size() == 1)
15842                 messageLabel = "with message";
15843             if (_stats.infoMessages.size() > 1)
15844                 messageLabel = "with messages";
15845             break;
15846         case ResultWas::ThrewException:
15847             colour = Colour::Error;
15848             passOrFail = "FAILED";
15849             messageLabel = "due to unexpected exception with ";
15850             if (_stats.infoMessages.size() == 1)
15851                 messageLabel += "message";
15852             if (_stats.infoMessages.size() > 1)
15853                 messageLabel += "messages";
15854             break;
15855         case ResultWas::FatalErrorCondition:
15856             colour = Colour::Error;
15857             passOrFail = "FAILED";
15858             messageLabel = "due to a fatal error condition";
15859             break;
15860         case ResultWas::DidntThrowException:
15861             colour = Colour::Error;
15862             passOrFail = "FAILED";
15863             messageLabel = "because no exception was thrown where one was expected";
15864             break;
15865         case ResultWas::Info:
15866             messageLabel = "info";
15867             break;
15868         case ResultWas::Warning:
15869             messageLabel = "warning";
15870             break;
15871         case ResultWas::ExplicitFailure:
15872             passOrFail = "FAILED";
15873             colour = Colour::Error;
15874             if (_stats.infoMessages.size() == 1)
15875                 messageLabel = "explicitly with message";
15876             if (_stats.infoMessages.size() > 1)
15877                 messageLabel = "explicitly with messages";
15878             break;
15879             // These cases are here to prevent compiler warnings
15880         case ResultWas::Unknown:
15881         case ResultWas::FailureBit:
15882         case ResultWas::Exception:
15883             passOrFail = "** internal error **";
15884             colour = Colour::Error;
15885             break;
15886         }
15887     }
15888
15889     void print() const {
15890         printSourceInfo();
15891         if (stats.totals.assertions.total() > 0) {
15892             printResultType();
15893             printOriginalExpression();
15894             printReconstructedExpression();
15895         } else {
15896             stream << '\n';
15897         }
15898         printMessage();
15899     }
15900
15901 private:
15902     void printResultType() const {
15903         if (!passOrFail.empty()) {
15904             Colour colourGuard(colour);
15905             stream << passOrFail << ":\n";
15906         }
15907     }
15908     void printOriginalExpression() const {
15909         if (result.hasExpression()) {
15910             Colour colourGuard(Colour::OriginalExpression);
15911             stream << "  ";
15912             stream << result.getExpressionInMacro();
15913             stream << '\n';
15914         }
15915     }
15916     void printReconstructedExpression() const {
15917         if (result.hasExpandedExpression()) {
15918             stream << "with expansion:\n";
15919             Colour colourGuard(Colour::ReconstructedExpression);
15920             stream << Column(result.getExpandedExpression()).indent(2) << '\n';
15921         }
15922     }
15923     void printMessage() const {
15924         if (!messageLabel.empty())
15925             stream << messageLabel << ':' << '\n';
15926         for (auto const& msg : messages) {
15927             // If this assertion is a warning ignore any INFO messages
15928             if (printInfoMessages || msg.type != ResultWas::Info)
15929                 stream << Column(msg.message).indent(2) << '\n';
15930         }
15931     }
15932     void printSourceInfo() const {
15933         Colour colourGuard(Colour::FileName);
15934         stream << result.getSourceInfo() << ": ";
15935     }
15936
15937     std::ostream& stream;
15938     AssertionStats const& stats;
15939     AssertionResult const& result;
15940     Colour::Code colour;
15941     std::string passOrFail;
15942     std::string messageLabel;
15943     std::string message;
15944     std::vector<MessageInfo> messages;
15945     bool printInfoMessages;
15946 };
15947
15948 std::size_t makeRatio(std::size_t number, std::size_t total) {
15949     std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
15950     return (ratio == 0 && number > 0) ? 1 : ratio;
15951 }
15952
15953 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
15954     if (i > j && i > k)
15955         return i;
15956     else if (j > k)
15957         return j;
15958     else
15959         return k;
15960 }
15961
15962 struct ColumnInfo {
15963     enum Justification { Left, Right };
15964     std::string name;
15965     int width;
15966     Justification justification;
15967 };
15968 struct ColumnBreak {};
15969 struct RowBreak {};
15970
15971 class Duration {
15972     enum class Unit {
15973         Auto,
15974         Nanoseconds,
15975         Microseconds,
15976         Milliseconds,
15977         Seconds,
15978         Minutes
15979     };
15980     static const uint64_t s_nanosecondsInAMicrosecond = 1000;
15981     static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
15982     static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
15983     static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
15984
15985     uint64_t m_inNanoseconds;
15986     Unit m_units;
15987
15988 public:
15989         explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
15990         : Duration(static_cast<uint64_t>(inNanoseconds), units) {
15991     }
15992
15993     explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
15994         : m_inNanoseconds(inNanoseconds),
15995         m_units(units) {
15996         if (m_units == Unit::Auto) {
15997             if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
15998                 m_units = Unit::Nanoseconds;
15999             else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
16000                 m_units = Unit::Microseconds;
16001             else if (m_inNanoseconds < s_nanosecondsInASecond)
16002                 m_units = Unit::Milliseconds;
16003             else if (m_inNanoseconds < s_nanosecondsInAMinute)
16004                 m_units = Unit::Seconds;
16005             else
16006                 m_units = Unit::Minutes;
16007         }
16008
16009     }
16010
16011     auto value() const -> double {
16012         switch (m_units) {
16013         case Unit::Microseconds:
16014             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
16015         case Unit::Milliseconds:
16016             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
16017         case Unit::Seconds:
16018             return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
16019         case Unit::Minutes:
16020             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
16021         default:
16022             return static_cast<double>(m_inNanoseconds);
16023         }
16024     }
16025     auto unitsAsString() const -> std::string {
16026         switch (m_units) {
16027         case Unit::Nanoseconds:
16028             return "ns";
16029         case Unit::Microseconds:
16030             return "us";
16031         case Unit::Milliseconds:
16032             return "ms";
16033         case Unit::Seconds:
16034             return "s";
16035         case Unit::Minutes:
16036             return "m";
16037         default:
16038             return "** internal error **";
16039         }
16040
16041     }
16042     friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
16043         return os << duration.value() << ' ' << duration.unitsAsString();
16044     }
16045 };
16046 } // end anon namespace
16047
16048 class TablePrinter {
16049     std::ostream& m_os;
16050     std::vector<ColumnInfo> m_columnInfos;
16051     std::ostringstream m_oss;
16052     int m_currentColumn = -1;
16053     bool m_isOpen = false;
16054
16055 public:
16056     TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
16057     :   m_os( os ),
16058         m_columnInfos( std::move( columnInfos ) ) {}
16059
16060     auto columnInfos() const -> std::vector<ColumnInfo> const& {
16061         return m_columnInfos;
16062     }
16063
16064     void open() {
16065         if (!m_isOpen) {
16066             m_isOpen = true;
16067             *this << RowBreak();
16068
16069                         Columns headerCols;
16070                         Spacer spacer(2);
16071                         for (auto const& info : m_columnInfos) {
16072                                 headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
16073                                 headerCols += spacer;
16074                         }
16075                         m_os << headerCols << '\n';
16076
16077             m_os << Catch::getLineOfChars<'-'>() << '\n';
16078         }
16079     }
16080     void close() {
16081         if (m_isOpen) {
16082             *this << RowBreak();
16083             m_os << std::endl;
16084             m_isOpen = false;
16085         }
16086     }
16087
16088     template<typename T>
16089     friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
16090         tp.m_oss << value;
16091         return tp;
16092     }
16093
16094     friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
16095         auto colStr = tp.m_oss.str();
16096         const auto strSize = colStr.size();
16097         tp.m_oss.str("");
16098         tp.open();
16099         if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
16100             tp.m_currentColumn = -1;
16101             tp.m_os << '\n';
16102         }
16103         tp.m_currentColumn++;
16104
16105         auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
16106         auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
16107             ? std::string(colInfo.width - (strSize + 1), ' ')
16108             : std::string();
16109         if (colInfo.justification == ColumnInfo::Left)
16110             tp.m_os << colStr << padding << ' ';
16111         else
16112             tp.m_os << padding << colStr << ' ';
16113         return tp;
16114     }
16115
16116     friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
16117         if (tp.m_currentColumn > 0) {
16118             tp.m_os << '\n';
16119             tp.m_currentColumn = -1;
16120         }
16121         return tp;
16122     }
16123 };
16124
16125 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
16126     : StreamingReporterBase(config),
16127     m_tablePrinter(new TablePrinter(config.stream(),
16128         [&config]() -> std::vector<ColumnInfo> {
16129         if (config.fullConfig()->benchmarkNoAnalysis())
16130         {
16131             return{
16132                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16133                 { "     samples", 14, ColumnInfo::Right },
16134                 { "  iterations", 14, ColumnInfo::Right },
16135                 { "        mean", 14, ColumnInfo::Right }
16136             };
16137         }
16138         else
16139         {
16140             return{
16141                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
16142                 { "samples      mean       std dev", 14, ColumnInfo::Right },
16143                 { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
16144                 { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
16145             };
16146         }
16147     }())) {}
16148 ConsoleReporter::~ConsoleReporter() = default;
16149
16150 std::string ConsoleReporter::getDescription() {
16151     return "Reports test results as plain lines of text";
16152 }
16153
16154 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
16155     stream << "No test cases matched '" << spec << '\'' << std::endl;
16156 }
16157
16158 void ConsoleReporter::reportInvalidArguments(std::string const&arg){
16159     stream << "Invalid Filter: " << arg << std::endl;
16160 }
16161
16162 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
16163
16164 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
16165     AssertionResult const& result = _assertionStats.assertionResult;
16166
16167     bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16168
16169     // Drop out if result was successful but we're not printing them.
16170     if (!includeResults && result.getResultType() != ResultWas::Warning)
16171         return false;
16172
16173     lazyPrint();
16174
16175     ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
16176     printer.print();
16177     stream << std::endl;
16178     return true;
16179 }
16180
16181 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
16182     m_tablePrinter->close();
16183     m_headerPrinted = false;
16184     StreamingReporterBase::sectionStarting(_sectionInfo);
16185 }
16186 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
16187     m_tablePrinter->close();
16188     if (_sectionStats.missingAssertions) {
16189         lazyPrint();
16190         Colour colour(Colour::ResultError);
16191         if (m_sectionStack.size() > 1)
16192             stream << "\nNo assertions in section";
16193         else
16194             stream << "\nNo assertions in test case";
16195         stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
16196     }
16197     if (m_config->showDurations() == ShowDurations::Always) {
16198         stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16199     }
16200     if (m_headerPrinted) {
16201         m_headerPrinted = false;
16202     }
16203     StreamingReporterBase::sectionEnded(_sectionStats);
16204 }
16205
16206 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16207 void ConsoleReporter::benchmarkPreparing(std::string const& name) {
16208         lazyPrintWithoutClosingBenchmarkTable();
16209
16210         auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
16211
16212         bool firstLine = true;
16213         for (auto line : nameCol) {
16214                 if (!firstLine)
16215                         (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
16216                 else
16217                         firstLine = false;
16218
16219                 (*m_tablePrinter) << line << ColumnBreak();
16220         }
16221 }
16222
16223 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
16224     (*m_tablePrinter) << info.samples << ColumnBreak()
16225         << info.iterations << ColumnBreak();
16226     if (!m_config->benchmarkNoAnalysis())
16227         (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
16228 }
16229 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
16230     if (m_config->benchmarkNoAnalysis())
16231     {
16232         (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
16233     }
16234     else
16235     {
16236         (*m_tablePrinter) << ColumnBreak()
16237             << Duration(stats.mean.point.count()) << ColumnBreak()
16238             << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
16239             << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
16240             << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
16241             << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
16242             << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
16243     }
16244 }
16245
16246 void ConsoleReporter::benchmarkFailed(std::string const& error) {
16247         Colour colour(Colour::Red);
16248     (*m_tablePrinter)
16249         << "Benchmark failed (" << error << ')'
16250         << ColumnBreak() << RowBreak();
16251 }
16252 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16253
16254 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
16255     m_tablePrinter->close();
16256     StreamingReporterBase::testCaseEnded(_testCaseStats);
16257     m_headerPrinted = false;
16258 }
16259 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
16260     if (currentGroupInfo.used) {
16261         printSummaryDivider();
16262         stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
16263         printTotals(_testGroupStats.totals);
16264         stream << '\n' << std::endl;
16265     }
16266     StreamingReporterBase::testGroupEnded(_testGroupStats);
16267 }
16268 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
16269     printTotalsDivider(_testRunStats.totals);
16270     printTotals(_testRunStats.totals);
16271     stream << std::endl;
16272     StreamingReporterBase::testRunEnded(_testRunStats);
16273 }
16274 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
16275     StreamingReporterBase::testRunStarting(_testInfo);
16276     printTestFilters();
16277 }
16278
16279 void ConsoleReporter::lazyPrint() {
16280
16281     m_tablePrinter->close();
16282     lazyPrintWithoutClosingBenchmarkTable();
16283 }
16284
16285 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
16286
16287     if (!currentTestRunInfo.used)
16288         lazyPrintRunInfo();
16289     if (!currentGroupInfo.used)
16290         lazyPrintGroupInfo();
16291
16292     if (!m_headerPrinted) {
16293         printTestCaseAndSectionHeader();
16294         m_headerPrinted = true;
16295     }
16296 }
16297 void ConsoleReporter::lazyPrintRunInfo() {
16298     stream << '\n' << getLineOfChars<'~'>() << '\n';
16299     Colour colour(Colour::SecondaryText);
16300     stream << currentTestRunInfo->name
16301         << " is a Catch v" << libraryVersion() << " host application.\n"
16302         << "Run with -? for options\n\n";
16303
16304     if (m_config->rngSeed() != 0)
16305         stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
16306
16307     currentTestRunInfo.used = true;
16308 }
16309 void ConsoleReporter::lazyPrintGroupInfo() {
16310     if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
16311         printClosedHeader("Group: " + currentGroupInfo->name);
16312         currentGroupInfo.used = true;
16313     }
16314 }
16315 void ConsoleReporter::printTestCaseAndSectionHeader() {
16316     assert(!m_sectionStack.empty());
16317     printOpenHeader(currentTestCaseInfo->name);
16318
16319     if (m_sectionStack.size() > 1) {
16320         Colour colourGuard(Colour::Headers);
16321
16322         auto
16323             it = m_sectionStack.begin() + 1, // Skip first section (test case)
16324             itEnd = m_sectionStack.end();
16325         for (; it != itEnd; ++it)
16326             printHeaderString(it->name, 2);
16327     }
16328
16329     SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
16330
16331     stream << getLineOfChars<'-'>() << '\n';
16332     Colour colourGuard(Colour::FileName);
16333     stream << lineInfo << '\n';
16334     stream << getLineOfChars<'.'>() << '\n' << std::endl;
16335 }
16336
16337 void ConsoleReporter::printClosedHeader(std::string const& _name) {
16338     printOpenHeader(_name);
16339     stream << getLineOfChars<'.'>() << '\n';
16340 }
16341 void ConsoleReporter::printOpenHeader(std::string const& _name) {
16342     stream << getLineOfChars<'-'>() << '\n';
16343     {
16344         Colour colourGuard(Colour::Headers);
16345         printHeaderString(_name);
16346     }
16347 }
16348
16349 // if string has a : in first line will set indent to follow it on
16350 // subsequent lines
16351 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
16352     std::size_t i = _string.find(": ");
16353     if (i != std::string::npos)
16354         i += 2;
16355     else
16356         i = 0;
16357     stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
16358 }
16359
16360 struct SummaryColumn {
16361
16362     SummaryColumn( std::string _label, Colour::Code _colour )
16363     :   label( std::move( _label ) ),
16364         colour( _colour ) {}
16365     SummaryColumn addRow( std::size_t count ) {
16366         ReusableStringStream rss;
16367         rss << count;
16368         std::string row = rss.str();
16369         for (auto& oldRow : rows) {
16370             while (oldRow.size() < row.size())
16371                 oldRow = ' ' + oldRow;
16372             while (oldRow.size() > row.size())
16373                 row = ' ' + row;
16374         }
16375         rows.push_back(row);
16376         return *this;
16377     }
16378
16379     std::string label;
16380     Colour::Code colour;
16381     std::vector<std::string> rows;
16382
16383 };
16384
16385 void ConsoleReporter::printTotals( Totals const& totals ) {
16386     if (totals.testCases.total() == 0) {
16387         stream << Colour(Colour::Warning) << "No tests ran\n";
16388     } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
16389         stream << Colour(Colour::ResultSuccess) << "All tests passed";
16390         stream << " ("
16391             << pluralise(totals.assertions.passed, "assertion") << " in "
16392             << pluralise(totals.testCases.passed, "test case") << ')'
16393             << '\n';
16394     } else {
16395
16396         std::vector<SummaryColumn> columns;
16397         columns.push_back(SummaryColumn("", Colour::None)
16398                           .addRow(totals.testCases.total())
16399                           .addRow(totals.assertions.total()));
16400         columns.push_back(SummaryColumn("passed", Colour::Success)
16401                           .addRow(totals.testCases.passed)
16402                           .addRow(totals.assertions.passed));
16403         columns.push_back(SummaryColumn("failed", Colour::ResultError)
16404                           .addRow(totals.testCases.failed)
16405                           .addRow(totals.assertions.failed));
16406         columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
16407                           .addRow(totals.testCases.failedButOk)
16408                           .addRow(totals.assertions.failedButOk));
16409
16410         printSummaryRow("test cases", columns, 0);
16411         printSummaryRow("assertions", columns, 1);
16412     }
16413 }
16414 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
16415     for (auto col : cols) {
16416         std::string value = col.rows[row];
16417         if (col.label.empty()) {
16418             stream << label << ": ";
16419             if (value != "0")
16420                 stream << value;
16421             else
16422                 stream << Colour(Colour::Warning) << "- none -";
16423         } else if (value != "0") {
16424             stream << Colour(Colour::LightGrey) << " | ";
16425             stream << Colour(col.colour)
16426                 << value << ' ' << col.label;
16427         }
16428     }
16429     stream << '\n';
16430 }
16431
16432 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
16433     if (totals.testCases.total() > 0) {
16434         std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
16435         std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
16436         std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
16437         while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
16438             findMax(failedRatio, failedButOkRatio, passedRatio)++;
16439         while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
16440             findMax(failedRatio, failedButOkRatio, passedRatio)--;
16441
16442         stream << Colour(Colour::Error) << std::string(failedRatio, '=');
16443         stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
16444         if (totals.testCases.allPassed())
16445             stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
16446         else
16447             stream << Colour(Colour::Success) << std::string(passedRatio, '=');
16448     } else {
16449         stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
16450     }
16451     stream << '\n';
16452 }
16453 void ConsoleReporter::printSummaryDivider() {
16454     stream << getLineOfChars<'-'>() << '\n';
16455 }
16456
16457 void ConsoleReporter::printTestFilters() {
16458     if (m_config->testSpec().hasFilters())
16459         stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
16460 }
16461
16462 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
16463
16464 } // end namespace Catch
16465
16466 #if defined(_MSC_VER)
16467 #pragma warning(pop)
16468 #endif
16469
16470 #if defined(__clang__)
16471 #  pragma clang diagnostic pop
16472 #endif
16473 // end catch_reporter_console.cpp
16474 // start catch_reporter_junit.cpp
16475
16476 #include <cassert>
16477 #include <sstream>
16478 #include <ctime>
16479 #include <algorithm>
16480
16481 namespace Catch {
16482
16483     namespace {
16484         std::string getCurrentTimestamp() {
16485             // Beware, this is not reentrant because of backward compatibility issues
16486             // Also, UTC only, again because of backward compatibility (%z is C++11)
16487             time_t rawtime;
16488             std::time(&rawtime);
16489             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
16490
16491 #ifdef _MSC_VER
16492             std::tm timeInfo = {};
16493             gmtime_s(&timeInfo, &rawtime);
16494 #else
16495             std::tm* timeInfo;
16496             timeInfo = std::gmtime(&rawtime);
16497 #endif
16498
16499             char timeStamp[timeStampSize];
16500             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
16501
16502 #ifdef _MSC_VER
16503             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
16504 #else
16505             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
16506 #endif
16507             return std::string(timeStamp);
16508         }
16509
16510         std::string fileNameTag(const std::vector<std::string> &tags) {
16511             auto it = std::find_if(begin(tags),
16512                                    end(tags),
16513                                    [] (std::string const& tag) {return tag.front() == '#'; });
16514             if (it != tags.end())
16515                 return it->substr(1);
16516             return std::string();
16517         }
16518     } // anonymous namespace
16519
16520     JunitReporter::JunitReporter( ReporterConfig const& _config )
16521         :   CumulativeReporterBase( _config ),
16522             xml( _config.stream() )
16523         {
16524             m_reporterPrefs.shouldRedirectStdOut = true;
16525             m_reporterPrefs.shouldReportAllAssertions = true;
16526         }
16527
16528     JunitReporter::~JunitReporter() {}
16529
16530     std::string JunitReporter::getDescription() {
16531         return "Reports test results in an XML format that looks like Ant's junitreport target";
16532     }
16533
16534     void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
16535
16536     void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
16537         CumulativeReporterBase::testRunStarting( runInfo );
16538         xml.startElement( "testsuites" );
16539     }
16540
16541     void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16542         suiteTimer.start();
16543         stdOutForSuite.clear();
16544         stdErrForSuite.clear();
16545         unexpectedExceptions = 0;
16546         CumulativeReporterBase::testGroupStarting( groupInfo );
16547     }
16548
16549     void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
16550         m_okToFail = testCaseInfo.okToFail();
16551     }
16552
16553     bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
16554         if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
16555             unexpectedExceptions++;
16556         return CumulativeReporterBase::assertionEnded( assertionStats );
16557     }
16558
16559     void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
16560         stdOutForSuite += testCaseStats.stdOut;
16561         stdErrForSuite += testCaseStats.stdErr;
16562         CumulativeReporterBase::testCaseEnded( testCaseStats );
16563     }
16564
16565     void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
16566         double suiteTime = suiteTimer.getElapsedSeconds();
16567         CumulativeReporterBase::testGroupEnded( testGroupStats );
16568         writeGroup( *m_testGroups.back(), suiteTime );
16569     }
16570
16571     void JunitReporter::testRunEndedCumulative() {
16572         xml.endElement();
16573     }
16574
16575     void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
16576         XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
16577
16578         TestGroupStats const& stats = groupNode.value;
16579         xml.writeAttribute( "name", stats.groupInfo.name );
16580         xml.writeAttribute( "errors", unexpectedExceptions );
16581         xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
16582         xml.writeAttribute( "tests", stats.totals.assertions.total() );
16583         xml.writeAttribute( "hostname", "tbd" ); // !TBD
16584         if( m_config->showDurations() == ShowDurations::Never )
16585             xml.writeAttribute( "time", "" );
16586         else
16587             xml.writeAttribute( "time", suiteTime );
16588         xml.writeAttribute( "timestamp", getCurrentTimestamp() );
16589
16590         // Write properties if there are any
16591         if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
16592             auto properties = xml.scopedElement("properties");
16593             if (m_config->hasTestFilters()) {
16594                 xml.scopedElement("property")
16595                     .writeAttribute("name", "filters")
16596                     .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
16597             }
16598             if (m_config->rngSeed() != 0) {
16599                 xml.scopedElement("property")
16600                     .writeAttribute("name", "random-seed")
16601                     .writeAttribute("value", m_config->rngSeed());
16602             }
16603         }
16604
16605         // Write test cases
16606         for( auto const& child : groupNode.children )
16607             writeTestCase( *child );
16608
16609         xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
16610         xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
16611     }
16612
16613     void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
16614         TestCaseStats const& stats = testCaseNode.value;
16615
16616         // All test cases have exactly one section - which represents the
16617         // test case itself. That section may have 0-n nested sections
16618         assert( testCaseNode.children.size() == 1 );
16619         SectionNode const& rootSection = *testCaseNode.children.front();
16620
16621         std::string className = stats.testInfo.className;
16622
16623         if( className.empty() ) {
16624             className = fileNameTag(stats.testInfo.tags);
16625             if ( className.empty() )
16626                 className = "global";
16627         }
16628
16629         if ( !m_config->name().empty() )
16630             className = m_config->name() + "." + className;
16631
16632         writeSection( className, "", rootSection );
16633     }
16634
16635     void JunitReporter::writeSection(  std::string const& className,
16636                         std::string const& rootName,
16637                         SectionNode const& sectionNode ) {
16638         std::string name = trim( sectionNode.stats.sectionInfo.name );
16639         if( !rootName.empty() )
16640             name = rootName + '/' + name;
16641
16642         if( !sectionNode.assertions.empty() ||
16643             !sectionNode.stdOut.empty() ||
16644             !sectionNode.stdErr.empty() ) {
16645             XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
16646             if( className.empty() ) {
16647                 xml.writeAttribute( "classname", name );
16648                 xml.writeAttribute( "name", "root" );
16649             }
16650             else {
16651                 xml.writeAttribute( "classname", className );
16652                 xml.writeAttribute( "name", name );
16653             }
16654             xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
16655
16656             writeAssertions( sectionNode );
16657
16658             if( !sectionNode.stdOut.empty() )
16659                 xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
16660             if( !sectionNode.stdErr.empty() )
16661                 xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
16662         }
16663         for( auto const& childNode : sectionNode.childSections )
16664             if( className.empty() )
16665                 writeSection( name, "", *childNode );
16666             else
16667                 writeSection( className, name, *childNode );
16668     }
16669
16670     void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
16671         for( auto const& assertion : sectionNode.assertions )
16672             writeAssertion( assertion );
16673     }
16674
16675     void JunitReporter::writeAssertion( AssertionStats const& stats ) {
16676         AssertionResult const& result = stats.assertionResult;
16677         if( !result.isOk() ) {
16678             std::string elementName;
16679             switch( result.getResultType() ) {
16680                 case ResultWas::ThrewException:
16681                 case ResultWas::FatalErrorCondition:
16682                     elementName = "error";
16683                     break;
16684                 case ResultWas::ExplicitFailure:
16685                     elementName = "failure";
16686                     break;
16687                 case ResultWas::ExpressionFailed:
16688                     elementName = "failure";
16689                     break;
16690                 case ResultWas::DidntThrowException:
16691                     elementName = "failure";
16692                     break;
16693
16694                 // We should never see these here:
16695                 case ResultWas::Info:
16696                 case ResultWas::Warning:
16697                 case ResultWas::Ok:
16698                 case ResultWas::Unknown:
16699                 case ResultWas::FailureBit:
16700                 case ResultWas::Exception:
16701                     elementName = "internalError";
16702                     break;
16703             }
16704
16705             XmlWriter::ScopedElement e = xml.scopedElement( elementName );
16706
16707             xml.writeAttribute( "message", result.getExpression() );
16708             xml.writeAttribute( "type", result.getTestMacroName() );
16709
16710             ReusableStringStream rss;
16711             if (stats.totals.assertions.total() > 0) {
16712                 rss << "FAILED" << ":\n";
16713                 if (result.hasExpression()) {
16714                     rss << "  ";
16715                     rss << result.getExpressionInMacro();
16716                     rss << '\n';
16717                 }
16718                 if (result.hasExpandedExpression()) {
16719                     rss << "with expansion:\n";
16720                     rss << Column(result.getExpandedExpression()).indent(2) << '\n';
16721                 }
16722             } else {
16723                 rss << '\n';
16724             }
16725
16726             if( !result.getMessage().empty() )
16727                 rss << result.getMessage() << '\n';
16728             for( auto const& msg : stats.infoMessages )
16729                 if( msg.type == ResultWas::Info )
16730                     rss << msg.message << '\n';
16731
16732             rss << "at " << result.getSourceInfo();
16733             xml.writeText( rss.str(), XmlFormatting::Newline );
16734         }
16735     }
16736
16737     CATCH_REGISTER_REPORTER( "junit", JunitReporter )
16738
16739 } // end namespace Catch
16740 // end catch_reporter_junit.cpp
16741 // start catch_reporter_listening.cpp
16742
16743 #include <cassert>
16744
16745 namespace Catch {
16746
16747     ListeningReporter::ListeningReporter() {
16748         // We will assume that listeners will always want all assertions
16749         m_preferences.shouldReportAllAssertions = true;
16750     }
16751
16752     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
16753         m_listeners.push_back( std::move( listener ) );
16754     }
16755
16756     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
16757         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
16758         m_reporter = std::move( reporter );
16759         m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
16760     }
16761
16762     ReporterPreferences ListeningReporter::getPreferences() const {
16763         return m_preferences;
16764     }
16765
16766     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
16767         return std::set<Verbosity>{ };
16768     }
16769
16770     void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
16771         for ( auto const& listener : m_listeners ) {
16772             listener->noMatchingTestCases( spec );
16773         }
16774         m_reporter->noMatchingTestCases( spec );
16775     }
16776
16777     void ListeningReporter::reportInvalidArguments(std::string const&arg){
16778         for ( auto const& listener : m_listeners ) {
16779             listener->reportInvalidArguments( arg );
16780         }
16781         m_reporter->reportInvalidArguments( arg );
16782     }
16783
16784 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16785     void ListeningReporter::benchmarkPreparing( std::string const& name ) {
16786                 for (auto const& listener : m_listeners) {
16787                         listener->benchmarkPreparing(name);
16788                 }
16789                 m_reporter->benchmarkPreparing(name);
16790         }
16791     void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
16792         for ( auto const& listener : m_listeners ) {
16793             listener->benchmarkStarting( benchmarkInfo );
16794         }
16795         m_reporter->benchmarkStarting( benchmarkInfo );
16796     }
16797     void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
16798         for ( auto const& listener : m_listeners ) {
16799             listener->benchmarkEnded( benchmarkStats );
16800         }
16801         m_reporter->benchmarkEnded( benchmarkStats );
16802     }
16803
16804         void ListeningReporter::benchmarkFailed( std::string const& error ) {
16805                 for (auto const& listener : m_listeners) {
16806                         listener->benchmarkFailed(error);
16807                 }
16808                 m_reporter->benchmarkFailed(error);
16809         }
16810 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16811
16812     void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
16813         for ( auto const& listener : m_listeners ) {
16814             listener->testRunStarting( testRunInfo );
16815         }
16816         m_reporter->testRunStarting( testRunInfo );
16817     }
16818
16819     void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16820         for ( auto const& listener : m_listeners ) {
16821             listener->testGroupStarting( groupInfo );
16822         }
16823         m_reporter->testGroupStarting( groupInfo );
16824     }
16825
16826     void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
16827         for ( auto const& listener : m_listeners ) {
16828             listener->testCaseStarting( testInfo );
16829         }
16830         m_reporter->testCaseStarting( testInfo );
16831     }
16832
16833     void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
16834         for ( auto const& listener : m_listeners ) {
16835             listener->sectionStarting( sectionInfo );
16836         }
16837         m_reporter->sectionStarting( sectionInfo );
16838     }
16839
16840     void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
16841         for ( auto const& listener : m_listeners ) {
16842             listener->assertionStarting( assertionInfo );
16843         }
16844         m_reporter->assertionStarting( assertionInfo );
16845     }
16846
16847     // The return value indicates if the messages buffer should be cleared:
16848     bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
16849         for( auto const& listener : m_listeners ) {
16850             static_cast<void>( listener->assertionEnded( assertionStats ) );
16851         }
16852         return m_reporter->assertionEnded( assertionStats );
16853     }
16854
16855     void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
16856         for ( auto const& listener : m_listeners ) {
16857             listener->sectionEnded( sectionStats );
16858         }
16859         m_reporter->sectionEnded( sectionStats );
16860     }
16861
16862     void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
16863         for ( auto const& listener : m_listeners ) {
16864             listener->testCaseEnded( testCaseStats );
16865         }
16866         m_reporter->testCaseEnded( testCaseStats );
16867     }
16868
16869     void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
16870         for ( auto const& listener : m_listeners ) {
16871             listener->testGroupEnded( testGroupStats );
16872         }
16873         m_reporter->testGroupEnded( testGroupStats );
16874     }
16875
16876     void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
16877         for ( auto const& listener : m_listeners ) {
16878             listener->testRunEnded( testRunStats );
16879         }
16880         m_reporter->testRunEnded( testRunStats );
16881     }
16882
16883     void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
16884         for ( auto const& listener : m_listeners ) {
16885             listener->skipTest( testInfo );
16886         }
16887         m_reporter->skipTest( testInfo );
16888     }
16889
16890     bool ListeningReporter::isMulti() const {
16891         return true;
16892     }
16893
16894 } // end namespace Catch
16895 // end catch_reporter_listening.cpp
16896 // start catch_reporter_xml.cpp
16897
16898 #if defined(_MSC_VER)
16899 #pragma warning(push)
16900 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
16901                               // Note that 4062 (not all labels are handled
16902                               // and default is missing) is enabled
16903 #endif
16904
16905 namespace Catch {
16906     XmlReporter::XmlReporter( ReporterConfig const& _config )
16907     :   StreamingReporterBase( _config ),
16908         m_xml(_config.stream())
16909     {
16910         m_reporterPrefs.shouldRedirectStdOut = true;
16911         m_reporterPrefs.shouldReportAllAssertions = true;
16912     }
16913
16914     XmlReporter::~XmlReporter() = default;
16915
16916     std::string XmlReporter::getDescription() {
16917         return "Reports test results as an XML document";
16918     }
16919
16920     std::string XmlReporter::getStylesheetRef() const {
16921         return std::string();
16922     }
16923
16924     void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
16925         m_xml
16926             .writeAttribute( "filename", sourceInfo.file )
16927             .writeAttribute( "line", sourceInfo.line );
16928     }
16929
16930     void XmlReporter::noMatchingTestCases( std::string const& s ) {
16931         StreamingReporterBase::noMatchingTestCases( s );
16932     }
16933
16934     void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
16935         StreamingReporterBase::testRunStarting( testInfo );
16936         std::string stylesheetRef = getStylesheetRef();
16937         if( !stylesheetRef.empty() )
16938             m_xml.writeStylesheetRef( stylesheetRef );
16939         m_xml.startElement( "Catch" );
16940         if( !m_config->name().empty() )
16941             m_xml.writeAttribute( "name", m_config->name() );
16942         if (m_config->testSpec().hasFilters())
16943             m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
16944         if( m_config->rngSeed() != 0 )
16945             m_xml.scopedElement( "Randomness" )
16946                 .writeAttribute( "seed", m_config->rngSeed() );
16947     }
16948
16949     void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16950         StreamingReporterBase::testGroupStarting( groupInfo );
16951         m_xml.startElement( "Group" )
16952             .writeAttribute( "name", groupInfo.name );
16953     }
16954
16955     void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
16956         StreamingReporterBase::testCaseStarting(testInfo);
16957         m_xml.startElement( "TestCase" )
16958             .writeAttribute( "name", trim( testInfo.name ) )
16959             .writeAttribute( "description", testInfo.description )
16960             .writeAttribute( "tags", testInfo.tagsAsString() );
16961
16962         writeSourceInfo( testInfo.lineInfo );
16963
16964         if ( m_config->showDurations() == ShowDurations::Always )
16965             m_testCaseTimer.start();
16966         m_xml.ensureTagClosed();
16967     }
16968
16969     void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
16970         StreamingReporterBase::sectionStarting( sectionInfo );
16971         if( m_sectionDepth++ > 0 ) {
16972             m_xml.startElement( "Section" )
16973                 .writeAttribute( "name", trim( sectionInfo.name ) );
16974             writeSourceInfo( sectionInfo.lineInfo );
16975             m_xml.ensureTagClosed();
16976         }
16977     }
16978
16979     void XmlReporter::assertionStarting( AssertionInfo const& ) { }
16980
16981     bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
16982
16983         AssertionResult const& result = assertionStats.assertionResult;
16984
16985         bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16986
16987         if( includeResults || result.getResultType() == ResultWas::Warning ) {
16988             // Print any info messages in <Info> tags.
16989             for( auto const& msg : assertionStats.infoMessages ) {
16990                 if( msg.type == ResultWas::Info && includeResults ) {
16991                     m_xml.scopedElement( "Info" )
16992                             .writeText( msg.message );
16993                 } else if ( msg.type == ResultWas::Warning ) {
16994                     m_xml.scopedElement( "Warning" )
16995                             .writeText( msg.message );
16996                 }
16997             }
16998         }
16999
17000         // Drop out if result was successful but we're not printing them.
17001         if( !includeResults && result.getResultType() != ResultWas::Warning )
17002             return true;
17003
17004         // Print the expression if there is one.
17005         if( result.hasExpression() ) {
17006             m_xml.startElement( "Expression" )
17007                 .writeAttribute( "success", result.succeeded() )
17008                 .writeAttribute( "type", result.getTestMacroName() );
17009
17010             writeSourceInfo( result.getSourceInfo() );
17011
17012             m_xml.scopedElement( "Original" )
17013                 .writeText( result.getExpression() );
17014             m_xml.scopedElement( "Expanded" )
17015                 .writeText( result.getExpandedExpression() );
17016         }
17017
17018         // And... Print a result applicable to each result type.
17019         switch( result.getResultType() ) {
17020             case ResultWas::ThrewException:
17021                 m_xml.startElement( "Exception" );
17022                 writeSourceInfo( result.getSourceInfo() );
17023                 m_xml.writeText( result.getMessage() );
17024                 m_xml.endElement();
17025                 break;
17026             case ResultWas::FatalErrorCondition:
17027                 m_xml.startElement( "FatalErrorCondition" );
17028                 writeSourceInfo( result.getSourceInfo() );
17029                 m_xml.writeText( result.getMessage() );
17030                 m_xml.endElement();
17031                 break;
17032             case ResultWas::Info:
17033                 m_xml.scopedElement( "Info" )
17034                     .writeText( result.getMessage() );
17035                 break;
17036             case ResultWas::Warning:
17037                 // Warning will already have been written
17038                 break;
17039             case ResultWas::ExplicitFailure:
17040                 m_xml.startElement( "Failure" );
17041                 writeSourceInfo( result.getSourceInfo() );
17042                 m_xml.writeText( result.getMessage() );
17043                 m_xml.endElement();
17044                 break;
17045             default:
17046                 break;
17047         }
17048
17049         if( result.hasExpression() )
17050             m_xml.endElement();
17051
17052         return true;
17053     }
17054
17055     void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
17056         StreamingReporterBase::sectionEnded( sectionStats );
17057         if( --m_sectionDepth > 0 ) {
17058             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
17059             e.writeAttribute( "successes", sectionStats.assertions.passed );
17060             e.writeAttribute( "failures", sectionStats.assertions.failed );
17061             e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
17062
17063             if ( m_config->showDurations() == ShowDurations::Always )
17064                 e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
17065
17066             m_xml.endElement();
17067         }
17068     }
17069
17070     void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
17071         StreamingReporterBase::testCaseEnded( testCaseStats );
17072         XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
17073         e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
17074
17075         if ( m_config->showDurations() == ShowDurations::Always )
17076             e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
17077
17078         if( !testCaseStats.stdOut.empty() )
17079             m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
17080         if( !testCaseStats.stdErr.empty() )
17081             m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
17082
17083         m_xml.endElement();
17084     }
17085
17086     void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17087         StreamingReporterBase::testGroupEnded( testGroupStats );
17088         // TODO: Check testGroupStats.aborting and act accordingly.
17089         m_xml.scopedElement( "OverallResults" )
17090             .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
17091             .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
17092             .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
17093         m_xml.endElement();
17094     }
17095
17096     void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
17097         StreamingReporterBase::testRunEnded( testRunStats );
17098         m_xml.scopedElement( "OverallResults" )
17099             .writeAttribute( "successes", testRunStats.totals.assertions.passed )
17100             .writeAttribute( "failures", testRunStats.totals.assertions.failed )
17101             .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
17102         m_xml.endElement();
17103     }
17104
17105 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17106     void XmlReporter::benchmarkPreparing(std::string const& name) {
17107         m_xml.startElement("BenchmarkResults")
17108             .writeAttribute("name", name);
17109     }
17110
17111     void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
17112         m_xml.writeAttribute("samples", info.samples)
17113             .writeAttribute("resamples", info.resamples)
17114             .writeAttribute("iterations", info.iterations)
17115             .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
17116             .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
17117             .writeComment("All values in nano seconds");
17118     }
17119
17120     void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
17121         m_xml.startElement("mean")
17122             .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
17123             .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
17124             .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
17125             .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
17126         m_xml.endElement();
17127         m_xml.startElement("standardDeviation")
17128             .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
17129             .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
17130             .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
17131             .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
17132         m_xml.endElement();
17133         m_xml.startElement("outliers")
17134             .writeAttribute("variance", benchmarkStats.outlierVariance)
17135             .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
17136             .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
17137             .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
17138             .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
17139         m_xml.endElement();
17140         m_xml.endElement();
17141     }
17142
17143     void XmlReporter::benchmarkFailed(std::string const &error) {
17144         m_xml.scopedElement("failed").
17145             writeAttribute("message", error);
17146         m_xml.endElement();
17147     }
17148 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17149
17150     CATCH_REGISTER_REPORTER( "xml", XmlReporter )
17151
17152 } // end namespace Catch
17153
17154 #if defined(_MSC_VER)
17155 #pragma warning(pop)
17156 #endif
17157 // end catch_reporter_xml.cpp
17158
17159 namespace Catch {
17160     LeakDetector leakDetector;
17161 }
17162
17163 #ifdef __clang__
17164 #pragma clang diagnostic pop
17165 #endif
17166
17167 // end catch_impl.hpp
17168 #endif
17169
17170 #ifdef CATCH_CONFIG_MAIN
17171 // start catch_default_main.hpp
17172
17173 #ifndef __OBJC__
17174
17175 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
17176 // Standard C/C++ Win32 Unicode wmain entry point
17177 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
17178 #else
17179 // Standard C/C++ main entry point
17180 int main (int argc, char * argv[]) {
17181 #endif
17182
17183     return Catch::Session().run( argc, argv );
17184 }
17185
17186 #else // __OBJC__
17187
17188 // Objective-C entry point
17189 int main (int argc, char * const argv[]) {
17190 #if !CATCH_ARC_ENABLED
17191     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
17192 #endif
17193
17194     Catch::registerTestMethods();
17195     int result = Catch::Session().run( argc, (char**)argv );
17196
17197 #if !CATCH_ARC_ENABLED
17198     [pool drain];
17199 #endif
17200
17201     return result;
17202 }
17203
17204 #endif // __OBJC__
17205
17206 // end catch_default_main.hpp
17207 #endif
17208
17209 #if !defined(CATCH_CONFIG_IMPL_ONLY)
17210
17211 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
17212 #  undef CLARA_CONFIG_MAIN
17213 #endif
17214
17215 #if !defined(CATCH_CONFIG_DISABLE)
17216 //////
17217 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17218 #ifdef CATCH_CONFIG_PREFIX_ALL
17219
17220 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17221 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17222
17223 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17224 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17225 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17226 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17227 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17228 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17229 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17230
17231 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17232 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17233 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17234 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17235 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17236
17237 #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17238 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17239 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17240 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17241 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17242 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17243 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17244
17245 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17246 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17247
17248 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17249 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17250
17251 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
17252 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
17253 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17254 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
17255
17256 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17257 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17258 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17259 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17260 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17261 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17262 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17263 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17264 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17265
17266 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17267
17268 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17269 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17270 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17271 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17272 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17273 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17274 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17275 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17276 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17277 #else
17278 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17279 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17280 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17281 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17282 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17283 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17284 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17285 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17286 #endif
17287
17288 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17289 #define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )
17290 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
17291 #else
17292 #define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )
17293 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
17294 #endif
17295
17296 // "BDD-style" convenience wrappers
17297 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
17298 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17299 #define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
17300 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17301 #define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
17302 #define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17303 #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
17304 #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
17305
17306 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17307 #define CATCH_BENCHMARK(...) \
17308     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__,,))
17309 #define CATCH_BENCHMARK_ADVANCED(name) \
17310     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17311 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17312
17313 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17314 #else
17315
17316 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
17317 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17318
17319 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17320 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17321 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17322 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17323 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17324 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17325 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17326
17327 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17328 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17329 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17330 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17331 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17332
17333 #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17334 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17335 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17336 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17337 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17338 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17339 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17340
17341 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17342 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17343
17344 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17345 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17346
17347 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
17348 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
17349 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17350 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
17351
17352 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17353 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17354 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17355 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17356 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17357 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17358 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17359 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17360 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17361 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17362
17363 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17364 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17365 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17366 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17367 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17368 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17369 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17370 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17371 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17372 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
17373 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
17374 #else
17375 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17376 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17377 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17378 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17379 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17380 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17381 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17382 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17383 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
17384 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17385 #endif
17386
17387 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17388 #define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
17389 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
17390 #else
17391 #define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )
17392 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
17393 #endif
17394
17395 #endif
17396
17397 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
17398
17399 // "BDD-style" convenience wrappers
17400 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
17401 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17402
17403 #define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
17404 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17405 #define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
17406 #define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17407 #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
17408 #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
17409
17410 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17411 #define BENCHMARK(...) \
17412     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__,,))
17413 #define BENCHMARK_ADVANCED(name) \
17414     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17415 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17416
17417 using Catch::Detail::Approx;
17418
17419 #else // CATCH_CONFIG_DISABLE
17420
17421 //////
17422 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17423 #ifdef CATCH_CONFIG_PREFIX_ALL
17424
17425 #define CATCH_REQUIRE( ... )        (void)(0)
17426 #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
17427
17428 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
17429 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17430 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
17431 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17432 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17433 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17434 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
17435
17436 #define CATCH_CHECK( ... )         (void)(0)
17437 #define CATCH_CHECK_FALSE( ... )   (void)(0)
17438 #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
17439 #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
17440 #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
17441
17442 #define CATCH_CHECK_THROWS( ... )  (void)(0)
17443 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17444 #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
17445 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17446 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17447 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17448 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
17449
17450 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17451 #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
17452
17453 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
17454 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17455
17456 #define CATCH_INFO( msg )          (void)(0)
17457 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
17458 #define CATCH_WARN( msg )          (void)(0)
17459 #define CATCH_CAPTURE( msg )       (void)(0)
17460
17461 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17462 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17463 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
17464 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
17465 #define CATCH_SECTION( ... )
17466 #define CATCH_DYNAMIC_SECTION( ... )
17467 #define CATCH_FAIL( ... ) (void)(0)
17468 #define CATCH_FAIL_CHECK( ... ) (void)(0)
17469 #define CATCH_SUCCEED( ... ) (void)(0)
17470
17471 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17472
17473 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17474 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17475 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17476 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17477 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17478 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17479 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17480 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17481 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17482 #else
17483 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17484 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17485 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17486 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17487 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17488 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17489 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17490 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17491 #endif
17492
17493 // "BDD-style" convenience wrappers
17494 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17495 #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 )
17496 #define CATCH_GIVEN( desc )
17497 #define CATCH_AND_GIVEN( desc )
17498 #define CATCH_WHEN( desc )
17499 #define CATCH_AND_WHEN( desc )
17500 #define CATCH_THEN( desc )
17501 #define CATCH_AND_THEN( desc )
17502
17503 #define CATCH_STATIC_REQUIRE( ... )       (void)(0)
17504 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
17505
17506 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17507 #else
17508
17509 #define REQUIRE( ... )       (void)(0)
17510 #define REQUIRE_FALSE( ... ) (void)(0)
17511
17512 #define REQUIRE_THROWS( ... ) (void)(0)
17513 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17514 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
17515 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17516 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17517 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17518 #define REQUIRE_NOTHROW( ... ) (void)(0)
17519
17520 #define CHECK( ... ) (void)(0)
17521 #define CHECK_FALSE( ... ) (void)(0)
17522 #define CHECKED_IF( ... ) if (__VA_ARGS__)
17523 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
17524 #define CHECK_NOFAIL( ... ) (void)(0)
17525
17526 #define CHECK_THROWS( ... )  (void)(0)
17527 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17528 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
17529 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17530 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17531 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17532 #define CHECK_NOTHROW( ... ) (void)(0)
17533
17534 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17535 #define CHECK_THAT( arg, matcher ) (void)(0)
17536
17537 #define REQUIRE_THAT( arg, matcher ) (void)(0)
17538 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17539
17540 #define INFO( msg ) (void)(0)
17541 #define UNSCOPED_INFO( msg ) (void)(0)
17542 #define WARN( msg ) (void)(0)
17543 #define CAPTURE( msg ) (void)(0)
17544
17545 #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17546 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17547 #define METHOD_AS_TEST_CASE( method, ... )
17548 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
17549 #define SECTION( ... )
17550 #define DYNAMIC_SECTION( ... )
17551 #define FAIL( ... ) (void)(0)
17552 #define FAIL_CHECK( ... ) (void)(0)
17553 #define SUCCEED( ... ) (void)(0)
17554 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17555
17556 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17557 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17558 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17559 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17560 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17561 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17562 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17563 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17564 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17565 #else
17566 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17567 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17568 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17569 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17570 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17571 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17572 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17573 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17574 #endif
17575
17576 #define STATIC_REQUIRE( ... )       (void)(0)
17577 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
17578
17579 #endif
17580
17581 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
17582
17583 // "BDD-style" convenience wrappers
17584 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
17585 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
17586
17587 #define GIVEN( desc )
17588 #define AND_GIVEN( desc )
17589 #define WHEN( desc )
17590 #define AND_WHEN( desc )
17591 #define THEN( desc )
17592 #define AND_THEN( desc )
17593
17594 using Catch::Detail::Approx;
17595
17596 #endif
17597
17598 #endif // ! CATCH_CONFIG_IMPL_ONLY
17599
17600 // start catch_reenable_warnings.h
17601
17602
17603 #ifdef __clang__
17604 #    ifdef __ICC // icpc defines the __clang__ macro
17605 #        pragma warning(pop)
17606 #    else
17607 #        pragma clang diagnostic pop
17608 #    endif
17609 #elif defined __GNUC__
17610 #    pragma GCC diagnostic pop
17611 #endif
17612
17613 // end catch_reenable_warnings.h
17614 // end catch.hpp
17615 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
17616