QtBase  v6.3.1
catch_p_p.h
Go to the documentation of this file.
1 /*
2  * Catch v2.13.8
3  * Generated: 2022-01-03 21:20:09.589503
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2022 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 13
18 #define CATCH_VERSION_PATCH 8
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 // See e.g.:
70 // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
71 #ifdef __APPLE__
72 # include <TargetConditionals.h>
73 # if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
74  (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
75 # define CATCH_PLATFORM_MAC
76 # elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
77 # define CATCH_PLATFORM_IPHONE
78 # endif
79 
80 #elif defined(linux) || defined(__linux) || defined(__linux__)
81 # define CATCH_PLATFORM_LINUX
82 
83 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
84 # define CATCH_PLATFORM_WINDOWS
85 #endif
86 
87 // end catch_platform.h
88 
89 #ifdef CATCH_IMPL
90 # ifndef CLARA_CONFIG_MAIN
91 # define CLARA_CONFIG_MAIN_NOT_DEFINED
92 # define CLARA_CONFIG_MAIN
93 # endif
94 #endif
95 
96 // start catch_user_interfaces.h
97 
98 namespace Catch {
99  unsigned int rngSeed();
100 }
101 
102 // end catch_user_interfaces.h
103 // start catch_tag_alias_autoregistrar.h
104 
105 // start catch_common.h
106 
107 // start catch_compiler_capabilities.h
108 
109 // Detect a number of compiler features - by compiler
110 // The following features are defined:
111 //
112 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
113 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
114 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
115 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
116 // ****************
117 // Note to maintainers: if new toggles are added please document them
118 // in configuration.md, too
119 // ****************
120 
121 // In general each macro has a _NO_<feature name> form
122 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
123 // Many features, at point of detection, define an _INTERNAL_ macro, so they
124 // can be combined, en-mass, with the _NO_ forms later.
125 
126 #ifdef __cplusplus
127 
128 # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
129 # define CATCH_CPP14_OR_GREATER
130 # endif
131 
132 # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
133 # define CATCH_CPP17_OR_GREATER
134 # endif
135 
136 #endif
137 
138 // Only GCC compiler should be used in this block, so other compilers trying to
139 // mask themselves as GCC should be ignored.
140 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
141 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
142 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
143 
144 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
145 
146 #endif
147 
148 #if defined(__clang__)
149 
150 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
151 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
152 
153 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
154 // which results in calls to destructors being emitted for each temporary,
155 // without a matching initialization. In practice, this can result in something
156 // like `std::string::~string` being called on an uninitialized value.
157 //
158 // For example, this code will likely segfault under IBM XL:
159 // ```
160 // REQUIRE(std::string("12") + "34" == "1234")
161 // ```
162 //
163 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
164 # if !defined(__ibmxl__) && !defined(__CUDACC__)
165 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
166 # endif
167 
168 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
169  _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
170  _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
171 
172 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
173  _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
174 
175 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
176  _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
177 
178 # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
179  _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
180 
181 # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
182  _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
183 
184 #endif // __clang__
185 
187 // Assume that non-Windows platforms support posix signals by default
188 #if !defined(CATCH_PLATFORM_WINDOWS)
189  #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
190 #endif
191 
193 // We know some environments not to support full POSIX signals
194 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__ghs) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
195  #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
196 #endif
197 
198 #ifdef __OS400__
199 # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
200 # define CATCH_CONFIG_COLOUR_NONE
201 #endif
202 
204 // Android somehow still does not support std::to_string
205 #if defined(__ANDROID__)
206 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
207 # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
208 #endif
209 
211 // Not all Windows environments support SEH properly
212 #if defined(__MINGW32__)
213 # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
214 #endif
215 
217 // PS4
218 #if defined(__ORBIS__)
219 # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
220 #endif
221 
223 // Cygwin
224 #ifdef __CYGWIN__
225 
226 // Required for some versions of Cygwin to declare gettimeofday
227 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
228 # define _BSD_SOURCE
229 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
230 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
231 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
232  && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
233 
234 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
235 
236 # endif
237 #endif // __CYGWIN__
238 
240 // Visual C++
241 #if defined(_MSC_VER)
242 
243 // Universal Windows platform does not support SEH
244 // Or console colours (or console at all...)
245 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
246 # define CATCH_CONFIG_COLOUR_NONE
247 # else
248 # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
249 # endif
250 
251 # if !defined(__clang__) // Handle Clang masquerading for msvc
252 
253 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
254 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
255 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
256 # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
257 # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
258 # endif // MSVC_TRADITIONAL
259 
260 // Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`
261 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
262 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
263 # endif // __clang__
264 
265 #endif // _MSC_VER
266 
267 #if defined(_REENTRANT) || defined(_MSC_VER)
268 // Enable async processing, as -pthread is specified or no additional linking is required
269 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
270 #endif // _MSC_VER
271 
273 // Check if we are compiled with -fno-exceptions or equivalent
274 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
275 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
276 #endif
277 
279 // DJGPP
280 #ifdef __DJGPP__
281 # define CATCH_INTERNAL_CONFIG_NO_WCHAR
282 #endif // __DJGPP__
283 
285 // Embarcadero C++Build
286 #if defined(__BORLANDC__)
287  #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
288 #endif
289 
291 
292 // Use of __COUNTER__ is suppressed during code analysis in
293 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
294 // handled by it.
295 // Otherwise all supported compilers support COUNTER macro,
296 // but user still might want to turn it off
297 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
298  #define CATCH_INTERNAL_CONFIG_COUNTER
299 #endif
300 
302 
303 // RTX is a special version of Windows that is real time.
304 // This means that it is detected as Windows, but does not provide
305 // the same set of capabilities as real Windows does.
306 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
307  #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
308  #define CATCH_INTERNAL_CONFIG_NO_ASYNC
309  #define CATCH_CONFIG_COLOUR_NONE
310 #endif
311 
312 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
313 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
314 #endif
315 
316 // Various stdlib support checks that require __has_include
317 #if defined(__has_include)
318  // Check if string_view is available and usable
319  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
320  # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
321  #endif
322 
323  // Check if optional is available and usable
324  # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
325  # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
326  # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
327 
328  // Check if byte is available and usable
329  # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
330  # include <cstddef>
331  # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
332  # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
333  # endif
334  # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
335 
336  // Check if variant is available and usable
337  # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
338  # if defined(__clang__) && (__clang_major__ < 8)
339  // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
340  // fix should be in clang 8, workaround in libstdc++ 8.2
341  # include <ciso646>
342  # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
343  # define CATCH_CONFIG_NO_CPP17_VARIANT
344  # else
345  # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
346  # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
347  # else
348  # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
349  # endif // defined(__clang__) && (__clang_major__ < 8)
350  # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
351 #endif // defined(__has_include)
352 
353 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
354 # define CATCH_CONFIG_COUNTER
355 #endif
356 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
357 # define CATCH_CONFIG_WINDOWS_SEH
358 #endif
359 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
360 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
361 # define CATCH_CONFIG_POSIX_SIGNALS
362 #endif
363 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
364 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
365 # define CATCH_CONFIG_WCHAR
366 #endif
367 
368 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
369 # define CATCH_CONFIG_CPP11_TO_STRING
370 #endif
371 
372 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
373 # define CATCH_CONFIG_CPP17_OPTIONAL
374 #endif
375 
376 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
377 # define CATCH_CONFIG_CPP17_STRING_VIEW
378 #endif
379 
380 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
381 # define CATCH_CONFIG_CPP17_VARIANT
382 #endif
383 
384 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
385 # define CATCH_CONFIG_CPP17_BYTE
386 #endif
387 
388 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
389 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
390 #endif
391 
392 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
393 # define CATCH_CONFIG_NEW_CAPTURE
394 #endif
395 
396 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
397 # define CATCH_CONFIG_DISABLE_EXCEPTIONS
398 #endif
399 
400 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
401 # define CATCH_CONFIG_POLYFILL_ISNAN
402 #endif
403 
404 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
405 # define CATCH_CONFIG_USE_ASYNC
406 #endif
407 
408 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
409 # define CATCH_CONFIG_ANDROID_LOGWRITE
410 #endif
411 
412 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
413 # define CATCH_CONFIG_GLOBAL_NEXTAFTER
414 #endif
415 
416 // Even if we do not think the compiler has that warning, we still have
417 // to provide a macro that can be used by the code.
418 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
419 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
420 #endif
421 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
422 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
423 #endif
424 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
425 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
426 #endif
427 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
428 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
429 #endif
430 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
431 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
432 #endif
433 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
434 # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
435 #endif
436 
437 // The goal of this macro is to avoid evaluation of the arguments, but
438 // still have the compiler warn on problems inside...
439 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
440 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
441 #endif
442 
443 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
444 # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
445 #elif defined(__clang__) && (__clang_major__ < 5)
446 # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
447 #endif
448 
449 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
450 # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
451 #endif
452 
453 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
454 #define CATCH_TRY if ((true))
455 #define CATCH_CATCH_ALL if ((false))
456 #define CATCH_CATCH_ANON(type) if ((false))
457 #else
458 #define CATCH_TRY try
459 #define CATCH_CATCH_ALL catch (...)
460 #define CATCH_CATCH_ANON(type) catch (type)
461 #endif
462 
463 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
464 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
465 #endif
466 
467 // end catch_compiler_capabilities.h
468 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
469 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
470 #ifdef CATCH_CONFIG_COUNTER
471 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
472 #else
473 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
474 #endif
475 
476 #include <iosfwd>
477 #include <string>
478 #include <cstdint>
479 
480 // We need a dummy global operator<< so we can bring it into Catch namespace later
482 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
483 
484 namespace Catch {
485 
486  struct CaseSensitive { enum Choice {
488  No
489  }; };
490 
491  class NonCopyable {
492  NonCopyable( NonCopyable const& ) = delete;
493  NonCopyable( NonCopyable && ) = delete;
494  NonCopyable& operator = ( NonCopyable const& ) = delete;
495  NonCopyable& operator = ( NonCopyable && ) = delete;
496 
497  protected:
499  virtual ~NonCopyable();
500  };
501 
502  struct SourceLineInfo {
503 
504  SourceLineInfo() = delete;
505  SourceLineInfo( char const* _file, std::size_t _line ) noexcept
506  : file( _file ),
507  line( _line )
508  {}
509 
510  SourceLineInfo( SourceLineInfo const& other ) = default;
513  SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
514 
515  bool empty() const noexcept { return file[0] == '\0'; }
516  bool operator == ( SourceLineInfo const& other ) const noexcept;
517  bool operator < ( SourceLineInfo const& other ) const noexcept;
518 
519  char const* file;
520  std::size_t line;
521  };
522 
523  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
524 
525  // Bring in operator<< from global namespace into Catch namespace
526  // This is necessary because the overload of operator<< above makes
527  // lookup stop at namespace Catch
528  using ::operator<<;
529 
530  // Use this in variadic streaming macros to allow
531  // >> +StreamEndStop
532  // as well as
533  // >> stuff +StreamEndStop
534  struct StreamEndStop {
536  };
537  template<typename T>
538  T const& operator + ( T const& value, StreamEndStop ) {
539  return value;
540  }
541 }
542 
543 #define CATCH_INTERNAL_LINEINFO \
544  ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
545 
546 // end catch_common.h
547 namespace Catch {
548 
550  RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
551  };
552 
553 } // end namespace Catch
554 
555 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
556  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
557  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
558  namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
559  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
560 
561 // end catch_tag_alias_autoregistrar.h
562 // start catch_test_registry.h
563 
564 // start catch_interfaces_testcase.h
565 
566 #include <vector>
567 
568 namespace Catch {
569 
570  class TestSpec;
571 
572  struct ITestInvoker {
573  virtual void invoke () const = 0;
574  virtual ~ITestInvoker();
575  };
576 
577  class TestCase;
578  struct IConfig;
579 
582  virtual std::vector<TestCase> const& getAllTests() const = 0;
583  virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
584  };
585 
586  bool isThrowSafe( TestCase const& testCase, IConfig const& config );
587  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
588  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
589  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
590 
591 }
592 
593 // end catch_interfaces_testcase.h
594 // start catch_stringref.h
595 
596 #include <cstddef>
597 #include <string>
598 #include <iosfwd>
599 #include <cassert>
600 
601 namespace Catch {
602 
606  class StringRef {
607  public:
608  using size_type = std::size_t;
609  using const_iterator = const char*;
610 
611  private:
612  static constexpr char const* const s_empty = "";
613 
614  char const* m_start = s_empty;
615  size_type m_size = 0;
616 
617  public: // construction
618  constexpr StringRef() noexcept = default;
619 
620  StringRef( char const* rawChars ) noexcept;
621 
622  constexpr StringRef( char const* rawChars, size_type size ) noexcept
623  : m_start( rawChars ),
624  m_size( size )
625  {}
626 
627  StringRef( std::string const& stdString ) noexcept
628  : m_start( stdString.c_str() ),
629  m_size( stdString.size() )
630  {}
631 
632  explicit operator std::string() const {
633  return std::string(m_start, m_size);
634  }
635 
636  public: // operators
637  auto operator == ( StringRef const& other ) const noexcept -> bool;
638  auto operator != (StringRef const& other) const noexcept -> bool {
639  return !(*this == other);
640  }
641 
642  auto operator[] ( size_type index ) const noexcept -> char {
643  assert(index < m_size);
644  return m_start[index];
645  }
646 
647  public: // named queries
648  constexpr auto empty() const noexcept -> bool {
649  return m_size == 0;
650  }
651  constexpr auto size() const noexcept -> size_type {
652  return m_size;
653  }
654 
655  // Returns the current start pointer. If the StringRef is not
656  // null-terminated, throws std::domain_exception
657  auto c_str() const -> char const*;
658 
659  public: // substrings and searches
660  // Returns a substring of [start, start + length).
661  // If start + length > size(), then the substring is [start, size()).
662  // If start > size(), then the substring is empty.
664 
665  // Returns the current start pointer. May not be null-terminated.
666  auto data() const noexcept -> char const*;
667 
668  constexpr auto isNullTerminated() const noexcept -> bool {
669  return m_start[m_size] == '\0';
670  }
671 
672  public: // iterators
673  constexpr const_iterator begin() const { return m_start; }
674  constexpr const_iterator end() const { return m_start + m_size; }
675  };
676 
677  auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
678  auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
679 
680  constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
681  return StringRef( rawChars, size );
682  }
683 } // namespace Catch
684 
685 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
686  return Catch::StringRef( rawChars, size );
687 }
688 
689 // end catch_stringref.h
690 // start catch_preprocessor.hpp
691 
692 
693 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
694 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
695 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
696 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
697 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
698 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
699 
700 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
701 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
702 // MSVC needs more evaluations
703 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
704 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
705 #else
706 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
707 #endif
708 
709 #define CATCH_REC_END(...)
710 #define CATCH_REC_OUT
711 
712 #define CATCH_EMPTY()
713 #define CATCH_DEFER(id) id CATCH_EMPTY()
714 
715 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
716 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
717 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
718 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
719 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
720 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
721 
722 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
723 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
724 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
725 
726 #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__ )
727 #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__ )
728 #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__ )
729 
730 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
731 // and passes userdata as the first parameter to each invocation,
732 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
733 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
734 
735 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
736 
737 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
738 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
739 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
740 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
741 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
742 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
743 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
744 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
745 #else
746 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
747 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
748 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
749 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
750 #endif
751 
752 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
753 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
754 
755 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
756 
757 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
758 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
759 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
760 #else
761 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
762 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
763 #endif
764 
765 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
766  CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
767 
768 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
769 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
770 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
771 #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)
772 #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)
773 #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)
774 #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
775 #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)
776 #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)
777 #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)
778 #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)
779 
780 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
781 
782 #define INTERNAL_CATCH_TYPE_GEN\
783  template<typename...> struct TypeList {};\
784  template<typename...Ts>\
785  constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
786  template<template<typename...> class...> struct TemplateTypeList{};\
787  template<template<typename...> class...Cs>\
788  constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
789  template<typename...>\
790  struct append;\
791  template<typename...>\
792  struct rewrap;\
793  template<template<typename...> class, typename...>\
794  struct create;\
795  template<template<typename...> class, typename>\
796  struct convert;\
797  \
798  template<typename T> \
799  struct append<T> { using type = T; };\
800  template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
801  struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
802  template< template<typename...> class L1, typename...E1, typename...Rest>\
803  struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
804  \
805  template< template<typename...> class Container, template<typename...> class List, typename...elems>\
806  struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
807  template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
808  struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
809  \
810  template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
811  struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
812  template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
813  struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
814 
815 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
816  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
817  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
818  constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
819  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
820  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
821  constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
822  \
823  template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
824  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
825  template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
826  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
827  template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
828  struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
829 
830 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
831 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
832  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
833  static void TestName()
834 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
835  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
836  static void TestName()
837 
838 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
839 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
840  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
841  static void TestName()
842 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
843  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
844  static void TestName()
845 
846 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
847  template<typename Type>\
848  void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
849  {\
850  Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
851  }
852 
853 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
854  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
855  void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
856  {\
857  Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
858  }
859 
860 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
861  template<typename Type>\
862  void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
863  {\
864  Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
865  }
866 
867 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
868  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
869  void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
870  {\
871  Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
872  }
873 
874 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
875 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
876  template<typename TestType> \
877  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
878  void test();\
879  }
880 
881 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
882  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
883  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
884  void test();\
885  }
886 
887 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
888 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
889  template<typename TestType> \
890  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
891 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
892  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
893  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
894 
895 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
896 #define INTERNAL_CATCH_NTTP_0
897 #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)
898 #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__)
899 #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__)
900 #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__)
901 #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__)
902 #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__)
903 #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__)
904 #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__)
905 #else
906 #define INTERNAL_CATCH_NTTP_0(signature)
907 #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__))
908 #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__))
909 #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__))
910 #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__))
911 #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__))
912 #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__))
913 #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__))
914 #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__))
915 #endif
916 
917 // end catch_preprocessor.hpp
918 // start catch_meta.hpp
919 
920 
921 #include <type_traits>
922 
923 namespace Catch {
924  template<typename T>
925  struct always_false : std::false_type {};
926 
927  template <typename> struct true_given : std::true_type {};
929  template <typename Fun, typename... Args>
930  true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
931  template <typename...>
932  std::false_type static test(...);
933  };
934 
935  template <typename T>
936  struct is_callable;
937 
938  template <typename Fun, typename... Args>
939  struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
940 
941 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
942  // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
943  // replaced with std::invoke_result here.
944  template <typename Func, typename... U>
945  using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
946 #else
947  // Keep ::type here because we still support C++11
948  template <typename Func, typename... U>
949  using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
950 #endif
951 
952 } // namespace Catch
953 
954 namespace mpl_{
955  struct na;
956 }
957 
958 // end catch_meta.hpp
959 namespace Catch {
960 
961 template<typename C>
963  void (C::*m_testAsMethod)();
964 public:
965  TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
966 
967  void invoke() const override {
968  C obj;
969  (obj.*m_testAsMethod)();
970  }
971 };
972 
973 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
974 
975 template<typename C>
976 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
977  return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
978 }
979 
980 struct NameAndTags {
981  NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
984 };
985 
987  AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
989 };
990 
991 } // end namespace Catch
992 
993 #if defined(CATCH_CONFIG_DISABLE)
994  #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
995  static void TestName()
996  #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
997  namespace{ \
998  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
999  void test(); \
1000  }; \
1001  } \
1002  void TestName::test()
1003  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
1004  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1005  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1006  namespace{ \
1007  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1008  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1009  } \
1010  } \
1011  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1012 
1013  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1014  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1015  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__ )
1016  #else
1017  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1018  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__ ) )
1019  #endif
1020 
1021  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1022  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1023  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__ )
1024  #else
1025  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1026  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__ ) )
1027  #endif
1028 
1029  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1030  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1031  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__ )
1032  #else
1033  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1034  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__ ) )
1035  #endif
1036 
1037  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1038  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1039  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__ )
1040  #else
1041  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1042  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__ ) )
1043  #endif
1044 #endif
1045 
1047  #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
1048  static void TestName(); \
1049  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1050  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1051  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1052  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1053  static void TestName()
1054  #define INTERNAL_CATCH_TESTCASE( ... ) \
1055  INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )
1056 
1058  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
1059  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1060  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1061  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1062  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1063 
1065  #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
1066  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1067  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1068  namespace{ \
1069  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1070  void test(); \
1071  }; \
1072  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1073  } \
1074  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1075  void TestName::test()
1076  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
1077  INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )
1078 
1080  #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
1081  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1082  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1083  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1084  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1085 
1087  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
1088  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1089  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1090  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1091  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1092  INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1093  namespace {\
1094  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1095  INTERNAL_CATCH_TYPE_GEN\
1096  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1097  INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1098  template<typename...Types> \
1099  struct TestName{\
1100  TestName(){\
1101  int index = 0; \
1102  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1103  using expander = int[];\
1104  (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
1105  }\
1106  };\
1107  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1108  TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1109  return 0;\
1110  }();\
1111  }\
1112  }\
1113  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1114  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
1115 
1116 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1117  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1118  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__ )
1119 #else
1120  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1121  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__ ) )
1122 #endif
1123 
1124 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1125  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1126  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__ )
1127 #else
1128  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1129  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__ ) )
1130 #endif
1131 
1132  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
1133  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1134  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1135  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1136  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1137  template<typename TestType> static void TestFuncName(); \
1138  namespace {\
1139  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1140  INTERNAL_CATCH_TYPE_GEN \
1141  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1142  template<typename... Types> \
1143  struct TestName { \
1144  void reg_tests() { \
1145  int index = 0; \
1146  using expander = int[]; \
1147  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1148  constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1149  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1150  (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++)... };/* NOLINT */\
1151  } \
1152  }; \
1153  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1154  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; \
1155  TestInit t; \
1156  t.reg_tests(); \
1157  return 0; \
1158  }(); \
1159  } \
1160  } \
1161  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1162  template<typename TestType> \
1163  static void TestFuncName()
1164 
1165 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1166  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1167  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__)
1168 #else
1169  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1170  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__ ) )
1171 #endif
1172 
1173 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1174  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1175  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__)
1176 #else
1177  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1178  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__ ) )
1179 #endif
1180 
1181  #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
1182  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1183  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1184  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1185  template<typename TestType> static void TestFunc(); \
1186  namespace {\
1187  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1188  INTERNAL_CATCH_TYPE_GEN\
1189  template<typename... Types> \
1190  struct TestName { \
1191  void reg_tests() { \
1192  int index = 0; \
1193  using expander = int[]; \
1194  (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++)... };/* NOLINT */\
1195  } \
1196  };\
1197  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1198  using TestInit = typename convert<TestName, TmplList>::type; \
1199  TestInit t; \
1200  t.reg_tests(); \
1201  return 0; \
1202  }(); \
1203  }}\
1204  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1205  template<typename TestType> \
1206  static void TestFunc()
1207 
1208  #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
1209  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 )
1210 
1211  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1212  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1213  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1214  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1215  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1216  namespace {\
1217  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1218  INTERNAL_CATCH_TYPE_GEN\
1219  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1220  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1221  INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1222  template<typename...Types> \
1223  struct TestNameClass{\
1224  TestNameClass(){\
1225  int index = 0; \
1226  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1227  using expander = int[];\
1228  (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
1229  }\
1230  };\
1231  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1232  TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1233  return 0;\
1234  }();\
1235  }\
1236  }\
1237  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1238  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1239 
1240 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1241  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1242  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__ )
1243 #else
1244  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1245  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__ ) )
1246 #endif
1247 
1248 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1249  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1250  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__ )
1251 #else
1252  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1253  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__ ) )
1254 #endif
1255 
1256  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
1257  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1258  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1259  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1260  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1261  template<typename TestType> \
1262  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1263  void test();\
1264  };\
1265  namespace {\
1266  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
1267  INTERNAL_CATCH_TYPE_GEN \
1268  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1269  template<typename...Types>\
1270  struct TestNameClass{\
1271  void reg_tests(){\
1272  int index = 0;\
1273  using expander = int[];\
1274  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1275  constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1276  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1277  (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++)... };/* NOLINT */ \
1278  }\
1279  };\
1280  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1281  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;\
1282  TestInit t;\
1283  t.reg_tests();\
1284  return 0;\
1285  }(); \
1286  }\
1287  }\
1288  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1289  template<typename TestType> \
1290  void TestName<TestType>::test()
1291 
1292 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1293  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1294  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__ )
1295 #else
1296  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1297  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__ ) )
1298 #endif
1299 
1300 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1301  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1302  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__ )
1303 #else
1304  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1305  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__ ) )
1306 #endif
1307 
1308  #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
1309  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1310  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1311  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1312  template<typename TestType> \
1313  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1314  void test();\
1315  };\
1316  namespace {\
1317  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1318  INTERNAL_CATCH_TYPE_GEN\
1319  template<typename...Types>\
1320  struct TestNameClass{\
1321  void reg_tests(){\
1322  int index = 0;\
1323  using expander = int[];\
1324  (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++)... };/* NOLINT */ \
1325  }\
1326  };\
1327  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1328  using TestInit = typename convert<TestNameClass, TmplList>::type;\
1329  TestInit t;\
1330  t.reg_tests();\
1331  return 0;\
1332  }(); \
1333  }}\
1334  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1335  template<typename TestType> \
1336  void TestName<TestType>::test()
1337 
1338 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
1339  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 )
1340 
1341 // end catch_test_registry.h
1342 // start catch_capture.hpp
1343 
1344 // start catch_assertionhandler.h
1345 
1346 // start catch_assertioninfo.h
1347 
1348 // start catch_result_type.h
1349 
1350 namespace Catch {
1351 
1352  // ResultWas::OfType enum
1353  struct ResultWas { enum OfType {
1354  Unknown = -1,
1355  Ok = 0,
1356  Info = 1,
1357  Warning = 2,
1358 
1359  FailureBit = 0x10,
1360 
1363 
1365 
1368 
1370 
1371  }; };
1372 
1373  bool isOk( ResultWas::OfType resultType );
1374  bool isJustInfo( int flags );
1375 
1376  // ResultDisposition::Flags enum
1377  struct ResultDisposition { enum Flags {
1378  Normal = 0x01,
1379 
1380  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
1381  FalseTest = 0x04, // Prefix expression with !
1382  SuppressFail = 0x08 // Failures are reported but do not fail the test
1383  }; };
1384 
1386 
1388  inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
1390 
1391 } // end namespace Catch
1392 
1393 // end catch_result_type.h
1394 namespace Catch {
1395 
1397  {
1402 
1403  // We want to delete this constructor but a compiler bug in 4.8 means
1404  // the struct is then treated as non-aggregate
1405  //AssertionInfo() = delete;
1406  };
1407 
1408 } // end namespace Catch
1409 
1410 // end catch_assertioninfo.h
1411 // start catch_decomposer.h
1412 
1413 // start catch_tostring.h
1414 
1415 #include <vector>
1416 #include <cstddef>
1417 #include <type_traits>
1418 #include <string>
1419 // start catch_stream.h
1420 
1421 #include <iosfwd>
1422 #include <cstddef>
1423 #include <ostream>
1424 
1425 namespace Catch {
1426 
1427  std::ostream& cout();
1428  std::ostream& cerr();
1429  std::ostream& clog();
1430 
1431  class StringRef;
1432 
1433  struct IStream {
1434  virtual ~IStream();
1435  virtual std::ostream& stream() const = 0;
1436  };
1437 
1438  auto makeStream( StringRef const &filename ) -> IStream const*;
1439 
1441  std::size_t m_index;
1442  std::ostream* m_oss;
1443  public:
1446 
1447  auto str() const -> std::string;
1448 
1449  template<typename T>
1450  auto operator << ( T const& value ) -> ReusableStringStream& {
1451  *m_oss << value;
1452  return *this;
1453  }
1454  auto get() -> std::ostream& { return *m_oss; }
1455  };
1456 }
1457 
1458 // end catch_stream.h
1459 // start catch_interfaces_enum_values_registry.h
1460 
1461 #include <vector>
1462 
1463 namespace Catch {
1464 
1465  namespace Detail {
1466  struct EnumInfo {
1468  std::vector<std::pair<int, StringRef>> m_values;
1469 
1471 
1472  StringRef lookup( int value ) const;
1473  };
1474  } // namespace Detail
1475 
1478 
1479  virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
1480 
1481  template<typename E>
1482  Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
1483  static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1484  std::vector<int> intValues;
1485  intValues.reserve( values.size() );
1486  for( auto enumValue : values )
1487  intValues.push_back( static_cast<int>( enumValue ) );
1488  return registerEnum( enumName, allEnums, intValues );
1489  }
1490  };
1491 
1492 } // Catch
1493 
1494 // end catch_interfaces_enum_values_registry.h
1495 
1496 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1497 #include <string_view>
1498 #endif
1499 
1500 #ifdef __OBJC__
1501 // start catch_objc_arc.hpp
1502 
1503 #import <Foundation/Foundation.h>
1504 
1505 #ifdef __has_feature
1506 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1507 #else
1508 #define CATCH_ARC_ENABLED 0
1509 #endif
1510 
1511 void arcSafeRelease( NSObject* obj );
1512 id performOptionalSelector( id obj, SEL sel );
1513 
1514 #if !CATCH_ARC_ENABLED
1515 inline void arcSafeRelease( NSObject* obj ) {
1516  [obj release];
1517 }
1518 inline id performOptionalSelector( id obj, SEL sel ) {
1519  if( [obj respondsToSelector: sel] )
1520  return [obj performSelector: sel];
1521  return nil;
1522 }
1523 #define CATCH_UNSAFE_UNRETAINED
1524 #define CATCH_ARC_STRONG
1525 #else
1526 inline void arcSafeRelease( NSObject* ){}
1527 inline id performOptionalSelector( id obj, SEL sel ) {
1528 #ifdef __clang__
1529 #pragma clang diagnostic push
1530 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1531 #endif
1532  if( [obj respondsToSelector: sel] )
1533  return [obj performSelector: sel];
1534 #ifdef __clang__
1535 #pragma clang diagnostic pop
1536 #endif
1537  return nil;
1538 }
1539 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1540 #define CATCH_ARC_STRONG __strong
1541 #endif
1542 
1543 // end catch_objc_arc.hpp
1544 #endif
1545 
1546 #ifdef _MSC_VER
1547 #pragma warning(push)
1548 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1549 #endif
1550 
1551 namespace Catch {
1552  namespace Detail {
1553 
1554  extern const std::string unprintableString;
1555 
1556  std::string rawMemoryToString( const void *object, std::size_t size );
1557 
1558  template<typename T>
1559  std::string rawMemoryToString( const T& object ) {
1560  return rawMemoryToString( &object, sizeof(object) );
1561  }
1562 
1563  template<typename T>
1565  template<typename Stream, typename U>
1566  static auto test(int)
1567  -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
1568 
1569  template<typename, typename>
1570  static auto test(...)->std::false_type;
1571 
1572  public:
1573  static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1574  };
1575 
1576  template<typename E>
1578 
1579  template<typename T>
1580  typename std::enable_if<
1584  }
1585  template<typename T>
1586  typename std::enable_if<
1589  return ex.what();
1590  }
1591 
1592  template<typename T>
1593  typename std::enable_if<
1597  }
1598 
1599 #if defined(_MANAGED)
1601  template<typename T>
1602  std::string clrReferenceToString( T^ ref ) {
1603  if (ref == nullptr)
1604  return std::string("null");
1605  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1606  cli::pin_ptr<System::Byte> p = &bytes[0];
1607  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1608  }
1609 #endif
1610 
1611  } // namespace Detail
1612 
1613  // If we decide for C++14, change these to enable_if_ts
1614  template <typename T, typename = void>
1615  struct StringMaker {
1616  template <typename Fake = T>
1617  static
1619  convert(const Fake& value) {
1621  // NB: call using the function-like syntax to avoid ambiguity with
1622  // user-defined templated operator<< under clang.
1623  rss.operator<<(value);
1624  return rss.str();
1625  }
1626 
1627  template <typename Fake = T>
1628  static
1630  convert( const Fake& value ) {
1631 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1633 #else
1634  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1635 #endif
1636  }
1637  };
1638 
1639  namespace Detail {
1640 
1641  // This function dispatches all stringification requests inside of Catch.
1642  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1643  template <typename T>
1646  }
1647 
1648  template<typename E>
1651  }
1652 
1653 #if defined(_MANAGED)
1654  template <typename T>
1655  std::string stringify( T^ e ) {
1657  }
1658 #endif
1659 
1660  } // namespace Detail
1661 
1662  // Some predefined specializations
1663 
1664  template<>
1667  };
1668 
1669 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1670  template<>
1671  struct StringMaker<std::string_view> {
1672  static std::string convert(std::string_view str);
1673  };
1674 #endif
1675 
1676  template<>
1677  struct StringMaker<char const *> {
1678  static std::string convert(char const * str);
1679  };
1680  template<>
1681  struct StringMaker<char *> {
1682  static std::string convert(char * str);
1683  };
1684 
1685 #ifdef CATCH_CONFIG_WCHAR
1686  template<>
1687  struct StringMaker<std::wstring> {
1688  static std::string convert(const std::wstring& wstr);
1689  };
1690 
1691 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1692  template<>
1693  struct StringMaker<std::wstring_view> {
1694  static std::string convert(std::wstring_view str);
1695  };
1696 # endif
1697 
1698  template<>
1699  struct StringMaker<wchar_t const *> {
1700  static std::string convert(wchar_t const * str);
1701  };
1702  template<>
1703  struct StringMaker<wchar_t *> {
1704  static std::string convert(wchar_t * str);
1705  };
1706 #endif
1707 
1708  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1709  // while keeping string semantics?
1710  template<int SZ>
1711  struct StringMaker<char[SZ]> {
1712  static std::string convert(char const* str) {
1714  }
1715  };
1716  template<int SZ>
1717  struct StringMaker<signed char[SZ]> {
1718  static std::string convert(signed char const* str) {
1719  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1720  }
1721  };
1722  template<int SZ>
1723  struct StringMaker<unsigned char[SZ]> {
1724  static std::string convert(unsigned char const* str) {
1725  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1726  }
1727  };
1728 
1729 #if defined(CATCH_CONFIG_CPP17_BYTE)
1730  template<>
1731  struct StringMaker<std::byte> {
1732  static std::string convert(std::byte value);
1733  };
1734 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
1735  template<>
1736  struct StringMaker<int> {
1738  };
1739  template<>
1740  struct StringMaker<long> {
1741  static std::string convert(long value);
1742  };
1743  template<>
1744  struct StringMaker<long long> {
1745  static std::string convert(long long value);
1746  };
1747  template<>
1748  struct StringMaker<unsigned int> {
1749  static std::string convert(unsigned int value);
1750  };
1751  template<>
1752  struct StringMaker<unsigned long> {
1753  static std::string convert(unsigned long value);
1754  };
1755  template<>
1756  struct StringMaker<unsigned long long> {
1757  static std::string convert(unsigned long long value);
1758  };
1759 
1760  template<>
1761  struct StringMaker<bool> {
1762  static std::string convert(bool b);
1763  };
1764 
1765  template<>
1766  struct StringMaker<char> {
1767  static std::string convert(char c);
1768  };
1769  template<>
1770  struct StringMaker<signed char> {
1771  static std::string convert(signed char c);
1772  };
1773  template<>
1774  struct StringMaker<unsigned char> {
1775  static std::string convert(unsigned char c);
1776  };
1777 
1778  template<>
1779  struct StringMaker<std::nullptr_t> {
1780  static std::string convert(std::nullptr_t);
1781  };
1782 
1783  template<>
1784  struct StringMaker<float> {
1785  static std::string convert(float value);
1786  static int precision;
1787  };
1788 
1789  template<>
1790  struct StringMaker<double> {
1791  static std::string convert(double value);
1792  static int precision;
1793  };
1794 
1795  template <typename T>
1796  struct StringMaker<T*> {
1797  template <typename U>
1798  static std::string convert(U* p) {
1799  if (p) {
1801  } else {
1802  return "nullptr";
1803  }
1804  }
1805  };
1806 
1807  template <typename R, typename C>
1808  struct StringMaker<R C::*> {
1809  static std::string convert(R C::* p) {
1810  if (p) {
1812  } else {
1813  return "nullptr";
1814  }
1815  }
1816  };
1817 
1818 #if defined(_MANAGED)
1819  template <typename T>
1820  struct StringMaker<T^> {
1821  static std::string convert( T^ ref ) {
1822  return ::Catch::Detail::clrReferenceToString(ref);
1823  }
1824  };
1825 #endif
1826 
1827  namespace Detail {
1828  template<typename InputIterator, typename Sentinel = InputIterator>
1829  std::string rangeToString(InputIterator first, Sentinel last) {
1831  rss << "{ ";
1832  if (first != last) {
1834  for (++first; first != last; ++first)
1835  rss << ", " << ::Catch::Detail::stringify(*first);
1836  }
1837  rss << " }";
1838  return rss.str();
1839  }
1840  }
1841 
1842 #ifdef __OBJC__
1843  template<>
1844  struct StringMaker<NSString*> {
1845  static std::string convert(NSString * nsstring) {
1846  if (!nsstring)
1847  return "nil";
1848  return std::string("@") + [nsstring UTF8String];
1849  }
1850  };
1851  template<>
1852  struct StringMaker<NSObject*> {
1853  static std::string convert(NSObject* nsObject) {
1854  return ::Catch::Detail::stringify([nsObject description]);
1855  }
1856 
1857  };
1858  namespace Detail {
1859  inline std::string stringify( NSString* nsstring ) {
1860  return StringMaker<NSString*>::convert( nsstring );
1861  }
1862 
1863  } // namespace Detail
1864 #endif // __OBJC__
1865 
1866 } // namespace Catch
1867 
1869 // Separate std-lib types stringification, so it can be selectively enabled
1870 // This means that we do not bring in
1871 
1872 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1873 # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1874 # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1875 # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1876 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1877 # define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1878 #endif
1879 
1880 // Separate std::pair specialization
1881 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1882 #include <utility>
1883 namespace Catch {
1884  template<typename T1, typename T2>
1885  struct StringMaker<std::pair<T1, T2> > {
1886  static std::string convert(const std::pair<T1, T2>& pair) {
1887  ReusableStringStream rss;
1888  rss << "{ "
1889  << ::Catch::Detail::stringify(pair.first)
1890  << ", "
1891  << ::Catch::Detail::stringify(pair.second)
1892  << " }";
1893  return rss.str();
1894  }
1895  };
1896 }
1897 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1898 
1899 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
1900 #include <optional>
1901 namespace Catch {
1902  template<typename T>
1903  struct StringMaker<std::optional<T> > {
1904  static std::string convert(const std::optional<T>& optional) {
1905  ReusableStringStream rss;
1906  if (optional.has_value()) {
1907  rss << ::Catch::Detail::stringify(*optional);
1908  } else {
1909  rss << "{ }";
1910  }
1911  return rss.str();
1912  }
1913  };
1914 }
1915 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1916 
1917 // Separate std::tuple specialization
1918 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1919 #include <tuple>
1920 namespace Catch {
1921  namespace Detail {
1922  template<
1923  typename Tuple,
1924  std::size_t N = 0,
1926  >
1927  struct TupleElementPrinter {
1928  static void print(const Tuple& tuple, std::ostream& os) {
1929  os << (N ? ", " : " ")
1930  << ::Catch::Detail::stringify(std::get<N>(tuple));
1931  TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1932  }
1933  };
1934 
1935  template<
1936  typename Tuple,
1937  std::size_t N
1938  >
1939  struct TupleElementPrinter<Tuple, N, false> {
1940  static void print(const Tuple&, std::ostream&) {}
1941  };
1942 
1943  }
1944 
1945  template<typename ...Types>
1946  struct StringMaker<std::tuple<Types...>> {
1947  static std::string convert(const std::tuple<Types...>& tuple) {
1948  ReusableStringStream rss;
1949  rss << '{';
1950  Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1951  rss << " }";
1952  return rss.str();
1953  }
1954  };
1955 }
1956 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1957 
1958 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1959 #include <variant>
1960 namespace Catch {
1961  template<>
1962  struct StringMaker<std::monostate> {
1963  static std::string convert(const std::monostate&) {
1964  return "{ }";
1965  }
1966  };
1967 
1968  template<typename... Elements>
1969  struct StringMaker<std::variant<Elements...>> {
1970  static std::string convert(const std::variant<Elements...>& variant) {
1971  if (variant.valueless_by_exception()) {
1972  return "{valueless variant}";
1973  } else {
1974  return std::visit(
1975  [](const auto& value) {
1977  },
1978  variant
1979  );
1980  }
1981  }
1982  };
1983 }
1984 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1985 
1986 namespace Catch {
1987  // Import begin/ end from std here
1988  using std::begin;
1989  using std::end;
1990 
1991  namespace detail {
1992  template <typename...>
1993  struct void_type {
1994  using type = void;
1995  };
1996 
1997  template <typename T, typename = void>
1998  struct is_range_impl : std::false_type {
1999  };
2000 
2001  template <typename T>
2003  };
2004  } // namespace detail
2005 
2006  template <typename T>
2008  };
2009 
2010 #if defined(_MANAGED) // Managed types are never ranges
2011  template <typename T>
2012  struct is_range<T^> {
2013  static const bool value = false;
2014  };
2015 #endif
2016 
2017  template<typename Range>
2018  std::string rangeToString( Range const& range ) {
2020  }
2021 
2022  // Handle vector<bool> specially
2023  template<typename Allocator>
2024  std::string rangeToString( std::vector<bool, Allocator> const& v ) {
2026  rss << "{ ";
2027  bool first = true;
2028  for( bool b : v ) {
2029  if( first )
2030  first = false;
2031  else
2032  rss << ", ";
2033  rss << ::Catch::Detail::stringify( b );
2034  }
2035  rss << " }";
2036  return rss.str();
2037  }
2038 
2039  template<typename R>
2040  struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
2041  static std::string convert( R const& range ) {
2042  return rangeToString( range );
2043  }
2044  };
2045 
2046  template <typename T, int SZ>
2047  struct StringMaker<T[SZ]> {
2048  static std::string convert(T const(&arr)[SZ]) {
2049  return rangeToString(arr);
2050  }
2051  };
2052 
2053 } // namespace Catch
2054 
2055 // Separate std::chrono::duration specialization
2056 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2057 #include <ctime>
2058 #include <ratio>
2059 #include <chrono>
2060 
2061 namespace Catch {
2062 
2063 template <class Ratio>
2064 struct ratio_string {
2065  static std::string symbol();
2066 };
2067 
2068 template <class Ratio>
2069 std::string ratio_string<Ratio>::symbol() {
2071  rss << '[' << Ratio::num << '/'
2072  << Ratio::den << ']';
2073  return rss.str();
2074 }
2075 template <>
2076 struct ratio_string<std::atto> {
2077  static std::string symbol();
2078 };
2079 template <>
2080 struct ratio_string<std::femto> {
2081  static std::string symbol();
2082 };
2083 template <>
2084 struct ratio_string<std::pico> {
2085  static std::string symbol();
2086 };
2087 template <>
2088 struct ratio_string<std::nano> {
2089  static std::string symbol();
2090 };
2091 template <>
2092 struct ratio_string<std::micro> {
2093  static std::string symbol();
2094 };
2095 template <>
2096 struct ratio_string<std::milli> {
2097  static std::string symbol();
2098 };
2099 
2101  // std::chrono::duration specializations
2102  template<typename Value, typename Ratio>
2103  struct StringMaker<std::chrono::duration<Value, Ratio>> {
2104  static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
2105  ReusableStringStream rss;
2106  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2107  return rss.str();
2108  }
2109  };
2110  template<typename Value>
2111  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2112  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
2113  ReusableStringStream rss;
2114  rss << duration.count() << " s";
2115  return rss.str();
2116  }
2117  };
2118  template<typename Value>
2119  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2120  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
2121  ReusableStringStream rss;
2122  rss << duration.count() << " m";
2123  return rss.str();
2124  }
2125  };
2126  template<typename Value>
2127  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2128  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
2129  ReusableStringStream rss;
2130  rss << duration.count() << " h";
2131  return rss.str();
2132  }
2133  };
2134 
2136  // std::chrono::time_point specialization
2137  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2138  template<typename Clock, typename Duration>
2139  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2140  static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
2141  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2142  }
2143  };
2144  // std::chrono::time_point<system_clock> specialization
2145  template<typename Duration>
2146  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
2147  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
2148  auto converted = std::chrono::system_clock::to_time_t(time_point);
2149 
2150 #ifdef _MSC_VER
2151  std::tm timeInfo = {};
2152  gmtime_s(&timeInfo, &converted);
2153 #else
2154  std::tm* timeInfo = std::gmtime(&converted);
2155 #endif
2156 
2157  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2158  char timeStamp[timeStampSize];
2159  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
2160 
2161 #ifdef _MSC_VER
2162  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2163 #else
2164  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2165 #endif
2166  return std::string(timeStamp);
2167  }
2168  };
2169 }
2170 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2171 
2172 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
2173 namespace Catch { \
2174  template<> struct StringMaker<enumName> { \
2175  static std::string convert( enumName value ) { \
2176  static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
2177  return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
2178  } \
2179  }; \
2180 }
2181 
2182 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
2183 
2184 #ifdef _MSC_VER
2185 #pragma warning(pop)
2186 #endif
2187 
2188 // end catch_tostring.h
2189 #include <iosfwd>
2190 
2191 #ifdef _MSC_VER
2192 #pragma warning(push)
2193 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
2194 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
2195 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2196 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
2197 #pragma warning(disable:4800) // Forcing result to true or false
2198 #endif
2199 
2200 namespace Catch {
2201 
2203  auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
2204  auto getResult() const -> bool { return m_result; }
2205  virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
2206 
2209  m_result( result )
2210  {}
2211 
2212  // We don't actually need a virtual destructor, but many static analysers
2213  // complain if it's not here :-(
2215 
2217  bool m_result;
2218 
2219  };
2220 
2221  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
2222 
2223  template<typename LhsT, typename RhsT>
2225  LhsT m_lhs;
2226  StringRef m_op;
2227  RhsT m_rhs;
2228 
2229  void streamReconstructedExpression( std::ostream &os ) const override {
2231  ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
2232  }
2233 
2234  public:
2235  BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
2236  : ITransientExpression{ true, comparisonResult },
2237  m_lhs( lhs ),
2238  m_op( op ),
2239  m_rhs( rhs )
2240  {}
2241 
2242  template<typename T>
2244  static_assert(always_false<T>::value,
2245  "chained comparisons are not supported inside assertions, "
2246  "wrap the expression inside parentheses, or decompose it");
2247  }
2248 
2249  template<typename T>
2251  static_assert(always_false<T>::value,
2252  "chained comparisons are not supported inside assertions, "
2253  "wrap the expression inside parentheses, or decompose it");
2254  }
2255 
2256  template<typename T>
2258  static_assert(always_false<T>::value,
2259  "chained comparisons are not supported inside assertions, "
2260  "wrap the expression inside parentheses, or decompose it");
2261  }
2262 
2263  template<typename T>
2265  static_assert(always_false<T>::value,
2266  "chained comparisons are not supported inside assertions, "
2267  "wrap the expression inside parentheses, or decompose it");
2268  }
2269 
2270  template<typename T>
2272  static_assert(always_false<T>::value,
2273  "chained comparisons are not supported inside assertions, "
2274  "wrap the expression inside parentheses, or decompose it");
2275  }
2276 
2277  template<typename T>
2279  static_assert(always_false<T>::value,
2280  "chained comparisons are not supported inside assertions, "
2281  "wrap the expression inside parentheses, or decompose it");
2282  }
2283 
2284  template<typename T>
2286  static_assert(always_false<T>::value,
2287  "chained comparisons are not supported inside assertions, "
2288  "wrap the expression inside parentheses, or decompose it");
2289  }
2290 
2291  template<typename T>
2293  static_assert(always_false<T>::value,
2294  "chained comparisons are not supported inside assertions, "
2295  "wrap the expression inside parentheses, or decompose it");
2296  }
2297  };
2298 
2299  template<typename LhsT>
2301  LhsT m_lhs;
2302 
2303  void streamReconstructedExpression( std::ostream &os ) const override {
2304  os << Catch::Detail::stringify( m_lhs );
2305  }
2306 
2307  public:
2308  explicit UnaryExpr( LhsT lhs )
2309  : ITransientExpression{ false, static_cast<bool>(lhs) },
2310  m_lhs( lhs )
2311  {}
2312  };
2313 
2314  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2315  template<typename LhsT, typename RhsT>
2316  auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
2317  template<typename T>
2318  auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2319  template<typename T>
2320  auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2321  template<typename T>
2322  auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2323  template<typename T>
2324  auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2325 
2326  template<typename LhsT, typename RhsT>
2327  auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
2328  template<typename T>
2329  auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2330  template<typename T>
2331  auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2332  template<typename T>
2333  auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2334  template<typename T>
2335  auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2336 
2337  template<typename LhsT>
2338  class ExprLhs {
2339  LhsT m_lhs;
2340  public:
2341  explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
2342 
2343  template<typename RhsT>
2344  auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2345  return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
2346  }
2347  auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2348  return { m_lhs == rhs, m_lhs, "==", rhs };
2349  }
2350 
2351  template<typename RhsT>
2352  auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2353  return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
2354  }
2355  auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2356  return { m_lhs != rhs, m_lhs, "!=", rhs };
2357  }
2358 
2359  template<typename RhsT>
2360  auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2361  return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
2362  }
2363  template<typename RhsT>
2364  auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2365  return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
2366  }
2367  template<typename RhsT>
2368  auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2369  return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
2370  }
2371  template<typename RhsT>
2372  auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2373  return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
2374  }
2375  template <typename RhsT>
2376  auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2377  return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
2378  }
2379  template <typename RhsT>
2380  auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2381  return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
2382  }
2383  template <typename RhsT>
2384  auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2385  return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
2386  }
2387 
2388  template<typename RhsT>
2389  auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2390  static_assert(always_false<RhsT>::value,
2391  "operator&& is not supported inside assertions, "
2392  "wrap the expression inside parentheses, or decompose it");
2393  }
2394 
2395  template<typename RhsT>
2396  auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2397  static_assert(always_false<RhsT>::value,
2398  "operator|| is not supported inside assertions, "
2399  "wrap the expression inside parentheses, or decompose it");
2400  }
2401 
2402  auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
2403  return UnaryExpr<LhsT>{ m_lhs };
2404  }
2405  };
2406 
2408 
2409  template<typename T>
2410  void handleExpression( ExprLhs<T> const& expr ) {
2411  handleExpression( expr.makeUnaryExpr() );
2412  }
2413 
2414  struct Decomposer {
2415  template<typename T>
2416  auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
2417  return ExprLhs<T const&>{ lhs };
2418  }
2419 
2420  auto operator <=( bool value ) -> ExprLhs<bool> {
2421  return ExprLhs<bool>{ value };
2422  }
2423  };
2424 
2425 } // end namespace Catch
2426 
2427 #ifdef _MSC_VER
2428 #pragma warning(pop)
2429 #endif
2430 
2431 // end catch_decomposer.h
2432 // start catch_interfaces_capture.h
2433 
2434 #include <string>
2435 #include <chrono>
2436 
2437 namespace Catch {
2438 
2439  class AssertionResult;
2440  struct AssertionInfo;
2441  struct SectionInfo;
2442  struct SectionEndInfo;
2443  struct MessageInfo;
2444  struct MessageBuilder;
2445  struct Counts;
2446  struct AssertionReaction;
2447  struct SourceLineInfo;
2448 
2449  struct ITransientExpression;
2450  struct IGeneratorTracker;
2451 
2452 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2453  struct BenchmarkInfo;
2454  template <typename Duration = std::chrono::duration<double, std::nano>>
2455  struct BenchmarkStats;
2456 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2457 
2459 
2460  virtual ~IResultCapture();
2461 
2462  virtual bool sectionStarted( SectionInfo const& sectionInfo,
2463  Counts& assertions ) = 0;
2464  virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2465  virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2466 
2467  virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
2468 
2469 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2470  virtual void benchmarkPreparing( std::string const& name ) = 0;
2471  virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
2472  virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
2473  virtual void benchmarkFailed( std::string const& error ) = 0;
2474 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2475 
2476  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2477  virtual void popScopedMessage( MessageInfo const& message ) = 0;
2478 
2479  virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
2480 
2482 
2483  virtual void handleExpr
2484  ( AssertionInfo const& info,
2485  ITransientExpression const& expr,
2486  AssertionReaction& reaction ) = 0;
2487  virtual void handleMessage
2488  ( AssertionInfo const& info,
2489  ResultWas::OfType resultType,
2490  StringRef const& message,
2491  AssertionReaction& reaction ) = 0;
2493  ( AssertionInfo const& info,
2494  AssertionReaction& reaction ) = 0;
2496  ( AssertionInfo const& info,
2497  std::string const& message,
2498  AssertionReaction& reaction ) = 0;
2499  virtual void handleIncomplete
2500  ( AssertionInfo const& info ) = 0;
2501  virtual void handleNonExpr
2502  ( AssertionInfo const &info,
2503  ResultWas::OfType resultType,
2504  AssertionReaction &reaction ) = 0;
2505 
2506  virtual bool lastAssertionPassed() = 0;
2507  virtual void assertionPassed() = 0;
2508 
2509  // Deprecated, do not use:
2510  virtual std::string getCurrentTestName() const = 0;
2511  virtual const AssertionResult* getLastResult() const = 0;
2512  virtual void exceptionEarlyReported() = 0;
2513  };
2514 
2516 }
2517 
2518 // end catch_interfaces_capture.h
2519 namespace Catch {
2520 
2522  struct AssertionResultData;
2523  struct IResultCapture;
2524  class RunContext;
2525 
2527  friend class AssertionHandler;
2528  friend struct AssertionStats;
2529  friend class RunContext;
2530 
2531  ITransientExpression const* m_transientExpression = nullptr;
2532  bool m_isNegated;
2533  public:
2534  LazyExpression( bool isNegated );
2537 
2538  explicit operator bool() const;
2539 
2540  friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
2541  };
2542 
2544  bool shouldDebugBreak = false;
2545  bool shouldThrow = false;
2546  };
2547 
2549  AssertionInfo m_assertionInfo;
2550  AssertionReaction m_reaction;
2551  bool m_completed = false;
2552  IResultCapture& m_resultCapture;
2553 
2554  public:
2556  ( StringRef const& macroName,
2557  SourceLineInfo const& lineInfo,
2558  StringRef capturedExpression,
2559  ResultDisposition::Flags resultDisposition );
2561  if ( !m_completed ) {
2562  m_resultCapture.handleIncomplete( m_assertionInfo );
2563  }
2564  }
2565 
2566  template<typename T>
2567  void handleExpr( ExprLhs<T> const& expr ) {
2568  handleExpr( expr.makeUnaryExpr() );
2569  }
2570  void handleExpr( ITransientExpression const& expr );
2571 
2573 
2579 
2580  void complete();
2582 
2583  // query
2584  auto allowThrows() const -> bool;
2585  };
2586 
2587  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
2588 
2589 } // namespace Catch
2590 
2591 // end catch_assertionhandler.h
2592 // start catch_message.h
2593 
2594 #include <string>
2595 #include <vector>
2596 
2597 namespace Catch {
2598 
2599  struct MessageInfo {
2600  MessageInfo( StringRef const& _macroName,
2601  SourceLineInfo const& _lineInfo,
2602  ResultWas::OfType _type );
2603 
2608  unsigned int sequence;
2609 
2610  bool operator == ( MessageInfo const& other ) const;
2611  bool operator < ( MessageInfo const& other ) const;
2612  private:
2613  static unsigned int globalCount;
2614  };
2615 
2616  struct MessageStream {
2617 
2618  template<typename T>
2620  m_stream << value;
2621  return *this;
2622  }
2623 
2625  };
2626 
2628  MessageBuilder( StringRef const& macroName,
2629  SourceLineInfo const& lineInfo,
2631 
2632  template<typename T>
2634  m_stream << value;
2635  return *this;
2636  }
2637 
2639  };
2640 
2642  public:
2643  explicit ScopedMessage( MessageBuilder const& builder );
2644  ScopedMessage( ScopedMessage& duplicate ) = delete;
2647 
2649  bool m_moved;
2650  };
2651 
2652  class Capturer {
2653  std::vector<MessageInfo> m_messages;
2654  IResultCapture& m_resultCapture = getResultCapture();
2655  size_t m_captured = 0;
2656  public:
2657  Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
2659 
2660  void captureValue( size_t index, std::string const& value );
2661 
2662  template<typename T>
2663  void captureValues( size_t index, T const& value ) {
2664  captureValue( index, Catch::Detail::stringify( value ) );
2665  }
2666 
2667  template<typename T, typename... Ts>
2668  void captureValues( size_t index, T const& value, Ts const&... values ) {
2669  captureValue( index, Catch::Detail::stringify(value) );
2670  captureValues( index+1, values... );
2671  }
2672  };
2673 
2674 } // end namespace Catch
2675 
2676 // end catch_message.h
2677 #if !defined(CATCH_CONFIG_DISABLE)
2678 
2679 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2680  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2681 #else
2682  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2683 #endif
2684 
2685 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2686 
2688 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2689 // macros.
2690 #define INTERNAL_CATCH_TRY
2691 #define INTERNAL_CATCH_CATCH( capturer )
2692 
2693 #else // CATCH_CONFIG_FAST_COMPILE
2694 
2695 #define INTERNAL_CATCH_TRY try
2696 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
2697 
2698 #endif
2699 
2700 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
2701 
2703 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2704  do { \
2705  CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
2706  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2707  INTERNAL_CATCH_TRY { \
2708  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2709  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2710  catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
2711  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
2712  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2713  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2714  } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
2715 
2717 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
2718  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2719  if( Catch::getResultCapture().lastAssertionPassed() )
2720 
2722 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
2723  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2724  if( !Catch::getResultCapture().lastAssertionPassed() )
2725 
2727 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2728  do { \
2729  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2730  try { \
2731  static_cast<void>(__VA_ARGS__); \
2732  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
2733  } \
2734  catch( ... ) { \
2735  catchAssertionHandler.handleUnexpectedInflightException(); \
2736  } \
2737  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2738  } while( false )
2739 
2741 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2742  do { \
2743  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
2744  if( catchAssertionHandler.allowThrows() ) \
2745  try { \
2746  static_cast<void>(__VA_ARGS__); \
2747  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2748  } \
2749  catch( ... ) { \
2750  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2751  } \
2752  else \
2753  catchAssertionHandler.handleThrowingCallSkipped(); \
2754  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2755  } while( false )
2756 
2758 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2759  do { \
2760  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2761  if( catchAssertionHandler.allowThrows() ) \
2762  try { \
2763  static_cast<void>(expr); \
2764  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2765  } \
2766  catch( exceptionType const& ) { \
2767  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2768  } \
2769  catch( ... ) { \
2770  catchAssertionHandler.handleUnexpectedInflightException(); \
2771  } \
2772  else \
2773  catchAssertionHandler.handleThrowingCallSkipped(); \
2774  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2775  } while( false )
2776 
2778 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2779  do { \
2780  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
2781  catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
2782  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2783  } while( false )
2784 
2786 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
2787  auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
2788  varName.captureValues( 0, __VA_ARGS__ )
2789 
2791 #define INTERNAL_CATCH_INFO( macroName, log ) \
2792  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
2793 
2795 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
2796  Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
2797 
2799 // Although this is matcher-based, it can be used with just a string
2800 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
2801  do { \
2802  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2803  if( catchAssertionHandler.allowThrows() ) \
2804  try { \
2805  static_cast<void>(__VA_ARGS__); \
2806  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2807  } \
2808  catch( ... ) { \
2809  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
2810  } \
2811  else \
2812  catchAssertionHandler.handleThrowingCallSkipped(); \
2813  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2814  } while( false )
2815 
2816 #endif // CATCH_CONFIG_DISABLE
2817 
2818 // end catch_capture.hpp
2819 // start catch_section.h
2820 
2821 // start catch_section_info.h
2822 
2823 // start catch_totals.h
2824 
2825 #include <cstddef>
2826 
2827 namespace Catch {
2828 
2829  struct Counts {
2830  Counts operator - ( Counts const& other ) const;
2832 
2833  std::size_t total() const;
2834  bool allPassed() const;
2835  bool allOk() const;
2836 
2837  std::size_t passed = 0;
2838  std::size_t failed = 0;
2839  std::size_t failedButOk = 0;
2840  };
2841 
2842  struct Totals {
2843 
2844  Totals operator - ( Totals const& other ) const;
2846 
2847  Totals delta( Totals const& prevTotals ) const;
2848 
2849  int error = 0;
2852  };
2853 }
2854 
2855 // end catch_totals.h
2856 #include <string>
2857 
2858 namespace Catch {
2859 
2860  struct SectionInfo {
2862  ( SourceLineInfo const& _lineInfo,
2863  std::string const& _name );
2864 
2865  // Deprecated
2867  ( SourceLineInfo const& _lineInfo,
2868  std::string const& _name,
2869  std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2870 
2872  std::string description; // !Deprecated: this will always be empty
2874  };
2875 
2880  };
2881 
2882 } // end namespace Catch
2883 
2884 // end catch_section_info.h
2885 // start catch_timer.h
2886 
2887 #include <cstdint>
2888 
2889 namespace Catch {
2890 
2892  auto getEstimatedClockResolution() -> uint64_t;
2893 
2894  class Timer {
2895  uint64_t m_nanoseconds = 0;
2896  public:
2897  void start();
2898  auto getElapsedNanoseconds() const -> uint64_t;
2899  auto getElapsedMicroseconds() const -> uint64_t;
2900  auto getElapsedMilliseconds() const -> unsigned int;
2901  auto getElapsedSeconds() const -> double;
2902  };
2903 
2904 } // namespace Catch
2905 
2906 // end catch_timer.h
2907 #include <string>
2908 
2909 namespace Catch {
2910 
2912  public:
2915 
2916  // This indicates whether the section should be executed or not
2917  explicit operator bool() const;
2918 
2919  private:
2920  SectionInfo m_info;
2921 
2922  std::string m_name;
2923  Counts m_assertions;
2924  bool m_sectionIncluded;
2925  Timer m_timer;
2926  };
2927 
2928 } // end namespace Catch
2929 
2930 #define INTERNAL_CATCH_SECTION( ... ) \
2931  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2932  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2933  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2934  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2935 
2936 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2937  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2938  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2939  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2940  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2941 
2942 // end catch_section.h
2943 // start catch_interfaces_exception.h
2944 
2945 // start catch_interfaces_registry_hub.h
2946 
2947 #include <string>
2948 #include <memory>
2949 
2950 namespace Catch {
2951 
2952  class TestCase;
2953  struct ITestCaseRegistry;
2954  struct IExceptionTranslatorRegistry;
2955  struct IExceptionTranslator;
2956  struct IReporterRegistry;
2957  struct IReporterFactory;
2958  struct ITagAliasRegistry;
2959  struct IMutableEnumValuesRegistry;
2960 
2961  class StartupExceptionRegistry;
2962 
2963  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2964 
2965  struct IRegistryHub {
2966  virtual ~IRegistryHub();
2967 
2968  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2969  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2970  virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2972 
2973  virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2974  };
2975 
2978  virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2979  virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2980  virtual void registerTest( TestCase const& testInfo ) = 0;
2981  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2982  virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2983  virtual void registerStartupException() noexcept = 0;
2984  virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
2985  };
2986 
2989  void cleanUp();
2991 
2992 }
2993 
2994 // end catch_interfaces_registry_hub.h
2995 #if defined(CATCH_CONFIG_DISABLE)
2996  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
2997  static std::string translatorName( signature )
2998 #endif
2999 
3000 #include <exception>
3001 #include <string>
3002 #include <vector>
3003 
3004 namespace Catch {
3006 
3007  struct IExceptionTranslator;
3008  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
3009 
3013  };
3014 
3017 
3019  };
3020 
3022  template<typename T>
3023  class ExceptionTranslator : public IExceptionTranslator {
3024  public:
3025 
3026  ExceptionTranslator( std::string(*translateFunction)( T& ) )
3027  : m_translateFunction( translateFunction )
3028  {}
3029 
3031 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3032  return "";
3033 #else
3034  try {
3035  if( it == itEnd )
3036  std::rethrow_exception(std::current_exception());
3037  else
3038  return (*it)->translate( it+1, itEnd );
3039  }
3040  catch( T& ex ) {
3041  return m_translateFunction( ex );
3042  }
3043 #endif
3044  }
3045 
3046  protected:
3047  std::string(*m_translateFunction)( T& );
3048  };
3049 
3050  public:
3051  template<typename T>
3052  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
3054  ( new ExceptionTranslator<T>( translateFunction ) );
3055  }
3056  };
3057 }
3058 
3060 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
3061  static std::string translatorName( signature ); \
3062  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3063  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
3064  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
3065  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
3066  static std::string translatorName( signature )
3067 
3068 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
3069 
3070 // end catch_interfaces_exception.h
3071 // start catch_approx.h
3072 
3073 #include <type_traits>
3074 
3075 namespace Catch {
3076 namespace Detail {
3077 
3078  class Approx {
3079  private:
3080  bool equalityComparisonImpl(double other) const;
3081  // Validates the new margin (margin >= 0)
3082  // out-of-line to avoid including stdexcept in the header
3083  void setMargin(double margin);
3084  // Validates the new epsilon (0 < epsilon < 1)
3085  // out-of-line to avoid including stdexcept in the header
3086  void setEpsilon(double epsilon);
3087 
3088  public:
3089  explicit Approx ( double value );
3090 
3091  static Approx custom();
3092 
3094 
3096  Approx operator()( T const& value ) const {
3097  Approx approx( static_cast<double>(value) );
3098  approx.m_epsilon = m_epsilon;
3099  approx.m_margin = m_margin;
3100  approx.m_scale = m_scale;
3101  return approx;
3102  }
3103 
3105  explicit Approx( T const& value ): Approx(static_cast<double>(value))
3106  {}
3107 
3109  friend bool operator == ( const T& lhs, Approx const& rhs ) {
3110  auto lhs_v = static_cast<double>(lhs);
3111  return rhs.equalityComparisonImpl(lhs_v);
3112  }
3113 
3115  friend bool operator == ( Approx const& lhs, const T& rhs ) {
3116  return operator==( rhs, lhs );
3117  }
3118 
3120  friend bool operator != ( T const& lhs, Approx const& rhs ) {
3121  return !operator==( lhs, rhs );
3122  }
3123 
3125  friend bool operator != ( Approx const& lhs, T const& rhs ) {
3126  return !operator==( rhs, lhs );
3127  }
3128 
3130  friend bool operator <= ( T const& lhs, Approx const& rhs ) {
3131  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3132  }
3133 
3135  friend bool operator <= ( Approx const& lhs, T const& rhs ) {
3136  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3137  }
3138 
3140  friend bool operator >= ( T const& lhs, Approx const& rhs ) {
3141  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3142  }
3143 
3145  friend bool operator >= ( Approx const& lhs, T const& rhs ) {
3146  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3147  }
3148 
3150  Approx& epsilon( T const& newEpsilon ) {
3151  double epsilonAsDouble = static_cast<double>(newEpsilon);
3152  setEpsilon(epsilonAsDouble);
3153  return *this;
3154  }
3155 
3157  Approx& margin( T const& newMargin ) {
3158  double marginAsDouble = static_cast<double>(newMargin);
3159  setMargin(marginAsDouble);
3160  return *this;
3161  }
3162 
3164  Approx& scale( T const& newScale ) {
3165  m_scale = static_cast<double>(newScale);
3166  return *this;
3167  }
3168 
3170 
3171  private:
3172  double m_epsilon;
3173  double m_margin;
3174  double m_scale;
3175  double m_value;
3176  };
3177 } // end namespace Detail
3178 
3179 namespace literals {
3180  Detail::Approx operator "" _a(long double val);
3181  Detail::Approx operator "" _a(unsigned long long val);
3182 } // end namespace literals
3183 
3184 template<>
3187 };
3188 
3189 } // end namespace Catch
3190 
3191 // end catch_approx.h
3192 // start catch_string_manip.h
3193 
3194 #include <string>
3195 #include <iosfwd>
3196 #include <vector>
3197 
3198 namespace Catch {
3199 
3200  bool startsWith( std::string const& s, std::string const& prefix );
3201  bool startsWith( std::string const& s, char prefix );
3202  bool endsWith( std::string const& s, std::string const& suffix );
3203  bool endsWith( std::string const& s, char suffix );
3204  bool contains( std::string const& s, std::string const& infix );
3211 
3212  // !!! Be aware, returns refs into original string - make sure original string outlives them
3213  std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
3214  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
3215 
3216  struct pluralise {
3217  pluralise( std::size_t count, std::string const& label );
3218 
3219  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
3220 
3221  std::size_t m_count;
3223  };
3224 }
3225 
3226 // end catch_string_manip.h
3227 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
3228 // start catch_capture_matchers.h
3229 
3230 // start catch_matchers.h
3231 
3232 #include <string>
3233 #include <vector>
3234 
3235 namespace Catch {
3236 namespace Matchers {
3237  namespace Impl {
3238 
3239  template<typename ArgT> struct MatchAllOf;
3240  template<typename ArgT> struct MatchAnyOf;
3241  template<typename ArgT> struct MatchNotOf;
3242 
3244  public:
3245  MatcherUntypedBase() = default;
3247  MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
3249 
3250  protected:
3252  virtual std::string describe() const = 0;
3254  };
3255 
3256 #ifdef __clang__
3257 # pragma clang diagnostic push
3258 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
3259 #endif
3260 
3261  template<typename ObjectT>
3262  struct MatcherMethod {
3263  virtual bool match( ObjectT const& arg ) const = 0;
3264  };
3265 
3266 #if defined(__OBJC__)
3267  // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
3268  // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
3269  template<>
3270  struct MatcherMethod<NSString*> {
3271  virtual bool match( NSString* arg ) const = 0;
3272  };
3273 #endif
3274 
3275 #ifdef __clang__
3276 # pragma clang diagnostic pop
3277 #endif
3278 
3279  template<typename T>
3281 
3282  MatchAllOf<T> operator && ( MatcherBase const& other ) const;
3283  MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
3285  };
3286 
3287  template<typename ArgT>
3288  struct MatchAllOf : MatcherBase<ArgT> {
3289  bool match( ArgT const& arg ) const override {
3290  for( auto matcher : m_matchers ) {
3291  if (!matcher->match(arg))
3292  return false;
3293  }
3294  return true;
3295  }
3296  std::string describe() const override {
3297  std::string description;
3298  description.reserve( 4 + m_matchers.size()*32 );
3299  description += "( ";
3300  bool first = true;
3301  for( auto matcher : m_matchers ) {
3302  if( first )
3303  first = false;
3304  else
3305  description += " and ";
3306  description += matcher->toString();
3307  }
3308  description += " )";
3309  return description;
3310  }
3311 
3312  MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
3313  auto copy(*this);
3314  copy.m_matchers.push_back( &other );
3315  return copy;
3316  }
3317 
3318  std::vector<MatcherBase<ArgT> const*> m_matchers;
3319  };
3320  template<typename ArgT>
3321  struct MatchAnyOf : MatcherBase<ArgT> {
3322 
3323  bool match( ArgT const& arg ) const override {
3324  for( auto matcher : m_matchers ) {
3325  if (matcher->match(arg))
3326  return true;
3327  }
3328  return false;
3329  }
3330  std::string describe() const override {
3331  std::string description;
3332  description.reserve( 4 + m_matchers.size()*32 );
3333  description += "( ";
3334  bool first = true;
3335  for( auto matcher : m_matchers ) {
3336  if( first )
3337  first = false;
3338  else
3339  description += " or ";
3340  description += matcher->toString();
3341  }
3342  description += " )";
3343  return description;
3344  }
3345 
3346  MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
3347  auto copy(*this);
3348  copy.m_matchers.push_back( &other );
3349  return copy;
3350  }
3351 
3352  std::vector<MatcherBase<ArgT> const*> m_matchers;
3353  };
3354 
3355  template<typename ArgT>
3356  struct MatchNotOf : MatcherBase<ArgT> {
3357 
3358  MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
3359 
3360  bool match( ArgT const& arg ) const override {
3361  return !m_underlyingMatcher.match( arg );
3362  }
3363 
3364  std::string describe() const override {
3365  return "not " + m_underlyingMatcher.toString();
3366  }
3368  };
3369 
3370  template<typename T>
3372  return MatchAllOf<T>() && *this && other;
3373  }
3374  template<typename T>
3376  return MatchAnyOf<T>() || *this || other;
3377  }
3378  template<typename T>
3380  return MatchNotOf<T>( *this );
3381  }
3382 
3383  } // namespace Impl
3384 
3385 } // namespace Matchers
3386 
3387 using namespace Matchers;
3389 
3390 } // namespace Catch
3391 
3392 // end catch_matchers.h
3393 // start catch_matchers_exception.hpp
3394 
3395 namespace Catch {
3396 namespace Matchers {
3397 namespace Exception {
3398 
3399 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
3400  std::string m_message;
3401 public:
3402 
3404  m_message(message)
3405  {}
3406 
3407  bool match(std::exception const& ex) const override;
3408 
3409  std::string describe() const override;
3410 };
3411 
3412 } // namespace Exception
3413 
3415 
3416 } // namespace Matchers
3417 } // namespace Catch
3418 
3419 // end catch_matchers_exception.hpp
3420 // start catch_matchers_floating.h
3421 
3422 namespace Catch {
3423 namespace Matchers {
3424 
3425  namespace Floating {
3426 
3427  enum class FloatingPointKind : uint8_t;
3428 
3429  struct WithinAbsMatcher : MatcherBase<double> {
3430  WithinAbsMatcher(double target, double margin);
3431  bool match(double const& matchee) const override;
3432  std::string describe() const override;
3433  private:
3434  double m_target;
3435  double m_margin;
3436  };
3437 
3438  struct WithinUlpsMatcher : MatcherBase<double> {
3439  WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
3440  bool match(double const& matchee) const override;
3441  std::string describe() const override;
3442  private:
3443  double m_target;
3444  uint64_t m_ulps;
3445  FloatingPointKind m_type;
3446  };
3447 
3448  // Given IEEE-754 format for floats and doubles, we can assume
3449  // that float -> double promotion is lossless. Given this, we can
3450  // assume that if we do the standard relative comparison of
3451  // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
3452  // the same result if we do this for floats, as if we do this for
3453  // doubles that were promoted from floats.
3454  struct WithinRelMatcher : MatcherBase<double> {
3456  bool match(double const& matchee) const override;
3457  std::string describe() const override;
3458  private:
3459  double m_target;
3460  double m_epsilon;
3461  };
3462 
3463  } // namespace Floating
3464 
3465  // The following functions create the actual matcher objects.
3466  // This allows the types to be inferred
3467  Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
3468  Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
3471  // defaults epsilon to 100*numeric_limits<double>::epsilon()
3474  // defaults epsilon to 100*numeric_limits<float>::epsilon()
3476 
3477 } // namespace Matchers
3478 } // namespace Catch
3479 
3480 // end catch_matchers_floating.h
3481 // start catch_matchers_generic.hpp
3482 
3483 #include <functional>
3484 #include <string>
3485 
3486 namespace Catch {
3487 namespace Matchers {
3488 namespace Generic {
3489 
3490 namespace Detail {
3492 }
3493 
3494 template <typename T>
3495 class PredicateMatcher : public MatcherBase<T> {
3496  std::function<bool(T const&)> m_predicate;
3497  std::string m_description;
3498 public:
3499 
3500  PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
3501  :m_predicate(std::move(elem)),
3502  m_description(Detail::finalizeDescription(descr))
3503  {}
3504 
3505  bool match( T const& item ) const override {
3506  return m_predicate(item);
3507  }
3508 
3509  std::string describe() const override {
3510  return m_description;
3511  }
3512 };
3513 
3514 } // namespace Generic
3515 
3516  // The following functions create the actual matcher objects.
3517  // The user has to explicitly specify type to the function, because
3518  // inferring std::function<bool(T const&)> is hard (but possible) and
3519  // requires a lot of TMP.
3520  template<typename T>
3521  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
3522  return Generic::PredicateMatcher<T>(predicate, description);
3523  }
3524 
3525 } // namespace Matchers
3526 } // namespace Catch
3527 
3528 // end catch_matchers_generic.hpp
3529 // start catch_matchers_string.h
3530 
3531 #include <string>
3532 
3533 namespace Catch {
3534 namespace Matchers {
3535 
3536  namespace StdString {
3537 
3539  {
3540  CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
3543 
3546  };
3547 
3548  struct StringMatcherBase : MatcherBase<std::string> {
3549  StringMatcherBase( std::string const& operation, CasedString const& comparator );
3550  std::string describe() const override;
3551 
3554  };
3555 
3557  EqualsMatcher( CasedString const& comparator );
3558  bool match( std::string const& source ) const override;
3559  };
3561  ContainsMatcher( CasedString const& comparator );
3562  bool match( std::string const& source ) const override;
3563  };
3565  StartsWithMatcher( CasedString const& comparator );
3566  bool match( std::string const& source ) const override;
3567  };
3569  EndsWithMatcher( CasedString const& comparator );
3570  bool match( std::string const& source ) const override;
3571  };
3572 
3573  struct RegexMatcher : MatcherBase<std::string> {
3575  bool match( std::string const& matchee ) const override;
3576  std::string describe() const override;
3577 
3578  private:
3579  std::string m_regex;
3580  CaseSensitive::Choice m_caseSensitivity;
3581  };
3582 
3583  } // namespace StdString
3584 
3585  // The following functions create the actual matcher objects.
3586  // This allows the types to be inferred
3587 
3593 
3594 } // namespace Matchers
3595 } // namespace Catch
3596 
3597 // end catch_matchers_string.h
3598 // start catch_matchers_vector.h
3599 
3600 #include <algorithm>
3601 
3602 namespace Catch {
3603 namespace Matchers {
3604 
3605  namespace Vector {
3606  template<typename T, typename Alloc>
3607  struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
3608 
3609  ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3610 
3611  bool match(std::vector<T, Alloc> const &v) const override {
3612  for (auto const& el : v) {
3613  if (el == m_comparator) {
3614  return true;
3615  }
3616  }
3617  return false;
3618  }
3619 
3620  std::string describe() const override {
3621  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3622  }
3623 
3624  T const& m_comparator;
3625  };
3626 
3627  template<typename T, typename AllocComp, typename AllocMatch>
3628  struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3629 
3630  ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
3631 
3632  bool match(std::vector<T, AllocMatch> const &v) const override {
3633  // !TBD: see note in EqualsMatcher
3634  if (m_comparator.size() > v.size())
3635  return false;
3636  for (auto const& comparator : m_comparator) {
3637  auto present = false;
3638  for (const auto& el : v) {
3639  if (el == comparator) {
3640  present = true;
3641  break;
3642  }
3643  }
3644  if (!present) {
3645  return false;
3646  }
3647  }
3648  return true;
3649  }
3650  std::string describe() const override {
3651  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3652  }
3653 
3654  std::vector<T, AllocComp> const& m_comparator;
3655  };
3656 
3657  template<typename T, typename AllocComp, typename AllocMatch>
3658  struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3659 
3660  EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
3661 
3662  bool match(std::vector<T, AllocMatch> const &v) const override {
3663  // !TBD: This currently works if all elements can be compared using !=
3664  // - a more general approach would be via a compare template that defaults
3665  // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
3666  // - then just call that directly
3667  if (m_comparator.size() != v.size())
3668  return false;
3669  for (std::size_t i = 0; i < v.size(); ++i)
3670  if (m_comparator[i] != v[i])
3671  return false;
3672  return true;
3673  }
3674  std::string describe() const override {
3675  return "Equals: " + ::Catch::Detail::stringify( m_comparator );
3676  }
3677  std::vector<T, AllocComp> const& m_comparator;
3678  };
3679 
3680  template<typename T, typename AllocComp, typename AllocMatch>
3681  struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3682 
3683  ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
3684 
3685  bool match(std::vector<T, AllocMatch> const &v) const override {
3686  if (m_comparator.size() != v.size())
3687  return false;
3688  for (std::size_t i = 0; i < v.size(); ++i)
3689  if (m_comparator[i] != approx(v[i]))
3690  return false;
3691  return true;
3692  }
3693  std::string describe() const override {
3694  return "is approx: " + ::Catch::Detail::stringify( m_comparator );
3695  }
3697  ApproxMatcher& epsilon( T const& newEpsilon ) {
3698  approx.epsilon(newEpsilon);
3699  return *this;
3700  }
3702  ApproxMatcher& margin( T const& newMargin ) {
3703  approx.margin(newMargin);
3704  return *this;
3705  }
3707  ApproxMatcher& scale( T const& newScale ) {
3708  approx.scale(newScale);
3709  return *this;
3710  }
3711 
3712  std::vector<T, AllocComp> const& m_comparator;
3714  };
3715 
3716  template<typename T, typename AllocComp, typename AllocMatch>
3717  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3718  UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
3719  bool match(std::vector<T, AllocMatch> const& vec) const override {
3720  if (m_target.size() != vec.size()) {
3721  return false;
3722  }
3723  return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
3724  }
3725 
3726  std::string describe() const override {
3727  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
3728  }
3729  private:
3730  std::vector<T, AllocComp> const& m_target;
3731  };
3732 
3733  } // namespace Vector
3734 
3735  // The following functions create the actual matcher objects.
3736  // This allows the types to be inferred
3737 
3738  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3739  Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
3741  }
3742 
3743  template<typename T, typename Alloc = std::allocator<T>>
3745  return Vector::ContainsElementMatcher<T, Alloc>( comparator );
3746  }
3747 
3748  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3749  Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
3751  }
3752 
3753  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3754  Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
3756  }
3757 
3758  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3761  }
3762 
3763 } // namespace Matchers
3764 } // namespace Catch
3765 
3766 // end catch_matchers_vector.h
3767 namespace Catch {
3768 
3769  template<typename ArgT, typename MatcherT>
3771  ArgT const& m_arg;
3772  MatcherT m_matcher;
3773  StringRef m_matcherString;
3774  public:
3775  MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
3776  : ITransientExpression{ true, matcher.match( arg ) },
3777  m_arg( arg ),
3778  m_matcher( matcher ),
3779  m_matcherString( matcherString )
3780  {}
3781 
3782  void streamReconstructedExpression( std::ostream &os ) const override {
3783  auto matcherAsString = m_matcher.toString();
3784  os << Catch::Detail::stringify( m_arg ) << ' ';
3785  if( matcherAsString == Detail::unprintableString )
3786  os << m_matcherString;
3787  else
3788  os << matcherAsString;
3789  }
3790  };
3791 
3793 
3794  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
3795 
3796  template<typename ArgT, typename MatcherT>
3797  auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
3798  return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
3799  }
3800 
3801 } // namespace Catch
3802 
3804 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
3805  do { \
3806  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3807  INTERNAL_CATCH_TRY { \
3808  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
3809  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
3810  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3811  } while( false )
3812 
3814 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
3815  do { \
3816  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3817  if( catchAssertionHandler.allowThrows() ) \
3818  try { \
3819  static_cast<void>(__VA_ARGS__ ); \
3820  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3821  } \
3822  catch( exceptionType const& ex ) { \
3823  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
3824  } \
3825  catch( ... ) { \
3826  catchAssertionHandler.handleUnexpectedInflightException(); \
3827  } \
3828  else \
3829  catchAssertionHandler.handleThrowingCallSkipped(); \
3830  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3831  } while( false )
3832 
3833 // end catch_capture_matchers.h
3834 #endif
3835 // start catch_generators.hpp
3836 
3837 // start catch_interfaces_generatortracker.h
3838 
3839 
3840 #include <memory>
3841 
3842 namespace Catch {
3843 
3844  namespace Generators {
3846  public:
3849  // Attempts to move the generator to the next element
3850  //
3851  // Returns true iff the move succeeded (and a valid element
3852  // can be retrieved).
3853  virtual bool next() = 0;
3854  };
3855  using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
3856 
3857  } // namespace Generators
3858 
3861  virtual auto hasGenerator() const -> bool = 0;
3862  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3863  virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3864  };
3865 
3866 } // namespace Catch
3867 
3868 // end catch_interfaces_generatortracker.h
3869 // start catch_enforce.h
3870 
3871 #include <exception>
3872 
3873 namespace Catch {
3874 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3875  template <typename Ex>
3876  [[noreturn]]
3877  void throw_exception(Ex const& e) {
3878  throw e;
3879  }
3880 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
3881  [[noreturn]]
3882  void throw_exception(std::exception const& e);
3883 #endif
3884 
3885  [[noreturn]]
3887  [[noreturn]]
3889  [[noreturn]]
3891 
3892 } // namespace Catch;
3893 
3894 #define CATCH_MAKE_MSG(...) \
3895  (Catch::ReusableStringStream() << __VA_ARGS__).str()
3896 
3897 #define CATCH_INTERNAL_ERROR(...) \
3898  Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
3899 
3900 #define CATCH_ERROR(...) \
3901  Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3902 
3903 #define CATCH_RUNTIME_ERROR(...) \
3904  Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3905 
3906 #define CATCH_ENFORCE( condition, ... ) \
3907  do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
3908 
3909 // end catch_enforce.h
3910 #include <memory>
3911 #include <vector>
3912 #include <cassert>
3913 
3914 #include <utility>
3915 #include <exception>
3916 
3917 namespace Catch {
3918 
3919 class GeneratorException : public std::exception {
3920  const char* const m_msg = "";
3921 
3922 public:
3923  GeneratorException(const char* msg):
3924  m_msg(msg)
3925  {}
3926 
3927  const char* what() const noexcept override final;
3928 };
3929 
3930 namespace Generators {
3931 
3932  // !TBD move this into its own location?
3933  namespace pf{
3934  template<typename T, typename... Args>
3935  std::unique_ptr<T> make_unique( Args&&... args ) {
3936  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3937  }
3938  }
3939 
3940  template<typename T>
3942  virtual ~IGenerator() = default;
3943 
3944  // Returns the current element of the generator
3945  //
3946  // \Precondition The generator is either freshly constructed,
3947  // or the last call to `next()` returned true
3948  virtual T const& get() const = 0;
3949  using type = T;
3950  };
3951 
3952  template<typename T>
3954  T m_value;
3955  public:
3956  SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
3957 
3958  T const& get() const override {
3959  return m_value;
3960  }
3961  bool next() override {
3962  return false;
3963  }
3964  };
3965 
3966  template<typename T>
3968  static_assert(!std::is_same<T, bool>::value,
3969  "FixedValuesGenerator does not support bools because of std::vector<bool>"
3970  "specialization, use SingleValue Generator instead.");
3971  std::vector<T> m_values;
3972  size_t m_idx = 0;
3973  public:
3974  FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3975 
3976  T const& get() const override {
3977  return m_values[m_idx];
3978  }
3979  bool next() override {
3980  ++m_idx;
3981  return m_idx < m_values.size();
3982  }
3983  };
3984 
3985  template <typename T>
3987  std::unique_ptr<IGenerator<T>> m_generator;
3988  public:
3990  m_generator(std::move(generator))
3991  {}
3992  T const& get() const {
3993  return m_generator->get();
3994  }
3995  bool next() {
3996  return m_generator->next();
3997  }
3998  };
3999 
4000  template <typename T>
4003  }
4004  template <typename T>
4005  GeneratorWrapper<T> values(std::initializer_list<T> values) {
4007  }
4008 
4009  template<typename T>
4010  class Generators : public IGenerator<T> {
4011  std::vector<GeneratorWrapper<T>> m_generators;
4012  size_t m_current = 0;
4013 
4015  m_generators.emplace_back(std::move(generator));
4016  }
4017  void populate(T&& val) {
4018  m_generators.emplace_back(value(std::forward<T>(val)));
4019  }
4020  template<typename U>
4021  void populate(U&& val) {
4022  populate(T(std::forward<U>(val)));
4023  }
4024  template<typename U, typename... Gs>
4025  void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
4026  populate(std::forward<U>(valueOrGenerator));
4027  populate(std::forward<Gs>(moreGenerators)...);
4028  }
4029 
4030  public:
4031  template <typename... Gs>
4032  Generators(Gs &&... moreGenerators) {
4033  m_generators.reserve(sizeof...(Gs));
4034  populate(std::forward<Gs>(moreGenerators)...);
4035  }
4036 
4037  T const& get() const override {
4038  return m_generators[m_current].get();
4039  }
4040 
4041  bool next() override {
4042  if (m_current >= m_generators.size()) {
4043  return false;
4044  }
4045  const bool current_status = m_generators[m_current].next();
4046  if (!current_status) {
4047  ++m_current;
4048  }
4049  return m_current < m_generators.size();
4050  }
4051  };
4052 
4053  template<typename... Ts>
4054  GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
4055  return values<std::tuple<Ts...>>( tuples );
4056  }
4057 
4058  // Tag type to signal that a generator sequence should convert arguments to a specific type
4059  template <typename T>
4060  struct as {};
4061 
4062  template<typename T, typename... Gs>
4063  auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
4064  return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
4065  }
4066  template<typename T>
4068  return Generators<T>(std::move(generator));
4069  }
4070  template<typename T, typename... Gs>
4071  auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
4072  return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
4073  }
4074  template<typename T, typename U, typename... Gs>
4075  auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
4076  return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
4077  }
4078 
4079  auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
4080 
4081  template<typename L>
4082  // Note: The type after -> is weird, because VS2015 cannot parse
4083  // the expression used in the typedef inside, when it is in
4084  // return type. Yeah.
4085  auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
4086  using UnderlyingType = typename decltype(generatorExpression())::type;
4087 
4088  IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
4089  if (!tracker.hasGenerator()) {
4090  tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
4091  }
4092 
4093  auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
4094  return generator.get();
4095  }
4096 
4097 } // namespace Generators
4098 } // namespace Catch
4099 
4100 #define GENERATE( ... ) \
4101  Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4102  CATCH_INTERNAL_LINEINFO, \
4103  [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4104 #define GENERATE_COPY( ... ) \
4105  Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4106  CATCH_INTERNAL_LINEINFO, \
4107  [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4108 #define GENERATE_REF( ... ) \
4109  Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4110  CATCH_INTERNAL_LINEINFO, \
4111  [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4112 
4113 // end catch_generators.hpp
4114 // start catch_generators_generic.hpp
4115 
4116 namespace Catch {
4117 namespace Generators {
4118 
4119  template <typename T>
4120  class TakeGenerator : public IGenerator<T> {
4121  GeneratorWrapper<T> m_generator;
4122  size_t m_returned = 0;
4123  size_t m_target;
4124  public:
4126  m_generator(std::move(generator)),
4127  m_target(target)
4128  {
4129  assert(target != 0 && "Empty generators are not allowed");
4130  }
4131  T const& get() const override {
4132  return m_generator.get();
4133  }
4134  bool next() override {
4135  ++m_returned;
4136  if (m_returned >= m_target) {
4137  return false;
4138  }
4139 
4140  const auto success = m_generator.next();
4141  // If the underlying generator does not contain enough values
4142  // then we cut short as well
4143  if (!success) {
4144  m_returned = m_target;
4145  }
4146  return success;
4147  }
4148  };
4149 
4150  template <typename T>
4153  }
4154 
4155  template <typename T, typename Predicate>
4156  class FilterGenerator : public IGenerator<T> {
4157  GeneratorWrapper<T> m_generator;
4158  Predicate m_predicate;
4159  public:
4160  template <typename P = Predicate>
4162  m_generator(std::move(generator)),
4163  m_predicate(std::forward<P>(pred))
4164  {
4165  if (!m_predicate(m_generator.get())) {
4166  // It might happen that there are no values that pass the
4167  // filter. In that case we throw an exception.
4168  auto has_initial_value = nextImpl();
4169  if (!has_initial_value) {
4170  Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
4171  }
4172  }
4173  }
4174 
4175  T const& get() const override {
4176  return m_generator.get();
4177  }
4178 
4179  bool next() override {
4180  return nextImpl();
4181  }
4182 
4183  private:
4184  bool nextImpl() {
4185  bool success = m_generator.next();
4186  if (!success) {
4187  return false;
4188  }
4189  while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
4190  return success;
4191  }
4192  };
4193 
4194  template <typename T, typename Predicate>
4196  return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
4197  }
4198 
4199  template <typename T>
4200  class RepeatGenerator : public IGenerator<T> {
4201  static_assert(!std::is_same<T, bool>::value,
4202  "RepeatGenerator currently does not support bools"
4203  "because of std::vector<bool> specialization");
4204  GeneratorWrapper<T> m_generator;
4205  mutable std::vector<T> m_returned;
4206  size_t m_target_repeats;
4207  size_t m_current_repeat = 0;
4208  size_t m_repeat_index = 0;
4209  public:
4211  m_generator(std::move(generator)),
4212  m_target_repeats(repeats)
4213  {
4214  assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
4215  }
4216 
4217  T const& get() const override {
4218  if (m_current_repeat == 0) {
4219  m_returned.push_back(m_generator.get());
4220  return m_returned.back();
4221  }
4222  return m_returned[m_repeat_index];
4223  }
4224 
4225  bool next() override {
4226  // There are 2 basic cases:
4227  // 1) We are still reading the generator
4228  // 2) We are reading our own cache
4229 
4230  // In the first case, we need to poke the underlying generator.
4231  // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
4232  if (m_current_repeat == 0) {
4233  const auto success = m_generator.next();
4234  if (!success) {
4235  ++m_current_repeat;
4236  }
4237  return m_current_repeat < m_target_repeats;
4238  }
4239 
4240  // In the second case, we need to move indices forward and check that we haven't run up against the end
4241  ++m_repeat_index;
4242  if (m_repeat_index == m_returned.size()) {
4243  m_repeat_index = 0;
4244  ++m_current_repeat;
4245  }
4246  return m_current_repeat < m_target_repeats;
4247  }
4248  };
4249 
4250  template <typename T>
4252  return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
4253  }
4254 
4255  template <typename T, typename U, typename Func>
4256  class MapGenerator : public IGenerator<T> {
4257  // TBD: provide static assert for mapping function, for friendly error message
4258  GeneratorWrapper<U> m_generator;
4259  Func m_function;
4260  // To avoid returning dangling reference, we have to save the values
4261  T m_cache;
4262  public:
4263  template <typename F2 = Func>
4265  m_generator(std::move(generator)),
4266  m_function(std::forward<F2>(function)),
4267  m_cache(m_function(m_generator.get()))
4268  {}
4269 
4270  T const& get() const override {
4271  return m_cache;
4272  }
4273  bool next() override {
4274  const auto success = m_generator.next();
4275  if (success) {
4276  m_cache = m_function(m_generator.get());
4277  }
4278  return success;
4279  }
4280  };
4281 
4282  template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
4284  return GeneratorWrapper<T>(
4285  pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4286  );
4287  }
4288 
4289  template <typename T, typename U, typename Func>
4290  GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4291  return GeneratorWrapper<T>(
4292  pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4293  );
4294  }
4295 
4296  template <typename T>
4297  class ChunkGenerator final : public IGenerator<std::vector<T>> {
4298  std::vector<T> m_chunk;
4299  size_t m_chunk_size;
4300  GeneratorWrapper<T> m_generator;
4301  bool m_used_up = false;
4302  public:
4304  m_chunk_size(size), m_generator(std::move(generator))
4305  {
4306  m_chunk.reserve(m_chunk_size);
4307  if (m_chunk_size != 0) {
4308  m_chunk.push_back(m_generator.get());
4309  for (size_t i = 1; i < m_chunk_size; ++i) {
4310  if (!m_generator.next()) {
4311  Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
4312  }
4313  m_chunk.push_back(m_generator.get());
4314  }
4315  }
4316  }
4317  std::vector<T> const& get() const override {
4318  return m_chunk;
4319  }
4320  bool next() override {
4321  m_chunk.clear();
4322  for (size_t idx = 0; idx < m_chunk_size; ++idx) {
4323  if (!m_generator.next()) {
4324  return false;
4325  }
4326  m_chunk.push_back(m_generator.get());
4327  }
4328  return true;
4329  }
4330  };
4331 
4332  template <typename T>
4335  pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
4336  );
4337  }
4338 
4339 } // namespace Generators
4340 } // namespace Catch
4341 
4342 // end catch_generators_generic.hpp
4343 // start catch_generators_specific.hpp
4344 
4345 // start catch_context.h
4346 
4347 #include <memory>
4348 
4349 namespace Catch {
4350 
4351  struct IResultCapture;
4352  struct IRunner;
4353  struct IConfig;
4354  struct IMutableContext;
4355 
4356  using IConfigPtr = std::shared_ptr<IConfig const>;
4357 
4358  struct IContext
4359  {
4360  virtual ~IContext();
4361 
4363  virtual IRunner* getRunner() = 0;
4364  virtual IConfigPtr const& getConfig() const = 0;
4365  };
4366 
4368  {
4369  virtual ~IMutableContext();
4370  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
4371  virtual void setRunner( IRunner* runner ) = 0;
4372  virtual void setConfig( IConfigPtr const& config ) = 0;
4373 
4374  private:
4375  static IMutableContext *currentContext;
4377  friend void cleanUpContext();
4378  static void createContext();
4379  };
4380 
4382  {
4383  if( !IMutableContext::currentContext )
4384  IMutableContext::createContext();
4385  // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
4386  return *IMutableContext::currentContext;
4387  }
4388 
4390  {
4391  return getCurrentMutableContext();
4392  }
4393 
4395 
4396  class SimplePcg32;
4398 }
4399 
4400 // end catch_context.h
4401 // start catch_interfaces_config.h
4402 
4403 // start catch_option.hpp
4404 
4405 namespace Catch {
4406 
4407  // An optional type
4408  template<typename T>
4409  class Option {
4410  public:
4411  Option() : nullableValue( nullptr ) {}
4412  Option( T const& _value )
4413  : nullableValue( new( storage ) T( _value ) )
4414  {}
4415  Option( Option const& _other )
4416  : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4417  {}
4418 
4420  reset();
4421  }
4422 
4423  Option& operator= ( Option const& _other ) {
4424  if( &_other != this ) {
4425  reset();
4426  if( _other )
4427  nullableValue = new( storage ) T( *_other );
4428  }
4429  return *this;
4430  }
4431  Option& operator = ( T const& _value ) {
4432  reset();
4433  nullableValue = new( storage ) T( _value );
4434  return *this;
4435  }
4436 
4437  void reset() {
4438  if( nullableValue )
4439  nullableValue->~T();
4440  nullableValue = nullptr;
4441  }
4442 
4443  T& operator*() { return *nullableValue; }
4444  T const& operator*() const { return *nullableValue; }
4445  T* operator->() { return nullableValue; }
4446  const T* operator->() const { return nullableValue; }
4447 
4448  T valueOr( T const& defaultValue ) const {
4449  return nullableValue ? *nullableValue : defaultValue;
4450  }
4451 
4452  bool some() const { return nullableValue != nullptr; }
4453  bool none() const { return nullableValue == nullptr; }
4454 
4455  bool operator !() const { return nullableValue == nullptr; }
4456  explicit operator bool() const {
4457  return some();
4458  }
4459 
4460  private:
4461  T *nullableValue;
4462  alignas(alignof(T)) char storage[sizeof(T)];
4463  };
4464 
4465 } // end namespace Catch
4466 
4467 // end catch_option.hpp
4468 #include <chrono>
4469 #include <iosfwd>
4470 #include <string>
4471 #include <vector>
4472 #include <memory>
4473 
4474 namespace Catch {
4475 
4476  enum class Verbosity {
4477  Quiet = 0,
4478  Normal,
4479  High
4480  };
4481 
4482  struct WarnAbout { enum What {
4483  Nothing = 0x00,
4484  NoAssertions = 0x01,
4485  NoTests = 0x02
4486  }; };
4487 
4488  struct ShowDurations { enum OrNot {
4491  Never
4492  }; };
4493  struct RunTests { enum InWhatOrder {
4496  InRandomOrder
4497  }; };
4498  struct UseColour { enum YesOrNo {
4501  No
4502  }; };
4503  struct WaitForKeypress { enum When {
4505  BeforeStart = 1,
4506  BeforeExit = 2,
4507  BeforeStartAndExit = BeforeStart | BeforeExit
4508  }; };
4509 
4510  class TestSpec;
4511 
4513 
4514  virtual ~IConfig();
4515 
4516  virtual bool allowThrows() const = 0;
4517  virtual std::ostream& stream() const = 0;
4518  virtual std::string name() const = 0;
4519  virtual bool includeSuccessfulResults() const = 0;
4520  virtual bool shouldDebugBreak() const = 0;
4521  virtual bool warnAboutMissingAssertions() const = 0;
4522  virtual bool warnAboutNoTests() const = 0;
4523  virtual int abortAfter() const = 0;
4524  virtual bool showInvisibles() const = 0;
4526  virtual double minDuration() const = 0;
4527  virtual TestSpec const& testSpec() const = 0;
4528  virtual bool hasTestFilters() const = 0;
4529  virtual std::vector<std::string> const& getTestsOrTags() const = 0;
4530  virtual RunTests::InWhatOrder runOrder() const = 0;
4531  virtual unsigned int rngSeed() const = 0;
4532  virtual UseColour::YesOrNo useColour() const = 0;
4533  virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4534  virtual Verbosity verbosity() const = 0;
4535 
4536  virtual bool benchmarkNoAnalysis() const = 0;
4537  virtual int benchmarkSamples() const = 0;
4538  virtual double benchmarkConfidenceInterval() const = 0;
4539  virtual unsigned int benchmarkResamples() const = 0;
4540  virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
4541  };
4542 
4543  using IConfigPtr = std::shared_ptr<IConfig const>;
4544 }
4545 
4546 // end catch_interfaces_config.h
4547 // start catch_random_number_generator.h
4548 
4549 #include <cstdint>
4550 
4551 namespace Catch {
4552 
4553  // This is a simple implementation of C++11 Uniform Random Number
4554  // Generator. It does not provide all operators, because Catch2
4555  // does not use it, but it should behave as expected inside stdlib's
4556  // distributions.
4557  // The implementation is based on the PCG family (http://pcg-random.org)
4558  class SimplePcg32 {
4559  using state_type = std::uint64_t;
4560  public:
4561  using result_type = std::uint32_t;
4562  static constexpr result_type (min)() {
4563  return 0;
4564  }
4565  static constexpr result_type (max)() {
4566  return static_cast<result_type>(-1);
4567  }
4568 
4569  // Provide some default initial state for the default constructor
4570  SimplePcg32():SimplePcg32(0xed743cc4U) {}
4571 
4572  explicit SimplePcg32(result_type seed_);
4573 
4574  void seed(result_type seed_);
4575  void discard(uint64_t skip);
4576 
4578 
4579  private:
4580  friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4581  friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4582 
4583  // In theory we also need operator<< and operator>>
4584  // In practice we do not use them, so we will skip them for now
4585 
4586  std::uint64_t m_state;
4587  // This part of the state determines which "stream" of the numbers
4588  // is chosen -- we take it as a constant for Catch2, so we only
4589  // need to deal with seeding the main state.
4590  // Picked by reading 8 bytes from `/dev/random` :-)
4591  static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
4592  };
4593 
4594 } // end namespace Catch
4595 
4596 // end catch_random_number_generator.h
4597 #include <random>
4598 
4599 namespace Catch {
4600 namespace Generators {
4601 
4602 template <typename Float>
4604  Catch::SimplePcg32& m_rng;
4605  std::uniform_real_distribution<Float> m_dist;
4606  Float m_current_number;
4607 public:
4608 
4610  m_rng(rng()),
4611  m_dist(a, b) {
4612  static_cast<void>(next());
4613  }
4614 
4615  Float const& get() const override {
4616  return m_current_number;
4617  }
4618  bool next() override {
4619  m_current_number = m_dist(m_rng);
4620  return true;
4621  }
4622 };
4623 
4624 template <typename Integer>
4625 class RandomIntegerGenerator final : public IGenerator<Integer> {
4626  Catch::SimplePcg32& m_rng;
4627  std::uniform_int_distribution<Integer> m_dist;
4628  Integer m_current_number;
4629 public:
4630 
4631  RandomIntegerGenerator(Integer a, Integer b):
4632  m_rng(rng()),
4633  m_dist(a, b) {
4634  static_cast<void>(next());
4635  }
4636 
4637  Integer const& get() const override {
4638  return m_current_number;
4639  }
4640  bool next() override {
4641  m_current_number = m_dist(m_rng);
4642  return true;
4643  }
4644 };
4645 
4646 // TODO: Ideally this would be also constrained against the various char types,
4647 // but I don't expect users to run into that in practice.
4648 template <typename T>
4650 GeneratorWrapper<T>>::type
4651 random(T a, T b) {
4652  return GeneratorWrapper<T>(
4654  );
4655 }
4656 
4657 template <typename T>
4659 GeneratorWrapper<T>>::type
4660 random(T a, T b) {
4661  return GeneratorWrapper<T>(
4663  );
4664 }
4665 
4666 template <typename T>
4667 class RangeGenerator final : public IGenerator<T> {
4668  T m_current;
4669  T m_end;
4670  T m_step;
4671  bool m_positive;
4672 
4673 public:
4674  RangeGenerator(T const& start, T const& end, T const& step):
4675  m_current(start),
4676  m_end(end),
4677  m_step(step),
4678  m_positive(m_step > T(0))
4679  {
4680  assert(m_current != m_end && "Range start and end cannot be equal");
4681  assert(m_step != T(0) && "Step size cannot be zero");
4682  assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
4683  }
4684 
4685  RangeGenerator(T const& start, T const& end):
4686  RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
4687  {}
4688 
4689  T const& get() const override {
4690  return m_current;
4691  }
4692 
4693  bool next() override {
4694  m_current += m_step;
4695  return (m_positive) ? (m_current < m_end) : (m_current > m_end);
4696  }
4697 };
4698 
4699 template <typename T>
4700 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
4701  static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
4703 }
4704 
4705 template <typename T>
4707  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4709 }
4710 
4711 template <typename T>
4713  static_assert(!std::is_same<T, bool>::value,
4714  "IteratorGenerator currently does not support bools"
4715  "because of std::vector<bool> specialization");
4716 
4717  std::vector<T> m_elems;
4718  size_t m_current = 0;
4719 public:
4720  template <typename InputIterator, typename InputSentinel>
4721  IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
4722  if (m_elems.empty()) {
4723  Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
4724  }
4725  }
4726 
4727  T const& get() const override {
4728  return m_elems[m_current];
4729  }
4730 
4731  bool next() override {
4732  ++m_current;
4733  return m_current != m_elems.size();
4734  }
4735 };
4736 
4737 template <typename InputIterator,
4738  typename InputSentinel,
4739  typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
4740 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
4742 }
4743 
4744 template <typename Container,
4745  typename ResultType = typename Container::value_type>
4748 }
4749 
4750 } // namespace Generators
4751 } // namespace Catch
4752 
4753 // end catch_generators_specific.hpp
4754 
4755 // These files are included here so the single_include script doesn't put them
4756 // in the conditionally compiled sections
4757 // start catch_test_case_info.h
4758 
4759 #include <string>
4760 #include <vector>
4761 #include <memory>
4762 
4763 #ifdef __clang__
4764 #pragma clang diagnostic push
4765 #pragma clang diagnostic ignored "-Wpadded"
4766 #endif
4767 
4768 namespace Catch {
4769 
4770  struct ITestInvoker;
4771 
4772  struct TestCaseInfo {
4774  None = 0,
4775  IsHidden = 1 << 1,
4776  ShouldFail = 1 << 2,
4777  MayFail = 1 << 3,
4778  Throws = 1 << 4,
4779  NonPortable = 1 << 5,
4780  Benchmark = 1 << 6
4781  };
4782 
4783  TestCaseInfo( std::string const& _name,
4784  std::string const& _className,
4785  std::string const& _description,
4786  std::vector<std::string> const& _tags,
4787  SourceLineInfo const& _lineInfo );
4788 
4789  friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
4790 
4791  bool isHidden() const;
4792  bool throws() const;
4793  bool okToFail() const;
4794  bool expectedToFail() const;
4795 
4797 
4801  std::vector<std::string> tags;
4802  std::vector<std::string> lcaseTags;
4805  };
4806 
4807  class TestCase : public TestCaseInfo {
4808  public:
4809 
4811 
4812  TestCase withName( std::string const& _newName ) const;
4813 
4814  void invoke() const;
4815 
4817 
4818  bool operator == ( TestCase const& other ) const;
4819  bool operator < ( TestCase const& other ) const;
4820 
4821  private:
4822  std::shared_ptr<ITestInvoker> test;
4823  };
4824 
4826  std::string const& className,
4827  NameAndTags const& nameAndTags,
4828  SourceLineInfo const& lineInfo );
4829 }
4830 
4831 #ifdef __clang__
4832 #pragma clang diagnostic pop
4833 #endif
4834 
4835 // end catch_test_case_info.h
4836 // start catch_interfaces_runner.h
4837 
4838 namespace Catch {
4839 
4840  struct IRunner {
4841  virtual ~IRunner();
4842  virtual bool aborting() const = 0;
4843  };
4844 }
4845 
4846 // end catch_interfaces_runner.h
4847 
4848 #ifdef __OBJC__
4849 // start catch_objc.hpp
4850 
4851 #import <objc/runtime.h>
4852 
4853 #include <string>
4854 
4855 // NB. Any general catch headers included here must be included
4856 // in catch.hpp first to make sure they are included by the single
4857 // header for non obj-usage
4858 
4860 // This protocol is really only here for (self) documenting purposes, since
4861 // all its methods are optional.
4862 @protocol OcFixture
4863 
4864 @optional
4865 
4866 -(void) setUp;
4867 -(void) tearDown;
4868 
4869 @end
4870 
4871 namespace Catch {
4872 
4873  class OcMethod : public ITestInvoker {
4874 
4875  public:
4876  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
4877 
4878  virtual void invoke() const {
4879  id obj = [[m_cls alloc] init];
4880 
4881  performOptionalSelector( obj, @selector(setUp) );
4882  performOptionalSelector( obj, m_sel );
4883  performOptionalSelector( obj, @selector(tearDown) );
4884 
4885  arcSafeRelease( obj );
4886  }
4887  private:
4888  virtual ~OcMethod() {}
4889 
4890  Class m_cls;
4891  SEL m_sel;
4892  };
4893 
4894  namespace Detail{
4895 
4896  inline std::string getAnnotation( Class cls,
4897  std::string const& annotationName,
4898  std::string const& testCaseName ) {
4899  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
4900  SEL sel = NSSelectorFromString( selStr );
4901  arcSafeRelease( selStr );
4902  id value = performOptionalSelector( cls, sel );
4903  if( value )
4904  return [(NSString*)value UTF8String];
4905  return "";
4906  }
4907  }
4908 
4909  inline std::size_t registerTestMethods() {
4910  std::size_t noTestMethods = 0;
4911  int noClasses = objc_getClassList( nullptr, 0 );
4912 
4913  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
4914  objc_getClassList( classes, noClasses );
4915 
4916  for( int c = 0; c < noClasses; c++ ) {
4917  Class cls = classes[c];
4918  {
4919  u_int count;
4920  Method* methods = class_copyMethodList( cls, &count );
4921  for( u_int m = 0; m < count ; m++ ) {
4922  SEL selector = method_getName(methods[m]);
4923  std::string methodName = sel_getName(selector);
4924  if( startsWith( methodName, "Catch_TestCase_" ) ) {
4925  std::string testCaseName = methodName.substr( 15 );
4926  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
4927  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
4928  const char* className = class_getName( cls );
4929 
4930  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
4931  noTestMethods++;
4932  }
4933  }
4934  free(methods);
4935  }
4936  }
4937  return noTestMethods;
4938  }
4939 
4940 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
4941 
4942  namespace Matchers {
4943  namespace Impl {
4944  namespace NSStringMatchers {
4945 
4946  struct StringHolder : MatcherBase<NSString*>{
4947  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
4948  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
4949  StringHolder() {
4950  arcSafeRelease( m_substr );
4951  }
4952 
4953  bool match( NSString* str ) const override {
4954  return false;
4955  }
4956 
4957  NSString* CATCH_ARC_STRONG m_substr;
4958  };
4959 
4960  struct Equals : StringHolder {
4961  Equals( NSString* substr ) : StringHolder( substr ){}
4962 
4963  bool match( NSString* str ) const override {
4964  return (str != nil || m_substr == nil ) &&
4965  [str isEqualToString:m_substr];
4966  }
4967 
4968  std::string describe() const override {
4969  return "equals string: " + Catch::Detail::stringify( m_substr );
4970  }
4971  };
4972 
4973  struct Contains : StringHolder {
4974  Contains( NSString* substr ) : StringHolder( substr ){}
4975 
4976  bool match( NSString* str ) const override {
4977  return (str != nil || m_substr == nil ) &&
4978  [str rangeOfString:m_substr].location != NSNotFound;
4979  }
4980 
4981  std::string describe() const override {
4982  return "contains string: " + Catch::Detail::stringify( m_substr );
4983  }
4984  };
4985 
4986  struct StartsWith : StringHolder {
4987  StartsWith( NSString* substr ) : StringHolder( substr ){}
4988 
4989  bool match( NSString* str ) const override {
4990  return (str != nil || m_substr == nil ) &&
4991  [str rangeOfString:m_substr].location == 0;
4992  }
4993 
4994  std::string describe() const override {
4995  return "starts with: " + Catch::Detail::stringify( m_substr );
4996  }
4997  };
4998  struct EndsWith : StringHolder {
4999  EndsWith( NSString* substr ) : StringHolder( substr ){}
5000 
5001  bool match( NSString* str ) const override {
5002  return (str != nil || m_substr == nil ) &&
5003  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
5004  }
5005 
5006  std::string describe() const override {
5007  return "ends with: " + Catch::Detail::stringify( m_substr );
5008  }
5009  };
5010 
5011  } // namespace NSStringMatchers
5012  } // namespace Impl
5013 
5015  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
5016 
5018  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
5019 
5021  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
5022 
5024  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
5025 
5026  } // namespace Matchers
5027 
5028  using namespace Matchers;
5029 
5030 #endif // CATCH_CONFIG_DISABLE_MATCHERS
5031 
5032 } // namespace Catch
5033 
5035 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
5036 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
5037 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
5038 { \
5039 return @ name; \
5040 } \
5041 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
5042 { \
5043 return @ desc; \
5044 } \
5045 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
5046 
5047 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
5048 
5049 // end catch_objc.hpp
5050 #endif
5051 
5052 // Benchmarking needs the externally-facing parts of reporters to work
5053 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5054 // start catch_external_interfaces.h
5055 
5056 // start catch_reporter_bases.hpp
5057 
5058 // start catch_interfaces_reporter.h
5059 
5060 // start catch_config.hpp
5061 
5062 // start catch_test_spec_parser.h
5063 
5064 #ifdef __clang__
5065 #pragma clang diagnostic push
5066 #pragma clang diagnostic ignored "-Wpadded"
5067 #endif
5068 
5069 // start catch_test_spec.h
5070 
5071 #ifdef __clang__
5072 #pragma clang diagnostic push
5073 #pragma clang diagnostic ignored "-Wpadded"
5074 #endif
5075 
5076 // start catch_wildcard_pattern.h
5077 
5078 namespace Catch
5079 {
5080  class WildcardPattern {
5081  enum WildcardPosition {
5082  NoWildcard = 0,
5083  WildcardAtStart = 1,
5084  WildcardAtEnd = 2,
5085  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
5086  };
5087 
5088  public:
5089 
5090  WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
5091  virtual ~WildcardPattern() = default;
5092  virtual bool matches( std::string const& str ) const;
5093 
5094  private:
5095  std::string normaliseString( std::string const& str ) const;
5096  CaseSensitive::Choice m_caseSensitivity;
5097  WildcardPosition m_wildcard = NoWildcard;
5098  std::string m_pattern;
5099  };
5100 }
5101 
5102 // end catch_wildcard_pattern.h
5103 #include <string>
5104 #include <vector>
5105 #include <memory>
5106 
5107 namespace Catch {
5108 
5109  struct IConfig;
5110 
5111  class TestSpec {
5112  class Pattern {
5113  public:
5114  explicit Pattern( std::string const& name );
5115  virtual ~Pattern();
5116  virtual bool matches( TestCaseInfo const& testCase ) const = 0;
5117  std::string const& name() const;
5118  private:
5119  std::string const m_name;
5120  };
5121  using PatternPtr = std::shared_ptr<Pattern>;
5122 
5123  class NamePattern : public Pattern {
5124  public:
5125  explicit NamePattern( std::string const& name, std::string const& filterString );
5126  bool matches( TestCaseInfo const& testCase ) const override;
5127  private:
5128  WildcardPattern m_wildcardPattern;
5129  };
5130 
5131  class TagPattern : public Pattern {
5132  public:
5133  explicit TagPattern( std::string const& tag, std::string const& filterString );
5134  bool matches( TestCaseInfo const& testCase ) const override;
5135  private:
5136  std::string m_tag;
5137  };
5138 
5139  class ExcludedPattern : public Pattern {
5140  public:
5141  explicit ExcludedPattern( PatternPtr const& underlyingPattern );
5142  bool matches( TestCaseInfo const& testCase ) const override;
5143  private:
5144  PatternPtr m_underlyingPattern;
5145  };
5146 
5147  struct Filter {
5148  std::vector<PatternPtr> m_patterns;
5149 
5150  bool matches( TestCaseInfo const& testCase ) const;
5151  std::string name() const;
5152  };
5153 
5154  public:
5155  struct FilterMatch {
5156  std::string name;
5157  std::vector<TestCase const*> tests;
5158  };
5159  using Matches = std::vector<FilterMatch>;
5160  using vectorStrings = std::vector<std::string>;
5161 
5162  bool hasFilters() const;
5163  bool matches( TestCaseInfo const& testCase ) const;
5164  Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
5165  const vectorStrings & getInvalidArgs() const;
5166 
5167  private:
5168  std::vector<Filter> m_filters;
5169  std::vector<std::string> m_invalidArgs;
5170  friend class TestSpecParser;
5171  };
5172 }
5173 
5174 #ifdef __clang__
5175 #pragma clang diagnostic pop
5176 #endif
5177 
5178 // end catch_test_spec.h
5179 // start catch_interfaces_tag_alias_registry.h
5180 
5181 #include <string>
5182 
5183 namespace Catch {
5184 
5185  struct TagAlias;
5186 
5187  struct ITagAliasRegistry {
5188  virtual ~ITagAliasRegistry();
5189  // Nullptr if not present
5190  virtual TagAlias const* find( std::string const& alias ) const = 0;
5191  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
5192 
5193  static ITagAliasRegistry const& get();
5194  };
5195 
5196 } // end namespace Catch
5197 
5198 // end catch_interfaces_tag_alias_registry.h
5199 namespace Catch {
5200 
5201  class TestSpecParser {
5202  enum Mode{ None, Name, QuotedName, Tag, EscapedName };
5203  Mode m_mode = None;
5204  Mode lastMode = None;
5205  bool m_exclusion = false;
5206  std::size_t m_pos = 0;
5207  std::size_t m_realPatternPos = 0;
5208  std::string m_arg;
5209  std::string m_substring;
5210  std::string m_patternName;
5211  std::vector<std::size_t> m_escapeChars;
5212  TestSpec::Filter m_currentFilter;
5213  TestSpec m_testSpec;
5214  ITagAliasRegistry const* m_tagAliases = nullptr;
5215 
5216  public:
5217  TestSpecParser( ITagAliasRegistry const& tagAliases );
5218 
5219  TestSpecParser& parse( std::string const& arg );
5220  TestSpec testSpec();
5221 
5222  private:
5223  bool visitChar( char c );
5224  void startNewMode( Mode mode );
5225  bool processNoneChar( char c );
5226  void processNameChar( char c );
5227  bool processOtherChar( char c );
5228  void endMode();
5229  void escape();
5230  bool isControlChar( char c ) const;
5231  void saveLastMode();
5232  void revertBackToLastMode();
5233  void addFilter();
5234  bool separate();
5235 
5236  // Handles common preprocessing of the pattern for name/tag patterns
5237  std::string preprocessPattern();
5238  // Adds the current pattern as a test name
5239  void addNamePattern();
5240  // Adds the current pattern as a tag
5241  void addTagPattern();
5242 
5243  inline void addCharToPattern(char c) {
5244  m_substring += c;
5245  m_patternName += c;
5246  m_realPatternPos++;
5247  }
5248 
5249  };
5250  TestSpec parseTestSpec( std::string const& arg );
5251 
5252 } // namespace Catch
5253 
5254 #ifdef __clang__
5255 #pragma clang diagnostic pop
5256 #endif
5257 
5258 // end catch_test_spec_parser.h
5259 // Libstdc++ doesn't like incomplete classes for unique_ptr
5260 
5261 #include <memory>
5262 #include <vector>
5263 #include <string>
5264 
5265 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
5266 #define CATCH_CONFIG_CONSOLE_WIDTH 80
5267 #endif
5268 
5269 namespace Catch {
5270 
5271  struct IStream;
5272 
5273  struct ConfigData {
5274  bool listTests = false;
5275  bool listTags = false;
5276  bool listReporters = false;
5277  bool listTestNamesOnly = false;
5278 
5279  bool showSuccessfulTests = false;
5280  bool shouldDebugBreak = false;
5281  bool noThrow = false;
5282  bool showHelp = false;
5283  bool showInvisibles = false;
5284  bool filenamesAsTags = false;
5285  bool libIdentify = false;
5286 
5287  int abortAfter = -1;
5288  unsigned int rngSeed = 0;
5289 
5290  bool benchmarkNoAnalysis = false;
5291  unsigned int benchmarkSamples = 100;
5292  double benchmarkConfidenceInterval = 0.95;
5293  unsigned int benchmarkResamples = 100000;
5294  std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
5295 
5296  Verbosity verbosity = Verbosity::Normal;
5299  double minDuration = -1;
5301  UseColour::YesOrNo useColour = UseColour::Auto;
5303 
5304  std::string outputFilename;
5305  std::string name;
5306  std::string processName;
5307 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
5308 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
5309 #endif
5310  std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
5311 #undef CATCH_CONFIG_DEFAULT_REPORTER
5312 
5313  std::vector<std::string> testsOrTags;
5314  std::vector<std::string> sectionsToRun;
5315  };
5316 
5317  class Config : public IConfig {
5318  public:
5319 
5320  Config() = default;
5321  Config( ConfigData const& data );
5322  virtual ~Config() = default;
5323 
5324  std::string const& getFilename() const;
5325 
5326  bool listTests() const;
5327  bool listTestNamesOnly() const;
5328  bool listTags() const;
5329  bool listReporters() const;
5330 
5331  std::string getProcessName() const;
5332  std::string const& getReporterName() const;
5333 
5334  std::vector<std::string> const& getTestsOrTags() const override;
5335  std::vector<std::string> const& getSectionsToRun() const override;
5336 
5337  TestSpec const& testSpec() const override;
5338  bool hasTestFilters() const override;
5339 
5340  bool showHelp() const;
5341 
5342  // IConfig interface
5343  bool allowThrows() const override;
5344  std::ostream& stream() const override;
5345  std::string name() const override;
5346  bool includeSuccessfulResults() const override;
5347  bool warnAboutMissingAssertions() const override;
5348  bool warnAboutNoTests() const override;
5349  ShowDurations::OrNot showDurations() const override;
5350  double minDuration() const override;
5351  RunTests::InWhatOrder runOrder() const override;
5352  unsigned int rngSeed() const override;
5353  UseColour::YesOrNo useColour() const override;
5354  bool shouldDebugBreak() const override;
5355  int abortAfter() const override;
5356  bool showInvisibles() const override;
5357  Verbosity verbosity() const override;
5358  bool benchmarkNoAnalysis() const override;
5359  int benchmarkSamples() const override;
5360  double benchmarkConfidenceInterval() const override;
5361  unsigned int benchmarkResamples() const override;
5362  std::chrono::milliseconds benchmarkWarmupTime() const override;
5363 
5364  private:
5365 
5366  IStream const* openStream();
5367  ConfigData m_data;
5368 
5369  std::unique_ptr<IStream const> m_stream;
5370  TestSpec m_testSpec;
5371  bool m_hasTestFilters = false;
5372  };
5373 
5374 } // end namespace Catch
5375 
5376 // end catch_config.hpp
5377 // start catch_assertionresult.h
5378 
5379 #include <string>
5380 
5381 namespace Catch {
5382 
5383  struct AssertionResultData
5384  {
5385  AssertionResultData() = delete;
5386 
5387  AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
5388 
5390  mutable std::string reconstructedExpression;
5391  LazyExpression lazyExpression;
5392  ResultWas::OfType resultType;
5393 
5394  std::string reconstructExpression() const;
5395  };
5396 
5397  class AssertionResult {
5398  public:
5399  AssertionResult() = delete;
5400  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
5401 
5402  bool isOk() const;
5403  bool succeeded() const;
5404  ResultWas::OfType getResultType() const;
5405  bool hasExpression() const;
5406  bool hasMessage() const;
5407  std::string getExpression() const;
5408  std::string getExpressionInMacro() const;
5409  bool hasExpandedExpression() const;
5410  std::string getExpandedExpression() const;
5411  std::string getMessage() const;
5412  SourceLineInfo getSourceInfo() const;
5413  StringRef getTestMacroName() const;
5414 
5415  //protected:
5416  AssertionInfo m_info;
5417  AssertionResultData m_resultData;
5418  };
5419 
5420 } // end namespace Catch
5421 
5422 // end catch_assertionresult.h
5423 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5424 // start catch_estimate.hpp
5425 
5426  // Statistics estimates
5427 
5428 
5429 namespace Catch {
5430  namespace Benchmark {
5431  template <typename Duration>
5432  struct Estimate {
5433  Duration point;
5434  Duration lower_bound;
5435  Duration upper_bound;
5436  double confidence_interval;
5437 
5438  template <typename Duration2>
5439  operator Estimate<Duration2>() const {
5440  return { point, lower_bound, upper_bound, confidence_interval };
5441  }
5442  };
5443  } // namespace Benchmark
5444 } // namespace Catch
5445 
5446 // end catch_estimate.hpp
5447 // start catch_outlier_classification.hpp
5448 
5449 // Outlier information
5450 
5451 namespace Catch {
5452  namespace Benchmark {
5453  struct OutlierClassification {
5454  int samples_seen = 0;
5455  int low_severe = 0; // more than 3 times IQR below Q1
5456  int low_mild = 0; // 1.5 to 3 times IQR below Q1
5457  int high_mild = 0; // 1.5 to 3 times IQR above Q3
5458  int high_severe = 0; // more than 3 times IQR above Q3
5459 
5460  int total() const {
5461  return low_severe + low_mild + high_mild + high_severe;
5462  }
5463  };
5464  } // namespace Benchmark
5465 } // namespace Catch
5466 
5467 // end catch_outlier_classification.hpp
5468 
5469 #include <iterator>
5470 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5471 
5472 #include <string>
5473 #include <iosfwd>
5474 #include <map>
5475 #include <set>
5476 #include <memory>
5477 #include <algorithm>
5478 
5479 namespace Catch {
5480 
5481  struct ReporterConfig {
5482  explicit ReporterConfig( IConfigPtr const& _fullConfig );
5483 
5484  ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
5485 
5486  std::ostream& stream() const;
5487  IConfigPtr fullConfig() const;
5488 
5489  private:
5490  std::ostream* m_stream;
5491  IConfigPtr m_fullConfig;
5492  };
5493 
5494  struct ReporterPreferences {
5495  bool shouldRedirectStdOut = false;
5496  bool shouldReportAllAssertions = false;
5497  };
5498 
5499  template<typename T>
5500  struct LazyStat : Option<T> {
5501  LazyStat& operator=( T const& _value ) {
5502  Option<T>::operator=( _value );
5503  used = false;
5504  return *this;
5505  }
5506  void reset() {
5507  Option<T>::reset();
5508  used = false;
5509  }
5510  bool used = false;
5511  };
5512 
5513  struct TestRunInfo {
5514  TestRunInfo( std::string const& _name );
5515  std::string name;
5516  };
5517  struct GroupInfo {
5518  GroupInfo( std::string const& _name,
5519  std::size_t _groupIndex,
5520  std::size_t _groupsCount );
5521 
5522  std::string name;
5523  std::size_t groupIndex;
5524  std::size_t groupsCounts;
5525  };
5526 
5527  struct AssertionStats {
5528  AssertionStats( AssertionResult const& _assertionResult,
5529  std::vector<MessageInfo> const& _infoMessages,
5530  Totals const& _totals );
5531 
5532  AssertionStats( AssertionStats const& ) = default;
5533  AssertionStats( AssertionStats && ) = default;
5534  AssertionStats& operator = ( AssertionStats const& ) = delete;
5535  AssertionStats& operator = ( AssertionStats && ) = delete;
5536  virtual ~AssertionStats();
5537 
5538  AssertionResult assertionResult;
5539  std::vector<MessageInfo> infoMessages;
5540  Totals totals;
5541  };
5542 
5543  struct SectionStats {
5544  SectionStats( SectionInfo const& _sectionInfo,
5545  Counts const& _assertions,
5546  double _durationInSeconds,
5547  bool _missingAssertions );
5548  SectionStats( SectionStats const& ) = default;
5549  SectionStats( SectionStats && ) = default;
5550  SectionStats& operator = ( SectionStats const& ) = default;
5551  SectionStats& operator = ( SectionStats && ) = default;
5552  virtual ~SectionStats();
5553 
5554  SectionInfo sectionInfo;
5555  Counts assertions;
5556  double durationInSeconds;
5557  bool missingAssertions;
5558  };
5559 
5560  struct TestCaseStats {
5561  TestCaseStats( TestCaseInfo const& _testInfo,
5562  Totals const& _totals,
5563  std::string const& _stdOut,
5564  std::string const& _stdErr,
5565  bool _aborting );
5566 
5567  TestCaseStats( TestCaseStats const& ) = default;
5568  TestCaseStats( TestCaseStats && ) = default;
5569  TestCaseStats& operator = ( TestCaseStats const& ) = default;
5570  TestCaseStats& operator = ( TestCaseStats && ) = default;
5571  virtual ~TestCaseStats();
5572 
5573  TestCaseInfo testInfo;
5574  Totals totals;
5575  std::string stdOut;
5576  std::string stdErr;
5577  bool aborting;
5578  };
5579 
5580  struct TestGroupStats {
5581  TestGroupStats( GroupInfo const& _groupInfo,
5582  Totals const& _totals,
5583  bool _aborting );
5584  TestGroupStats( GroupInfo const& _groupInfo );
5585 
5586  TestGroupStats( TestGroupStats const& ) = default;
5587  TestGroupStats( TestGroupStats && ) = default;
5588  TestGroupStats& operator = ( TestGroupStats const& ) = default;
5589  TestGroupStats& operator = ( TestGroupStats && ) = default;
5590  virtual ~TestGroupStats();
5591 
5592  GroupInfo groupInfo;
5593  Totals totals;
5594  bool aborting;
5595  };
5596 
5597  struct TestRunStats {
5598  TestRunStats( TestRunInfo const& _runInfo,
5599  Totals const& _totals,
5600  bool _aborting );
5601 
5602  TestRunStats( TestRunStats const& ) = default;
5603  TestRunStats( TestRunStats && ) = default;
5604  TestRunStats& operator = ( TestRunStats const& ) = default;
5605  TestRunStats& operator = ( TestRunStats && ) = default;
5606  virtual ~TestRunStats();
5607 
5608  TestRunInfo runInfo;
5609  Totals totals;
5610  bool aborting;
5611  };
5612 
5613 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5614  struct BenchmarkInfo {
5615  std::string name;
5616  double estimatedDuration;
5617  int iterations;
5618  int samples;
5619  unsigned int resamples;
5620  double clockResolution;
5621  double clockCost;
5622  };
5623 
5624  template <class Duration>
5625  struct BenchmarkStats {
5626  BenchmarkInfo info;
5627 
5628  std::vector<Duration> samples;
5629  Benchmark::Estimate<Duration> mean;
5630  Benchmark::Estimate<Duration> standardDeviation;
5631  Benchmark::OutlierClassification outliers;
5632  double outlierVariance;
5633 
5634  template <typename Duration2>
5635  operator BenchmarkStats<Duration2>() const {
5636  std::vector<Duration2> samples2;
5637  samples2.reserve(samples.size());
5638  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
5639  return {
5640  info,
5641  std::move(samples2),
5642  mean,
5643  standardDeviation,
5644  outliers,
5645  outlierVariance,
5646  };
5647  }
5648  };
5649 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5650 
5651  struct IStreamingReporter {
5652  virtual ~IStreamingReporter() = default;
5653 
5654  // Implementing class must also provide the following static methods:
5655  // static std::string getDescription();
5656  // static std::set<Verbosity> getSupportedVerbosities()
5657 
5658  virtual ReporterPreferences getPreferences() const = 0;
5659 
5660  virtual void noMatchingTestCases( std::string const& spec ) = 0;
5661 
5662  virtual void reportInvalidArguments(std::string const&) {}
5663 
5664  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5665  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5666 
5667  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5668  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5669 
5670 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5671  virtual void benchmarkPreparing( std::string const& ) {}
5672  virtual void benchmarkStarting( BenchmarkInfo const& ) {}
5673  virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
5674  virtual void benchmarkFailed( std::string const& ) {}
5675 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5676 
5677  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5678 
5679  // The return value indicates if the messages buffer should be cleared:
5680  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5681 
5682  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5683  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5684  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5685  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5686 
5687  virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5688 
5689  // Default empty implementation provided
5690  virtual void fatalErrorEncountered( StringRef name );
5691 
5692  virtual bool isMulti() const;
5693  };
5694  using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
5695 
5696  struct IReporterFactory {
5697  virtual ~IReporterFactory();
5698  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
5699  virtual std::string getDescription() const = 0;
5700  };
5701  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
5702 
5703  struct IReporterRegistry {
5704  using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
5705  using Listeners = std::vector<IReporterFactoryPtr>;
5706 
5707  virtual ~IReporterRegistry();
5708  virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
5709  virtual FactoryMap const& getFactories() const = 0;
5710  virtual Listeners const& getListeners() const = 0;
5711  };
5712 
5713 } // end namespace Catch
5714 
5715 // end catch_interfaces_reporter.h
5716 #include <algorithm>
5717 #include <cstring>
5718 #include <cfloat>
5719 #include <cstdio>
5720 #include <cassert>
5721 #include <memory>
5722 #include <ostream>
5723 
5724 namespace Catch {
5725  void prepareExpandedExpression(AssertionResult& result);
5726 
5727  // Returns double formatted as %.3f (format expected on output)
5728  std::string getFormattedDuration( double duration );
5729 
5731  bool shouldShowDuration( IConfig const& config, double duration );
5732 
5733  std::string serializeFilters( std::vector<std::string> const& container );
5734 
5735  template<typename DerivedT>
5736  struct StreamingReporterBase : IStreamingReporter {
5737 
5738  StreamingReporterBase( ReporterConfig const& _config )
5739  : m_config( _config.fullConfig() ),
5740  stream( _config.stream() )
5741  {
5742  m_reporterPrefs.shouldRedirectStdOut = false;
5743  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5744  CATCH_ERROR( "Verbosity level not supported by this reporter" );
5745  }
5746 
5747  ReporterPreferences getPreferences() const override {
5748  return m_reporterPrefs;
5749  }
5750 
5751  static std::set<Verbosity> getSupportedVerbosities() {
5752  return { Verbosity::Normal };
5753  }
5754 
5755  ~StreamingReporterBase() override = default;
5756 
5757  void noMatchingTestCases(std::string const&) override {}
5758 
5759  void reportInvalidArguments(std::string const&) override {}
5760 
5761  void testRunStarting(TestRunInfo const& _testRunInfo) override {
5762  currentTestRunInfo = _testRunInfo;
5763  }
5764 
5765  void testGroupStarting(GroupInfo const& _groupInfo) override {
5766  currentGroupInfo = _groupInfo;
5767  }
5768 
5769  void testCaseStarting(TestCaseInfo const& _testInfo) override {
5770  currentTestCaseInfo = _testInfo;
5771  }
5772  void sectionStarting(SectionInfo const& _sectionInfo) override {
5773  m_sectionStack.push_back(_sectionInfo);
5774  }
5775 
5776  void sectionEnded(SectionStats const& /* _sectionStats */) override {
5777  m_sectionStack.pop_back();
5778  }
5779  void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
5780  currentTestCaseInfo.reset();
5781  }
5782  void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
5783  currentGroupInfo.reset();
5784  }
5785  void testRunEnded(TestRunStats const& /* _testRunStats */) override {
5786  currentTestCaseInfo.reset();
5787  currentGroupInfo.reset();
5788  currentTestRunInfo.reset();
5789  }
5790 
5791  void skipTest(TestCaseInfo const&) override {
5792  // Don't do anything with this by default.
5793  // It can optionally be overridden in the derived class.
5794  }
5795 
5796  IConfigPtr m_config;
5797  std::ostream& stream;
5798 
5799  LazyStat<TestRunInfo> currentTestRunInfo;
5800  LazyStat<GroupInfo> currentGroupInfo;
5801  LazyStat<TestCaseInfo> currentTestCaseInfo;
5802 
5803  std::vector<SectionInfo> m_sectionStack;
5804  ReporterPreferences m_reporterPrefs;
5805  };
5806 
5807  template<typename DerivedT>
5808  struct CumulativeReporterBase : IStreamingReporter {
5809  template<typename T, typename ChildNodeT>
5810  struct Node {
5811  explicit Node( T const& _value ) : value( _value ) {}
5812  virtual ~Node() {}
5813 
5814  using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
5815  T value;
5816  ChildNodes children;
5817  };
5818  struct SectionNode {
5819  explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
5820  virtual ~SectionNode() = default;
5821 
5822  bool operator == (SectionNode const& other) const {
5823  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
5824  }
5825  bool operator == (std::shared_ptr<SectionNode> const& other) const {
5826  return operator==(*other);
5827  }
5828 
5829  SectionStats stats;
5830  using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
5831  using Assertions = std::vector<AssertionStats>;
5832  ChildSections childSections;
5833  Assertions assertions;
5834  std::string stdOut;
5835  std::string stdErr;
5836  };
5837 
5838  struct BySectionInfo {
5839  BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
5840  BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
5841  bool operator() (std::shared_ptr<SectionNode> const& node) const {
5842  return ((node->stats.sectionInfo.name == m_other.name) &&
5843  (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
5844  }
5845  void operator=(BySectionInfo const&) = delete;
5846 
5847  private:
5848  SectionInfo const& m_other;
5849  };
5850 
5851  using TestCaseNode = Node<TestCaseStats, SectionNode>;
5852  using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
5853  using TestRunNode = Node<TestRunStats, TestGroupNode>;
5854 
5855  CumulativeReporterBase( ReporterConfig const& _config )
5856  : m_config( _config.fullConfig() ),
5857  stream( _config.stream() )
5858  {
5859  m_reporterPrefs.shouldRedirectStdOut = false;
5860  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5861  CATCH_ERROR( "Verbosity level not supported by this reporter" );
5862  }
5863  ~CumulativeReporterBase() override = default;
5864 
5865  ReporterPreferences getPreferences() const override {
5866  return m_reporterPrefs;
5867  }
5868 
5869  static std::set<Verbosity> getSupportedVerbosities() {
5870  return { Verbosity::Normal };
5871  }
5872 
5873  void testRunStarting( TestRunInfo const& ) override {}
5874  void testGroupStarting( GroupInfo const& ) override {}
5875 
5876  void testCaseStarting( TestCaseInfo const& ) override {}
5877 
5878  void sectionStarting( SectionInfo const& sectionInfo ) override {
5879  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
5880  std::shared_ptr<SectionNode> node;
5881  if( m_sectionStack.empty() ) {
5882  if( !m_rootSection )
5883  m_rootSection = std::make_shared<SectionNode>( incompleteStats );
5884  node = m_rootSection;
5885  }
5886  else {
5887  SectionNode& parentNode = *m_sectionStack.back();
5888  auto it =
5889  std::find_if( parentNode.childSections.begin(),
5890  parentNode.childSections.end(),
5891  BySectionInfo( sectionInfo ) );
5892  if( it == parentNode.childSections.end() ) {
5893  node = std::make_shared<SectionNode>( incompleteStats );
5894  parentNode.childSections.push_back( node );
5895  }
5896  else
5897  node = *it;
5898  }
5899  m_sectionStack.push_back( node );
5900  m_deepestSection = std::move(node);
5901  }
5902 
5903  void assertionStarting(AssertionInfo const&) override {}
5904 
5905  bool assertionEnded(AssertionStats const& assertionStats) override {
5906  assert(!m_sectionStack.empty());
5907  // AssertionResult holds a pointer to a temporary DecomposedExpression,
5908  // which getExpandedExpression() calls to build the expression string.
5909  // Our section stack copy of the assertionResult will likely outlive the
5910  // temporary, so it must be expanded or discarded now to avoid calling
5911  // a destroyed object later.
5912  prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
5913  SectionNode& sectionNode = *m_sectionStack.back();
5914  sectionNode.assertions.push_back(assertionStats);
5915  return true;
5916  }
5917  void sectionEnded(SectionStats const& sectionStats) override {
5918  assert(!m_sectionStack.empty());
5919  SectionNode& node = *m_sectionStack.back();
5920  node.stats = sectionStats;
5921  m_sectionStack.pop_back();
5922  }
5923  void testCaseEnded(TestCaseStats const& testCaseStats) override {
5924  auto node = std::make_shared<TestCaseNode>(testCaseStats);
5925  assert(m_sectionStack.size() == 0);
5926  node->children.push_back(m_rootSection);
5927  m_testCases.push_back(node);
5928  m_rootSection.reset();
5929 
5930  assert(m_deepestSection);
5931  m_deepestSection->stdOut = testCaseStats.stdOut;
5932  m_deepestSection->stdErr = testCaseStats.stdErr;
5933  }
5934  void testGroupEnded(TestGroupStats const& testGroupStats) override {
5935  auto node = std::make_shared<TestGroupNode>(testGroupStats);
5936  node->children.swap(m_testCases);
5937  m_testGroups.push_back(node);
5938  }
5939  void testRunEnded(TestRunStats const& testRunStats) override {
5940  auto node = std::make_shared<TestRunNode>(testRunStats);
5941  node->children.swap(m_testGroups);
5942  m_testRuns.push_back(node);
5943  testRunEndedCumulative();
5944  }
5945  virtual void testRunEndedCumulative() = 0;
5946 
5947  void skipTest(TestCaseInfo const&) override {}
5948 
5949  IConfigPtr m_config;
5950  std::ostream& stream;
5951  std::vector<AssertionStats> m_assertions;
5952  std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
5953  std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
5954  std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
5955 
5956  std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
5957 
5958  std::shared_ptr<SectionNode> m_rootSection;
5959  std::shared_ptr<SectionNode> m_deepestSection;
5960  std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
5961  ReporterPreferences m_reporterPrefs;
5962  };
5963 
5964  template<char C>
5965  char const* getLineOfChars() {
5966  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
5967  if( !*line ) {
5968  std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
5969  line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
5970  }
5971  return line;
5972  }
5973 
5974  struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
5975  TestEventListenerBase( ReporterConfig const& _config );
5976 
5977  static std::set<Verbosity> getSupportedVerbosities();
5978 
5979  void assertionStarting(AssertionInfo const&) override;
5980  bool assertionEnded(AssertionStats const&) override;
5981  };
5982 
5983 } // end namespace Catch
5984 
5985 // end catch_reporter_bases.hpp
5986 // start catch_console_colour.h
5987 
5988 namespace Catch {
5989 
5990  struct Colour {
5991  enum Code {
5992  None = 0,
5993 
5994  White,
5995  Red,
5996  Green,
5997  Blue,
5998  Cyan,
5999  Yellow,
6000  Grey,
6001 
6002  Bright = 0x10,
6003 
6004  BrightRed = Bright | Red,
6005  BrightGreen = Bright | Green,
6006  LightGrey = Bright | Grey,
6007  BrightWhite = Bright | White,
6008  BrightYellow = Bright | Yellow,
6009 
6010  // By intention
6011  FileName = LightGrey,
6012  Warning = BrightYellow,
6013  ResultError = BrightRed,
6014  ResultSuccess = BrightGreen,
6015  ResultExpectedFailure = Warning,
6016 
6017  Error = BrightRed,
6018  Success = Green,
6019 
6020  OriginalExpression = Cyan,
6021  ReconstructedExpression = BrightYellow,
6022 
6023  SecondaryText = LightGrey,
6024  Headers = White
6025  };
6026 
6027  // Use constructed object for RAII guard
6028  Colour( Code _colourCode );
6029  Colour( Colour&& other ) noexcept;
6030  Colour& operator=( Colour&& other ) noexcept;
6031  ~Colour();
6032 
6033  // Use static method for one-shot changes
6034  static void use( Code _colourCode );
6035 
6036  private:
6037  bool m_moved = false;
6038  };
6039 
6040  std::ostream& operator << ( std::ostream& os, Colour const& );
6041 
6042 } // end namespace Catch
6043 
6044 // end catch_console_colour.h
6045 // start catch_reporter_registrars.hpp
6046 
6047 
6048 namespace Catch {
6049 
6050  template<typename T>
6051  class ReporterRegistrar {
6052 
6053  class ReporterFactory : public IReporterFactory {
6054 
6055  IStreamingReporterPtr create( ReporterConfig const& config ) const override {
6056  return std::unique_ptr<T>( new T( config ) );
6057  }
6058 
6059  std::string getDescription() const override {
6060  return T::getDescription();
6061  }
6062  };
6063 
6064  public:
6065 
6066  explicit ReporterRegistrar( std::string const& name ) {
6067  getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
6068  }
6069  };
6070 
6071  template<typename T>
6072  class ListenerRegistrar {
6073 
6074  class ListenerFactory : public IReporterFactory {
6075 
6076  IStreamingReporterPtr create( ReporterConfig const& config ) const override {
6077  return std::unique_ptr<T>( new T( config ) );
6078  }
6079  std::string getDescription() const override {
6080  return std::string();
6081  }
6082  };
6083 
6084  public:
6085 
6086  ListenerRegistrar() {
6087  getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
6088  }
6089  };
6090 }
6091 
6092 #if !defined(CATCH_CONFIG_DISABLE)
6093 
6094 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
6095  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6096  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6097  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
6098  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6099 
6100 #define CATCH_REGISTER_LISTENER( listenerType ) \
6101  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6102  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6103  namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
6104  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6105 #else // CATCH_CONFIG_DISABLE
6106 
6107 #define CATCH_REGISTER_REPORTER(name, reporterType)
6108 #define CATCH_REGISTER_LISTENER(listenerType)
6109 
6110 #endif // CATCH_CONFIG_DISABLE
6111 
6112 // end catch_reporter_registrars.hpp
6113 // Allow users to base their work off existing reporters
6114 // start catch_reporter_compact.h
6115 
6116 namespace Catch {
6117 
6118  struct CompactReporter : StreamingReporterBase<CompactReporter> {
6119 
6120  using StreamingReporterBase::StreamingReporterBase;
6121 
6122  ~CompactReporter() override;
6123 
6124  static std::string getDescription();
6125 
6126  void noMatchingTestCases(std::string const& spec) override;
6127 
6128  void assertionStarting(AssertionInfo const&) override;
6129 
6130  bool assertionEnded(AssertionStats const& _assertionStats) override;
6131 
6132  void sectionEnded(SectionStats const& _sectionStats) override;
6133 
6134  void testRunEnded(TestRunStats const& _testRunStats) override;
6135 
6136  };
6137 
6138 } // end namespace Catch
6139 
6140 // end catch_reporter_compact.h
6141 // start catch_reporter_console.h
6142 
6143 #if defined(_MSC_VER)
6144 #pragma warning(push)
6145 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
6146  // Note that 4062 (not all labels are handled
6147  // and default is missing) is enabled
6148 #endif
6149 
6150 namespace Catch {
6151  // Fwd decls
6152  struct SummaryColumn;
6153  class TablePrinter;
6154 
6155  struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
6156  std::unique_ptr<TablePrinter> m_tablePrinter;
6157 
6158  ConsoleReporter(ReporterConfig const& config);
6159  ~ConsoleReporter() override;
6160  static std::string getDescription();
6161 
6162  void noMatchingTestCases(std::string const& spec) override;
6163 
6164  void reportInvalidArguments(std::string const&arg) override;
6165 
6166  void assertionStarting(AssertionInfo const&) override;
6167 
6168  bool assertionEnded(AssertionStats const& _assertionStats) override;
6169 
6170  void sectionStarting(SectionInfo const& _sectionInfo) override;
6171  void sectionEnded(SectionStats const& _sectionStats) override;
6172 
6173 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6174  void benchmarkPreparing(std::string const& name) override;
6175  void benchmarkStarting(BenchmarkInfo const& info) override;
6176  void benchmarkEnded(BenchmarkStats<> const& stats) override;
6177  void benchmarkFailed(std::string const& error) override;
6178 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6179 
6180  void testCaseEnded(TestCaseStats const& _testCaseStats) override;
6181  void testGroupEnded(TestGroupStats const& _testGroupStats) override;
6182  void testRunEnded(TestRunStats const& _testRunStats) override;
6183  void testRunStarting(TestRunInfo const& _testRunInfo) override;
6184  private:
6185 
6186  void lazyPrint();
6187 
6188  void lazyPrintWithoutClosingBenchmarkTable();
6189  void lazyPrintRunInfo();
6190  void lazyPrintGroupInfo();
6191  void printTestCaseAndSectionHeader();
6192 
6193  void printClosedHeader(std::string const& _name);
6194  void printOpenHeader(std::string const& _name);
6195 
6196  // if string has a : in first line will set indent to follow it on
6197  // subsequent lines
6198  void printHeaderString(std::string const& _string, std::size_t indent = 0);
6199 
6200  void printTotals(Totals const& totals);
6201  void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
6202 
6203  void printTotalsDivider(Totals const& totals);
6204  void printSummaryDivider();
6205  void printTestFilters();
6206 
6207  private:
6208  bool m_headerPrinted = false;
6209  };
6210 
6211 } // end namespace Catch
6212 
6213 #if defined(_MSC_VER)
6214 #pragma warning(pop)
6215 #endif
6216 
6217 // end catch_reporter_console.h
6218 // start catch_reporter_junit.h
6219 
6220 // start catch_xmlwriter.h
6221 
6222 #include <vector>
6223 
6224 namespace Catch {
6225  enum class XmlFormatting {
6226  None = 0x00,
6227  Indent = 0x01,
6228  Newline = 0x02,
6229  };
6230 
6231  XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
6232  XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
6233 
6234  class XmlEncode {
6235  public:
6236  enum ForWhat { ForTextNodes, ForAttributes };
6237 
6238  XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
6239 
6240  void encodeTo( std::ostream& os ) const;
6241 
6242  friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
6243 
6244  private:
6245  std::string m_str;
6246  ForWhat m_forWhat;
6247  };
6248 
6249  class XmlWriter {
6250  public:
6251 
6252  class ScopedElement {
6253  public:
6254  ScopedElement( XmlWriter* writer, XmlFormatting fmt );
6255 
6256  ScopedElement( ScopedElement&& other ) noexcept;
6257  ScopedElement& operator=( ScopedElement&& other ) noexcept;
6258 
6259  ~ScopedElement();
6260 
6261  ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
6262 
6263  template<typename T>
6264  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
6265  m_writer->writeAttribute( name, attribute );
6266  return *this;
6267  }
6268 
6269  private:
6270  mutable XmlWriter* m_writer = nullptr;
6271  XmlFormatting m_fmt;
6272  };
6273 
6274  XmlWriter( std::ostream& os = Catch::cout() );
6275  ~XmlWriter();
6276 
6277  XmlWriter( XmlWriter const& ) = delete;
6278  XmlWriter& operator=( XmlWriter const& ) = delete;
6279 
6280  XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6281 
6282  ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6283 
6284  XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6285 
6286  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
6287 
6288  XmlWriter& writeAttribute( std::string const& name, bool attribute );
6289 
6290  template<typename T>
6291  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
6292  ReusableStringStream rss;
6293  rss << attribute;
6294  return writeAttribute( name, rss.str() );
6295  }
6296 
6297  XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6298 
6299  XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6300 
6301  void writeStylesheetRef( std::string const& url );
6302 
6303  XmlWriter& writeBlankLine();
6304 
6305  void ensureTagClosed();
6306 
6307  private:
6308 
6309  void applyFormatting(XmlFormatting fmt);
6310 
6311  void writeDeclaration();
6312 
6313  void newlineIfNecessary();
6314 
6315  bool m_tagIsOpen = false;
6316  bool m_needsNewline = false;
6317  std::vector<std::string> m_tags;
6318  std::string m_indent;
6319  std::ostream& m_os;
6320  };
6321 
6322 }
6323 
6324 // end catch_xmlwriter.h
6325 namespace Catch {
6326 
6327  class JunitReporter : public CumulativeReporterBase<JunitReporter> {
6328  public:
6329  JunitReporter(ReporterConfig const& _config);
6330 
6331  ~JunitReporter() override;
6332 
6333  static std::string getDescription();
6334 
6335  void noMatchingTestCases(std::string const& /*spec*/) override;
6336 
6337  void testRunStarting(TestRunInfo const& runInfo) override;
6338 
6339  void testGroupStarting(GroupInfo const& groupInfo) override;
6340 
6341  void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
6342  bool assertionEnded(AssertionStats const& assertionStats) override;
6343 
6344  void testCaseEnded(TestCaseStats const& testCaseStats) override;
6345 
6346  void testGroupEnded(TestGroupStats const& testGroupStats) override;
6347 
6348  void testRunEndedCumulative() override;
6349 
6350  void writeGroup(TestGroupNode const& groupNode, double suiteTime);
6351 
6352  void writeTestCase(TestCaseNode const& testCaseNode);
6353 
6354  void writeSection( std::string const& className,
6355  std::string const& rootName,
6356  SectionNode const& sectionNode,
6357  bool testOkToFail );
6358 
6359  void writeAssertions(SectionNode const& sectionNode);
6360  void writeAssertion(AssertionStats const& stats);
6361 
6362  XmlWriter xml;
6363  Timer suiteTimer;
6364  std::string stdOutForSuite;
6365  std::string stdErrForSuite;
6366  unsigned int unexpectedExceptions = 0;
6367  bool m_okToFail = false;
6368  };
6369 
6370 } // end namespace Catch
6371 
6372 // end catch_reporter_junit.h
6373 // start catch_reporter_xml.h
6374 
6375 namespace Catch {
6376  class XmlReporter : public StreamingReporterBase<XmlReporter> {
6377  public:
6378  XmlReporter(ReporterConfig const& _config);
6379 
6380  ~XmlReporter() override;
6381 
6382  static std::string getDescription();
6383 
6384  virtual std::string getStylesheetRef() const;
6385 
6386  void writeSourceInfo(SourceLineInfo const& sourceInfo);
6387 
6388  public: // StreamingReporterBase
6389 
6390  void noMatchingTestCases(std::string const& s) override;
6391 
6392  void testRunStarting(TestRunInfo const& testInfo) override;
6393 
6394  void testGroupStarting(GroupInfo const& groupInfo) override;
6395 
6396  void testCaseStarting(TestCaseInfo const& testInfo) override;
6397 
6398  void sectionStarting(SectionInfo const& sectionInfo) override;
6399 
6400  void assertionStarting(AssertionInfo const&) override;
6401 
6402  bool assertionEnded(AssertionStats const& assertionStats) override;
6403 
6404  void sectionEnded(SectionStats const& sectionStats) override;
6405 
6406  void testCaseEnded(TestCaseStats const& testCaseStats) override;
6407 
6408  void testGroupEnded(TestGroupStats const& testGroupStats) override;
6409 
6410  void testRunEnded(TestRunStats const& testRunStats) override;
6411 
6412 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6413  void benchmarkPreparing(std::string const& name) override;
6414  void benchmarkStarting(BenchmarkInfo const&) override;
6415  void benchmarkEnded(BenchmarkStats<> const&) override;
6416  void benchmarkFailed(std::string const&) override;
6417 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6418 
6419  private:
6420  Timer m_testCaseTimer;
6421  XmlWriter m_xml;
6422  int m_sectionDepth = 0;
6423  };
6424 
6425 } // end namespace Catch
6426 
6427 // end catch_reporter_xml.h
6428 
6429 // end catch_external_interfaces.h
6430 #endif
6431 
6432 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6433 // start catch_benchmarking_all.hpp
6434 
6435 // A proxy header that includes all of the benchmarking headers to allow
6436 // concise include of the benchmarking features. You should prefer the
6437 // individual includes in standard use.
6438 
6439 // start catch_benchmark.hpp
6440 
6441  // Benchmark
6442 
6443 // start catch_chronometer.hpp
6444 
6445 // User-facing chronometer
6446 
6447 
6448 // start catch_clock.hpp
6449 
6450 // Clocks
6451 
6452 
6453 #include <chrono>
6454 #include <ratio>
6455 
6456 namespace Catch {
6457  namespace Benchmark {
6458  template <typename Clock>
6459  using ClockDuration = typename Clock::duration;
6460  template <typename Clock>
6461  using FloatDuration = std::chrono::duration<double, typename Clock::period>;
6462 
6463  template <typename Clock>
6464  using TimePoint = typename Clock::time_point;
6465 
6466  using default_clock = std::chrono::steady_clock;
6467 
6468  template <typename Clock>
6469  struct now {
6470  TimePoint<Clock> operator()() const {
6471  return Clock::now();
6472  }
6473  };
6474 
6475  using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
6476  } // namespace Benchmark
6477 } // namespace Catch
6478 
6479 // end catch_clock.hpp
6480 // start catch_optimizer.hpp
6481 
6482  // Hinting the optimizer
6483 
6484 
6485 #if defined(_MSC_VER)
6486 # include <atomic> // atomic_thread_fence
6487 #endif
6488 
6489 namespace Catch {
6490  namespace Benchmark {
6491 #if defined(__GNUC__) || defined(__clang__)
6492  template <typename T>
6493  inline void keep_memory(T* p) {
6494  asm volatile("" : : "g"(p) : "memory");
6495  }
6496  inline void keep_memory() {
6497  asm volatile("" : : : "memory");
6498  }
6499 
6500  namespace Detail {
6501  inline void optimizer_barrier() { keep_memory(); }
6502  } // namespace Detail
6503 #elif defined(_MSC_VER)
6504 
6505 #pragma optimize("", off)
6506  template <typename T>
6507  inline void keep_memory(T* p) {
6508  // thanks @milleniumbug
6509  *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
6510  }
6511  // TODO equivalent keep_memory()
6512 #pragma optimize("", on)
6513 
6514  namespace Detail {
6515  inline void optimizer_barrier() {
6516  std::atomic_thread_fence(std::memory_order_seq_cst);
6517  }
6518  } // namespace Detail
6519 
6520 #endif
6521 
6522  template <typename T>
6523  inline void deoptimize_value(T&& x) {
6524  keep_memory(&x);
6525  }
6526 
6527  template <typename Fn, typename... Args>
6528  inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
6529  deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
6530  }
6531 
6532  template <typename Fn, typename... Args>
6533  inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
6534  std::forward<Fn>(fn) (std::forward<Args...>(args...));
6535  }
6536  } // namespace Benchmark
6537 } // namespace Catch
6538 
6539 // end catch_optimizer.hpp
6540 // start catch_complete_invoke.hpp
6541 
6542 // Invoke with a special case for void
6543 
6544 
6545 #include <type_traits>
6546 #include <utility>
6547 
6548 namespace Catch {
6549  namespace Benchmark {
6550  namespace Detail {
6551  template <typename T>
6552  struct CompleteType { using type = T; };
6553  template <>
6554  struct CompleteType<void> { struct type {}; };
6555 
6556  template <typename T>
6557  using CompleteType_t = typename CompleteType<T>::type;
6558 
6559  template <typename Result>
6560  struct CompleteInvoker {
6561  template <typename Fun, typename... Args>
6562  static Result invoke(Fun&& fun, Args&&... args) {
6563  return std::forward<Fun>(fun)(std::forward<Args>(args)...);
6564  }
6565  };
6566  template <>
6567  struct CompleteInvoker<void> {
6568  template <typename Fun, typename... Args>
6569  static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
6570  std::forward<Fun>(fun)(std::forward<Args>(args)...);
6571  return {};
6572  }
6573  };
6574 
6575  // invoke and not return void :(
6576  template <typename Fun, typename... Args>
6577  CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
6578  return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
6579  }
6580 
6581  const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
6582  } // namespace Detail
6583 
6584  template <typename Fun>
6585  Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
6586  CATCH_TRY{
6587  return Detail::complete_invoke(std::forward<Fun>(fun));
6588  } CATCH_CATCH_ALL{
6589  getResultCapture().benchmarkFailed(translateActiveException());
6590  CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
6591  }
6592  }
6593  } // namespace Benchmark
6594 } // namespace Catch
6595 
6596 // end catch_complete_invoke.hpp
6597 namespace Catch {
6598  namespace Benchmark {
6599  namespace Detail {
6600  struct ChronometerConcept {
6601  virtual void start() = 0;
6602  virtual void finish() = 0;
6603  virtual ~ChronometerConcept() = default;
6604  };
6605  template <typename Clock>
6606  struct ChronometerModel final : public ChronometerConcept {
6607  void start() override { started = Clock::now(); }
6608  void finish() override { finished = Clock::now(); }
6609 
6610  ClockDuration<Clock> elapsed() const { return finished - started; }
6611 
6612  TimePoint<Clock> started;
6613  TimePoint<Clock> finished;
6614  };
6615  } // namespace Detail
6616 
6617  struct Chronometer {
6618  public:
6619  template <typename Fun>
6620  void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
6621 
6622  int runs() const { return k; }
6623 
6624  Chronometer(Detail::ChronometerConcept& meter, int k)
6625  : impl(&meter)
6626  , k(k) {}
6627 
6628  private:
6629  template <typename Fun>
6630  void measure(Fun&& fun, std::false_type) {
6631  measure([&fun](int) { return fun(); }, std::true_type());
6632  }
6633 
6634  template <typename Fun>
6635  void measure(Fun&& fun, std::true_type) {
6636  Detail::optimizer_barrier();
6637  impl->start();
6638  for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
6639  impl->finish();
6640  Detail::optimizer_barrier();
6641  }
6642 
6643  Detail::ChronometerConcept* impl;
6644  int k;
6645  };
6646  } // namespace Benchmark
6647 } // namespace Catch
6648 
6649 // end catch_chronometer.hpp
6650 // start catch_environment.hpp
6651 
6652 // Environment information
6653 
6654 
6655 namespace Catch {
6656  namespace Benchmark {
6657  template <typename Duration>
6658  struct EnvironmentEstimate {
6659  Duration mean;
6660  OutlierClassification outliers;
6661 
6662  template <typename Duration2>
6663  operator EnvironmentEstimate<Duration2>() const {
6664  return { mean, outliers };
6665  }
6666  };
6667  template <typename Clock>
6668  struct Environment {
6669  using clock_type = Clock;
6670  EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
6671  EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
6672  };
6673  } // namespace Benchmark
6674 } // namespace Catch
6675 
6676 // end catch_environment.hpp
6677 // start catch_execution_plan.hpp
6678 
6679  // Execution plan
6680 
6681 
6682 // start catch_benchmark_function.hpp
6683 
6684  // Dumb std::function implementation for consistent call overhead
6685 
6686 
6687 #include <cassert>
6688 #include <type_traits>
6689 #include <utility>
6690 #include <memory>
6691 
6692 namespace Catch {
6693  namespace Benchmark {
6694  namespace Detail {
6695  template <typename T>
6696  using Decay = typename std::decay<T>::type;
6697  template <typename T, typename U>
6698  struct is_related
6699  : std::is_same<Decay<T>, Decay<U>> {};
6700 
6708  struct BenchmarkFunction {
6709  private:
6710  struct callable {
6711  virtual void call(Chronometer meter) const = 0;
6712  virtual callable* clone() const = 0;
6713  virtual ~callable() = default;
6714  };
6715  template <typename Fun>
6716  struct model : public callable {
6717  model(Fun&& fun) : fun(std::move(fun)) {}
6718  model(Fun const& fun) : fun(fun) {}
6719 
6720  model<Fun>* clone() const override { return new model<Fun>(*this); }
6721 
6722  void call(Chronometer meter) const override {
6723  call(meter, is_callable<Fun(Chronometer)>());
6724  }
6725  void call(Chronometer meter, std::true_type) const {
6726  fun(meter);
6727  }
6728  void call(Chronometer meter, std::false_type) const {
6729  meter.measure(fun);
6730  }
6731 
6732  Fun fun;
6733  };
6734 
6735  struct do_nothing { void operator()() const {} };
6736 
6737  template <typename T>
6738  BenchmarkFunction(model<T>* c) : f(c) {}
6739 
6740  public:
6741  BenchmarkFunction()
6742  : f(new model<do_nothing>{ {} }) {}
6743 
6744  template <typename Fun,
6746  BenchmarkFunction(Fun&& fun)
6747  : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
6748 
6749  BenchmarkFunction(BenchmarkFunction&& that)
6750  : f(std::move(that.f)) {}
6751 
6752  BenchmarkFunction(BenchmarkFunction const& that)
6753  : f(that.f->clone()) {}
6754 
6755  BenchmarkFunction& operator=(BenchmarkFunction&& that) {
6756  f = std::move(that.f);
6757  return *this;
6758  }
6759 
6760  BenchmarkFunction& operator=(BenchmarkFunction const& that) {
6761  f.reset(that.f->clone());
6762  return *this;
6763  }
6764 
6765  void operator()(Chronometer meter) const { f->call(meter); }
6766 
6767  private:
6768  std::unique_ptr<callable> f;
6769  };
6770  } // namespace Detail
6771  } // namespace Benchmark
6772 } // namespace Catch
6773 
6774 // end catch_benchmark_function.hpp
6775 // start catch_repeat.hpp
6776 
6777 // repeat algorithm
6778 
6779 
6780 #include <type_traits>
6781 #include <utility>
6782 
6783 namespace Catch {
6784  namespace Benchmark {
6785  namespace Detail {
6786  template <typename Fun>
6787  struct repeater {
6788  void operator()(int k) const {
6789  for (int i = 0; i < k; ++i) {
6790  fun();
6791  }
6792  }
6793  Fun fun;
6794  };
6795  template <typename Fun>
6797  return { std::forward<Fun>(fun) };
6798  }
6799  } // namespace Detail
6800  } // namespace Benchmark
6801 } // namespace Catch
6802 
6803 // end catch_repeat.hpp
6804 // start catch_run_for_at_least.hpp
6805 
6806 // Run a function for a minimum amount of time
6807 
6808 
6809 // start catch_measure.hpp
6810 
6811 // Measure
6812 
6813 
6814 // start catch_timing.hpp
6815 
6816 // Timing
6817 
6818 
6819 #include <tuple>
6820 #include <type_traits>
6821 
6822 namespace Catch {
6823  namespace Benchmark {
6824  template <typename Duration, typename Result>
6825  struct Timing {
6826  Duration elapsed;
6827  Result result;
6828  int iterations;
6829  };
6830  template <typename Clock, typename Func, typename... Args>
6831  using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
6832  } // namespace Benchmark
6833 } // namespace Catch
6834 
6835 // end catch_timing.hpp
6836 #include <utility>
6837 
6838 namespace Catch {
6839  namespace Benchmark {
6840  namespace Detail {
6841  template <typename Clock, typename Fun, typename... Args>
6842  TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
6843  auto start = Clock::now();
6844  auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
6845  auto end = Clock::now();
6846  auto delta = end - start;
6847  return { delta, std::forward<decltype(r)>(r), 1 };
6848  }
6849  } // namespace Detail
6850  } // namespace Benchmark
6851 } // namespace Catch
6852 
6853 // end catch_measure.hpp
6854 #include <utility>
6855 #include <type_traits>
6856 
6857 namespace Catch {
6858  namespace Benchmark {
6859  namespace Detail {
6860  template <typename Clock, typename Fun>
6861  TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
6862  return Detail::measure<Clock>(fun, iters);
6863  }
6864  template <typename Clock, typename Fun>
6865  TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
6866  Detail::ChronometerModel<Clock> meter;
6867  auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
6868 
6869  return { meter.elapsed(), std::move(result), iters };
6870  }
6871 
6872  template <typename Clock, typename Fun>
6873  using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
6874 
6875  struct optimized_away_error : std::exception {
6876  const char* what() const noexcept override {
6877  return "could not measure benchmark, maybe it was optimized away";
6878  }
6879  };
6880 
6881  template <typename Clock, typename Fun>
6882  TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
6883  auto iters = seed;
6884  while (iters < (1 << 30)) {
6885  auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
6886 
6887  if (Timing.elapsed >= how_long) {
6888  return { Timing.elapsed, std::move(Timing.result), iters };
6889  }
6890  iters *= 2;
6891  }
6892  Catch::throw_exception(optimized_away_error{});
6893  }
6894  } // namespace Detail
6895  } // namespace Benchmark
6896 } // namespace Catch
6897 
6898 // end catch_run_for_at_least.hpp
6899 #include <algorithm>
6900 #include <iterator>
6901 
6902 namespace Catch {
6903  namespace Benchmark {
6904  template <typename Duration>
6905  struct ExecutionPlan {
6906  int iterations_per_sample;
6907  Duration estimated_duration;
6908  Detail::BenchmarkFunction benchmark;
6909  Duration warmup_time;
6910  int warmup_iterations;
6911 
6912  template <typename Duration2>
6913  operator ExecutionPlan<Duration2>() const {
6914  return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
6915  }
6916 
6917  template <typename Clock>
6918  std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
6919  // warmup a bit
6920  Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
6921 
6922  std::vector<FloatDuration<Clock>> times;
6923  times.reserve(cfg.benchmarkSamples());
6924  std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
6925  Detail::ChronometerModel<Clock> model;
6926  this->benchmark(Chronometer(model, iterations_per_sample));
6927  auto sample_time = model.elapsed() - env.clock_cost.mean;
6928  if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
6929  return sample_time / iterations_per_sample;
6930  });
6931  return times;
6932  }
6933  };
6934  } // namespace Benchmark
6935 } // namespace Catch
6936 
6937 // end catch_execution_plan.hpp
6938 // start catch_estimate_clock.hpp
6939 
6940  // Environment measurement
6941 
6942 
6943 // start catch_stats.hpp
6944 
6945 // Statistical analysis tools
6946 
6947 
6948 #include <algorithm>
6949 #include <functional>
6950 #include <vector>
6951 #include <iterator>
6952 #include <numeric>
6953 #include <tuple>
6954 #include <cmath>
6955 #include <utility>
6956 #include <cstddef>
6957 #include <random>
6958 
6959 namespace Catch {
6960  namespace Benchmark {
6961  namespace Detail {
6962  using sample = std::vector<double>;
6963 
6964  double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
6965 
6966  template <typename Iterator>
6967  OutlierClassification classify_outliers(Iterator first, Iterator last) {
6968  std::vector<double> copy(first, last);
6969 
6970  auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
6971  auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
6972  auto iqr = q3 - q1;
6973  auto los = q1 - (iqr * 3.);
6974  auto lom = q1 - (iqr * 1.5);
6975  auto him = q3 + (iqr * 1.5);
6976  auto his = q3 + (iqr * 3.);
6977 
6978  OutlierClassification o;
6979  for (; first != last; ++first) {
6980  auto&& t = *first;
6981  if (t < los) ++o.low_severe;
6982  else if (t < lom) ++o.low_mild;
6983  else if (t > his) ++o.high_severe;
6984  else if (t > him) ++o.high_mild;
6985  ++o.samples_seen;
6986  }
6987  return o;
6988  }
6989 
6990  template <typename Iterator>
6991  double mean(Iterator first, Iterator last) {
6992  auto count = last - first;
6993  double sum = std::accumulate(first, last, 0.);
6994  return sum / count;
6995  }
6996 
6997  template <typename URng, typename Iterator, typename Estimator>
6998  sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
6999  auto n = last - first;
7000  std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
7001 
7002  sample out;
7003  out.reserve(resamples);
7004  std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
7005  std::vector<double> resampled;
7006  resampled.reserve(n);
7007  std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
7008  return estimator(resampled.begin(), resampled.end());
7009  });
7010  std::sort(out.begin(), out.end());
7011  return out;
7012  }
7013 
7014  template <typename Estimator, typename Iterator>
7015  sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
7016  auto n = last - first;
7017  auto second = std::next(first);
7018  sample results;
7019  results.reserve(n);
7020 
7021  for (auto it = first; it != last; ++it) {
7022  std::iter_swap(it, first);
7023  results.push_back(estimator(second, last));
7024  }
7025 
7026  return results;
7027  }
7028 
7029  inline double normal_cdf(double x) {
7030  return std::erfc(-x / std::sqrt(2.0)) / 2.0;
7031  }
7032 
7033  double erfc_inv(double x);
7034 
7035  double normal_quantile(double p);
7036 
7037  template <typename Iterator, typename Estimator>
7038  Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
7039  auto n_samples = last - first;
7040 
7041  double point = estimator(first, last);
7042  // Degenerate case with a single sample
7043  if (n_samples == 1) return { point, point, point, confidence_level };
7044 
7045  sample jack = jackknife(estimator, first, last);
7046  double jack_mean = mean(jack.begin(), jack.end());
7047  double sum_squares, sum_cubes;
7048  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> {
7049  auto d = jack_mean - x;
7050  auto d2 = d * d;
7051  auto d3 = d2 * d;
7052  return { sqcb.first + d2, sqcb.second + d3 };
7053  });
7054 
7055  double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
7056  int n = static_cast<int>(resample.size());
7057  double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
7058  // degenerate case with uniform samples
7059  if (prob_n == 0) return { point, point, point, confidence_level };
7060 
7061  double bias = normal_quantile(prob_n);
7062  double z1 = normal_quantile((1. - confidence_level) / 2.);
7063 
7064  auto cumn = [n](double x) -> int {
7065  return std::lround(normal_cdf(x) * n); };
7066  auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
7067  double b1 = bias + z1;
7068  double b2 = bias - z1;
7069  double a1 = a(b1);
7070  double a2 = a(b2);
7071  auto lo = (std::max)(cumn(a1), 0);
7072  auto hi = (std::min)(cumn(a2), n - 1);
7073 
7074  return { point, resample[lo], resample[hi], confidence_level };
7075  }
7076 
7077  double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
7078 
7079  struct bootstrap_analysis {
7080  Estimate<double> mean;
7081  Estimate<double> standard_deviation;
7082  double outlier_variance;
7083  };
7084 
7085  bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
7086  } // namespace Detail
7087  } // namespace Benchmark
7088 } // namespace Catch
7089 
7090 // end catch_stats.hpp
7091 #include <algorithm>
7092 #include <iterator>
7093 #include <tuple>
7094 #include <vector>
7095 #include <cmath>
7096 
7097 namespace Catch {
7098  namespace Benchmark {
7099  namespace Detail {
7100  template <typename Clock>
7101  std::vector<double> resolution(int k) {
7102  std::vector<TimePoint<Clock>> times;
7103  times.reserve(k + 1);
7104  std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
7105 
7106  std::vector<double> deltas;
7107  deltas.reserve(k);
7108  std::transform(std::next(times.begin()), times.end(), times.begin(),
7109  std::back_inserter(deltas),
7110  [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
7111 
7112  return deltas;
7113  }
7114 
7115  const auto warmup_iterations = 10000;
7116  const auto warmup_time = std::chrono::milliseconds(100);
7117  const auto minimum_ticks = 1000;
7118  const auto warmup_seed = 10000;
7119  const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
7120  const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
7121  const auto clock_cost_estimation_tick_limit = 100000;
7122  const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
7123  const auto clock_cost_estimation_iterations = 10000;
7124 
7125  template <typename Clock>
7126  int warmup() {
7127  return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
7128  .iterations;
7129  }
7130  template <typename Clock>
7131  EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
7132  auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
7133  .result;
7134  return {
7135  FloatDuration<Clock>(mean(r.begin(), r.end())),
7136  classify_outliers(r.begin(), r.end()),
7137  };
7138  }
7139  template <typename Clock>
7140  EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
7141  auto time_limit = (std::min)(
7142  resolution * clock_cost_estimation_tick_limit,
7143  FloatDuration<Clock>(clock_cost_estimation_time_limit));
7144  auto time_clock = [](int k) {
7145  return Detail::measure<Clock>([k] {
7146  for (int i = 0; i < k; ++i) {
7147  volatile auto ignored = Clock::now();
7148  (void)ignored;
7149  }
7150  }).elapsed;
7151  };
7152  time_clock(1);
7153  int iters = clock_cost_estimation_iterations;
7154  auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
7155  std::vector<double> times;
7156  int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
7157  times.reserve(nsamples);
7158  std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
7159  return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
7160  });
7161  return {
7162  FloatDuration<Clock>(mean(times.begin(), times.end())),
7163  classify_outliers(times.begin(), times.end()),
7164  };
7165  }
7166 
7167  template <typename Clock>
7168  Environment<FloatDuration<Clock>> measure_environment() {
7169  static Environment<FloatDuration<Clock>>* env = nullptr;
7170  if (env) {
7171  return *env;
7172  }
7173 
7174  auto iters = Detail::warmup<Clock>();
7175  auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
7176  auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
7177 
7178  env = new Environment<FloatDuration<Clock>>{ resolution, cost };
7179  return *env;
7180  }
7181  } // namespace Detail
7182  } // namespace Benchmark
7183 } // namespace Catch
7184 
7185 // end catch_estimate_clock.hpp
7186 // start catch_analyse.hpp
7187 
7188  // Run and analyse one benchmark
7189 
7190 
7191 // start catch_sample_analysis.hpp
7192 
7193 // Benchmark results
7194 
7195 
7196 #include <algorithm>
7197 #include <vector>
7198 #include <string>
7199 #include <iterator>
7200 
7201 namespace Catch {
7202  namespace Benchmark {
7203  template <typename Duration>
7204  struct SampleAnalysis {
7205  std::vector<Duration> samples;
7206  Estimate<Duration> mean;
7207  Estimate<Duration> standard_deviation;
7208  OutlierClassification outliers;
7209  double outlier_variance;
7210 
7211  template <typename Duration2>
7212  operator SampleAnalysis<Duration2>() const {
7213  std::vector<Duration2> samples2;
7214  samples2.reserve(samples.size());
7215  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
7216  return {
7217  std::move(samples2),
7218  mean,
7219  standard_deviation,
7220  outliers,
7221  outlier_variance,
7222  };
7223  }
7224  };
7225  } // namespace Benchmark
7226 } // namespace Catch
7227 
7228 // end catch_sample_analysis.hpp
7229 #include <algorithm>
7230 #include <iterator>
7231 #include <vector>
7232 
7233 namespace Catch {
7234  namespace Benchmark {
7235  namespace Detail {
7236  template <typename Duration, typename Iterator>
7237  SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
7238  if (!cfg.benchmarkNoAnalysis()) {
7239  std::vector<double> samples;
7240  samples.reserve(last - first);
7241  std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
7242 
7243  auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
7244  auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
7245 
7246  auto wrap_estimate = [](Estimate<double> e) {
7247  return Estimate<Duration> {
7248  Duration(e.point),
7249  Duration(e.lower_bound),
7250  Duration(e.upper_bound),
7251  e.confidence_interval,
7252  };
7253  };
7254  std::vector<Duration> samples2;
7255  samples2.reserve(samples.size());
7256  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
7257  return {
7258  std::move(samples2),
7259  wrap_estimate(analysis.mean),
7260  wrap_estimate(analysis.standard_deviation),
7261  outliers,
7262  analysis.outlier_variance,
7263  };
7264  } else {
7265  std::vector<Duration> samples;
7266  samples.reserve(last - first);
7267 
7268  Duration mean = Duration(0);
7269  int i = 0;
7270  for (auto it = first; it < last; ++it, ++i) {
7271  samples.push_back(Duration(*it));
7272  mean += Duration(*it);
7273  }
7274  mean /= i;
7275 
7276  return {
7277  std::move(samples),
7278  Estimate<Duration>{mean, mean, mean, 0.0},
7279  Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
7280  OutlierClassification{},
7281  0.0
7282  };
7283  }
7284  }
7285  } // namespace Detail
7286  } // namespace Benchmark
7287 } // namespace Catch
7288 
7289 // end catch_analyse.hpp
7290 #include <algorithm>
7291 #include <functional>
7292 #include <string>
7293 #include <vector>
7294 #include <cmath>
7295 
7296 namespace Catch {
7297  namespace Benchmark {
7298  struct Benchmark {
7300  : name(std::move(name)) {}
7301 
7302  template <class FUN>
7303  Benchmark(std::string &&name, FUN &&func)
7304  : fun(std::move(func)), name(std::move(name)) {}
7305 
7306  template <typename Clock>
7307  ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
7308  auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
7309  auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
7310  auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
7311  int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
7312  return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
7313  }
7314 
7315  template <typename Clock = default_clock>
7316  void run() {
7318 
7319  auto env = Detail::measure_environment<Clock>();
7320 
7321  getResultCapture().benchmarkPreparing(name);
7322  CATCH_TRY{
7323  auto plan = user_code([&] {
7324  return prepare<Clock>(*cfg, env);
7325  });
7326 
7327  BenchmarkInfo info {
7328  name,
7329  plan.estimated_duration.count(),
7330  plan.iterations_per_sample,
7331  cfg->benchmarkSamples(),
7332  cfg->benchmarkResamples(),
7333  env.clock_resolution.mean.count(),
7334  env.clock_cost.mean.count()
7335  };
7336 
7337  getResultCapture().benchmarkStarting(info);
7338 
7339  auto samples = user_code([&] {
7340  return plan.template run<Clock>(*cfg, env);
7341  });
7342 
7343  auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
7344  BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
7345  getResultCapture().benchmarkEnded(stats);
7346 
7347  } CATCH_CATCH_ALL{
7348  if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
7349  std::rethrow_exception(std::current_exception());
7350  }
7351  }
7352 
7353  // sets lambda to be used in fun *and* executes benchmark!
7354  template <typename Fun,
7356  Benchmark & operator=(Fun func) {
7357  fun = Detail::BenchmarkFunction(func);
7358  run();
7359  return *this;
7360  }
7361 
7362  explicit operator bool() {
7363  return true;
7364  }
7365 
7366  private:
7367  Detail::BenchmarkFunction fun;
7368  std::string name;
7369  };
7370  }
7371 } // namespace Catch
7372 
7373 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
7374 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
7375 
7376 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
7377  if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7378  BenchmarkName = [&](int benchmarkIndex)
7379 
7380 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
7381  if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7382  BenchmarkName = [&]
7383 
7384 // end catch_benchmark.hpp
7385 // start catch_constructor.hpp
7386 
7387 // Constructor and destructor helpers
7388 
7389 
7390 #include <type_traits>
7391 
7392 namespace Catch {
7393  namespace Benchmark {
7394  namespace Detail {
7395  template <typename T, bool Destruct>
7396  struct ObjectStorage
7397  {
7398  using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
7399 
7400  ObjectStorage() : data() {}
7401 
7402  ObjectStorage(const ObjectStorage& other)
7403  {
7404  new(&data) T(other.stored_object());
7405  }
7406 
7407  ObjectStorage(ObjectStorage&& other)
7408  {
7409  new(&data) T(std::move(other.stored_object()));
7410  }
7411 
7412  ~ObjectStorage() { destruct_on_exit<T>(); }
7413 
7414  template <typename... Args>
7415  void construct(Args&&... args)
7416  {
7417  new (&data) T(std::forward<Args>(args)...);
7418  }
7419 
7420  template <bool AllowManualDestruction = !Destruct>
7422  {
7423  stored_object().~T();
7424  }
7425 
7426  private:
7427  // If this is a constructor benchmark, destruct the underlying object
7428  template <typename U>
7429  void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
7430  // Otherwise, don't
7431  template <typename U>
7432  void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
7433 
7434  T& stored_object() {
7435  return *static_cast<T*>(static_cast<void*>(&data));
7436  }
7437 
7438  T const& stored_object() const {
7439  return *static_cast<T*>(static_cast<void*>(&data));
7440  }
7441 
7442  TStorage data;
7443  };
7444  }
7445 
7446  template <typename T>
7447  using storage_for = Detail::ObjectStorage<T, true>;
7448 
7449  template <typename T>
7450  using destructable_object = Detail::ObjectStorage<T, false>;
7451  }
7452 }
7453 
7454 // end catch_constructor.hpp
7455 // end catch_benchmarking_all.hpp
7456 #endif
7457 
7458 #endif // ! CATCH_CONFIG_IMPL_ONLY
7459 
7460 #ifdef CATCH_IMPL
7461 // start catch_impl.hpp
7462 
7463 #ifdef __clang__
7464 #pragma clang diagnostic push
7465 #pragma clang diagnostic ignored "-Wweak-vtables"
7466 #endif
7467 
7468 // Keep these here for external reporters
7469 // start catch_test_case_tracker.h
7470 
7471 #include <string>
7472 #include <vector>
7473 #include <memory>
7474 
7475 namespace Catch {
7476 namespace TestCaseTracking {
7477 
7478  struct NameAndLocation {
7479  std::string name;
7480  SourceLineInfo location;
7481 
7482  NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
7483  friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
7484  return lhs.name == rhs.name
7485  && lhs.location == rhs.location;
7486  }
7487  };
7488 
7489  class ITracker;
7490 
7491  using ITrackerPtr = std::shared_ptr<ITracker>;
7492 
7493  class ITracker {
7494  NameAndLocation m_nameAndLocation;
7495 
7496  public:
7497  ITracker(NameAndLocation const& nameAndLoc) :
7498  m_nameAndLocation(nameAndLoc)
7499  {}
7500 
7501  // static queries
7502  NameAndLocation const& nameAndLocation() const {
7503  return m_nameAndLocation;
7504  }
7505 
7506  virtual ~ITracker();
7507 
7508  // dynamic queries
7509  virtual bool isComplete() const = 0; // Successfully completed or failed
7510  virtual bool isSuccessfullyCompleted() const = 0;
7511  virtual bool isOpen() const = 0; // Started but not complete
7512  virtual bool hasChildren() const = 0;
7513  virtual bool hasStarted() const = 0;
7514 
7515  virtual ITracker& parent() = 0;
7516 
7517  // actions
7518  virtual void close() = 0; // Successfully complete
7519  virtual void fail() = 0;
7520  virtual void markAsNeedingAnotherRun() = 0;
7521 
7522  virtual void addChild( ITrackerPtr const& child ) = 0;
7523  virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
7524  virtual void openChild() = 0;
7525 
7526  // Debug/ checking
7527  virtual bool isSectionTracker() const = 0;
7528  virtual bool isGeneratorTracker() const = 0;
7529  };
7530 
7531  class TrackerContext {
7532 
7533  enum RunState {
7534  NotStarted,
7535  Executing,
7536  CompletedCycle
7537  };
7538 
7539  ITrackerPtr m_rootTracker;
7540  ITracker* m_currentTracker = nullptr;
7541  RunState m_runState = NotStarted;
7542 
7543  public:
7544 
7545  ITracker& startRun();
7546  void endRun();
7547 
7548  void startCycle();
7549  void completeCycle();
7550 
7551  bool completedCycle() const;
7552  ITracker& currentTracker();
7553  void setCurrentTracker( ITracker* tracker );
7554  };
7555 
7556  class TrackerBase : public ITracker {
7557  protected:
7558  enum CycleState {
7559  NotStarted,
7560  Executing,
7561  ExecutingChildren,
7562  NeedsAnotherRun,
7563  CompletedSuccessfully,
7564  Failed
7565  };
7566 
7567  using Children = std::vector<ITrackerPtr>;
7568  TrackerContext& m_ctx;
7569  ITracker* m_parent;
7570  Children m_children;
7571  CycleState m_runState = NotStarted;
7572 
7573  public:
7574  TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7575 
7576  bool isComplete() const override;
7577  bool isSuccessfullyCompleted() const override;
7578  bool isOpen() const override;
7579  bool hasChildren() const override;
7580  bool hasStarted() const override {
7581  return m_runState != NotStarted;
7582  }
7583 
7584  void addChild( ITrackerPtr const& child ) override;
7585 
7586  ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
7587  ITracker& parent() override;
7588 
7589  void openChild() override;
7590 
7591  bool isSectionTracker() const override;
7592  bool isGeneratorTracker() const override;
7593 
7594  void open();
7595 
7596  void close() override;
7597  void fail() override;
7598  void markAsNeedingAnotherRun() override;
7599 
7600  private:
7601  void moveToParent();
7602  void moveToThis();
7603  };
7604 
7605  class SectionTracker : public TrackerBase {
7606  std::vector<std::string> m_filters;
7607  std::string m_trimmed_name;
7608  public:
7609  SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7610 
7611  bool isSectionTracker() const override;
7612 
7613  bool isComplete() const override;
7614 
7615  static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
7616 
7617  void tryOpen();
7618 
7619  void addInitialFilters( std::vector<std::string> const& filters );
7620  void addNextFilters( std::vector<std::string> const& filters );
7622  std::vector<std::string> const& getFilters() const;
7624  std::string const& trimmedName() const;
7625  };
7626 
7627 } // namespace TestCaseTracking
7628 
7629 using TestCaseTracking::ITracker;
7630 using TestCaseTracking::TrackerContext;
7631 using TestCaseTracking::SectionTracker;
7632 
7633 } // namespace Catch
7634 
7635 // end catch_test_case_tracker.h
7636 
7637 // start catch_leak_detector.h
7638 
7639 namespace Catch {
7640 
7641  struct LeakDetector {
7642  LeakDetector();
7643  ~LeakDetector();
7644  };
7645 
7646 }
7647 // end catch_leak_detector.h
7648 // Cpp files will be included in the single-header file here
7649 // start catch_stats.cpp
7650 
7651 // Statistical analysis tools
7652 
7653 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
7654 
7655 #include <cassert>
7656 #include <random>
7657 
7658 #if defined(CATCH_CONFIG_USE_ASYNC)
7659 #include <future>
7660 #endif
7661 
7662 namespace {
7663  double erf_inv(double x) {
7664  // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
7665  double w, p;
7666 
7667  w = -log((1.0 - x) * (1.0 + x));
7668 
7669  if (w < 6.250000) {
7670  w = w - 3.125000;
7671  p = -3.6444120640178196996e-21;
7672  p = -1.685059138182016589e-19 + p * w;
7673  p = 1.2858480715256400167e-18 + p * w;
7674  p = 1.115787767802518096e-17 + p * w;
7675  p = -1.333171662854620906e-16 + p * w;
7676  p = 2.0972767875968561637e-17 + p * w;
7677  p = 6.6376381343583238325e-15 + p * w;
7678  p = -4.0545662729752068639e-14 + p * w;
7679  p = -8.1519341976054721522e-14 + p * w;
7680  p = 2.6335093153082322977e-12 + p * w;
7681  p = -1.2975133253453532498e-11 + p * w;
7682  p = -5.4154120542946279317e-11 + p * w;
7683  p = 1.051212273321532285e-09 + p * w;
7684  p = -4.1126339803469836976e-09 + p * w;
7685  p = -2.9070369957882005086e-08 + p * w;
7686  p = 4.2347877827932403518e-07 + p * w;
7687  p = -1.3654692000834678645e-06 + p * w;
7688  p = -1.3882523362786468719e-05 + p * w;
7689  p = 0.0001867342080340571352 + p * w;
7690  p = -0.00074070253416626697512 + p * w;
7691  p = -0.0060336708714301490533 + p * w;
7692  p = 0.24015818242558961693 + p * w;
7693  p = 1.6536545626831027356 + p * w;
7694  } else if (w < 16.000000) {
7695  w = sqrt(w) - 3.250000;
7696  p = 2.2137376921775787049e-09;
7697  p = 9.0756561938885390979e-08 + p * w;
7698  p = -2.7517406297064545428e-07 + p * w;
7699  p = 1.8239629214389227755e-08 + p * w;
7700  p = 1.5027403968909827627e-06 + p * w;
7701  p = -4.013867526981545969e-06 + p * w;
7702  p = 2.9234449089955446044e-06 + p * w;
7703  p = 1.2475304481671778723e-05 + p * w;
7704  p = -4.7318229009055733981e-05 + p * w;
7705  p = 6.8284851459573175448e-05 + p * w;
7706  p = 2.4031110387097893999e-05 + p * w;
7707  p = -0.0003550375203628474796 + p * w;
7708  p = 0.00095328937973738049703 + p * w;
7709  p = -0.0016882755560235047313 + p * w;
7710  p = 0.0024914420961078508066 + p * w;
7711  p = -0.0037512085075692412107 + p * w;
7712  p = 0.005370914553590063617 + p * w;
7713  p = 1.0052589676941592334 + p * w;
7714  p = 3.0838856104922207635 + p * w;
7715  } else {
7716  w = sqrt(w) - 5.000000;
7717  p = -2.7109920616438573243e-11;
7718  p = -2.5556418169965252055e-10 + p * w;
7719  p = 1.5076572693500548083e-09 + p * w;
7720  p = -3.7894654401267369937e-09 + p * w;
7721  p = 7.6157012080783393804e-09 + p * w;
7722  p = -1.4960026627149240478e-08 + p * w;
7723  p = 2.9147953450901080826e-08 + p * w;
7724  p = -6.7711997758452339498e-08 + p * w;
7725  p = 2.2900482228026654717e-07 + p * w;
7726  p = -9.9298272942317002539e-07 + p * w;
7727  p = 4.5260625972231537039e-06 + p * w;
7728  p = -1.9681778105531670567e-05 + p * w;
7729  p = 7.5995277030017761139e-05 + p * w;
7730  p = -0.00021503011930044477347 + p * w;
7731  p = -0.00013871931833623122026 + p * w;
7732  p = 1.0103004648645343977 + p * w;
7733  p = 4.8499064014085844221 + p * w;
7734  }
7735  return p * x;
7736  }
7737 
7738  double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
7739  auto m = Catch::Benchmark::Detail::mean(first, last);
7740  double variance = std::accumulate(first, last, 0., [m](double a, double b) {
7741  double diff = b - m;
7742  return a + diff * diff;
7743  }) / (last - first);
7744  return std::sqrt(variance);
7745  }
7746 
7747 }
7748 
7749 namespace Catch {
7750  namespace Benchmark {
7751  namespace Detail {
7752 
7753  double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7754  auto count = last - first;
7755  double idx = (count - 1) * k / static_cast<double>(q);
7756  int j = static_cast<int>(idx);
7757  double g = idx - j;
7758  std::nth_element(first, first + j, last);
7759  auto xj = first[j];
7760  if (g == 0) return xj;
7761 
7762  auto xj1 = *std::min_element(first + (j + 1), last);
7763  return xj + g * (xj1 - xj);
7764  }
7765 
7766  double erfc_inv(double x) {
7767  return erf_inv(1.0 - x);
7768  }
7769 
7770  double normal_quantile(double p) {
7771  static const double ROOT_TWO = std::sqrt(2.0);
7772 
7773  double result = 0.0;
7774  assert(p >= 0 && p <= 1);
7775  if (p < 0 || p > 1) {
7776  return result;
7777  }
7778 
7779  result = -erfc_inv(2.0 * p);
7780  // result *= normal distribution standard deviation (1.0) * sqrt(2)
7781  result *= /*sd * */ ROOT_TWO;
7782  // result += normal disttribution mean (0)
7783  return result;
7784  }
7785 
7786  double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
7787  double sb = stddev.point;
7788  double mn = mean.point / n;
7789  double mg_min = mn / 2.;
7790  double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
7791  double sg2 = sg * sg;
7792  double sb2 = sb * sb;
7793 
7794  auto c_max = [n, mn, sb2, sg2](double x) -> double {
7795  double k = mn - x;
7796  double d = k * k;
7797  double nd = n * d;
7798  double k0 = -n * nd;
7799  double k1 = sb2 - n * sg2 + nd;
7800  double det = k1 * k1 - 4 * sg2 * k0;
7801  return (int)(-2. * k0 / (k1 + std::sqrt(det)));
7802  };
7803 
7804  auto var_out = [n, sb2, sg2](double c) {
7805  double nc = n - c;
7806  return (nc / n) * (sb2 - nc * sg2);
7807  };
7808 
7809  return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
7810  }
7811 
7812  bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7815  static std::random_device entropy;
7817 
7818  auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
7819 
7821  auto stddev = &standard_deviation;
7822 
7823 #if defined(CATCH_CONFIG_USE_ASYNC)
7824  auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7825  auto seed = entropy();
7826  return std::async(std::launch::async, [=] {
7827  std::mt19937 rng(seed);
7828  auto resampled = resample(rng, n_resamples, first, last, f);
7829  return bootstrap(confidence_level, first, last, resampled, f);
7830  });
7831  };
7832 
7833  auto mean_future = Estimate(mean);
7834  auto stddev_future = Estimate(stddev);
7835 
7836  auto mean_estimate = mean_future.get();
7837  auto stddev_estimate = stddev_future.get();
7838 #else
7839  auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7840  auto seed = entropy();
7841  std::mt19937 rng(seed);
7842  auto resampled = resample(rng, n_resamples, first, last, f);
7843  return bootstrap(confidence_level, first, last, resampled, f);
7844  };
7845 
7846  auto mean_estimate = Estimate(mean);
7847  auto stddev_estimate = Estimate(stddev);
7848 #endif // CATCH_USE_ASYNC
7849 
7850  double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
7851 
7852  return { mean_estimate, stddev_estimate, outlier_variance };
7853  }
7854  } // namespace Detail
7855  } // namespace Benchmark
7856 } // namespace Catch
7857 
7858 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
7859 // end catch_stats.cpp
7860 // start catch_approx.cpp
7861 
7862 #include <cmath>
7863 #include <limits>
7864 
7865 namespace {
7866 
7867 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
7868 // But without the subtraction to allow for INFINITY in comparison
7869 bool marginComparison(double lhs, double rhs, double margin) {
7870  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
7871 }
7872 
7873 }
7874 
7875 namespace Catch {
7876 namespace Detail {
7877 
7878  Approx::Approx ( double value )
7879  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
7880  m_margin( 0.0 ),
7881  m_scale( 0.0 ),
7882  m_value( value )
7883  {}
7884 
7885  Approx Approx::custom() {
7886  return Approx( 0 );
7887  }
7888 
7889  Approx Approx::operator-() const {
7890  auto temp(*this);
7891  temp.m_value = -temp.m_value;
7892  return temp;
7893  }
7894 
7895  std::string Approx::toString() const {
7896  ReusableStringStream rss;
7897  rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
7898  return rss.str();
7899  }
7900 
7901  bool Approx::equalityComparisonImpl(const double other) const {
7902  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
7903  // Thanks to Richard Harris for his help refining the scaled margin value
7904  return marginComparison(m_value, other, m_margin)
7905  || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
7906  }
7907 
7908  void Approx::setMargin(double newMargin) {
7909  CATCH_ENFORCE(newMargin >= 0,
7910  "Invalid Approx::margin: " << newMargin << '.'
7911  << " Approx::Margin has to be non-negative.");
7912  m_margin = newMargin;
7913  }
7914 
7915  void Approx::setEpsilon(double newEpsilon) {
7916  CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
7917  "Invalid Approx::epsilon: " << newEpsilon << '.'
7918  << " Approx::epsilon has to be in [0, 1]");
7919  m_epsilon = newEpsilon;
7920  }
7921 
7922 } // end namespace Detail
7923 
7924 namespace literals {
7925  Detail::Approx operator "" _a(long double val) {
7926  return Detail::Approx(val);
7927  }
7928  Detail::Approx operator "" _a(unsigned long long val) {
7929  return Detail::Approx(val);
7930  }
7931 } // end namespace literals
7932 
7934  return value.toString();
7935 }
7936 
7937 } // end namespace Catch
7938 // end catch_approx.cpp
7939 // start catch_assertionhandler.cpp
7940 
7941 // start catch_debugger.h
7942 
7943 namespace Catch {
7944  bool isDebuggerActive();
7945 }
7946 
7947 #ifdef CATCH_PLATFORM_MAC
7948 
7949  #if defined(__i386__) || defined(__x86_64__)
7950  #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
7951  #elif defined(__aarch64__)
7952  #define CATCH_TRAP() __asm__(".inst 0xd4200000")
7953  #endif
7954 
7955 #elif defined(CATCH_PLATFORM_IPHONE)
7956 
7957  // use inline assembler
7958  #if defined(__i386__) || defined(__x86_64__)
7959  #define CATCH_TRAP() __asm__("int $3")
7960  #elif defined(__aarch64__)
7961  #define CATCH_TRAP() __asm__(".inst 0xd4200000")
7962  #elif defined(__arm__) && !defined(__thumb__)
7963  #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
7964  #elif defined(__arm__) && defined(__thumb__)
7965  #define CATCH_TRAP() __asm__(".inst 0xde01")
7966  #endif
7967 
7968 #elif defined(CATCH_PLATFORM_LINUX)
7969  // If we can use inline assembler, do it because this allows us to break
7970  // directly at the location of the failing check instead of breaking inside
7971  // raise() called from it, i.e. one stack frame below.
7972  #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
7973  #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
7974  #else // Fall back to the generic way.
7975  #include <signal.h>
7976 
7977  #define CATCH_TRAP() raise(SIGTRAP)
7978  #endif
7979 #elif defined(_MSC_VER)
7980  #define CATCH_TRAP() __debugbreak()
7981 #elif defined(__MINGW32__)
7982  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
7983  #define CATCH_TRAP() DebugBreak()
7984 #endif
7985 
7986 #ifndef CATCH_BREAK_INTO_DEBUGGER
7987  #ifdef CATCH_TRAP
7988  #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
7989  #else
7990  #define CATCH_BREAK_INTO_DEBUGGER() []{}()
7991  #endif
7992 #endif
7993 
7994 // end catch_debugger.h
7995 // start catch_run_context.h
7996 
7997 // start catch_fatal_condition.h
7998 
7999 #include <cassert>
8000 
8001 namespace Catch {
8002 
8003  // Wrapper for platform-specific fatal error (signals/SEH) handlers
8004  //
8005  // Tries to be cooperative with other handlers, and not step over
8006  // other handlers. This means that unknown structured exceptions
8007  // are passed on, previous signal handlers are called, and so on.
8008  //
8009  // Can only be instantiated once, and assumes that once a signal
8010  // is caught, the binary will end up terminating. Thus, there
8011  class FatalConditionHandler {
8012  bool m_started = false;
8013 
8014  // Install/disengage implementation for specific platform.
8015  // Should be if-defed to work on current platform, can assume
8016  // engage-disengage 1:1 pairing.
8017  void engage_platform();
8018  void disengage_platform();
8019  public:
8020  // Should also have platform-specific implementations as needed
8021  FatalConditionHandler();
8022  ~FatalConditionHandler();
8023 
8024  void engage() {
8025  assert(!m_started && "Handler cannot be installed twice.");
8026  m_started = true;
8027  engage_platform();
8028  }
8029 
8030  void disengage() {
8031  assert(m_started && "Handler cannot be uninstalled without being installed first");
8032  m_started = false;
8033  disengage_platform();
8034  }
8035  };
8036 
8038  class FatalConditionHandlerGuard {
8039  FatalConditionHandler* m_handler;
8040  public:
8041  FatalConditionHandlerGuard(FatalConditionHandler* handler):
8042  m_handler(handler) {
8043  m_handler->engage();
8044  }
8045  ~FatalConditionHandlerGuard() {
8046  m_handler->disengage();
8047  }
8048  };
8049 
8050 } // end namespace Catch
8051 
8052 // end catch_fatal_condition.h
8053 #include <string>
8054 
8055 namespace Catch {
8056 
8057  struct IMutableContext;
8058 
8060 
8061  class RunContext : public IResultCapture, public IRunner {
8062 
8063  public:
8064  RunContext( RunContext const& ) = delete;
8065  RunContext& operator =( RunContext const& ) = delete;
8066 
8067  explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
8068 
8069  ~RunContext() override;
8070 
8071  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
8072  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
8073 
8074  Totals runTest(TestCase const& testCase);
8075 
8076  IConfigPtr config() const;
8077  IStreamingReporter& reporter() const;
8078 
8079  public: // IResultCapture
8080 
8081  // Assertion handlers
8082  void handleExpr
8083  ( AssertionInfo const& info,
8084  ITransientExpression const& expr,
8085  AssertionReaction& reaction ) override;
8086  void handleMessage
8087  ( AssertionInfo const& info,
8088  ResultWas::OfType resultType,
8089  StringRef const& message,
8090  AssertionReaction& reaction ) override;
8091  void handleUnexpectedExceptionNotThrown
8092  ( AssertionInfo const& info,
8093  AssertionReaction& reaction ) override;
8094  void handleUnexpectedInflightException
8095  ( AssertionInfo const& info,
8096  std::string const& message,
8097  AssertionReaction& reaction ) override;
8098  void handleIncomplete
8099  ( AssertionInfo const& info ) override;
8100  void handleNonExpr
8101  ( AssertionInfo const &info,
8102  ResultWas::OfType resultType,
8103  AssertionReaction &reaction ) override;
8104 
8105  bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
8106 
8107  void sectionEnded( SectionEndInfo const& endInfo ) override;
8108  void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
8109 
8110  auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
8111 
8112 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
8113  void benchmarkPreparing( std::string const& name ) override;
8114  void benchmarkStarting( BenchmarkInfo const& info ) override;
8115  void benchmarkEnded( BenchmarkStats<> const& stats ) override;
8116  void benchmarkFailed( std::string const& error ) override;
8117 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
8118 
8119  void pushScopedMessage( MessageInfo const& message ) override;
8120  void popScopedMessage( MessageInfo const& message ) override;
8121 
8122  void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
8123 
8124  std::string getCurrentTestName() const override;
8125 
8126  const AssertionResult* getLastResult() const override;
8127 
8128  void exceptionEarlyReported() override;
8129 
8130  void handleFatalErrorCondition( StringRef message ) override;
8131 
8132  bool lastAssertionPassed() override;
8133 
8134  void assertionPassed() override;
8135 
8136  public:
8137  // !TBD We need to do this another way!
8138  bool aborting() const final;
8139 
8140  private:
8141 
8142  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
8143  void invokeActiveTestCase();
8144 
8145  void resetAssertionInfo();
8146  bool testForMissingAssertions( Counts& assertions );
8147 
8148  void assertionEnded( AssertionResult const& result );
8149  void reportExpr
8150  ( AssertionInfo const &info,
8151  ResultWas::OfType resultType,
8152  ITransientExpression const *expr,
8153  bool negated );
8154 
8155  void populateReaction( AssertionReaction& reaction );
8156 
8157  private:
8158 
8159  void handleUnfinishedSections();
8160 
8161  TestRunInfo m_runInfo;
8162  IMutableContext& m_context;
8163  TestCase const* m_activeTestCase = nullptr;
8164  ITracker* m_testCaseTracker = nullptr;
8165  Option<AssertionResult> m_lastResult;
8166 
8167  IConfigPtr m_config;
8168  Totals m_totals;
8169  IStreamingReporterPtr m_reporter;
8170  std::vector<MessageInfo> m_messages;
8171  std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
8172  AssertionInfo m_lastAssertionInfo;
8173  std::vector<SectionEndInfo> m_unfinishedSections;
8174  std::vector<ITracker*> m_activeSections;
8175  TrackerContext m_trackerContext;
8176  FatalConditionHandler m_fatalConditionhandler;
8177  bool m_lastAssertionPassed = false;
8178  bool m_shouldReportUnexpected = true;
8179  bool m_includeSuccessfulResults;
8180  };
8181 
8182  void seedRng(IConfig const& config);
8183  unsigned int rngSeed();
8184 } // end namespace Catch
8185 
8186 // end catch_run_context.h
8187 namespace Catch {
8188 
8189  namespace {
8190  auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
8191  expr.streamReconstructedExpression( os );
8192  return os;
8193  }
8194  }
8195 
8196  LazyExpression::LazyExpression( bool isNegated )
8197  : m_isNegated( isNegated )
8198  {}
8199 
8200  LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
8201 
8202  LazyExpression::operator bool() const {
8203  return m_transientExpression != nullptr;
8204  }
8205 
8206  auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
8207  if( lazyExpr.m_isNegated )
8208  os << "!";
8209 
8210  if( lazyExpr ) {
8211  if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
8212  os << "(" << *lazyExpr.m_transientExpression << ")";
8213  else
8214  os << *lazyExpr.m_transientExpression;
8215  }
8216  else {
8217  os << "{** error - unchecked empty expression requested **}";
8218  }
8219  return os;
8220  }
8221 
8223  ( StringRef const& macroName,
8224  SourceLineInfo const& lineInfo,
8225  StringRef capturedExpression,
8226  ResultDisposition::Flags resultDisposition )
8227  : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
8228  m_resultCapture( getResultCapture() )
8229  {}
8230 
8231  void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
8232  m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
8233  }
8234  void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
8235  m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
8236  }
8237 
8238  auto AssertionHandler::allowThrows() const -> bool {
8239  return getCurrentContext().getConfig()->allowThrows();
8240  }
8241 
8243  setCompleted();
8244  if( m_reaction.shouldDebugBreak ) {
8245 
8246  // If you find your debugger stopping you here then go one level up on the
8247  // call-stack for the code that caused it (typically a failed assertion)
8248 
8249  // (To go back to the test and change execution, jump over the throw, next)
8250  CATCH_BREAK_INTO_DEBUGGER();
8251  }
8252  if (m_reaction.shouldThrow) {
8253 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8255 #else
8256  CATCH_ERROR( "Test failure requires aborting test!" );
8257 #endif
8258  }
8259  }
8261  m_completed = true;
8262  }
8263 
8265  m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
8266  }
8267 
8269  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8270  }
8272  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8273  }
8274 
8276  m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
8277  }
8278 
8280  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8281  }
8282 
8283  // This is the overload that takes a string and infers the Equals matcher from it
8284  // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
8285  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
8286  handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
8287  }
8288 
8289 } // namespace Catch
8290 // end catch_assertionhandler.cpp
8291 // start catch_assertionresult.cpp
8292 
8293 namespace Catch {
8294  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
8295  lazyExpression(_lazyExpression),
8296  resultType(_resultType) {}
8297 
8298  std::string AssertionResultData::reconstructExpression() const {
8299 
8300  if( reconstructedExpression.empty() ) {
8301  if( lazyExpression ) {
8302  ReusableStringStream rss;
8303  rss << lazyExpression;
8304  reconstructedExpression = rss.str();
8305  }
8306  }
8307  return reconstructedExpression;
8308  }
8309 
8310  AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
8311  : m_info( info ),
8312  m_resultData( data )
8313  {}
8314 
8315  // Result was a success
8316  bool AssertionResult::succeeded() const {
8317  return Catch::isOk( m_resultData.resultType );
8318  }
8319 
8320  // Result was a success, or failure is suppressed
8321  bool AssertionResult::isOk() const {
8322  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
8323  }
8324 
8325  ResultWas::OfType AssertionResult::getResultType() const {
8326  return m_resultData.resultType;
8327  }
8328 
8329  bool AssertionResult::hasExpression() const {
8330  return !m_info.capturedExpression.empty();
8331  }
8332 
8333  bool AssertionResult::hasMessage() const {
8334  return !m_resultData.message.empty();
8335  }
8336 
8337  std::string AssertionResult::getExpression() const {
8338  // Possibly overallocating by 3 characters should be basically free
8339  std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
8340  if (isFalseTest(m_info.resultDisposition)) {
8341  expr += "!(";
8342  }
8343  expr += m_info.capturedExpression;
8344  if (isFalseTest(m_info.resultDisposition)) {
8345  expr += ')';
8346  }
8347  return expr;
8348  }
8349 
8350  std::string AssertionResult::getExpressionInMacro() const {
8351  std::string expr;
8352  if( m_info.macroName.empty() )
8353  expr = static_cast<std::string>(m_info.capturedExpression);
8354  else {
8355  expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
8356  expr += m_info.macroName;
8357  expr += "( ";
8358  expr += m_info.capturedExpression;
8359  expr += " )";
8360  }
8361  return expr;
8362  }
8363 
8364  bool AssertionResult::hasExpandedExpression() const {
8365  return hasExpression() && getExpandedExpression() != getExpression();
8366  }
8367 
8368  std::string AssertionResult::getExpandedExpression() const {
8369  std::string expr = m_resultData.reconstructExpression();
8370  return expr.empty()
8371  ? getExpression()
8372  : expr;
8373  }
8374 
8375  std::string AssertionResult::getMessage() const {
8376  return m_resultData.message;
8377  }
8378  SourceLineInfo AssertionResult::getSourceInfo() const {
8379  return m_info.lineInfo;
8380  }
8381 
8382  StringRef AssertionResult::getTestMacroName() const {
8383  return m_info.macroName;
8384  }
8385 
8386 } // end namespace Catch
8387 // end catch_assertionresult.cpp
8388 // start catch_capture_matchers.cpp
8389 
8390 namespace Catch {
8391 
8392  using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
8393 
8394  // This is the general overload that takes a any string matcher
8395  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
8396  // the Equals matcher (so the header does not mention matchers)
8397  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
8398  std::string exceptionMessage = Catch::translateActiveException();
8399  MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
8400  handler.handleExpr( expr );
8401  }
8402 
8403 } // namespace Catch
8404 // end catch_capture_matchers.cpp
8405 // start catch_commandline.cpp
8406 
8407 // start catch_commandline.h
8408 
8409 // start catch_clara.h
8410 
8411 // Use Catch's value for console width (store Clara's off to the side, if present)
8412 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
8413 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8414 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8415 #endif
8416 #if 0 // Disabled by Qt so that test failures are not line-broken
8417 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
8418 #endif
8419 
8420 #ifdef __clang__
8421 #pragma clang diagnostic push
8422 #pragma clang diagnostic ignored "-Wweak-vtables"
8423 #pragma clang diagnostic ignored "-Wexit-time-destructors"
8424 #pragma clang diagnostic ignored "-Wshadow"
8425 #endif
8426 
8427 // start clara.hpp
8428 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
8429 //
8430 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8431 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8432 //
8433 // See https://github.com/philsquared/Clara for more details
8434 
8435 // Clara v1.1.5
8436 
8437 
8438 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8439 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
8440 #endif
8441 
8442 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8443 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8444 #endif
8445 
8446 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
8447 #ifdef __has_include
8448 #if __has_include(<optional>) && __cplusplus >= 201703L
8449 #include <optional>
8450 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
8451 #endif
8452 #endif
8453 #endif
8454 
8455 // ----------- #included from clara_textflow.hpp -----------
8456 
8457 // TextFlowCpp
8458 //
8459 // A single-header library for wrapping and laying out basic text, by Phil Nash
8460 //
8461 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8462 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8463 //
8464 // This project is hosted at https://github.com/philsquared/textflowcpp
8465 
8466 
8467 #include <cassert>
8468 #include <ostream>
8469 #include <sstream>
8470 #include <vector>
8471 
8472 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8473 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
8474 #endif
8475 
8476 namespace Catch {
8477 namespace clara {
8478 namespace TextFlow {
8479 
8480 inline auto isWhitespace(char c) -> bool {
8481  static std::string chars = " \t\n\r";
8482  return chars.find(c) != std::string::npos;
8483 }
8484 inline auto isBreakableBefore(char c) -> bool {
8485  static std::string chars = "[({<|";
8486  return chars.find(c) != std::string::npos;
8487 }
8488 inline auto isBreakableAfter(char c) -> bool {
8489  static std::string chars = "])}>.,:;*+-=&/\\";
8490  return chars.find(c) != std::string::npos;
8491 }
8492 
8493 class Columns;
8494 
8495 class Column {
8496  std::vector<std::string> m_strings;
8497  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
8498  size_t m_indent = 0;
8499  size_t m_initialIndent = std::string::npos;
8500 
8501 public:
8502  class iterator {
8503  friend Column;
8504 
8505  Column const& m_column;
8506  size_t m_stringIndex = 0;
8507  size_t m_pos = 0;
8508 
8509  size_t m_len = 0;
8510  size_t m_end = 0;
8511  bool m_suffix = false;
8512 
8513  iterator(Column const& column, size_t stringIndex)
8514  : m_column(column),
8515  m_stringIndex(stringIndex) {}
8516 
8517  auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
8518 
8519  auto isBoundary(size_t at) const -> bool {
8520  assert(at > 0);
8521  assert(at <= line().size());
8522 
8523  return at == line().size() ||
8524  (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
8525  isBreakableBefore(line()[at]) ||
8526  isBreakableAfter(line()[at - 1]);
8527  }
8528 
8529  void calcLength() {
8530  assert(m_stringIndex < m_column.m_strings.size());
8531 
8532  m_suffix = false;
8533  auto width = m_column.m_width - indent();
8534  m_end = m_pos;
8535  if (line()[m_pos] == '\n') {
8536  ++m_end;
8537  }
8538  while (m_end < line().size() && line()[m_end] != '\n')
8539  ++m_end;
8540 
8541  if (m_end < m_pos + width) {
8542  m_len = m_end - m_pos;
8543  } else {
8544  size_t len = width;
8545  while (len > 0 && !isBoundary(m_pos + len))
8546  --len;
8547  while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
8548  --len;
8549 
8550  if (len > 0) {
8551  m_len = len;
8552  } else {
8553  m_suffix = true;
8554  m_len = width - 1;
8555  }
8556  }
8557  }
8558 
8559  auto indent() const -> size_t {
8560  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
8561  return initial == std::string::npos ? m_column.m_indent : initial;
8562  }
8563 
8564  auto addIndentAndSuffix(std::string const &plain) const -> std::string {
8565  return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
8566  }
8567 
8568  public:
8569  using difference_type = std::ptrdiff_t;
8570  using value_type = std::string;
8571  using pointer = value_type * ;
8572  using reference = value_type & ;
8573  using iterator_category = std::forward_iterator_tag;
8574 
8575  explicit iterator(Column const& column) : m_column(column) {
8576  assert(m_column.m_width > m_column.m_indent);
8577  assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
8578  calcLength();
8579  if (m_len == 0)
8580  m_stringIndex++; // Empty string
8581  }
8582 
8583  auto operator *() const -> std::string {
8584  assert(m_stringIndex < m_column.m_strings.size());
8585  assert(m_pos <= m_end);
8586  return addIndentAndSuffix(line().substr(m_pos, m_len));
8587  }
8588 
8589  auto operator ++() -> iterator& {
8590  m_pos += m_len;
8591  if (m_pos < line().size() && line()[m_pos] == '\n')
8592  m_pos += 1;
8593  else
8594  while (m_pos < line().size() && isWhitespace(line()[m_pos]))
8595  ++m_pos;
8596 
8597  if (m_pos == line().size()) {
8598  m_pos = 0;
8599  ++m_stringIndex;
8600  }
8601  if (m_stringIndex < m_column.m_strings.size())
8602  calcLength();
8603  return *this;
8604  }
8605  auto operator ++(int) -> iterator {
8606  iterator prev(*this);
8607  operator++();
8608  return prev;
8609  }
8610 
8611  auto operator ==(iterator const& other) const -> bool {
8612  return
8613  m_pos == other.m_pos &&
8614  m_stringIndex == other.m_stringIndex &&
8615  &m_column == &other.m_column;
8616  }
8617  auto operator !=(iterator const& other) const -> bool {
8618  return !operator==(other);
8619  }
8620  };
8621  using const_iterator = iterator;
8622 
8623  explicit Column(std::string const& text) { m_strings.push_back(text); }
8624 
8625  auto width(size_t newWidth) -> Column& {
8626  assert(newWidth > 0);
8627  m_width = newWidth;
8628  return *this;
8629  }
8630  auto indent(size_t newIndent) -> Column& {
8631  m_indent = newIndent;
8632  return *this;
8633  }
8634  auto initialIndent(size_t newIndent) -> Column& {
8635  m_initialIndent = newIndent;
8636  return *this;
8637  }
8638 
8639  auto width() const -> size_t { return m_width; }
8640  auto begin() const -> iterator { return iterator(*this); }
8641  auto end() const -> iterator { return { *this, m_strings.size() }; }
8642 
8643  inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
8644  bool first = true;
8645  for (auto line : col) {
8646  if (first)
8647  first = false;
8648  else
8649  os << "\n";
8650  os << line;
8651  }
8652  return os;
8653  }
8654 
8655  auto operator + (Column const& other)->Columns;
8656 
8657  auto toString() const -> std::string {
8658  std::ostringstream oss;
8659  oss << *this;
8660  return oss.str();
8661  }
8662 };
8663 
8664 class Spacer : public Column {
8665 
8666 public:
8667  explicit Spacer(size_t spaceWidth) : Column("") {
8668  width(spaceWidth);
8669  }
8670 };
8671 
8672 class Columns {
8673  std::vector<Column> m_columns;
8674 
8675 public:
8676 
8677  class iterator {
8678  friend Columns;
8679  struct EndTag {};
8680 
8681  std::vector<Column> const& m_columns;
8682  std::vector<Column::iterator> m_iterators;
8683  size_t m_activeIterators;
8684 
8685  iterator(Columns const& columns, EndTag)
8686  : m_columns(columns.m_columns),
8687  m_activeIterators(0) {
8688  m_iterators.reserve(m_columns.size());
8689 
8690  for (auto const& col : m_columns)
8691  m_iterators.push_back(col.end());
8692  }
8693 
8694  public:
8695  using difference_type = std::ptrdiff_t;
8696  using value_type = std::string;
8697  using pointer = value_type * ;
8698  using reference = value_type & ;
8699  using iterator_category = std::forward_iterator_tag;
8700 
8701  explicit iterator(Columns const& columns)
8702  : m_columns(columns.m_columns),
8703  m_activeIterators(m_columns.size()) {
8704  m_iterators.reserve(m_columns.size());
8705 
8706  for (auto const& col : m_columns)
8707  m_iterators.push_back(col.begin());
8708  }
8709 
8710  auto operator ==(iterator const& other) const -> bool {
8711  return m_iterators == other.m_iterators;
8712  }
8713  auto operator !=(iterator const& other) const -> bool {
8714  return m_iterators != other.m_iterators;
8715  }
8716  auto operator *() const -> std::string {
8717  std::string row, padding;
8718 
8719  for (size_t i = 0; i < m_columns.size(); ++i) {
8720  auto width = m_columns[i].width();
8721  if (m_iterators[i] != m_columns[i].end()) {
8722  std::string col = *m_iterators[i];
8723  row += padding + col;
8724  if (col.size() < width)
8725  padding = std::string(width - col.size(), ' ');
8726  else
8727  padding = "";
8728  } else {
8729  padding += std::string(width, ' ');
8730  }
8731  }
8732  return row;
8733  }
8734  auto operator ++() -> iterator& {
8735  for (size_t i = 0; i < m_columns.size(); ++i) {
8736  if (m_iterators[i] != m_columns[i].end())
8737  ++m_iterators[i];
8738  }
8739  return *this;
8740  }
8741  auto operator ++(int) -> iterator {
8742  iterator prev(*this);
8743  operator++();
8744  return prev;
8745  }
8746  };
8747  using const_iterator = iterator;
8748 
8749  auto begin() const -> iterator { return iterator(*this); }
8750  auto end() const -> iterator { return { *this, iterator::EndTag() }; }
8751 
8752  auto operator += (Column const& col) -> Columns& {
8753  m_columns.push_back(col);
8754  return *this;
8755  }
8756  auto operator + (Column const& col) -> Columns {
8757  Columns combined = *this;
8758  combined += col;
8759  return combined;
8760  }
8761 
8762  inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
8763 
8764  bool first = true;
8765  for (auto line : cols) {
8766  if (first)
8767  first = false;
8768  else
8769  os << "\n";
8770  os << line;
8771  }
8772  return os;
8773  }
8774 
8775  auto toString() const -> std::string {
8776  std::ostringstream oss;
8777  oss << *this;
8778  return oss.str();
8779  }
8780 };
8781 
8782 inline auto Column::operator + (Column const& other) -> Columns {
8783  Columns cols;
8784  cols += *this;
8785  cols += other;
8786  return cols;
8787 }
8788 }
8789 
8790 }
8791 }
8792 
8793 // ----------- end of #include from clara_textflow.hpp -----------
8794 // ........... back in clara.hpp
8795 
8796 #include <cctype>
8797 #include <string>
8798 #include <memory>
8799 #include <set>
8800 #include <algorithm>
8801 
8802 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
8803 #define CATCH_PLATFORM_WINDOWS
8804 #endif
8805 
8806 namespace Catch { namespace clara {
8807 namespace detail {
8808 
8809  // Traits for extracting arg and return type of lambdas (for single argument lambdas)
8810  template<typename L>
8811  struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
8812 
8813  template<typename ClassT, typename ReturnT, typename... Args>
8814  struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
8815  static const bool isValid = false;
8816  };
8817 
8818  template<typename ClassT, typename ReturnT, typename ArgT>
8819  struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
8820  static const bool isValid = true;
8822  using ReturnType = ReturnT;
8823  };
8824 
8825  class TokenStream;
8826 
8827  // Transport for raw args (copied from main args, or supplied via init list for testing)
8828  class Args {
8829  friend TokenStream;
8830  std::string m_exeName;
8831  std::vector<std::string> m_args;
8832 
8833  public:
8834  Args( int argc, char const* const* argv )
8835  : m_exeName(argv[0]),
8836  m_args(argv + 1, argv + argc) {}
8837 
8838  Args( std::initializer_list<std::string> args )
8839  : m_exeName( *args.begin() ),
8840  m_args( args.begin()+1, args.end() )
8841  {}
8842 
8843  auto exeName() const -> std::string {
8844  return m_exeName;
8845  }
8846  };
8847 
8848  // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
8849  // may encode an option + its argument if the : or = form is used
8850  enum class TokenType {
8851  Option, Argument
8852  };
8853  struct Token {
8854  TokenType type;
8856  };
8857 
8858  inline auto isOptPrefix( char c ) -> bool {
8859  return c == '-'
8860 #ifdef CATCH_PLATFORM_WINDOWS
8861  || c == '/'
8862 #endif
8863  ;
8864  }
8865 
8866  // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
8867  class TokenStream {
8869  Iterator it;
8870  Iterator itEnd;
8871  std::vector<Token> m_tokenBuffer;
8872 
8873  void loadBuffer() {
8874  m_tokenBuffer.resize( 0 );
8875 
8876  // Skip any empty strings
8877  while( it != itEnd && it->empty() )
8878  ++it;
8879 
8880  if( it != itEnd ) {
8881  auto const &next = *it;
8882  if( isOptPrefix( next[0] ) ) {
8883  auto delimiterPos = next.find_first_of( " :=" );
8884  if( delimiterPos != std::string::npos ) {
8885  m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
8886  m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
8887  } else {
8888  if( next[1] != '-' && next.size() > 2 ) {
8889  std::string opt = "- ";
8890  for( size_t i = 1; i < next.size(); ++i ) {
8891  opt[1] = next[i];
8892  m_tokenBuffer.push_back( { TokenType::Option, opt } );
8893  }
8894  } else {
8895  m_tokenBuffer.push_back( { TokenType::Option, next } );
8896  }
8897  }
8898  } else {
8899  m_tokenBuffer.push_back( { TokenType::Argument, next } );
8900  }
8901  }
8902  }
8903 
8904  public:
8905  explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
8906 
8907  TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
8908  loadBuffer();
8909  }
8910 
8911  explicit operator bool() const {
8912  return !m_tokenBuffer.empty() || it != itEnd;
8913  }
8914 
8915  auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
8916 
8917  auto operator*() const -> Token {
8918  assert( !m_tokenBuffer.empty() );
8919  return m_tokenBuffer.front();
8920  }
8921 
8922  auto operator->() const -> Token const * {
8923  assert( !m_tokenBuffer.empty() );
8924  return &m_tokenBuffer.front();
8925  }
8926 
8927  auto operator++() -> TokenStream & {
8928  if( m_tokenBuffer.size() >= 2 ) {
8929  m_tokenBuffer.erase( m_tokenBuffer.begin() );
8930  } else {
8931  if( it != itEnd )
8932  ++it;
8933  loadBuffer();
8934  }
8935  return *this;
8936  }
8937  };
8938 
8939  class ResultBase {
8940  public:
8941  enum Type {
8942  Ok, LogicError, RuntimeError
8943  };
8944 
8945  protected:
8946  ResultBase( Type type ) : m_type( type ) {}
8947  virtual ~ResultBase() = default;
8948 
8949  virtual void enforceOk() const = 0;
8950 
8951  Type m_type;
8952  };
8953 
8954  template<typename T>
8955  class ResultValueBase : public ResultBase {
8956  public:
8957  auto value() const -> T const & {
8958  enforceOk();
8959  return m_value;
8960  }
8961 
8962  protected:
8963  ResultValueBase( Type type ) : ResultBase( type ) {}
8964 
8965  ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
8966  if( m_type == ResultBase::Ok )
8967  new( &m_value ) T( other.m_value );
8968  }
8969 
8970  ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
8971  new( &m_value ) T( value );
8972  }
8973 
8974  auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
8975  if( m_type == ResultBase::Ok )
8976  m_value.~T();
8977  ResultBase::operator=(other);
8978  if( m_type == ResultBase::Ok )
8979  new( &m_value ) T( other.m_value );
8980  return *this;
8981  }
8982 
8983  ~ResultValueBase() override {
8984  if( m_type == Ok )
8985  m_value.~T();
8986  }
8987 
8988  union {
8989  T m_value;
8990  };
8991  };
8992 
8993  template<>
8994  class ResultValueBase<void> : public ResultBase {
8995  protected:
8996  using ResultBase::ResultBase;
8997  };
8998 
8999  template<typename T = void>
9000  class BasicResult : public ResultValueBase<T> {
9001  public:
9002  template<typename U>
9003  explicit BasicResult( BasicResult<U> const &other )
9004  : ResultValueBase<T>( other.type() ),
9005  m_errorMessage( other.errorMessage() )
9006  {
9007  assert( type() != ResultBase::Ok );
9008  }
9009 
9010  template<typename U>
9011  static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
9012  static auto ok() -> BasicResult { return { ResultBase::Ok }; }
9013  static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
9014  static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
9015 
9016  explicit operator bool() const { return m_type == ResultBase::Ok; }
9017  auto type() const -> ResultBase::Type { return m_type; }
9018  auto errorMessage() const -> std::string { return m_errorMessage; }
9019 
9020  protected:
9021  void enforceOk() const override {
9022 
9023  // Errors shouldn't reach this point, but if they do
9024  // the actual error message will be in m_errorMessage
9025  assert( m_type != ResultBase::LogicError );
9026  assert( m_type != ResultBase::RuntimeError );
9027  if( m_type != ResultBase::Ok )
9028  std::abort();
9029  }
9030 
9031  std::string m_errorMessage; // Only populated if resultType is an error
9032 
9033  BasicResult( ResultBase::Type type, std::string const &message )
9034  : ResultValueBase<T>(type),
9035  m_errorMessage(message)
9036  {
9037  assert( m_type != ResultBase::Ok );
9038  }
9039 
9040  using ResultValueBase<T>::ResultValueBase;
9041  using ResultBase::m_type;
9042  };
9043 
9044  enum class ParseResultType {
9045  Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
9046  };
9047 
9048  class ParseState {
9049  public:
9050 
9051  ParseState( ParseResultType type, TokenStream const &remainingTokens )
9052  : m_type(type),
9053  m_remainingTokens( remainingTokens )
9054  {}
9055 
9056  auto type() const -> ParseResultType { return m_type; }
9057  auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
9058 
9059  private:
9060  ParseResultType m_type;
9061  TokenStream m_remainingTokens;
9062  };
9063 
9064  using Result = BasicResult<void>;
9065  using ParserResult = BasicResult<ParseResultType>;
9066  using InternalParseResult = BasicResult<ParseState>;
9067 
9068  struct HelpColumns {
9069  std::string left;
9071  };
9072 
9073  template<typename T>
9074  inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
9075  std::stringstream ss;
9076  ss << source;
9077  ss >> target;
9078  if( ss.fail() )
9079  return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
9080  else
9081  return ParserResult::ok( ParseResultType::Matched );
9082  }
9083  inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
9084  target = source;
9085  return ParserResult::ok( ParseResultType::Matched );
9086  }
9087  inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
9088  std::string srcLC = source;
9089  std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
9090  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
9091  target = true;
9092  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
9093  target = false;
9094  else
9095  return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
9096  return ParserResult::ok( ParseResultType::Matched );
9097  }
9098 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
9099  template<typename T>
9100  inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
9101  T temp;
9102  auto result = convertInto( source, temp );
9103  if( result )
9104  target = std::move(temp);
9105  return result;
9106  }
9107 #endif // CLARA_CONFIG_OPTIONAL_TYPE
9108 
9109  struct NonCopyable {
9110  NonCopyable() = default;
9111  NonCopyable( NonCopyable const & ) = delete;
9112  NonCopyable( NonCopyable && ) = delete;
9113  NonCopyable &operator=( NonCopyable const & ) = delete;
9114  NonCopyable &operator=( NonCopyable && ) = delete;
9115  };
9116 
9117  struct BoundRef : NonCopyable {
9118  virtual ~BoundRef() = default;
9119  virtual auto isContainer() const -> bool { return false; }
9120  virtual auto isFlag() const -> bool { return false; }
9121  };
9122  struct BoundValueRefBase : BoundRef {
9123  virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
9124  };
9125  struct BoundFlagRefBase : BoundRef {
9126  virtual auto setFlag( bool flag ) -> ParserResult = 0;
9127  virtual auto isFlag() const -> bool { return true; }
9128  };
9129 
9130  template<typename T>
9131  struct BoundValueRef : BoundValueRefBase {
9132  T &m_ref;
9133 
9134  explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
9135 
9136  auto setValue( std::string const &arg ) -> ParserResult override {
9137  return convertInto( arg, m_ref );
9138  }
9139  };
9140 
9141  template<typename T>
9142  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
9143  std::vector<T> &m_ref;
9144 
9145  explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
9146 
9147  auto isContainer() const -> bool override { return true; }
9148 
9149  auto setValue( std::string const &arg ) -> ParserResult override {
9150  T temp;
9151  auto result = convertInto( arg, temp );
9152  if( result )
9153  m_ref.push_back( temp );
9154  return result;
9155  }
9156  };
9157 
9158  struct BoundFlagRef : BoundFlagRefBase {
9159  bool &m_ref;
9160 
9161  explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
9162 
9163  auto setFlag( bool flag ) -> ParserResult override {
9164  m_ref = flag;
9165  return ParserResult::ok( ParseResultType::Matched );
9166  }
9167  };
9168 
9169  template<typename ReturnType>
9170  struct LambdaInvoker {
9171  static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
9172 
9173  template<typename L, typename ArgType>
9174  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9175  return lambda( arg );
9176  }
9177  };
9178 
9179  template<>
9180  struct LambdaInvoker<void> {
9181  template<typename L, typename ArgType>
9182  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9183  lambda( arg );
9184  return ParserResult::ok( ParseResultType::Matched );
9185  }
9186  };
9187 
9188  template<typename ArgType, typename L>
9189  inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
9190  ArgType temp{};
9191  auto result = convertInto( arg, temp );
9192  return !result
9193  ? result
9194  : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
9195  }
9196 
9197  template<typename L>
9198  struct BoundLambda : BoundValueRefBase {
9199  L m_lambda;
9200 
9201  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9202  explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
9203 
9204  auto setValue( std::string const &arg ) -> ParserResult override {
9205  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
9206  }
9207  };
9208 
9209  template<typename L>
9210  struct BoundFlagLambda : BoundFlagRefBase {
9211  L m_lambda;
9212 
9213  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9214  static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
9215 
9216  explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
9217 
9218  auto setFlag( bool flag ) -> ParserResult override {
9219  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
9220  }
9221  };
9222 
9223  enum class Optionality { Optional, Required };
9224 
9225  struct Parser;
9226 
9227  class ParserBase {
9228  public:
9229  virtual ~ParserBase() = default;
9230  virtual auto validate() const -> Result { return Result::ok(); }
9231  virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
9232  virtual auto cardinality() const -> size_t { return 1; }
9233 
9234  auto parse( Args const &args ) const -> InternalParseResult {
9235  return parse( args.exeName(), TokenStream( args ) );
9236  }
9237  };
9238 
9239  template<typename DerivedT>
9240  class ComposableParserImpl : public ParserBase {
9241  public:
9242  template<typename T>
9243  auto operator|( T const &other ) const -> Parser;
9244 
9245  template<typename T>
9246  auto operator+( T const &other ) const -> Parser;
9247  };
9248 
9249  // Common code and state for Args and Opts
9250  template<typename DerivedT>
9251  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
9252  protected:
9253  Optionality m_optionality = Optionality::Optional;
9254  std::shared_ptr<BoundRef> m_ref;
9255  std::string m_hint;
9256  std::string m_description;
9257 
9258  explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
9259 
9260  public:
9261  template<typename T>
9262  ParserRefImpl( T &ref, std::string const &hint )
9263  : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
9264  m_hint( hint )
9265  {}
9266 
9267  template<typename LambdaT>
9268  ParserRefImpl( LambdaT const &ref, std::string const &hint )
9269  : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
9270  m_hint(hint)
9271  {}
9272 
9273  auto operator()( std::string const &description ) -> DerivedT & {
9274  m_description = description;
9275  return static_cast<DerivedT &>( *this );
9276  }
9277 
9278  auto optional() -> DerivedT & {
9279  m_optionality = Optionality::Optional;
9280  return static_cast<DerivedT &>( *this );
9281  };
9282 
9283  auto required() -> DerivedT & {
9284  m_optionality = Optionality::Required;
9285  return static_cast<DerivedT &>( *this );
9286  };
9287 
9288  auto isOptional() const -> bool {
9289  return m_optionality == Optionality::Optional;
9290  }
9291 
9292  auto cardinality() const -> size_t override {
9293  if( m_ref->isContainer() )
9294  return 0;
9295  else
9296  return 1;
9297  }
9298 
9299  auto hint() const -> std::string { return m_hint; }
9300  };
9301 
9302  class ExeName : public ComposableParserImpl<ExeName> {
9303  std::shared_ptr<std::string> m_name;
9304  std::shared_ptr<BoundValueRefBase> m_ref;
9305 
9306  template<typename LambdaT>
9307  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
9308  return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
9309  }
9310 
9311  public:
9312  ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
9313 
9314  explicit ExeName( std::string &ref ) : ExeName() {
9315  m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
9316  }
9317 
9318  template<typename LambdaT>
9319  explicit ExeName( LambdaT const& lambda ) : ExeName() {
9320  m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
9321  }
9322 
9323  // The exe name is not parsed out of the normal tokens, but is handled specially
9324  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9325  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9326  }
9327 
9328  auto name() const -> std::string { return *m_name; }
9329  auto set( std::string const& newName ) -> ParserResult {
9330 
9331  auto lastSlash = newName.find_last_of( "\\/" );
9332  auto filename = ( lastSlash == std::string::npos )
9333  ? newName
9334  : newName.substr( lastSlash+1 );
9335 
9336  *m_name = filename;
9337  if( m_ref )
9338  return m_ref->setValue( filename );
9339  else
9340  return ParserResult::ok( ParseResultType::Matched );
9341  }
9342  };
9343 
9344  class Arg : public ParserRefImpl<Arg> {
9345  public:
9346  using ParserRefImpl::ParserRefImpl;
9347 
9348  auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
9349  auto validationResult = validate();
9350  if( !validationResult )
9351  return InternalParseResult( validationResult );
9352 
9353  auto remainingTokens = tokens;
9354  auto const &token = *remainingTokens;
9355  if( token.type != TokenType::Argument )
9356  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9357 
9358  assert( !m_ref->isFlag() );
9359  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9360 
9361  auto result = valueRef->setValue( remainingTokens->token );
9362  if( !result )
9363  return InternalParseResult( result );
9364  else
9365  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9366  }
9367  };
9368 
9369  inline auto normaliseOpt( std::string const &optName ) -> std::string {
9370 #ifdef CATCH_PLATFORM_WINDOWS
9371  if( optName[0] == '/' )
9372  return "-" + optName.substr( 1 );
9373  else
9374 #endif
9375  return optName;
9376  }
9377 
9378  class Opt : public ParserRefImpl<Opt> {
9379  protected:
9380  std::vector<std::string> m_optNames;
9381 
9382  public:
9383  template<typename LambdaT>
9384  explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
9385 
9386  explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
9387 
9388  template<typename LambdaT>
9389  Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9390 
9391  template<typename T>
9392  Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9393 
9394  auto operator[]( std::string const &optName ) -> Opt & {
9395  m_optNames.push_back( optName );
9396  return *this;
9397  }
9398 
9399  auto getHelpColumns() const -> std::vector<HelpColumns> {
9400  std::ostringstream oss;
9401  bool first = true;
9402  for( auto const &opt : m_optNames ) {
9403  if (first)
9404  first = false;
9405  else
9406  oss << ", ";
9407  oss << opt;
9408  }
9409  if( !m_hint.empty() )
9410  oss << " <" << m_hint << ">";
9411  return { { oss.str(), m_description } };
9412  }
9413 
9414  auto isMatch( std::string const &optToken ) const -> bool {
9415  auto normalisedToken = normaliseOpt( optToken );
9416  for( auto const &name : m_optNames ) {
9417  if( normaliseOpt( name ) == normalisedToken )
9418  return true;
9419  }
9420  return false;
9421  }
9422 
9423  using ParserBase::parse;
9424 
9425  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9426  auto validationResult = validate();
9427  if( !validationResult )
9428  return InternalParseResult( validationResult );
9429 
9430  auto remainingTokens = tokens;
9431  if( remainingTokens && remainingTokens->type == TokenType::Option ) {
9432  auto const &token = *remainingTokens;
9433  if( isMatch(token.token ) ) {
9434  if( m_ref->isFlag() ) {
9435  auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
9436  auto result = flagRef->setFlag( true );
9437  if( !result )
9438  return InternalParseResult( result );
9439  if( result.value() == ParseResultType::ShortCircuitAll )
9440  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9441  } else {
9442  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9443  ++remainingTokens;
9444  if( !remainingTokens )
9445  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9446  auto const &argToken = *remainingTokens;
9447  if( argToken.type != TokenType::Argument )
9448  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9449  auto result = valueRef->setValue( argToken.token );
9450  if( !result )
9451  return InternalParseResult( result );
9452  if( result.value() == ParseResultType::ShortCircuitAll )
9453  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9454  }
9455  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9456  }
9457  }
9458  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9459  }
9460 
9461  auto validate() const -> Result override {
9462  if( m_optNames.empty() )
9463  return Result::logicError( "No options supplied to Opt" );
9464  for( auto const &name : m_optNames ) {
9465  if( name.empty() )
9466  return Result::logicError( "Option name cannot be empty" );
9467 #ifdef CATCH_PLATFORM_WINDOWS
9468  if( name[0] != '-' && name[0] != '/' )
9469  return Result::logicError( "Option name must begin with '-' or '/'" );
9470 #else
9471  if( name[0] != '-' )
9472  return Result::logicError( "Option name must begin with '-'" );
9473 #endif
9474  }
9475  return ParserRefImpl::validate();
9476  }
9477  };
9478 
9479  struct Help : Opt {
9480  Help( bool &showHelpFlag )
9481  : Opt([&]( bool flag ) {
9482  showHelpFlag = flag;
9483  return ParserResult::ok( ParseResultType::ShortCircuitAll );
9484  })
9485  {
9486  static_cast<Opt &>( *this )
9487  ("display usage information")
9488  ["-?"]["-h"]["--help"]
9489  .optional();
9490  }
9491  };
9492 
9493  struct Parser : ParserBase {
9494 
9495  mutable ExeName m_exeName;
9496  std::vector<Opt> m_options;
9497  std::vector<Arg> m_args;
9498 
9499  auto operator|=( ExeName const &exeName ) -> Parser & {
9500  m_exeName = exeName;
9501  return *this;
9502  }
9503 
9504  auto operator|=( Arg const &arg ) -> Parser & {
9505  m_args.push_back(arg);
9506  return *this;
9507  }
9508 
9509  auto operator|=( Opt const &opt ) -> Parser & {
9510  m_options.push_back(opt);
9511  return *this;
9512  }
9513 
9514  auto operator|=( Parser const &other ) -> Parser & {
9515  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
9516  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
9517  return *this;
9518  }
9519 
9520  template<typename T>
9521  auto operator|( T const &other ) const -> Parser {
9522  return Parser( *this ) |= other;
9523  }
9524 
9525  // Forward deprecated interface with '+' instead of '|'
9526  template<typename T>
9527  auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
9528  template<typename T>
9529  auto operator+( T const &other ) const -> Parser { return operator|( other ); }
9530 
9531  auto getHelpColumns() const -> std::vector<HelpColumns> {
9532  std::vector<HelpColumns> cols;
9533  for (auto const &o : m_options) {
9534  auto childCols = o.getHelpColumns();
9535  cols.insert( cols.end(), childCols.begin(), childCols.end() );
9536  }
9537  return cols;
9538  }
9539 
9540  void writeToStream( std::ostream &os ) const {
9541  if (!m_exeName.name().empty()) {
9542  os << "usage:\n" << " " << m_exeName.name() << " ";
9543  bool required = true, first = true;
9544  for( auto const &arg : m_args ) {
9545  if (first)
9546  first = false;
9547  else
9548  os << " ";
9549  if( arg.isOptional() && required ) {
9550  os << "[";
9551  required = false;
9552  }
9553  os << "<" << arg.hint() << ">";
9554  if( arg.cardinality() == 0 )
9555  os << " ... ";
9556  }
9557  if( !required )
9558  os << "]";
9559  if( !m_options.empty() )
9560  os << " options";
9561  os << "\n\nwhere options are:" << std::endl;
9562  }
9563 
9564  auto rows = getHelpColumns();
9565  size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
9566  size_t optWidth = 0;
9567  for( auto const &cols : rows )
9568  optWidth = (std::max)(optWidth, cols.left.size() + 2);
9569 
9570  optWidth = (std::min)(optWidth, consoleWidth/2);
9571 
9572  for( auto const &cols : rows ) {
9573  auto row =
9574  TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
9575  TextFlow::Spacer(4) +
9576  TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
9577  os << row << std::endl;
9578  }
9579  }
9580 
9581  friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
9582  parser.writeToStream( os );
9583  return os;
9584  }
9585 
9586  auto validate() const -> Result override {
9587  for( auto const &opt : m_options ) {
9588  auto result = opt.validate();
9589  if( !result )
9590  return result;
9591  }
9592  for( auto const &arg : m_args ) {
9593  auto result = arg.validate();
9594  if( !result )
9595  return result;
9596  }
9597  return Result::ok();
9598  }
9599 
9600  using ParserBase::parse;
9601 
9602  auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
9603 
9604  struct ParserInfo {
9605  ParserBase const* parser = nullptr;
9606  size_t count = 0;
9607  };
9608  const size_t totalParsers = m_options.size() + m_args.size();
9609  assert( totalParsers < 512 );
9610  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
9611  ParserInfo parseInfos[512];
9612 
9613  {
9614  size_t i = 0;
9615  for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
9616  for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
9617  }
9618 
9619  m_exeName.set( exeName );
9620 
9621  auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9622  while( result.value().remainingTokens() ) {
9623  bool tokenParsed = false;
9624 
9625  for( size_t i = 0; i < totalParsers; ++i ) {
9626  auto& parseInfo = parseInfos[i];
9627  if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
9628  result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
9629  if (!result)
9630  return result;
9631  if (result.value().type() != ParseResultType::NoMatch) {
9632  tokenParsed = true;
9633  ++parseInfo.count;
9634  break;
9635  }
9636  }
9637  }
9638 
9639  if( result.value().type() == ParseResultType::ShortCircuitAll )
9640  return result;
9641  if( !tokenParsed )
9642  return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
9643  }
9644  // !TBD Check missing required options
9645  return result;
9646  }
9647  };
9648 
9649  template<typename DerivedT>
9650  template<typename T>
9651  auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
9652  return Parser() | static_cast<DerivedT const &>( *this ) | other;
9653  }
9654 } // namespace detail
9655 
9656 // A Combined parser
9657 using detail::Parser;
9658 
9659 // A parser for options
9660 using detail::Opt;
9661 
9662 // A parser for arguments
9663 using detail::Arg;
9664 
9665 // Wrapper for argc, argv from main()
9666 using detail::Args;
9667 
9668 // Specifies the name of the executable
9669 using detail::ExeName;
9670 
9671 // Convenience wrapper for option parser that specifies the help option
9672 using detail::Help;
9673 
9674 // enum of result types from a parse
9675 using detail::ParseResultType;
9676 
9677 // Result type for parser operation
9678 using detail::ParserResult;
9679 
9680 }} // namespace Catch::clara
9681 
9682 // end clara.hpp
9683 #ifdef __clang__
9684 #pragma clang diagnostic pop
9685 #endif
9686 
9687 // Restore Clara's value for console width, if present
9688 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9689 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9690 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9691 #endif
9692 
9693 // end catch_clara.h
9694 namespace Catch {
9695 
9696  clara::Parser makeCommandLineParser( ConfigData& config );
9697 
9698 } // end namespace Catch
9699 
9700 // end catch_commandline.h
9701 #include <fstream>
9702 #include <ctime>
9703 
9704 namespace Catch {
9705 
9706  clara::Parser makeCommandLineParser( ConfigData& config ) {
9707 
9708  using namespace clara;
9709 
9710  auto const setWarning = [&]( std::string const& warning ) {
9711  auto warningSet = [&]() {
9712  if( warning == "NoAssertions" )
9713  return WarnAbout::NoAssertions;
9714 
9715  if ( warning == "NoTests" )
9716  return WarnAbout::NoTests;
9717 
9718  return WarnAbout::Nothing;
9719  }();
9720 
9721  if (warningSet == WarnAbout::Nothing)
9722  return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
9723  config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
9724  return ParserResult::ok( ParseResultType::Matched );
9725  };
9726  auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
9727  std::ifstream f( filename.c_str() );
9728  if( !f.is_open() )
9729  return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
9730 
9731  std::string line;
9732  while( std::getline( f, line ) ) {
9733  line = trim(line);
9734  if( !line.empty() && !startsWith( line, '#' ) ) {
9735  if( !startsWith( line, '"' ) )
9736  line = '"' + line + '"';
9737  config.testsOrTags.push_back( line );
9738  config.testsOrTags.emplace_back( "," );
9739  }
9740  }
9741  //Remove comma in the end
9742  if(!config.testsOrTags.empty())
9743  config.testsOrTags.erase( config.testsOrTags.end()-1 );
9744 
9745  return ParserResult::ok( ParseResultType::Matched );
9746  };
9747  auto const setTestOrder = [&]( std::string const& order ) {
9748  if( startsWith( "declared", order ) )
9750  else if( startsWith( "lexical", order ) )
9752  else if( startsWith( "random", order ) )
9753  config.runOrder = RunTests::InRandomOrder;
9754  else
9755  return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
9756  return ParserResult::ok( ParseResultType::Matched );
9757  };
9758  auto const setRngSeed = [&]( std::string const& seed ) {
9759  if( seed != "time" )
9760  return clara::detail::convertInto( seed, config.rngSeed );
9761  config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
9762  return ParserResult::ok( ParseResultType::Matched );
9763  };
9764  auto const setColourUsage = [&]( std::string const& useColour ) {
9765  auto mode = toLower( useColour );
9766 
9767  if( mode == "yes" )
9768  config.useColour = UseColour::Yes;
9769  else if( mode == "no" )
9770  config.useColour = UseColour::No;
9771  else if( mode == "auto" )
9772  config.useColour = UseColour::Auto;
9773  else
9774  return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
9775  return ParserResult::ok( ParseResultType::Matched );
9776  };
9777  auto const setWaitForKeypress = [&]( std::string const& keypress ) {
9778  auto keypressLc = toLower( keypress );
9779  if (keypressLc == "never")
9780  config.waitForKeypress = WaitForKeypress::Never;
9781  else if( keypressLc == "start" )
9782  config.waitForKeypress = WaitForKeypress::BeforeStart;
9783  else if( keypressLc == "exit" )
9784  config.waitForKeypress = WaitForKeypress::BeforeExit;
9785  else if( keypressLc == "both" )
9786  config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
9787  else
9788  return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
9789  return ParserResult::ok( ParseResultType::Matched );
9790  };
9791  auto const setVerbosity = [&]( std::string const& verbosity ) {
9792  auto lcVerbosity = toLower( verbosity );
9793  if( lcVerbosity == "quiet" )
9794  config.verbosity = Verbosity::Quiet;
9795  else if( lcVerbosity == "normal" )
9796  config.verbosity = Verbosity::Normal;
9797  else if( lcVerbosity == "high" )
9798  config.verbosity = Verbosity::High;
9799  else
9800  return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
9801  return ParserResult::ok( ParseResultType::Matched );
9802  };
9803  auto const setReporter = [&]( std::string const& reporter ) {
9804  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
9805 
9806  auto lcReporter = toLower( reporter );
9807  auto result = factories.find( lcReporter );
9808 
9809  if( factories.end() != result )
9810  config.reporterName = lcReporter;
9811  else
9812  return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
9813  return ParserResult::ok( ParseResultType::Matched );
9814  };
9815 
9816  auto cli
9817  = ExeName( config.processName )
9818  | Help( config.showHelp )
9819  | Opt( config.listTests )
9820  ["-l"]["--list-tests"]
9821  ( "list all/matching test cases" )
9822  | Opt( config.listTags )
9823  ["-t"]["--list-tags"]
9824  ( "list all/matching tags" )
9825  | Opt( config.showSuccessfulTests )
9826  ["-s"]["--success"]
9827  ( "include successful tests in output" )
9828  | Opt( config.shouldDebugBreak )
9829  ["-b"]["--break"]
9830  ( "break into debugger on failure" )
9831  | Opt( config.noThrow )
9832  ["-e"]["--nothrow"]
9833  ( "skip exception tests" )
9834  | Opt( config.showInvisibles )
9835  ["-i"]["--invisibles"]
9836  ( "show invisibles (tabs, newlines)" )
9837  | Opt( config.outputFilename, "filename" )
9838  ["-o"]["--out"]
9839  ( "output filename" )
9840  | Opt( setReporter, "name" )
9841  ["-r"]["--reporter"]
9842  ( "reporter to use (defaults to console)" )
9843  | Opt( config.name, "name" )
9844  ["-n"]["--name"]
9845  ( "suite name" )
9846  | Opt( [&]( bool ){ config.abortAfter = 1; } )
9847  ["-a"]["--abort"]
9848  ( "abort at first failure" )
9849  | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
9850  ["-x"]["--abortx"]
9851  ( "abort after x failures" )
9852  | Opt( setWarning, "warning name" )
9853  ["-w"]["--warn"]
9854  ( "enable warnings" )
9855  | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
9856  ["-d"]["--durations"]
9857  ( "show test durations" )
9858  | Opt( config.minDuration, "seconds" )
9859  ["-D"]["--min-duration"]
9860  ( "show test durations for tests taking at least the given number of seconds" )
9861  | Opt( loadTestNamesFromFile, "filename" )
9862  ["-f"]["--input-file"]
9863  ( "load test names to run from a file" )
9864  | Opt( config.filenamesAsTags )
9865  ["-#"]["--filenames-as-tags"]
9866  ( "adds a tag for the filename" )
9867  | Opt( config.sectionsToRun, "section name" )
9868  ["-c"]["--section"]
9869  ( "specify section to run" )
9870  | Opt( setVerbosity, "quiet|normal|high" )
9871  ["-v"]["--verbosity"]
9872  ( "set output verbosity" )
9873  | Opt( config.listTestNamesOnly )
9874  ["--list-test-names-only"]
9875  ( "list all/matching test cases names only" )
9876  | Opt( config.listReporters )
9877  ["--list-reporters"]
9878  ( "list all reporters" )
9879  | Opt( setTestOrder, "decl|lex|rand" )
9880  ["--order"]
9881  ( "test case order (defaults to decl)" )
9882  | Opt( setRngSeed, "'time'|number" )
9883  ["--rng-seed"]
9884  ( "set a specific seed for random numbers" )
9885  | Opt( setColourUsage, "yes|no" )
9886  ["--use-colour"]
9887  ( "should output be colourised" )
9888  | Opt( config.libIdentify )
9889  ["--libidentify"]
9890  ( "report name and version according to libidentify standard" )
9891  | Opt( setWaitForKeypress, "never|start|exit|both" )
9892  ["--wait-for-keypress"]
9893  ( "waits for a keypress before exiting" )
9894  | Opt( config.benchmarkSamples, "samples" )
9895  ["--benchmark-samples"]
9896  ( "number of samples to collect (default: 100)" )
9897  | Opt( config.benchmarkResamples, "resamples" )
9898  ["--benchmark-resamples"]
9899  ( "number of resamples for the bootstrap (default: 100000)" )
9900  | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
9901  ["--benchmark-confidence-interval"]
9902  ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
9903  | Opt( config.benchmarkNoAnalysis )
9904  ["--benchmark-no-analysis"]
9905  ( "perform only measurements; do not perform any analysis" )
9906  | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
9907  ["--benchmark-warmup-time"]
9908  ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
9909  | Arg( config.testsOrTags, "test name|pattern|tags" )
9910  ( "which test or tests to use" );
9911 
9912  return cli;
9913  }
9914 
9915 } // end namespace Catch
9916 // end catch_commandline.cpp
9917 // start catch_common.cpp
9918 
9919 #include <cstring>
9920 #include <ostream>
9921 
9922 namespace Catch {
9923 
9924  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
9925  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
9926  }
9927  bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
9928  // We can assume that the same file will usually have the same pointer.
9929  // Thus, if the pointers are the same, there is no point in calling the strcmp
9930  return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
9931  }
9932 
9933  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
9934 #ifndef __GNUG__
9935  os << info.file << '(' << info.line << ')';
9936 #else
9937  os << info.file << ':' << info.line;
9938 #endif
9939  return os;
9940  }
9941 
9943  return std::string();
9944  }
9945 
9946  NonCopyable::NonCopyable() = default;
9947  NonCopyable::~NonCopyable() = default;
9948 
9949 }
9950 // end catch_common.cpp
9951 // start catch_config.cpp
9952 
9953 namespace Catch {
9954 
9955  Config::Config( ConfigData const& data )
9956  : m_data( data ),
9957  m_stream( openStream() )
9958  {
9959  // We need to trim filter specs to avoid trouble with superfluous
9960  // whitespace (esp. important for bdd macros, as those are manually
9961  // aligned with whitespace).
9962 
9963  for (auto& elem : m_data.testsOrTags) {
9964  elem = trim(elem);
9965  }
9966  for (auto& elem : m_data.sectionsToRun) {
9967  elem = trim(elem);
9968  }
9969 
9970  TestSpecParser parser(ITagAliasRegistry::get());
9971  if (!m_data.testsOrTags.empty()) {
9972  m_hasTestFilters = true;
9973  for (auto const& testOrTags : m_data.testsOrTags) {
9974  parser.parse(testOrTags);
9975  }
9976  }
9977  m_testSpec = parser.testSpec();
9978  }
9979 
9980  std::string const& Config::getFilename() const {
9981  return m_data.outputFilename ;
9982  }
9983 
9984  bool Config::listTests() const { return m_data.listTests; }
9985  bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
9986  bool Config::listTags() const { return m_data.listTags; }
9987  bool Config::listReporters() const { return m_data.listReporters; }
9988 
9989  std::string Config::getProcessName() const { return m_data.processName; }
9990  std::string const& Config::getReporterName() const { return m_data.reporterName; }
9991 
9992  std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
9993  std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
9994 
9995  TestSpec const& Config::testSpec() const { return m_testSpec; }
9996  bool Config::hasTestFilters() const { return m_hasTestFilters; }
9997 
9998  bool Config::showHelp() const { return m_data.showHelp; }
9999 
10000  // IConfig interface
10001  bool Config::allowThrows() const { return !m_data.noThrow; }
10002  std::ostream& Config::stream() const { return m_stream->stream(); }
10003  std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
10004  bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
10005  bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
10006  bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
10007  ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
10008  double Config::minDuration() const { return m_data.minDuration; }
10009  RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
10010  unsigned int Config::rngSeed() const { return m_data.rngSeed; }
10011  UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
10012  bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
10013  int Config::abortAfter() const { return m_data.abortAfter; }
10014  bool Config::showInvisibles() const { return m_data.showInvisibles; }
10015  Verbosity Config::verbosity() const { return m_data.verbosity; }
10016 
10017  bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
10018  int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
10019  double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
10020  unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
10021  std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
10022 
10023  IStream const* Config::openStream() {
10024  return Catch::makeStream(m_data.outputFilename);
10025  }
10026 
10027 } // end namespace Catch
10028 // end catch_config.cpp
10029 // start catch_console_colour.cpp
10030 
10031 #if defined(__clang__)
10032 # pragma clang diagnostic push
10033 # pragma clang diagnostic ignored "-Wexit-time-destructors"
10034 #endif
10035 
10036 // start catch_errno_guard.h
10037 
10038 namespace Catch {
10039 
10040  class ErrnoGuard {
10041  public:
10042  ErrnoGuard();
10043  ~ErrnoGuard();
10044  private:
10045  int m_oldErrno;
10046  };
10047 
10048 }
10049 
10050 // end catch_errno_guard.h
10051 // start catch_windows_h_proxy.h
10052 
10053 
10054 #if defined(CATCH_PLATFORM_WINDOWS)
10055 
10056 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
10057 # define CATCH_DEFINED_NOMINMAX
10058 # define NOMINMAX
10059 #endif
10060 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
10061 # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
10062 # define WIN32_LEAN_AND_MEAN
10063 #endif
10064 
10065 #ifdef __AFXDLL
10066 #include <AfxWin.h>
10067 #else
10068 #include <windows.h>
10069 #endif
10070 
10071 #ifdef CATCH_DEFINED_NOMINMAX
10072 # undef NOMINMAX
10073 #endif
10074 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
10075 # undef WIN32_LEAN_AND_MEAN
10076 #endif
10077 
10078 #endif // defined(CATCH_PLATFORM_WINDOWS)
10079 
10080 // end catch_windows_h_proxy.h
10081 #include <sstream>
10082 
10083 namespace Catch {
10084  namespace {
10085 
10086  struct IColourImpl {
10087  virtual ~IColourImpl() = default;
10088  virtual void use( Colour::Code _colourCode ) = 0;
10089  };
10090 
10091  struct NoColourImpl : IColourImpl {
10092  void use( Colour::Code ) override {}
10093 
10094  static IColourImpl* instance() {
10095  static NoColourImpl s_instance;
10096  return &s_instance;
10097  }
10098  };
10099 
10100  } // anon namespace
10101 } // namespace Catch
10102 
10103 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
10104 # ifdef CATCH_PLATFORM_WINDOWS
10105 # define CATCH_CONFIG_COLOUR_WINDOWS
10106 # else
10107 # define CATCH_CONFIG_COLOUR_ANSI
10108 # endif
10109 #endif
10110 
10111 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
10112 
10113 namespace Catch {
10114 namespace {
10115 
10116  class Win32ColourImpl : public IColourImpl {
10117  public:
10118  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
10119  {
10120  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
10121  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
10122  originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
10123  originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
10124  }
10125 
10126  void use( Colour::Code _colourCode ) override {
10127  switch( _colourCode ) {
10128  case Colour::None: return setTextAttribute( originalForegroundAttributes );
10129  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10130  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
10131  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
10132  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
10133  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
10134  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
10135  case Colour::Grey: return setTextAttribute( 0 );
10136 
10137  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
10138  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
10139  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
10140  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10141  case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
10142 
10143  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10144 
10145  default:
10146  CATCH_ERROR( "Unknown colour requested" );
10147  }
10148  }
10149 
10150  private:
10151  void setTextAttribute( WORD _textAttribute ) {
10152  SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
10153  }
10154  HANDLE stdoutHandle;
10155  WORD originalForegroundAttributes;
10156  WORD originalBackgroundAttributes;
10157  };
10158 
10159  IColourImpl* platformColourInstance() {
10160  static Win32ColourImpl s_instance;
10161 
10163  UseColour::YesOrNo colourMode = config
10164  ? config->useColour()
10165  : UseColour::Auto;
10166  if( colourMode == UseColour::Auto )
10167  colourMode = UseColour::Yes;
10168  return colourMode == UseColour::Yes
10169  ? &s_instance
10170  : NoColourImpl::instance();
10171  }
10172 
10173 } // end anon namespace
10174 } // end namespace Catch
10175 
10176 #elif defined( CATCH_CONFIG_COLOUR_ANSI )
10177 
10178 #include <unistd.h>
10179 
10180 namespace Catch {
10181 namespace {
10182 
10183  // use POSIX/ ANSI console terminal codes
10184  // Thanks to Adam Strzelecki for original contribution
10185  // (http://github.com/nanoant)
10186  // https://github.com/philsquared/Catch/pull/131
10187  class PosixColourImpl : public IColourImpl {
10188  public:
10189  void use( Colour::Code _colourCode ) override {
10190  switch( _colourCode ) {
10191  case Colour::None:
10192  case Colour::White: return setColour( "[0m" );
10193  case Colour::Red: return setColour( "[0;31m" );
10194  case Colour::Green: return setColour( "[0;32m" );
10195  case Colour::Blue: return setColour( "[0;34m" );
10196  case Colour::Cyan: return setColour( "[0;36m" );
10197  case Colour::Yellow: return setColour( "[0;33m" );
10198  case Colour::Grey: return setColour( "[1;30m" );
10199 
10200  case Colour::LightGrey: return setColour( "[0;37m" );
10201  case Colour::BrightRed: return setColour( "[1;31m" );
10202  case Colour::BrightGreen: return setColour( "[1;32m" );
10203  case Colour::BrightWhite: return setColour( "[1;37m" );
10204  case Colour::BrightYellow: return setColour( "[1;33m" );
10205 
10206  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10207  default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
10208  }
10209  }
10210  static IColourImpl* instance() {
10211  static PosixColourImpl s_instance;
10212  return &s_instance;
10213  }
10214 
10215  private:
10216  void setColour( const char* _escapeCode ) {
10217  getCurrentContext().getConfig()->stream()
10218  << '\033' << _escapeCode;
10219  }
10220  };
10221 
10222  bool useColourOnPlatform() {
10223  return
10224 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10225  !isDebuggerActive() &&
10226 #endif
10227 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
10228  isatty(STDOUT_FILENO)
10229 #else
10230  false
10231 #endif
10232  ;
10233  }
10234  IColourImpl* platformColourInstance() {
10235  ErrnoGuard guard;
10237  UseColour::YesOrNo colourMode = config
10238  ? config->useColour()
10239  : UseColour::Auto;
10240  if( colourMode == UseColour::Auto )
10241  colourMode = useColourOnPlatform()
10242  ? UseColour::Yes
10243  : UseColour::No;
10244  return colourMode == UseColour::Yes
10245  ? PosixColourImpl::instance()
10246  : NoColourImpl::instance();
10247  }
10248 
10249 } // end anon namespace
10250 } // end namespace Catch
10251 
10252 #else // not Windows or ANSI ///////////////////////////////////////////////
10253 
10254 namespace Catch {
10255 
10256  static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
10257 
10258 } // end namespace Catch
10259 
10260 #endif // Windows/ ANSI/ None
10261 
10262 namespace Catch {
10263 
10264  Colour::Colour( Code _colourCode ) { use( _colourCode ); }
10265  Colour::Colour( Colour&& other ) noexcept {
10266  m_moved = other.m_moved;
10267  other.m_moved = true;
10268  }
10269  Colour& Colour::operator=( Colour&& other ) noexcept {
10270  m_moved = other.m_moved;
10271  other.m_moved = true;
10272  return *this;
10273  }
10274 
10275  Colour::~Colour(){ if( !m_moved ) use( None ); }
10276 
10277  void Colour::use( Code _colourCode ) {
10278  static IColourImpl* impl = platformColourInstance();
10279  // Strictly speaking, this cannot possibly happen.
10280  // However, under some conditions it does happen (see #1626),
10281  // and this change is small enough that we can let practicality
10282  // triumph over purity in this case.
10283  if (impl != nullptr) {
10284  impl->use( _colourCode );
10285  }
10286  }
10287 
10288  std::ostream& operator << ( std::ostream& os, Colour const& ) {
10289  return os;
10290  }
10291 
10292 } // end namespace Catch
10293 
10294 #if defined(__clang__)
10295 # pragma clang diagnostic pop
10296 #endif
10297 
10298 // end catch_console_colour.cpp
10299 // start catch_context.cpp
10300 
10301 namespace Catch {
10302 
10303  class Context : public IMutableContext, NonCopyable {
10304 
10305  public: // IContext
10306  IResultCapture* getResultCapture() override {
10307  return m_resultCapture;
10308  }
10309  IRunner* getRunner() override {
10310  return m_runner;
10311  }
10312 
10313  IConfigPtr const& getConfig() const override {
10314  return m_config;
10315  }
10316 
10317  ~Context() override;
10318 
10319  public: // IMutableContext
10320  void setResultCapture( IResultCapture* resultCapture ) override {
10321  m_resultCapture = resultCapture;
10322  }
10323  void setRunner( IRunner* runner ) override {
10324  m_runner = runner;
10325  }
10326  void setConfig( IConfigPtr const& config ) override {
10327  m_config = config;
10328  }
10329 
10330  friend IMutableContext& getCurrentMutableContext();
10331 
10332  private:
10333  IConfigPtr m_config;
10334  IRunner* m_runner = nullptr;
10335  IResultCapture* m_resultCapture = nullptr;
10336  };
10337 
10338  IMutableContext *IMutableContext::currentContext = nullptr;
10339 
10340  void IMutableContext::createContext()
10341  {
10342  currentContext = new Context();
10343  }
10344 
10345  void cleanUpContext() {
10346  delete IMutableContext::currentContext;
10347  IMutableContext::currentContext = nullptr;
10348  }
10349  IContext::~IContext() = default;
10351  Context::~Context() = default;
10352 
10353  SimplePcg32& rng() {
10354  static SimplePcg32 s_rng;
10355  return s_rng;
10356  }
10357 
10358 }
10359 // end catch_context.cpp
10360 // start catch_debug_console.cpp
10361 
10362 // start catch_debug_console.h
10363 
10364 #include <string>
10365 
10366 namespace Catch {
10367  void writeToDebugConsole( std::string const& text );
10368 }
10369 
10370 // end catch_debug_console.h
10371 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
10372 #include <android/log.h>
10373 
10374  namespace Catch {
10375  void writeToDebugConsole( std::string const& text ) {
10376  __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
10377  }
10378  }
10379 
10380 #elif defined(CATCH_PLATFORM_WINDOWS)
10381 
10382  namespace Catch {
10383  void writeToDebugConsole( std::string const& text ) {
10384  ::OutputDebugStringA( text.c_str() );
10385  }
10386  }
10387 
10388 #else
10389 
10390  namespace Catch {
10391  void writeToDebugConsole( std::string const& text ) {
10392  // !TBD: Need a version for Mac/ XCode and other IDEs
10393  Catch::cout() << text;
10394  }
10395  }
10396 
10397 #endif // Platform
10398 // end catch_debug_console.cpp
10399 // start catch_debugger.cpp
10400 
10401 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10402 
10403 # include <cassert>
10404 # include <sys/types.h>
10405 # include <unistd.h>
10406 # include <cstddef>
10407 # include <ostream>
10408 
10409 #ifdef __apple_build_version__
10410  // These headers will only compile with AppleClang (XCode)
10411  // For other compilers (Clang, GCC, ... ) we need to exclude them
10412 # include <sys/sysctl.h>
10413 #endif
10414 
10415  namespace Catch {
10416  #ifdef __apple_build_version__
10417  // The following function is taken directly from the following technical note:
10418  // https://developer.apple.com/library/archive/qa/qa1361/_index.html
10419 
10420  // Returns true if the current process is being debugged (either
10421  // running under the debugger or has a debugger attached post facto).
10422  bool isDebuggerActive(){
10423  int mib[4];
10424  struct kinfo_proc info;
10425  std::size_t size;
10426 
10427  // Initialize the flags so that, if sysctl fails for some bizarre
10428  // reason, we get a predictable result.
10429 
10430  info.kp_proc.p_flag = 0;
10431 
10432  // Initialize mib, which tells sysctl the info we want, in this case
10433  // we're looking for information about a specific process ID.
10434 
10435  mib[0] = CTL_KERN;
10436  mib[1] = KERN_PROC;
10437  mib[2] = KERN_PROC_PID;
10438  mib[3] = getpid();
10439 
10440  // Call sysctl.
10441 
10442  size = sizeof(info);
10443  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
10444  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
10445  return false;
10446  }
10447 
10448  // We're being debugged if the P_TRACED flag is set.
10449 
10450  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
10451  }
10452  #else
10453  bool isDebuggerActive() {
10454  // We need to find another way to determine this for non-appleclang compilers on macOS
10455  return false;
10456  }
10457  #endif
10458  } // namespace Catch
10459 
10460 #elif defined(CATCH_PLATFORM_LINUX)
10461  #include <fstream>
10462  #include <string>
10463 
10464  namespace Catch{
10465  // The standard POSIX way of detecting a debugger is to attempt to
10466  // ptrace() the process, but this needs to be done from a child and not
10467  // this process itself to still allow attaching to this process later
10468  // if wanted, so is rather heavy. Under Linux we have the PID of the
10469  // "debugger" (which doesn't need to be gdb, of course, it could also
10470  // be strace, for example) in /proc/$PID/status, so just get it from
10471  // there instead.
10472  bool isDebuggerActive(){
10473  // Libstdc++ has a bug, where std::ifstream sets errno to 0
10474  // This way our users can properly assert over errno values
10475  ErrnoGuard guard;
10476  std::ifstream in("/proc/self/status");
10477  for( std::string line; std::getline(in, line); ) {
10478  static const int PREFIX_LEN = 11;
10479  if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
10480  // We're traced if the PID is not 0 and no other PID starts
10481  // with 0 digit, so it's enough to check for just a single
10482  // character.
10483  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
10484  }
10485  }
10486 
10487  return false;
10488  }
10489  } // namespace Catch
10490 #elif defined(_MSC_VER)
10491  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10492  namespace Catch {
10493  bool isDebuggerActive() {
10494  return IsDebuggerPresent() != 0;
10495  }
10496  }
10497 #elif defined(__MINGW32__)
10498  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10499  namespace Catch {
10500  bool isDebuggerActive() {
10501  return IsDebuggerPresent() != 0;
10502  }
10503  }
10504 #else
10505  namespace Catch {
10506  bool isDebuggerActive() { return false; }
10507  }
10508 #endif // Platform
10509 // end catch_debugger.cpp
10510 // start catch_decomposer.cpp
10511 
10512 namespace Catch {
10513 
10515 
10516  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
10517  if( lhs.size() + rhs.size() < 40 &&
10518  lhs.find('\n') == std::string::npos &&
10519  rhs.find('\n') == std::string::npos )
10520  os << lhs << " " << op << " " << rhs;
10521  else
10522  os << lhs << "\n" << op << "\n" << rhs;
10523  }
10524 }
10525 // end catch_decomposer.cpp
10526 // start catch_enforce.cpp
10527 
10528 #include <stdexcept>
10529 
10530 namespace Catch {
10531 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
10532  [[noreturn]]
10533  void throw_exception(std::exception const& e) {
10534  Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
10535  << "The message was: " << e.what() << '\n';
10536  std::terminate();
10537  }
10538 #endif
10539 
10540  [[noreturn]]
10541  void throw_logic_error(std::string const& msg) {
10542  throw_exception(std::logic_error(msg));
10543  }
10544 
10545  [[noreturn]]
10546  void throw_domain_error(std::string const& msg) {
10547  throw_exception(std::domain_error(msg));
10548  }
10549 
10550  [[noreturn]]
10551  void throw_runtime_error(std::string const& msg) {
10552  throw_exception(std::runtime_error(msg));
10553  }
10554 
10555 } // namespace Catch;
10556 // end catch_enforce.cpp
10557 // start catch_enum_values_registry.cpp
10558 // start catch_enum_values_registry.h
10559 
10560 #include <vector>
10561 #include <memory>
10562 
10563 namespace Catch {
10564 
10565  namespace Detail {
10566 
10567  std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
10568 
10569  class EnumValuesRegistry : public IMutableEnumValuesRegistry {
10570 
10571  std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
10572 
10573  EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
10574  };
10575 
10576  std::vector<StringRef> parseEnums( StringRef enums );
10577 
10578  } // Detail
10579 
10580 } // Catch
10581 
10582 // end catch_enum_values_registry.h
10583 
10584 #include <map>
10585 #include <cassert>
10586 
10587 namespace Catch {
10588 
10590 
10591  namespace Detail {
10592 
10593  namespace {
10594  // Extracts the actual name part of an enum instance
10595  // In other words, it returns the Blue part of Bikeshed::Colour::Blue
10596  StringRef extractInstanceName(StringRef enumInstance) {
10597  // Find last occurrence of ":"
10598  size_t name_start = enumInstance.size();
10599  while (name_start > 0 && enumInstance[name_start - 1] != ':') {
10600  --name_start;
10601  }
10602  return enumInstance.substr(name_start, enumInstance.size() - name_start);
10603  }
10604  }
10605 
10606  std::vector<StringRef> parseEnums( StringRef enums ) {
10607  auto enumValues = splitStringRef( enums, ',' );
10608  std::vector<StringRef> parsed;
10609  parsed.reserve( enumValues.size() );
10610  for( auto const& enumValue : enumValues ) {
10611  parsed.push_back(trim(extractInstanceName(enumValue)));
10612  }
10613  return parsed;
10614  }
10615 
10616  EnumInfo::~EnumInfo() {}
10617 
10618  StringRef EnumInfo::lookup( int value ) const {
10619  for( auto const& valueToName : m_values ) {
10620  if( valueToName.first == value )
10621  return valueToName.second;
10622  }
10623  return "{** unexpected enum value **}"_sr;
10624  }
10625 
10626  std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10627  std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
10628  enumInfo->m_name = enumName;
10629  enumInfo->m_values.reserve( values.size() );
10630 
10631  const auto valueNames = Catch::Detail::parseEnums( allValueNames );
10632  assert( valueNames.size() == values.size() );
10633  std::size_t i = 0;
10634  for( auto value : values )
10635  enumInfo->m_values.emplace_back(value, valueNames[i++]);
10636 
10637  return enumInfo;
10638  }
10639 
10640  EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10641  m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
10642  return *m_enumInfos.back();
10643  }
10644 
10645  } // Detail
10646 } // Catch
10647 
10648 // end catch_enum_values_registry.cpp
10649 // start catch_errno_guard.cpp
10650 
10651 #include <cerrno>
10652 
10653 namespace Catch {
10654  ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
10655  ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
10656 }
10657 // end catch_errno_guard.cpp
10658 // start catch_exception_translator_registry.cpp
10659 
10660 // start catch_exception_translator_registry.h
10661 
10662 #include <vector>
10663 #include <string>
10664 #include <memory>
10665 
10666 namespace Catch {
10667 
10668  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
10669  public:
10670  ~ExceptionTranslatorRegistry();
10671  virtual void registerTranslator( const IExceptionTranslator* translator );
10672  std::string translateActiveException() const override;
10673  std::string tryTranslators() const;
10674 
10675  private:
10676  std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
10677  };
10678 }
10679 
10680 // end catch_exception_translator_registry.h
10681 #ifdef __OBJC__
10682 #import "Foundation/Foundation.h"
10683 #endif
10684 
10685 namespace Catch {
10686 
10687  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
10688  }
10689 
10690  void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
10691  m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
10692  }
10693 
10694 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10696  try {
10697 #ifdef __OBJC__
10698  // In Objective-C try objective-c exceptions first
10699  @try {
10700  return tryTranslators();
10701  }
10702  @catch (NSException *exception) {
10703  return Catch::Detail::stringify( [exception description] );
10704  }
10705 #else
10706  // Compiling a mixed mode project with MSVC means that CLR
10707  // exceptions will be caught in (...) as well. However, these
10708  // do not fill-in std::current_exception and thus lead to crash
10709  // when attempting rethrow.
10710  // /EHa switch also causes structured exceptions to be caught
10711  // here, but they fill-in current_exception properly, so
10712  // at worst the output should be a little weird, instead of
10713  // causing a crash.
10714  if (std::current_exception() == nullptr) {
10715  return "Non C++ exception. Possibly a CLR exception.";
10716  }
10717  return tryTranslators();
10718 #endif
10719  }
10720  catch( TestFailureException& ) {
10721  std::rethrow_exception(std::current_exception());
10722  }
10723  catch( std::exception& ex ) {
10724  return ex.what();
10725  }
10726  catch( std::string& msg ) {
10727  return msg;
10728  }
10729  catch( const char* msg ) {
10730  return msg;
10731  }
10732  catch(...) {
10733  return "Unknown exception";
10734  }
10735  }
10736 
10737  std::string ExceptionTranslatorRegistry::tryTranslators() const {
10738  if (m_translators.empty()) {
10739  std::rethrow_exception(std::current_exception());
10740  } else {
10741  return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
10742  }
10743  }
10744 
10745 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
10747  CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10748  }
10749 
10750  std::string ExceptionTranslatorRegistry::tryTranslators() const {
10751  CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10752  }
10753 #endif
10754 
10755 }
10756 // end catch_exception_translator_registry.cpp
10757 // start catch_fatal_condition.cpp
10758 
10759 #include <algorithm>
10760 
10761 #if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
10762 
10763 namespace Catch {
10764 
10765  // If neither SEH nor signal handling is required, the handler impls
10766  // do not have to do anything, and can be empty.
10767  void FatalConditionHandler::engage_platform() {}
10768  void FatalConditionHandler::disengage_platform() {}
10769  FatalConditionHandler::FatalConditionHandler() = default;
10770  FatalConditionHandler::~FatalConditionHandler() = default;
10771 
10772 } // end namespace Catch
10773 
10774 #endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
10775 
10776 #if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )
10777 #error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
10778 #endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
10779 
10780 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
10781 
10782 namespace {
10784  void reportFatal( char const * const message ) {
10786  }
10787 
10791  constexpr std::size_t minStackSizeForErrors = 32 * 1024;
10792 } // end unnamed namespace
10793 
10794 #endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
10795 
10796 #if defined( CATCH_CONFIG_WINDOWS_SEH )
10797 
10798 namespace Catch {
10799 
10800  struct SignalDefs { DWORD id; const char* name; };
10801 
10802  // There is no 1-1 mapping between signals and windows exceptions.
10803  // Windows can easily distinguish between SO and SigSegV,
10804  // but SigInt, SigTerm, etc are handled differently.
10805  static SignalDefs signalDefs[] = {
10806  { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
10807  { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
10808  { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
10809  { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
10810  };
10811 
10812  static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
10813  for (auto const& def : signalDefs) {
10814  if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
10815  reportFatal(def.name);
10816  }
10817  }
10818  // If its not an exception we care about, pass it along.
10819  // This stops us from eating debugger breaks etc.
10820  return EXCEPTION_CONTINUE_SEARCH;
10821  }
10822 
10823  // Since we do not support multiple instantiations, we put these
10824  // into global variables and rely on cleaning them up in outlined
10825  // constructors/destructors
10826  static PVOID exceptionHandlerHandle = nullptr;
10827 
10828  // For MSVC, we reserve part of the stack memory for handling
10829  // memory overflow structured exception.
10830  FatalConditionHandler::FatalConditionHandler() {
10831  ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);
10832  if (!SetThreadStackGuarantee(&guaranteeSize)) {
10833  // We do not want to fully error out, because needing
10834  // the stack reserve should be rare enough anyway.
10835  Catch::cerr()
10836  << "Failed to reserve piece of stack."
10837  << " Stack overflows will not be reported successfully.";
10838  }
10839  }
10840 
10841  // We do not attempt to unset the stack guarantee, because
10842  // Windows does not support lowering the stack size guarantee.
10843  FatalConditionHandler::~FatalConditionHandler() = default;
10844 
10845  void FatalConditionHandler::engage_platform() {
10846  // Register as first handler in current chain
10847  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
10848  if (!exceptionHandlerHandle) {
10849  CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
10850  }
10851  }
10852 
10853  void FatalConditionHandler::disengage_platform() {
10854  if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
10855  CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
10856  }
10857  exceptionHandlerHandle = nullptr;
10858  }
10859 
10860 } // end namespace Catch
10861 
10862 #endif // CATCH_CONFIG_WINDOWS_SEH
10863 
10864 #if defined( CATCH_CONFIG_POSIX_SIGNALS )
10865 
10866 #include <signal.h>
10867 
10868 namespace Catch {
10869 
10870  struct SignalDefs {
10871  int id;
10872  const char* name;
10873  };
10874 
10875  static SignalDefs signalDefs[] = {
10876  { SIGINT, "SIGINT - Terminal interrupt signal" },
10877  { SIGILL, "SIGILL - Illegal instruction signal" },
10878  { SIGFPE, "SIGFPE - Floating point error signal" },
10879  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
10880  { SIGTERM, "SIGTERM - Termination request signal" },
10881  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
10882  };
10883 
10884 // Older GCCs trigger -Wmissing-field-initializers for T foo = {}
10885 // which is zero initialization, but not explicit. We want to avoid
10886 // that.
10887 #if defined(__GNUC__)
10888 # pragma GCC diagnostic push
10889 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
10890 #endif
10891 
10892  static char* altStackMem = nullptr;
10893  static std::size_t altStackSize = 0;
10894  static stack_t oldSigStack{};
10895  static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
10896 
10897  static void restorePreviousSignalHandlers() {
10898  // We set signal handlers back to the previous ones. Hopefully
10899  // nobody overwrote them in the meantime, and doesn't expect
10900  // their signal handlers to live past ours given that they
10901  // installed them after ours..
10902  for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
10903  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
10904  }
10905  // Return the old stack
10906  sigaltstack(&oldSigStack, nullptr);
10907  }
10908 
10909  static void handleSignal( int sig ) {
10910  char const * name = "<unknown signal>";
10911  for (auto const& def : signalDefs) {
10912  if (sig == def.id) {
10913  name = def.name;
10914  break;
10915  }
10916  }
10917  // We need to restore previous signal handlers and let them do
10918  // their thing, so that the users can have the debugger break
10919  // when a signal is raised, and so on.
10920  restorePreviousSignalHandlers();
10921  reportFatal( name );
10922  raise( sig );
10923  }
10924 
10925  FatalConditionHandler::FatalConditionHandler() {
10926  assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
10927  if (altStackSize == 0) {
10928  altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);
10929  }
10930  altStackMem = new char[altStackSize]();
10931  }
10932 
10933  FatalConditionHandler::~FatalConditionHandler() {
10934  delete[] altStackMem;
10935  // We signal that another instance can be constructed by zeroing
10936  // out the pointer.
10937  altStackMem = nullptr;
10938  }
10939 
10940  void FatalConditionHandler::engage_platform() {
10941  stack_t sigStack;
10942  sigStack.ss_sp = altStackMem;
10943  sigStack.ss_size = altStackSize;
10944  sigStack.ss_flags = 0;
10945  sigaltstack(&sigStack, &oldSigStack);
10946  struct sigaction sa = { };
10947 
10948  sa.sa_handler = handleSignal;
10949  sa.sa_flags = SA_ONSTACK;
10950  for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
10951  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
10952  }
10953  }
10954 
10955 #if defined(__GNUC__)
10956 # pragma GCC diagnostic pop
10957 #endif
10958 
10959  void FatalConditionHandler::disengage_platform() {
10960  restorePreviousSignalHandlers();
10961  }
10962 
10963 } // end namespace Catch
10964 
10965 #endif // CATCH_CONFIG_POSIX_SIGNALS
10966 // end catch_fatal_condition.cpp
10967 // start catch_generators.cpp
10968 
10969 #include <limits>
10970 #include <set>
10971 
10972 namespace Catch {
10973 
10975 
10976 const char* GeneratorException::what() const noexcept {
10977  return m_msg;
10978 }
10979 
10980 namespace Generators {
10981 
10983 
10984  auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
10985  return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
10986  }
10987 
10988 } // namespace Generators
10989 } // namespace Catch
10990 // end catch_generators.cpp
10991 // start catch_interfaces_capture.cpp
10992 
10993 namespace Catch {
10994  IResultCapture::~IResultCapture() = default;
10995 }
10996 // end catch_interfaces_capture.cpp
10997 // start catch_interfaces_config.cpp
10998 
10999 namespace Catch {
11000  IConfig::~IConfig() = default;
11001 }
11002 // end catch_interfaces_config.cpp
11003 // start catch_interfaces_exception.cpp
11004 
11005 namespace Catch {
11008 }
11009 // end catch_interfaces_exception.cpp
11010 // start catch_interfaces_registry_hub.cpp
11011 
11012 namespace Catch {
11013  IRegistryHub::~IRegistryHub() = default;
11015 }
11016 // end catch_interfaces_registry_hub.cpp
11017 // start catch_interfaces_reporter.cpp
11018 
11019 // start catch_reporter_listening.h
11020 
11021 namespace Catch {
11022 
11023  class ListeningReporter : public IStreamingReporter {
11024  using Reporters = std::vector<IStreamingReporterPtr>;
11025  Reporters m_listeners;
11026  IStreamingReporterPtr m_reporter = nullptr;
11027  ReporterPreferences m_preferences;
11028 
11029  public:
11030  ListeningReporter();
11031 
11032  void addListener( IStreamingReporterPtr&& listener );
11033  void addReporter( IStreamingReporterPtr&& reporter );
11034 
11035  public: // IStreamingReporter
11036 
11037  ReporterPreferences getPreferences() const override;
11038 
11039  void noMatchingTestCases( std::string const& spec ) override;
11040 
11041  void reportInvalidArguments(std::string const&arg) override;
11042 
11043  static std::set<Verbosity> getSupportedVerbosities();
11044 
11045 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
11046  void benchmarkPreparing(std::string const& name) override;
11047  void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
11048  void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
11049  void benchmarkFailed(std::string const&) override;
11050 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
11051 
11052  void testRunStarting( TestRunInfo const& testRunInfo ) override;
11053  void testGroupStarting( GroupInfo const& groupInfo ) override;
11054  void testCaseStarting( TestCaseInfo const& testInfo ) override;
11055  void sectionStarting( SectionInfo const& sectionInfo ) override;
11056  void assertionStarting( AssertionInfo const& assertionInfo ) override;
11057 
11058  // The return value indicates if the messages buffer should be cleared:
11059  bool assertionEnded( AssertionStats const& assertionStats ) override;
11060  void sectionEnded( SectionStats const& sectionStats ) override;
11061  void testCaseEnded( TestCaseStats const& testCaseStats ) override;
11062  void testGroupEnded( TestGroupStats const& testGroupStats ) override;
11063  void testRunEnded( TestRunStats const& testRunStats ) override;
11064 
11065  void skipTest( TestCaseInfo const& testInfo ) override;
11066  bool isMulti() const override;
11067 
11068  };
11069 
11070 } // end namespace Catch
11071 
11072 // end catch_reporter_listening.h
11073 namespace Catch {
11074 
11075  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
11076  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
11077 
11078  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
11079  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
11080 
11081  std::ostream& ReporterConfig::stream() const { return *m_stream; }
11082  IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
11083 
11084  TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
11085 
11086  GroupInfo::GroupInfo( std::string const& _name,
11087  std::size_t _groupIndex,
11088  std::size_t _groupsCount )
11089  : name( _name ),
11090  groupIndex( _groupIndex ),
11091  groupsCounts( _groupsCount )
11092  {}
11093 
11094  AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
11095  std::vector<MessageInfo> const& _infoMessages,
11096  Totals const& _totals )
11097  : assertionResult( _assertionResult ),
11098  infoMessages( _infoMessages ),
11099  totals( _totals )
11100  {
11101  assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
11102 
11103  if( assertionResult.hasMessage() ) {
11104  // Copy message into messages list.
11105  // !TBD This should have been done earlier, somewhere
11106  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
11107  builder << assertionResult.getMessage();
11108  builder.m_info.message = builder.m_stream.str();
11109 
11110  infoMessages.push_back( builder.m_info );
11111  }
11112  }
11113 
11114  AssertionStats::~AssertionStats() = default;
11115 
11116  SectionStats::SectionStats( SectionInfo const& _sectionInfo,
11117  Counts const& _assertions,
11118  double _durationInSeconds,
11119  bool _missingAssertions )
11120  : sectionInfo( _sectionInfo ),
11121  assertions( _assertions ),
11122  durationInSeconds( _durationInSeconds ),
11123  missingAssertions( _missingAssertions )
11124  {}
11125 
11126  SectionStats::~SectionStats() = default;
11127 
11128  TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
11129  Totals const& _totals,
11130  std::string const& _stdOut,
11131  std::string const& _stdErr,
11132  bool _aborting )
11133  : testInfo( _testInfo ),
11134  totals( _totals ),
11135  stdOut( _stdOut ),
11136  stdErr( _stdErr ),
11137  aborting( _aborting )
11138  {}
11139 
11140  TestCaseStats::~TestCaseStats() = default;
11141 
11142  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
11143  Totals const& _totals,
11144  bool _aborting )
11145  : groupInfo( _groupInfo ),
11146  totals( _totals ),
11147  aborting( _aborting )
11148  {}
11149 
11150  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
11151  : groupInfo( _groupInfo ),
11152  aborting( false )
11153  {}
11154 
11155  TestGroupStats::~TestGroupStats() = default;
11156 
11157  TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
11158  Totals const& _totals,
11159  bool _aborting )
11160  : runInfo( _runInfo ),
11161  totals( _totals ),
11162  aborting( _aborting )
11163  {}
11164 
11165  TestRunStats::~TestRunStats() = default;
11166 
11167  void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
11168  bool IStreamingReporter::isMulti() const { return false; }
11169 
11170  IReporterFactory::~IReporterFactory() = default;
11171  IReporterRegistry::~IReporterRegistry() = default;
11172 
11173 } // end namespace Catch
11174 // end catch_interfaces_reporter.cpp
11175 // start catch_interfaces_runner.cpp
11176 
11177 namespace Catch {
11178  IRunner::~IRunner() = default;
11179 }
11180 // end catch_interfaces_runner.cpp
11181 // start catch_interfaces_testcase.cpp
11182 
11183 namespace Catch {
11184  ITestInvoker::~ITestInvoker() = default;
11186 }
11187 // end catch_interfaces_testcase.cpp
11188 // start catch_leak_detector.cpp
11189 
11190 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
11191 #include <crtdbg.h>
11192 
11193 namespace Catch {
11194 
11195  LeakDetector::LeakDetector() {
11196  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
11197  flag |= _CRTDBG_LEAK_CHECK_DF;
11198  flag |= _CRTDBG_ALLOC_MEM_DF;
11199  _CrtSetDbgFlag(flag);
11200  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
11201  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
11202  // Change this to leaking allocation's number to break there
11203  _CrtSetBreakAlloc(-1);
11204  }
11205 }
11206 
11207 #else
11208 
11209  Catch::LeakDetector::LeakDetector() {}
11210 
11211 #endif
11212 
11213 Catch::LeakDetector::~LeakDetector() {
11214  Catch::cleanUp();
11215 }
11216 // end catch_leak_detector.cpp
11217 // start catch_list.cpp
11218 
11219 // start catch_list.h
11220 
11221 #include <set>
11222 
11223 namespace Catch {
11224 
11225  std::size_t listTests( Config const& config );
11226 
11227  std::size_t listTestsNamesOnly( Config const& config );
11228 
11229  struct TagInfo {
11230  void add( std::string const& spelling );
11231  std::string all() const;
11232 
11233  std::set<std::string> spellings;
11234  std::size_t count = 0;
11235  };
11236 
11237  std::size_t listTags( Config const& config );
11238 
11239  std::size_t listReporters();
11240 
11241  Option<std::size_t> list( std::shared_ptr<Config> const& config );
11242 
11243 } // end namespace Catch
11244 
11245 // end catch_list.h
11246 // start catch_text.h
11247 
11248 namespace Catch {
11249  using namespace clara::TextFlow;
11250 }
11251 
11252 // end catch_text.h
11253 #include <limits>
11254 #include <algorithm>
11255 #include <iomanip>
11256 
11257 namespace Catch {
11258 
11259  std::size_t listTests( Config const& config ) {
11260  TestSpec const& testSpec = config.testSpec();
11261  if( config.hasTestFilters() )
11262  Catch::cout() << "Matching test cases:\n";
11263  else {
11264  Catch::cout() << "All available test cases:\n";
11265  }
11266 
11267  auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11268  for( auto const& testCaseInfo : matchedTestCases ) {
11269  Colour::Code colour = testCaseInfo.isHidden()
11270  ? Colour::SecondaryText
11271  : Colour::None;
11272  Colour colourGuard( colour );
11273 
11274  Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
11275  if( config.verbosity() >= Verbosity::High ) {
11276  Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
11277  std::string description = testCaseInfo.description;
11278  if( description.empty() )
11279  description = "(NO DESCRIPTION)";
11280  Catch::cout() << Column( description ).indent(4) << std::endl;
11281  }
11282  if( !testCaseInfo.tags.empty() )
11283  Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
11284  }
11285 
11286  if( !config.hasTestFilters() )
11287  Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
11288  else
11289  Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
11290  return matchedTestCases.size();
11291  }
11292 
11293  std::size_t listTestsNamesOnly( Config const& config ) {
11294  TestSpec const& testSpec = config.testSpec();
11295  std::size_t matchedTests = 0;
11296  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11297  for( auto const& testCaseInfo : matchedTestCases ) {
11298  matchedTests++;
11299  if( startsWith( testCaseInfo.name, '#' ) )
11300  Catch::cout() << '"' << testCaseInfo.name << '"';
11301  else
11302  Catch::cout() << testCaseInfo.name;
11303  if ( config.verbosity() >= Verbosity::High )
11304  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
11305  Catch::cout() << std::endl;
11306  }
11307  return matchedTests;
11308  }
11309 
11310  void TagInfo::add( std::string const& spelling ) {
11311  ++count;
11312  spellings.insert( spelling );
11313  }
11314 
11315  std::string TagInfo::all() const {
11316  size_t size = 0;
11317  for (auto const& spelling : spellings) {
11318  // Add 2 for the brackes
11319  size += spelling.size() + 2;
11320  }
11321 
11322  std::string out; out.reserve(size);
11323  for (auto const& spelling : spellings) {
11324  out += '[';
11325  out += spelling;
11326  out += ']';
11327  }
11328  return out;
11329  }
11330 
11331  std::size_t listTags( Config const& config ) {
11332  TestSpec const& testSpec = config.testSpec();
11333  if( config.hasTestFilters() )
11334  Catch::cout() << "Tags for matching test cases:\n";
11335  else {
11336  Catch::cout() << "All available tags:\n";
11337  }
11338 
11339  std::map<std::string, TagInfo> tagCounts;
11340 
11341  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11342  for( auto const& testCase : matchedTestCases ) {
11343  for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
11344  std::string lcaseTagName = toLower( tagName );
11345  auto countIt = tagCounts.find( lcaseTagName );
11346  if( countIt == tagCounts.end() )
11347  countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
11348  countIt->second.add( tagName );
11349  }
11350  }
11351 
11352  for( auto const& tagCount : tagCounts ) {
11353  ReusableStringStream rss;
11354  rss << " " << std::setw(2) << tagCount.second.count << " ";
11355  auto str = rss.str();
11356  auto wrapper = Column( tagCount.second.all() )
11357  .initialIndent( 0 )
11358  .indent( str.size() )
11359  .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
11360  Catch::cout() << str << wrapper << '\n';
11361  }
11362  Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
11363  return tagCounts.size();
11364  }
11365 
11366  std::size_t listReporters() {
11367  Catch::cout() << "Available reporters:\n";
11368  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
11369  std::size_t maxNameLen = 0;
11370  for( auto const& factoryKvp : factories )
11371  maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
11372 
11373  for( auto const& factoryKvp : factories ) {
11374  Catch::cout()
11375  << Column( factoryKvp.first + ":" )
11376  .indent(2)
11377  .width( 5+maxNameLen )
11378  + Column( factoryKvp.second->getDescription() )
11379  .initialIndent(0)
11380  .indent(2)
11381  .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
11382  << "\n";
11383  }
11384  Catch::cout() << std::endl;
11385  return factories.size();
11386  }
11387 
11388  Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
11389  Option<std::size_t> listedCount;
11391  if( config->listTests() )
11392  listedCount = listedCount.valueOr(0) + listTests( *config );
11393  if( config->listTestNamesOnly() )
11394  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
11395  if( config->listTags() )
11396  listedCount = listedCount.valueOr(0) + listTags( *config );
11397  if( config->listReporters() )
11398  listedCount = listedCount.valueOr(0) + listReporters();
11399  return listedCount;
11400  }
11401 
11402 } // end namespace Catch
11403 // end catch_list.cpp
11404 // start catch_matchers.cpp
11405 
11406 namespace Catch {
11407 namespace Matchers {
11408  namespace Impl {
11409 
11411  if( m_cachedToString.empty() )
11413  return m_cachedToString;
11414  }
11415 
11417 
11418  } // namespace Impl
11419 } // namespace Matchers
11420 
11421 using namespace Matchers;
11422 using Matchers::Impl::MatcherBase;
11423 
11424 } // namespace Catch
11425 // end catch_matchers.cpp
11426 // start catch_matchers_exception.cpp
11427 
11428 namespace Catch {
11429 namespace Matchers {
11430 namespace Exception {
11431 
11432 bool ExceptionMessageMatcher::match(std::exception const& ex) const {
11433  return ex.what() == m_message;
11434 }
11435 
11437  return "exception message matches \"" + m_message + "\"";
11438 }
11439 
11440 }
11441 Exception::ExceptionMessageMatcher Message(std::string const& message) {
11442  return Exception::ExceptionMessageMatcher(message);
11443 }
11444 
11445 // namespace Exception
11446 } // namespace Matchers
11447 } // namespace Catch
11448 // end catch_matchers_exception.cpp
11449 // start catch_matchers_floating.cpp
11450 
11451 // start catch_polyfills.hpp
11452 
11453 namespace Catch {
11454  bool isnan(float f);
11455  bool isnan(double d);
11456 }
11457 
11458 // end catch_polyfills.hpp
11459 // start catch_to_string.hpp
11460 
11461 #include <string>
11462 
11463 namespace Catch {
11464  template <typename T>
11465  std::string to_string(T const& t) {
11466 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11467  return std::to_string(t);
11468 #else
11469  ReusableStringStream rss;
11470  rss << t;
11471  return rss.str();
11472 #endif
11473  }
11474 } // end namespace Catch
11475 
11476 // end catch_to_string.hpp
11477 #include <algorithm>
11478 #include <cmath>
11479 #include <cstdlib>
11480 #include <cstdint>
11481 #include <cstring>
11482 #include <sstream>
11483 #include <type_traits>
11484 #include <iomanip>
11485 #include <limits>
11486 
11487 namespace Catch {
11488 namespace {
11489 
11490  int32_t convert(float f) {
11491  static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
11492  int32_t i;
11493  std::memcpy(&i, &f, sizeof(f));
11494  return i;
11495  }
11496 
11497  int64_t convert(double d) {
11498  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
11499  int64_t i;
11500  std::memcpy(&i, &d, sizeof(d));
11501  return i;
11502  }
11503 
11504  template <typename FP>
11505  bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
11506  // Comparison with NaN should always be false.
11507  // This way we can rule it out before getting into the ugly details
11508  if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
11509  return false;
11510  }
11511 
11512  auto lc = convert(lhs);
11513  auto rc = convert(rhs);
11514 
11515  if ((lc < 0) != (rc < 0)) {
11516  // Potentially we can have +0 and -0
11517  return lhs == rhs;
11518  }
11519 
11520  // static cast as a workaround for IBM XLC
11521  auto ulpDiff = std::abs(static_cast<FP>(lc - rc));
11522  return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
11523  }
11524 
11525 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11526 
11527  float nextafter(float x, float y) {
11528  return ::nextafterf(x, y);
11529  }
11530 
11531  double nextafter(double x, double y) {
11532  return ::nextafter(x, y);
11533  }
11534 
11535 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
11536 
11537 template <typename FP>
11538 FP step(FP start, FP direction, uint64_t steps) {
11539  for (uint64_t i = 0; i < steps; ++i) {
11540 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11541  start = Catch::nextafter(start, direction);
11542 #else
11543  start = std::nextafter(start, direction);
11544 #endif
11545  }
11546  return start;
11547 }
11548 
11549 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11550 // But without the subtraction to allow for INFINITY in comparison
11551 bool marginComparison(double lhs, double rhs, double margin) {
11552  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
11553 }
11554 
11555 template <typename FloatingPoint>
11556 void write(std::ostream& out, FloatingPoint num) {
11557  out << std::scientific
11558  << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
11559  << num;
11560 }
11561 
11562 } // end anonymous namespace
11563 
11564 namespace Matchers {
11565 namespace Floating {
11566 
11567  enum class FloatingPointKind : uint8_t {
11568  Float,
11569  Double
11570  };
11571 
11572  WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
11573  :m_target{ target }, m_margin{ margin } {
11574  CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
11575  << " Margin has to be non-negative.");
11576  }
11577 
11578  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11579  // But without the subtraction to allow for INFINITY in comparison
11580  bool WithinAbsMatcher::match(double const& matchee) const {
11581  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
11582  }
11583 
11584  std::string WithinAbsMatcher::describe() const {
11585  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
11586  }
11587 
11588  WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
11589  :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
11591  || m_ulps < (std::numeric_limits<uint32_t>::max)(),
11592  "Provided ULP is impossibly large for a float comparison.");
11593  }
11594 
11595 #if defined(__clang__)
11596 #pragma clang diagnostic push
11597 // Clang <3.5 reports on the default branch in the switch below
11598 #pragma clang diagnostic ignored "-Wunreachable-code"
11599 #endif
11600 
11601  bool WithinUlpsMatcher::match(double const& matchee) const {
11602  switch (m_type) {
11604  return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
11606  return almostEqualUlps<double>(matchee, m_target, m_ulps);
11607  default:
11608  CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
11609  }
11610  }
11611 
11612 #if defined(__clang__)
11613 #pragma clang diagnostic pop
11614 #endif
11615 
11616  std::string WithinUlpsMatcher::describe() const {
11617  std::stringstream ret;
11618 
11619  ret << "is within " << m_ulps << " ULPs of ";
11620 
11621  if (m_type == FloatingPointKind::Float) {
11622  write(ret, static_cast<float>(m_target));
11623  ret << 'f';
11624  } else {
11625  write(ret, m_target);
11626  }
11627 
11628  ret << " ([";
11629  if (m_type == FloatingPointKind::Double) {
11630  write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
11631  ret << ", ";
11632  write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
11633  } else {
11634  // We have to cast INFINITY to float because of MinGW, see #1782
11635  write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
11636  ret << ", ";
11637  write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
11638  }
11639  ret << "])";
11640 
11641  return ret.str();
11642  }
11643 
11644  WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
11645  m_target(target),
11646  m_epsilon(epsilon){
11647  CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense.");
11648  CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
11649  }
11650 
11651  bool WithinRelMatcher::match(double const& matchee) const {
11652  const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
11653  return marginComparison(matchee, m_target,
11654  std::isinf(relMargin)? 0 : relMargin);
11655  }
11656 
11657  std::string WithinRelMatcher::describe() const {
11658  Catch::ReusableStringStream sstr;
11659  sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
11660  return sstr.str();
11661  }
11662 
11663 }// namespace Floating
11664 
11665 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
11666  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
11667 }
11668 
11669 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
11670  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
11671 }
11672 
11673 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
11674  return Floating::WithinAbsMatcher(target, margin);
11675 }
11676 
11677 Floating::WithinRelMatcher WithinRel(double target, double eps) {
11678  return Floating::WithinRelMatcher(target, eps);
11679 }
11680 
11681 Floating::WithinRelMatcher WithinRel(double target) {
11682  return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
11683 }
11684 
11685 Floating::WithinRelMatcher WithinRel(float target, float eps) {
11686  return Floating::WithinRelMatcher(target, eps);
11687 }
11688 
11689 Floating::WithinRelMatcher WithinRel(float target) {
11690  return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
11691 }
11692 
11693 } // namespace Matchers
11694 } // namespace Catch
11695 // end catch_matchers_floating.cpp
11696 // start catch_matchers_generic.cpp
11697 
11698 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
11699  if (desc.empty()) {
11700  return "matches undescribed predicate";
11701  } else {
11702  return "matches predicate: \"" + desc + '"';
11703  }
11704 }
11705 // end catch_matchers_generic.cpp
11706 // start catch_matchers_string.cpp
11707 
11708 #include <regex>
11709 
11710 namespace Catch {
11711 namespace Matchers {
11712 
11713  namespace StdString {
11714 
11716  : m_caseSensitivity( caseSensitivity ),
11717  m_str( adjustString( str ) )
11718  {}
11719  std::string CasedString::adjustString( std::string const& str ) const {
11720  return m_caseSensitivity == CaseSensitive::No
11721  ? toLower( str )
11722  : str;
11723  }
11724  std::string CasedString::caseSensitivitySuffix() const {
11725  return m_caseSensitivity == CaseSensitive::No
11726  ? " (case insensitive)"
11727  : std::string();
11728  }
11729 
11730  StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
11731  : m_comparator( comparator ),
11732  m_operation( operation ) {
11733  }
11734 
11735  std::string StringMatcherBase::describe() const {
11736  std::string description;
11737  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
11738  m_comparator.caseSensitivitySuffix().size());
11739  description += m_operation;
11740  description += ": \"";
11741  description += m_comparator.m_str;
11742  description += "\"";
11743  description += m_comparator.caseSensitivitySuffix();
11744  return description;
11745  }
11746 
11747  EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
11748 
11749  bool EqualsMatcher::match( std::string const& source ) const {
11750  return m_comparator.adjustString( source ) == m_comparator.m_str;
11751  }
11752 
11753  ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
11754 
11755  bool ContainsMatcher::match( std::string const& source ) const {
11756  return contains( m_comparator.adjustString( source ), m_comparator.m_str );
11757  }
11758 
11759  StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
11760 
11761  bool StartsWithMatcher::match( std::string const& source ) const {
11762  return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11763  }
11764 
11765  EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
11766 
11767  bool EndsWithMatcher::match( std::string const& source ) const {
11768  return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11769  }
11770 
11771  RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
11772 
11773  bool RegexMatcher::match(std::string const& matchee) const {
11774  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
11775  if (m_caseSensitivity == CaseSensitive::Choice::No) {
11776  flags |= std::regex::icase;
11777  }
11778  auto reg = std::regex(m_regex, flags);
11779  return std::regex_match(matchee, reg);
11780  }
11781 
11782  std::string RegexMatcher::describe() const {
11783  return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
11784  }
11785 
11786  } // namespace StdString
11787 
11788  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11789  return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
11790  }
11791  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11792  return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
11793  }
11794  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11795  return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11796  }
11797  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11798  return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11799  }
11800 
11801  StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
11802  return StdString::RegexMatcher(regex, caseSensitivity);
11803  }
11804 
11805 } // namespace Matchers
11806 } // namespace Catch
11807 // end catch_matchers_string.cpp
11808 // start catch_message.cpp
11809 
11810 // start catch_uncaught_exceptions.h
11811 
11812 namespace Catch {
11813  bool uncaught_exceptions();
11814 } // end namespace Catch
11815 
11816 // end catch_uncaught_exceptions.h
11817 #include <cassert>
11818 #include <stack>
11819 
11820 namespace Catch {
11821 
11822  MessageInfo::MessageInfo( StringRef const& _macroName,
11823  SourceLineInfo const& _lineInfo,
11824  ResultWas::OfType _type )
11825  : macroName( _macroName ),
11826  lineInfo( _lineInfo ),
11827  type( _type ),
11828  sequence( ++globalCount )
11829  {}
11830 
11831  bool MessageInfo::operator==( MessageInfo const& other ) const {
11832  return sequence == other.sequence;
11833  }
11834 
11835  bool MessageInfo::operator<( MessageInfo const& other ) const {
11836  return sequence < other.sequence;
11837  }
11838 
11839  // This may need protecting if threading support is added
11840  unsigned int MessageInfo::globalCount = 0;
11841 
11843 
11844  Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
11845  SourceLineInfo const& lineInfo,
11847  :m_info(macroName, lineInfo, type) {}
11848 
11850 
11851  ScopedMessage::ScopedMessage( MessageBuilder const& builder )
11852  : m_info( builder.m_info ), m_moved()
11853  {
11854  m_info.message = builder.m_stream.str();
11855  getResultCapture().pushScopedMessage( m_info );
11856  }
11857 
11858  ScopedMessage::ScopedMessage( ScopedMessage&& old )
11859  : m_info( old.m_info ), m_moved()
11860  {
11861  old.m_moved = true;
11862  }
11863 
11865  if ( !uncaught_exceptions() && !m_moved ){
11867  }
11868  }
11869 
11870  Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
11871  auto trimmed = [&] (size_t start, size_t end) {
11872  while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
11873  ++start;
11874  }
11875  while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
11876  --end;
11877  }
11878  return names.substr(start, end - start + 1);
11879  };
11880  auto skipq = [&] (size_t start, char quote) {
11881  for (auto i = start + 1; i < names.size() ; ++i) {
11882  if (names[i] == quote)
11883  return i;
11884  if (names[i] == '\\')
11885  ++i;
11886  }
11887  CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
11888  };
11889 
11890  size_t start = 0;
11891  std::stack<char> openings;
11892  for (size_t pos = 0; pos < names.size(); ++pos) {
11893  char c = names[pos];
11894  switch (c) {
11895  case '[':
11896  case '{':
11897  case '(':
11898  // It is basically impossible to disambiguate between
11899  // comparison and start of template args in this context
11900 // case '<':
11901  openings.push(c);
11902  break;
11903  case ']':
11904  case '}':
11905  case ')':
11906 // case '>':
11907  openings.pop();
11908  break;
11909  case '"':
11910  case '\'':
11911  pos = skipq(pos, c);
11912  break;
11913  case ',':
11914  if (start != pos && openings.empty()) {
11915  m_messages.emplace_back(macroName, lineInfo, resultType);
11916  m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
11917  m_messages.back().message += " := ";
11918  start = pos;
11919  }
11920  }
11921  }
11922  assert(openings.empty() && "Mismatched openings");
11923  m_messages.emplace_back(macroName, lineInfo, resultType);
11924  m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
11925  m_messages.back().message += " := ";
11926  }
11927  Capturer::~Capturer() {
11928  if ( !uncaught_exceptions() ){
11929  assert( m_captured == m_messages.size() );
11930  for( size_t i = 0; i < m_captured; ++i )
11931  m_resultCapture.popScopedMessage( m_messages[i] );
11932  }
11933  }
11934 
11935  void Capturer::captureValue( size_t index, std::string const& value ) {
11936  assert( index < m_messages.size() );
11937  m_messages[index].message += value;
11938  m_resultCapture.pushScopedMessage( m_messages[index] );
11939  m_captured++;
11940  }
11941 
11942 } // end namespace Catch
11943 // end catch_message.cpp
11944 // start catch_output_redirect.cpp
11945 
11946 // start catch_output_redirect.h
11947 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11948 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11949 
11950 #include <cstdio>
11951 #include <iosfwd>
11952 #include <string>
11953 
11954 namespace Catch {
11955 
11956  class RedirectedStream {
11957  std::ostream& m_originalStream;
11958  std::ostream& m_redirectionStream;
11959  std::streambuf* m_prevBuf;
11960 
11961  public:
11962  RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
11963  ~RedirectedStream();
11964  };
11965 
11966  class RedirectedStdOut {
11967  ReusableStringStream m_rss;
11968  RedirectedStream m_cout;
11969  public:
11970  RedirectedStdOut();
11971  auto str() const -> std::string;
11972  };
11973 
11974  // StdErr has two constituent streams in C++, std::cerr and std::clog
11975  // This means that we need to redirect 2 streams into 1 to keep proper
11976  // order of writes
11977  class RedirectedStdErr {
11978  ReusableStringStream m_rss;
11979  RedirectedStream m_cerr;
11980  RedirectedStream m_clog;
11981  public:
11982  RedirectedStdErr();
11983  auto str() const -> std::string;
11984  };
11985 
11986  class RedirectedStreams {
11987  public:
11988  RedirectedStreams(RedirectedStreams const&) = delete;
11989  RedirectedStreams& operator=(RedirectedStreams const&) = delete;
11990  RedirectedStreams(RedirectedStreams&&) = delete;
11991  RedirectedStreams& operator=(RedirectedStreams&&) = delete;
11992 
11993  RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
11994  ~RedirectedStreams();
11995  private:
11996  std::string& m_redirectedCout;
11997  std::string& m_redirectedCerr;
11998  RedirectedStdOut m_redirectedStdOut;
11999  RedirectedStdErr m_redirectedStdErr;
12000  };
12001 
12002 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12003 
12004  // Windows's implementation of std::tmpfile is terrible (it tries
12005  // to create a file inside system folder, thus requiring elevated
12006  // privileges for the binary), so we have to use tmpnam(_s) and
12007  // create the file ourselves there.
12008  class TempFile {
12009  public:
12010  TempFile(TempFile const&) = delete;
12011  TempFile& operator=(TempFile const&) = delete;
12012  TempFile(TempFile&&) = delete;
12013  TempFile& operator=(TempFile&&) = delete;
12014 
12015  TempFile();
12016  ~TempFile();
12017 
12018  std::FILE* getFile();
12019  std::string getContents();
12020 
12021  private:
12022  std::FILE* m_file = nullptr;
12023  #if defined(_MSC_VER)
12024  char m_buffer[L_tmpnam] = { 0 };
12025  #endif
12026  };
12027 
12028  class OutputRedirect {
12029  public:
12030  OutputRedirect(OutputRedirect const&) = delete;
12031  OutputRedirect& operator=(OutputRedirect const&) = delete;
12032  OutputRedirect(OutputRedirect&&) = delete;
12033  OutputRedirect& operator=(OutputRedirect&&) = delete;
12034 
12035  OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
12036  ~OutputRedirect();
12037 
12038  private:
12039  int m_originalStdout = -1;
12040  int m_originalStderr = -1;
12041  TempFile m_stdoutFile;
12042  TempFile m_stderrFile;
12043  std::string& m_stdoutDest;
12044  std::string& m_stderrDest;
12045  };
12046 
12047 #endif
12048 
12049 } // end namespace Catch
12050 
12051 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
12052 // end catch_output_redirect.h
12053 #include <cstdio>
12054 #include <cstring>
12055 #include <fstream>
12056 #include <sstream>
12057 #include <stdexcept>
12058 
12059 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12060  #if defined(_MSC_VER)
12061  #include <io.h> //_dup and _dup2
12062  #define dup _dup
12063  #define dup2 _dup2
12064  #define fileno _fileno
12065  #else
12066  #include <unistd.h> // dup and dup2
12067  #endif
12068 #endif
12069 
12070 namespace Catch {
12071 
12072  RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
12073  : m_originalStream( originalStream ),
12074  m_redirectionStream( redirectionStream ),
12075  m_prevBuf( m_originalStream.rdbuf() )
12076  {
12077  m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
12078  }
12079 
12080  RedirectedStream::~RedirectedStream() {
12081  m_originalStream.rdbuf( m_prevBuf );
12082  }
12083 
12084  RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
12085  auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
12086 
12087  RedirectedStdErr::RedirectedStdErr()
12088  : m_cerr( Catch::cerr(), m_rss.get() ),
12089  m_clog( Catch::clog(), m_rss.get() )
12090  {}
12091  auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
12092 
12093  RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
12094  : m_redirectedCout(redirectedCout),
12095  m_redirectedCerr(redirectedCerr)
12096  {}
12097 
12098  RedirectedStreams::~RedirectedStreams() {
12099  m_redirectedCout += m_redirectedStdOut.str();
12100  m_redirectedCerr += m_redirectedStdErr.str();
12101  }
12102 
12103 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12104 
12105 #if defined(_MSC_VER)
12106  TempFile::TempFile() {
12107  if (tmpnam_s(m_buffer)) {
12108  CATCH_RUNTIME_ERROR("Could not get a temp filename");
12109  }
12110  if (fopen_s(&m_file, m_buffer, "w+")) {
12111  char buffer[100];
12112  if (strerror_s(buffer, errno)) {
12113  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
12114  }
12115  CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
12116  }
12117  }
12118 #else
12119  TempFile::TempFile() {
12120  m_file = std::tmpfile();
12121  if (!m_file) {
12122  CATCH_RUNTIME_ERROR("Could not create a temp file.");
12123  }
12124  }
12125 
12126 #endif
12127 
12129  // TBD: What to do about errors here?
12130  std::fclose(m_file);
12131  // We manually create the file on Windows only, on Linux
12132  // it will be autodeleted
12133 #if defined(_MSC_VER)
12134  std::remove(m_buffer);
12135 #endif
12136  }
12137 
12138  FILE* TempFile::getFile() {
12139  return m_file;
12140  }
12141 
12142  std::string TempFile::getContents() {
12143  std::stringstream sstr;
12144  char buffer[100] = {};
12145  std::rewind(m_file);
12146  while (std::fgets(buffer, sizeof(buffer), m_file)) {
12147  sstr << buffer;
12148  }
12149  return sstr.str();
12150  }
12151 
12152  OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
12153  m_originalStdout(dup(1)),
12154  m_originalStderr(dup(2)),
12155  m_stdoutDest(stdout_dest),
12156  m_stderrDest(stderr_dest) {
12157  dup2(fileno(m_stdoutFile.getFile()), 1);
12158  dup2(fileno(m_stderrFile.getFile()), 2);
12159  }
12160 
12161  OutputRedirect::~OutputRedirect() {
12162  Catch::cout() << std::flush;
12163  fflush(stdout);
12164  // Since we support overriding these streams, we flush cerr
12165  // even though std::cerr is unbuffered
12166  Catch::cerr() << std::flush;
12167  Catch::clog() << std::flush;
12168  fflush(stderr);
12169 
12170  dup2(m_originalStdout, 1);
12171  dup2(m_originalStderr, 2);
12172 
12173  m_stdoutDest += m_stdoutFile.getContents();
12174  m_stderrDest += m_stderrFile.getContents();
12175  }
12176 
12177 #endif // CATCH_CONFIG_NEW_CAPTURE
12178 
12179 } // namespace Catch
12180 
12181 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12182  #if defined(_MSC_VER)
12183  #undef dup
12184  #undef dup2
12185  #undef fileno
12186  #endif
12187 #endif
12188 // end catch_output_redirect.cpp
12189 // start catch_polyfills.cpp
12190 
12191 #include <cmath>
12192 
12193 namespace Catch {
12194 
12195 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
12196  bool isnan(float f) {
12197  return std::isnan(f);
12198  }
12199  bool isnan(double d) {
12200  return std::isnan(d);
12201  }
12202 #else
12203  // For now we only use this for embarcadero
12204  bool isnan(float f) {
12205  return std::_isnan(f);
12206  }
12207  bool isnan(double d) {
12208  return std::_isnan(d);
12209  }
12210 #endif
12211 
12212 } // end namespace Catch
12213 // end catch_polyfills.cpp
12214 // start catch_random_number_generator.cpp
12215 
12216 namespace Catch {
12217 
12218 namespace {
12219 
12220 #if defined(_MSC_VER)
12221 #pragma warning(push)
12222 #pragma warning(disable:4146) // we negate uint32 during the rotate
12223 #endif
12224  // Safe rotr implementation thanks to John Regehr
12225  uint32_t rotate_right(uint32_t val, uint32_t count) {
12226  const uint32_t mask = 31;
12227  count &= mask;
12228  return (val >> count) | (val << (-count & mask));
12229  }
12230 
12231 #if defined(_MSC_VER)
12232 #pragma warning(pop)
12233 #endif
12234 
12235 }
12236 
12237  SimplePcg32::SimplePcg32(result_type seed_) {
12238  seed(seed_);
12239  }
12240 
12241  void SimplePcg32::seed(result_type seed_) {
12242  m_state = 0;
12243  (*this)();
12244  m_state += seed_;
12245  (*this)();
12246  }
12247 
12248  void SimplePcg32::discard(uint64_t skip) {
12249  // We could implement this to run in O(log n) steps, but this
12250  // should suffice for our use case.
12251  for (uint64_t s = 0; s < skip; ++s) {
12252  static_cast<void>((*this)());
12253  }
12254  }
12255 
12256  SimplePcg32::result_type SimplePcg32::operator()() {
12257  // prepare the output value
12258  const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
12259  const auto output = rotate_right(xorshifted, m_state >> 59u);
12260 
12261  // advance state
12262  m_state = m_state * 6364136223846793005ULL + s_inc;
12263 
12264  return output;
12265  }
12266 
12267  bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12268  return lhs.m_state == rhs.m_state;
12269  }
12270 
12271  bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12272  return lhs.m_state != rhs.m_state;
12273  }
12274 }
12275 // end catch_random_number_generator.cpp
12276 // start catch_registry_hub.cpp
12277 
12278 // start catch_test_case_registry_impl.h
12279 
12280 #include <vector>
12281 #include <set>
12282 #include <algorithm>
12283 #include <ios>
12284 
12285 namespace Catch {
12286 
12287  class TestCase;
12288  struct IConfig;
12289 
12290  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
12291 
12292  bool isThrowSafe( TestCase const& testCase, IConfig const& config );
12293  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
12294 
12295  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
12296 
12297  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
12298  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
12299 
12300  class TestRegistry : public ITestCaseRegistry {
12301  public:
12302  virtual ~TestRegistry() = default;
12303 
12304  virtual void registerTest( TestCase const& testCase );
12305 
12306  std::vector<TestCase> const& getAllTests() const override;
12307  std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
12308 
12309  private:
12310  std::vector<TestCase> m_functions;
12311  mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
12312  mutable std::vector<TestCase> m_sortedFunctions;
12313  std::size_t m_unnamedCount = 0;
12314  std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
12315  };
12316 
12318 
12319  class TestInvokerAsFunction : public ITestInvoker {
12320  void(*m_testAsFunction)();
12321  public:
12322  TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
12323 
12324  void invoke() const override;
12325  };
12326 
12327  std::string extractClassName( StringRef const& classOrQualifiedMethodName );
12328 
12330 
12331 } // end namespace Catch
12332 
12333 // end catch_test_case_registry_impl.h
12334 // start catch_reporter_registry.h
12335 
12336 #include <map>
12337 
12338 namespace Catch {
12339 
12340  class ReporterRegistry : public IReporterRegistry {
12341 
12342  public:
12343 
12344  ~ReporterRegistry() override;
12345 
12346  IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
12347 
12348  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
12349  void registerListener( IReporterFactoryPtr const& factory );
12350 
12351  FactoryMap const& getFactories() const override;
12352  Listeners const& getListeners() const override;
12353 
12354  private:
12355  FactoryMap m_factories;
12356  Listeners m_listeners;
12357  };
12358 }
12359 
12360 // end catch_reporter_registry.h
12361 // start catch_tag_alias_registry.h
12362 
12363 // start catch_tag_alias.h
12364 
12365 #include <string>
12366 
12367 namespace Catch {
12368 
12369  struct TagAlias {
12370  TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
12371 
12372  std::string tag;
12373  SourceLineInfo lineInfo;
12374  };
12375 
12376 } // end namespace Catch
12377 
12378 // end catch_tag_alias.h
12379 #include <map>
12380 
12381 namespace Catch {
12382 
12383  class TagAliasRegistry : public ITagAliasRegistry {
12384  public:
12385  ~TagAliasRegistry() override;
12386  TagAlias const* find( std::string const& alias ) const override;
12387  std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
12388  void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
12389 
12390  private:
12391  std::map<std::string, TagAlias> m_registry;
12392  };
12393 
12394 } // end namespace Catch
12395 
12396 // end catch_tag_alias_registry.h
12397 // start catch_startup_exception_registry.h
12398 
12399 #include <vector>
12400 #include <exception>
12401 
12402 namespace Catch {
12403 
12404  class StartupExceptionRegistry {
12405 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12406  public:
12407  void add(std::exception_ptr const& exception) noexcept;
12408  std::vector<std::exception_ptr> const& getExceptions() const noexcept;
12409  private:
12410  std::vector<std::exception_ptr> m_exceptions;
12411 #endif
12412  };
12413 
12414 } // end namespace Catch
12415 
12416 // end catch_startup_exception_registry.h
12417 // start catch_singletons.hpp
12418 
12419 namespace Catch {
12420 
12421  struct ISingleton {
12422  virtual ~ISingleton();
12423  };
12424 
12425  void addSingleton( ISingleton* singleton );
12426  void cleanupSingletons();
12427 
12428  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
12429  class Singleton : SingletonImplT, public ISingleton {
12430 
12431  static auto getInternal() -> Singleton* {
12432  static Singleton* s_instance = nullptr;
12433  if( !s_instance ) {
12434  s_instance = new Singleton;
12435  addSingleton( s_instance );
12436  }
12437  return s_instance;
12438  }
12439 
12440  public:
12441  static auto get() -> InterfaceT const& {
12442  return *getInternal();
12443  }
12444  static auto getMutable() -> MutableInterfaceT& {
12445  return *getInternal();
12446  }
12447  };
12448 
12449 } // namespace Catch
12450 
12451 // end catch_singletons.hpp
12452 namespace Catch {
12453 
12454  namespace {
12455 
12456  class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
12457  private NonCopyable {
12458 
12459  public: // IRegistryHub
12460  RegistryHub() = default;
12461  IReporterRegistry const& getReporterRegistry() const override {
12462  return m_reporterRegistry;
12463  }
12464  ITestCaseRegistry const& getTestCaseRegistry() const override {
12465  return m_testCaseRegistry;
12466  }
12467  IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
12468  return m_exceptionTranslatorRegistry;
12469  }
12470  ITagAliasRegistry const& getTagAliasRegistry() const override {
12471  return m_tagAliasRegistry;
12472  }
12473  StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
12474  return m_exceptionRegistry;
12475  }
12476 
12477  public: // IMutableRegistryHub
12478  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
12479  m_reporterRegistry.registerReporter( name, factory );
12480  }
12481  void registerListener( IReporterFactoryPtr const& factory ) override {
12482  m_reporterRegistry.registerListener( factory );
12483  }
12484  void registerTest( TestCase const& testInfo ) override {
12485  m_testCaseRegistry.registerTest( testInfo );
12486  }
12487  void registerTranslator( const IExceptionTranslator* translator ) override {
12488  m_exceptionTranslatorRegistry.registerTranslator( translator );
12489  }
12490  void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
12491  m_tagAliasRegistry.add( alias, tag, lineInfo );
12492  }
12493  void registerStartupException() noexcept override {
12494 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12495  m_exceptionRegistry.add(std::current_exception());
12496 #else
12497  CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
12498 #endif
12499  }
12500  IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
12501  return m_enumValuesRegistry;
12502  }
12503 
12504  private:
12505  TestRegistry m_testCaseRegistry;
12506  ReporterRegistry m_reporterRegistry;
12507  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
12508  TagAliasRegistry m_tagAliasRegistry;
12509  StartupExceptionRegistry m_exceptionRegistry;
12510  Detail::EnumValuesRegistry m_enumValuesRegistry;
12511  };
12512  }
12513 
12514  using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
12515 
12516  IRegistryHub const& getRegistryHub() {
12517  return RegistryHubSingleton::get();
12518  }
12519  IMutableRegistryHub& getMutableRegistryHub() {
12520  return RegistryHubSingleton::getMutable();
12521  }
12522  void cleanUp() {
12523  cleanupSingletons();
12524  cleanUpContext();
12525  }
12528  }
12529 
12530 } // end namespace Catch
12531 // end catch_registry_hub.cpp
12532 // start catch_reporter_registry.cpp
12533 
12534 namespace Catch {
12535 
12536  ReporterRegistry::~ReporterRegistry() = default;
12537 
12538  IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
12539  auto it = m_factories.find( name );
12540  if( it == m_factories.end() )
12541  return nullptr;
12542  return it->second->create( ReporterConfig( config ) );
12543  }
12544 
12545  void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
12546  m_factories.emplace(name, factory);
12547  }
12548  void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
12549  m_listeners.push_back( factory );
12550  }
12551 
12552  IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
12553  return m_factories;
12554  }
12555  IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
12556  return m_listeners;
12557  }
12558 
12559 }
12560 // end catch_reporter_registry.cpp
12561 // start catch_result_type.cpp
12562 
12563 namespace Catch {
12564 
12565  bool isOk( ResultWas::OfType resultType ) {
12566  return ( resultType & ResultWas::FailureBit ) == 0;
12567  }
12568  bool isJustInfo( int flags ) {
12569  return flags == ResultWas::Info;
12570  }
12571 
12573  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
12574  }
12575 
12576  bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
12577  bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
12578 
12579 } // end namespace Catch
12580 // end catch_result_type.cpp
12581 // start catch_run_context.cpp
12582 
12583 #include <cassert>
12584 #include <algorithm>
12585 #include <sstream>
12586 
12587 namespace Catch {
12588 
12589  namespace Generators {
12590  struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
12591  GeneratorBasePtr m_generator;
12592 
12593  GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
12594  : TrackerBase( nameAndLocation, ctx, parent )
12595  {}
12596  ~GeneratorTracker();
12597 
12598  static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
12599  std::shared_ptr<GeneratorTracker> tracker;
12600 
12601  ITracker& currentTracker = ctx.currentTracker();
12602  // Under specific circumstances, the generator we want
12603  // to acquire is also the current tracker. If this is
12604  // the case, we have to avoid looking through current
12605  // tracker's children, and instead return the current
12606  // tracker.
12607  // A case where this check is important is e.g.
12608  // for (int i = 0; i < 5; ++i) {
12609  // int n = GENERATE(1, 2);
12610  // }
12611  //
12612  // without it, the code above creates 5 nested generators.
12613  if (currentTracker.nameAndLocation() == nameAndLocation) {
12614  auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
12615  assert(thisTracker);
12616  assert(thisTracker->isGeneratorTracker());
12617  tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
12618  } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
12619  assert( childTracker );
12620  assert( childTracker->isGeneratorTracker() );
12621  tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
12622  } else {
12623  tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
12624  currentTracker.addChild( tracker );
12625  }
12626 
12627  if( !tracker->isComplete() ) {
12628  tracker->open();
12629  }
12630 
12631  return *tracker;
12632  }
12633 
12634  // TrackerBase interface
12635  bool isGeneratorTracker() const override { return true; }
12636  auto hasGenerator() const -> bool override {
12637  return !!m_generator;
12638  }
12639  void close() override {
12640  TrackerBase::close();
12641  // If a generator has a child (it is followed by a section)
12642  // and none of its children have started, then we must wait
12643  // until later to start consuming its values.
12644  // This catches cases where `GENERATE` is placed between two
12645  // `SECTION`s.
12646  // **The check for m_children.empty cannot be removed**.
12647  // doing so would break `GENERATE` _not_ followed by `SECTION`s.
12648  const bool should_wait_for_child = [&]() {
12649  // No children -> nobody to wait for
12650  if ( m_children.empty() ) {
12651  return false;
12652  }
12653  // If at least one child started executing, don't wait
12654  if ( std::find_if(
12655  m_children.begin(),
12656  m_children.end(),
12657  []( TestCaseTracking::ITrackerPtr tracker ) {
12658  return tracker->hasStarted();
12659  } ) != m_children.end() ) {
12660  return false;
12661  }
12662 
12663  // No children have started. We need to check if they _can_
12664  // start, and thus we should wait for them, or they cannot
12665  // start (due to filters), and we shouldn't wait for them
12666  auto* parent = m_parent;
12667  // This is safe: there is always at least one section
12668  // tracker in a test case tracking tree
12669  while ( !parent->isSectionTracker() ) {
12670  parent = &( parent->parent() );
12671  }
12672  assert( parent &&
12673  "Missing root (test case) level section" );
12674 
12675  auto const& parentSection =
12676  static_cast<SectionTracker&>( *parent );
12677  auto const& filters = parentSection.getFilters();
12678  // No filters -> no restrictions on running sections
12679  if ( filters.empty() ) {
12680  return true;
12681  }
12682 
12683  for ( auto const& child : m_children ) {
12684  if ( child->isSectionTracker() &&
12685  std::find( filters.begin(),
12686  filters.end(),
12687  static_cast<SectionTracker&>( *child )
12688  .trimmedName() ) !=
12689  filters.end() ) {
12690  return true;
12691  }
12692  }
12693  return false;
12694  }();
12695 
12696  // This check is a bit tricky, because m_generator->next()
12697  // has a side-effect, where it consumes generator's current
12698  // value, but we do not want to invoke the side-effect if
12699  // this generator is still waiting for any child to start.
12700  if ( should_wait_for_child ||
12701  ( m_runState == CompletedSuccessfully &&
12702  m_generator->next() ) ) {
12703  m_children.clear();
12704  m_runState = Executing;
12705  }
12706  }
12707 
12708  // IGeneratorTracker interface
12709  auto getGenerator() const -> GeneratorBasePtr const& override {
12710  return m_generator;
12711  }
12712  void setGenerator( GeneratorBasePtr&& generator ) override {
12713  m_generator = std::move( generator );
12714  }
12715  };
12716  GeneratorTracker::~GeneratorTracker() {}
12717  }
12718 
12719  RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
12720  : m_runInfo(_config->name()),
12721  m_context(getCurrentMutableContext()),
12722  m_config(_config),
12723  m_reporter(std::move(reporter)),
12724  m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
12725  m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
12726  {
12727  m_context.setRunner(this);
12728  m_context.setConfig(m_config);
12729  m_context.setResultCapture(this);
12730  m_reporter->testRunStarting(m_runInfo);
12731  }
12732 
12733  RunContext::~RunContext() {
12734  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
12735  }
12736 
12737  void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
12738  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
12739  }
12740 
12741  void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
12742  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
12743  }
12744 
12745  Totals RunContext::runTest(TestCase const& testCase) {
12746  Totals prevTotals = m_totals;
12747 
12748  std::string redirectedCout;
12749  std::string redirectedCerr;
12750 
12751  auto const& testInfo = testCase.getTestCaseInfo();
12752 
12753  m_reporter->testCaseStarting(testInfo);
12754 
12755  m_activeTestCase = &testCase;
12756 
12757  ITracker& rootTracker = m_trackerContext.startRun();
12758  assert(rootTracker.isSectionTracker());
12759  static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
12760  do {
12761  m_trackerContext.startCycle();
12762  m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
12763  runCurrentTest(redirectedCout, redirectedCerr);
12764  } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
12765 
12766  Totals deltaTotals = m_totals.delta(prevTotals);
12767  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
12768  deltaTotals.assertions.failed++;
12769  deltaTotals.testCases.passed--;
12770  deltaTotals.testCases.failed++;
12771  }
12772  m_totals.testCases += deltaTotals.testCases;
12773  m_reporter->testCaseEnded(TestCaseStats(testInfo,
12774  deltaTotals,
12775  redirectedCout,
12776  redirectedCerr,
12777  aborting()));
12778 
12779  m_activeTestCase = nullptr;
12780  m_testCaseTracker = nullptr;
12781 
12782  return deltaTotals;
12783  }
12784 
12785  IConfigPtr RunContext::config() const {
12786  return m_config;
12787  }
12788 
12789  IStreamingReporter& RunContext::reporter() const {
12790  return *m_reporter;
12791  }
12792 
12793  void RunContext::assertionEnded(AssertionResult const & result) {
12794  if (result.getResultType() == ResultWas::Ok) {
12795  m_totals.assertions.passed++;
12796  m_lastAssertionPassed = true;
12797  } else if (!result.isOk()) {
12798  m_lastAssertionPassed = false;
12799  if( m_activeTestCase->getTestCaseInfo().okToFail() )
12800  m_totals.assertions.failedButOk++;
12801  else
12802  m_totals.assertions.failed++;
12803  }
12804  else {
12805  m_lastAssertionPassed = true;
12806  }
12807 
12808  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
12809  // and should be let to clear themselves out.
12810  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
12811 
12812  if (result.getResultType() != ResultWas::Warning)
12813  m_messageScopes.clear();
12814 
12815  // Reset working state
12816  resetAssertionInfo();
12817  m_lastResult = result;
12818  }
12819  void RunContext::resetAssertionInfo() {
12820  m_lastAssertionInfo.macroName = StringRef();
12821  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
12822  }
12823 
12824  bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
12825  ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
12826  if (!sectionTracker.isOpen())
12827  return false;
12828  m_activeSections.push_back(&sectionTracker);
12829 
12830  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
12831 
12832  m_reporter->sectionStarting(sectionInfo);
12833 
12834  assertions = m_totals.assertions;
12835 
12836  return true;
12837  }
12838  auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
12839  using namespace Generators;
12840  GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
12841  TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
12842  m_lastAssertionInfo.lineInfo = lineInfo;
12843  return tracker;
12844  }
12845 
12846  bool RunContext::testForMissingAssertions(Counts& assertions) {
12847  if (assertions.total() != 0)
12848  return false;
12849  if (!m_config->warnAboutMissingAssertions())
12850  return false;
12851  if (m_trackerContext.currentTracker().hasChildren())
12852  return false;
12853  m_totals.assertions.failed++;
12854  assertions.failed++;
12855  return true;
12856  }
12857 
12858  void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
12859  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
12860  bool missingAssertions = testForMissingAssertions(assertions);
12861 
12862  if (!m_activeSections.empty()) {
12863  m_activeSections.back()->close();
12864  m_activeSections.pop_back();
12865  }
12866 
12867  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
12868  m_messages.clear();
12869  m_messageScopes.clear();
12870  }
12871 
12872  void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
12873  if (m_unfinishedSections.empty())
12874  m_activeSections.back()->fail();
12875  else
12876  m_activeSections.back()->close();
12877  m_activeSections.pop_back();
12878 
12879  m_unfinishedSections.push_back(endInfo);
12880  }
12881 
12882 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
12883  void RunContext::benchmarkPreparing(std::string const& name) {
12884  m_reporter->benchmarkPreparing(name);
12885  }
12886  void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
12887  m_reporter->benchmarkStarting( info );
12888  }
12889  void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
12890  m_reporter->benchmarkEnded( stats );
12891  }
12892  void RunContext::benchmarkFailed(std::string const & error) {
12893  m_reporter->benchmarkFailed(error);
12894  }
12895 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
12896 
12897  void RunContext::pushScopedMessage(MessageInfo const & message) {
12898  m_messages.push_back(message);
12899  }
12900 
12901  void RunContext::popScopedMessage(MessageInfo const & message) {
12902  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
12903  }
12904 
12905  void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
12906  m_messageScopes.emplace_back( builder );
12907  }
12908 
12909  std::string RunContext::getCurrentTestName() const {
12910  return m_activeTestCase
12911  ? m_activeTestCase->getTestCaseInfo().name
12912  : std::string();
12913  }
12914 
12915  const AssertionResult * RunContext::getLastResult() const {
12916  return &(*m_lastResult);
12917  }
12918 
12919  void RunContext::exceptionEarlyReported() {
12920  m_shouldReportUnexpected = false;
12921  }
12922 
12923  void RunContext::handleFatalErrorCondition( StringRef message ) {
12924  // First notify reporter that bad things happened
12925  m_reporter->fatalErrorEncountered(message);
12926 
12927  // Don't rebuild the result -- the stringification itself can cause more fatal errors
12928  // Instead, fake a result data.
12929  AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
12930  tempResult.message = static_cast<std::string>(message);
12931  AssertionResult result(m_lastAssertionInfo, tempResult);
12932 
12933  assertionEnded(result);
12934 
12935  handleUnfinishedSections();
12936 
12937  // Recreate section for test case (as we will lose the one that was in scope)
12938  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12939  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12940 
12941  Counts assertions;
12942  assertions.failed = 1;
12943  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
12944  m_reporter->sectionEnded(testCaseSectionStats);
12945 
12946  auto const& testInfo = m_activeTestCase->getTestCaseInfo();
12947 
12948  Totals deltaTotals;
12949  deltaTotals.testCases.failed = 1;
12950  deltaTotals.assertions.failed = 1;
12951  m_reporter->testCaseEnded(TestCaseStats(testInfo,
12952  deltaTotals,
12953  std::string(),
12954  std::string(),
12955  false));
12956  m_totals.testCases.failed++;
12957  testGroupEnded(std::string(), m_totals, 1, 1);
12958  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
12959  }
12960 
12961  bool RunContext::lastAssertionPassed() {
12962  return m_lastAssertionPassed;
12963  }
12964 
12965  void RunContext::assertionPassed() {
12966  m_lastAssertionPassed = true;
12967  ++m_totals.assertions.passed;
12968  resetAssertionInfo();
12969  m_messageScopes.clear();
12970  }
12971 
12972  bool RunContext::aborting() const {
12973  return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
12974  }
12975 
12976  void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
12977  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12978  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12979  m_reporter->sectionStarting(testCaseSection);
12980  Counts prevAssertions = m_totals.assertions;
12981  double duration = 0;
12982  m_shouldReportUnexpected = true;
12983  m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
12984 
12985  seedRng(*m_config);
12986 
12987  Timer timer;
12988  CATCH_TRY {
12989  if (m_reporter->getPreferences().shouldRedirectStdOut) {
12990 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
12991  RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
12992 
12993  timer.start();
12994  invokeActiveTestCase();
12995 #else
12996  OutputRedirect r(redirectedCout, redirectedCerr);
12997  timer.start();
12998  invokeActiveTestCase();
12999 #endif
13000  } else {
13001  timer.start();
13002  invokeActiveTestCase();
13003  }
13004  duration = timer.getElapsedSeconds();
13005  } CATCH_CATCH_ANON (TestFailureException&) {
13006  // This just means the test was aborted due to failure
13007  } CATCH_CATCH_ALL {
13008  // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
13009  // are reported without translation at the point of origin.
13010  if( m_shouldReportUnexpected ) {
13011  AssertionReaction dummyReaction;
13012  handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
13013  }
13014  }
13015  Counts assertions = m_totals.assertions - prevAssertions;
13016  bool missingAssertions = testForMissingAssertions(assertions);
13017 
13018  m_testCaseTracker->close();
13019  handleUnfinishedSections();
13020  m_messages.clear();
13021  m_messageScopes.clear();
13022 
13023  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
13024  m_reporter->sectionEnded(testCaseSectionStats);
13025  }
13026 
13027  void RunContext::invokeActiveTestCase() {
13028  FatalConditionHandlerGuard _(&m_fatalConditionhandler);
13029  m_activeTestCase->invoke();
13030  }
13031 
13032  void RunContext::handleUnfinishedSections() {
13033  // If sections ended prematurely due to an exception we stored their
13034  // infos here so we can tear them down outside the unwind process.
13035  for (auto it = m_unfinishedSections.rbegin(),
13036  itEnd = m_unfinishedSections.rend();
13037  it != itEnd;
13038  ++it)
13039  sectionEnded(*it);
13040  m_unfinishedSections.clear();
13041  }
13042 
13043  void RunContext::handleExpr(
13044  AssertionInfo const& info,
13045  ITransientExpression const& expr,
13046  AssertionReaction& reaction
13047  ) {
13048  m_reporter->assertionStarting( info );
13049 
13050  bool negated = isFalseTest( info.resultDisposition );
13051  bool result = expr.getResult() != negated;
13052 
13053  if( result ) {
13054  if (!m_includeSuccessfulResults) {
13055  assertionPassed();
13056  }
13057  else {
13058  reportExpr(info, ResultWas::Ok, &expr, negated);
13059  }
13060  }
13061  else {
13062  reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
13063  populateReaction( reaction );
13064  }
13065  }
13066  void RunContext::reportExpr(
13067  AssertionInfo const &info,
13068  ResultWas::OfType resultType,
13069  ITransientExpression const *expr,
13070  bool negated ) {
13071 
13072  m_lastAssertionInfo = info;
13073  AssertionResultData data( resultType, LazyExpression( negated ) );
13074 
13075  AssertionResult assertionResult{ info, data };
13076  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
13077 
13078  assertionEnded( assertionResult );
13079  }
13080 
13081  void RunContext::handleMessage(
13082  AssertionInfo const& info,
13083  ResultWas::OfType resultType,
13084  StringRef const& message,
13085  AssertionReaction& reaction
13086  ) {
13087  m_reporter->assertionStarting( info );
13088 
13089  m_lastAssertionInfo = info;
13090 
13091  AssertionResultData data( resultType, LazyExpression( false ) );
13092  data.message = static_cast<std::string>(message);
13093  AssertionResult assertionResult{ m_lastAssertionInfo, data };
13094  assertionEnded( assertionResult );
13095  if( !assertionResult.isOk() )
13096  populateReaction( reaction );
13097  }
13098  void RunContext::handleUnexpectedExceptionNotThrown(
13099  AssertionInfo const& info,
13100  AssertionReaction& reaction
13101  ) {
13102  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
13103  }
13104 
13105  void RunContext::handleUnexpectedInflightException(
13106  AssertionInfo const& info,
13107  std::string const& message,
13108  AssertionReaction& reaction
13109  ) {
13110  m_lastAssertionInfo = info;
13111 
13112  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
13113  data.message = message;
13114  AssertionResult assertionResult{ info, data };
13115  assertionEnded( assertionResult );
13116  populateReaction( reaction );
13117  }
13118 
13119  void RunContext::populateReaction( AssertionReaction& reaction ) {
13120  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
13121  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
13122  }
13123 
13124  void RunContext::handleIncomplete(
13125  AssertionInfo const& info
13126  ) {
13127  m_lastAssertionInfo = info;
13128 
13129  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
13130  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
13131  AssertionResult assertionResult{ info, data };
13132  assertionEnded( assertionResult );
13133  }
13134  void RunContext::handleNonExpr(
13135  AssertionInfo const &info,
13136  ResultWas::OfType resultType,
13137  AssertionReaction &reaction
13138  ) {
13139  m_lastAssertionInfo = info;
13140 
13141  AssertionResultData data( resultType, LazyExpression( false ) );
13142  AssertionResult assertionResult{ info, data };
13143  assertionEnded( assertionResult );
13144 
13145  if( !assertionResult.isOk() )
13146  populateReaction( reaction );
13147  }
13148 
13149  IResultCapture& getResultCapture() {
13150  if (auto* capture = getCurrentContext().getResultCapture())
13151  return *capture;
13152  else
13153  CATCH_INTERNAL_ERROR("No result capture instance");
13154  }
13155 
13156  void seedRng(IConfig const& config) {
13157  if (config.rngSeed() != 0) {
13158  std::srand(config.rngSeed());
13159  rng().seed(config.rngSeed());
13160  }
13161  }
13162 
13163  unsigned int rngSeed() {
13164  return getCurrentContext().getConfig()->rngSeed();
13165  }
13166 
13167 }
13168 // end catch_run_context.cpp
13169 // start catch_section.cpp
13170 
13171 namespace Catch {
13172 
13173  Section::Section( SectionInfo const& info )
13174  : m_info( info ),
13175  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
13176  {
13177  m_timer.start();
13178  }
13179 
13180  Section::~Section() {
13181  if( m_sectionIncluded ) {
13182  SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
13183  if( uncaught_exceptions() )
13184  getResultCapture().sectionEndedEarly( endInfo );
13185  else
13186  getResultCapture().sectionEnded( endInfo );
13187  }
13188  }
13189 
13190  // This indicates whether the section should be executed or not
13191  Section::operator bool() const {
13192  return m_sectionIncluded;
13193  }
13194 
13195 } // end namespace Catch
13196 // end catch_section.cpp
13197 // start catch_section_info.cpp
13198 
13199 namespace Catch {
13200 
13202  ( SourceLineInfo const& _lineInfo,
13203  std::string const& _name )
13204  : name( _name ),
13205  lineInfo( _lineInfo )
13206  {}
13207 
13208 } // end namespace Catch
13209 // end catch_section_info.cpp
13210 // start catch_session.cpp
13211 
13212 // start catch_session.h
13213 
13214 #include <memory>
13215 
13216 namespace Catch {
13217 
13218  class Session : NonCopyable {
13219  public:
13220 
13221  Session();
13222  ~Session() override;
13223 
13224  void showHelp() const;
13225  void libIdentify();
13226 
13227  int applyCommandLine( int argc, char const * const * argv );
13228  #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13229  int applyCommandLine( int argc, wchar_t const * const * argv );
13230  #endif
13231 
13232  void useConfigData( ConfigData const& configData );
13233 
13234  template<typename CharT>
13235  int run(int argc, CharT const * const argv[]) {
13236  if (m_startupExceptions)
13237  return 1;
13238  int returnCode = applyCommandLine(argc, argv);
13239  if (returnCode == 0)
13240  returnCode = run();
13241  return returnCode;
13242  }
13243 
13244  int run();
13245 
13246  clara::Parser const& cli() const;
13247  void cli( clara::Parser const& newParser );
13248  ConfigData& configData();
13249  Config& config();
13250  private:
13251  int runInternal();
13252 
13253  clara::Parser m_cli;
13254  ConfigData m_configData;
13255  std::shared_ptr<Config> m_config;
13256  bool m_startupExceptions = false;
13257  };
13258 
13259 } // end namespace Catch
13260 
13261 // end catch_session.h
13262 // start catch_version.h
13263 
13264 #include <iosfwd>
13265 
13266 namespace Catch {
13267 
13268  // Versioning information
13269  struct Version {
13270  Version( Version const& ) = delete;
13271  Version& operator=( Version const& ) = delete;
13272  Version( unsigned int _majorVersion,
13273  unsigned int _minorVersion,
13274  unsigned int _patchNumber,
13275  char const * const _branchName,
13276  unsigned int _buildNumber );
13277 
13278  unsigned int const majorVersion;
13279  unsigned int const minorVersion;
13280  unsigned int const patchNumber;
13281 
13282  // buildNumber is only used if branchName is not null
13283  char const * const branchName;
13284  unsigned int const buildNumber;
13285 
13286  friend std::ostream& operator << ( std::ostream& os, Version const& version );
13287  };
13288 
13289  Version const& libraryVersion();
13290 }
13291 
13292 // end catch_version.h
13293 #include <cstdlib>
13294 #include <iomanip>
13295 #include <set>
13296 #include <iterator>
13297 
13298 namespace Catch {
13299 
13300  namespace {
13301  const int MaxExitCode = 255;
13302 
13303  IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
13304  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
13305  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
13306 
13307  return reporter;
13308  }
13309 
13310  IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
13311  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
13312  return createReporter(config->getReporterName(), config);
13313  }
13314 
13315  // On older platforms, returning std::unique_ptr<ListeningReporter>
13316  // when the return type is std::unique_ptr<IStreamingReporter>
13317  // doesn't compile without a std::move call. However, this causes
13318  // a warning on newer platforms. Thus, we have to work around
13319  // it a bit and downcast the pointer manually.
13320  auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
13321  auto& multi = static_cast<ListeningReporter&>(*ret);
13322  auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
13323  for (auto const& listener : listeners) {
13324  multi.addListener(listener->create(Catch::ReporterConfig(config)));
13325  }
13326  multi.addReporter(createReporter(config->getReporterName(), config));
13327  return ret;
13328  }
13329 
13330  class TestGroup {
13331  public:
13332  explicit TestGroup(std::shared_ptr<Config> const& config)
13333  : m_config{config}
13334  , m_context{config, makeReporter(config)}
13335  {
13336  auto const& allTestCases = getAllTestCasesSorted(*m_config);
13337  m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
13338  auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13339 
13340  if (m_matches.empty() && invalidArgs.empty()) {
13341  for (auto const& test : allTestCases)
13342  if (!test.isHidden())
13343  m_tests.emplace(&test);
13344  } else {
13345  for (auto const& match : m_matches)
13346  m_tests.insert(match.tests.begin(), match.tests.end());
13347  }
13348  }
13349 
13350  Totals execute() {
13351  auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13352  Totals totals;
13353  m_context.testGroupStarting(m_config->name(), 1, 1);
13354  for (auto const& testCase : m_tests) {
13355  if (!m_context.aborting())
13356  totals += m_context.runTest(*testCase);
13357  else
13358  m_context.reporter().skipTest(*testCase);
13359  }
13360 
13361  for (auto const& match : m_matches) {
13362  if (match.tests.empty()) {
13363  m_context.reporter().noMatchingTestCases(match.name);
13364  totals.error = -1;
13365  }
13366  }
13367 
13368  if (!invalidArgs.empty()) {
13369  for (auto const& invalidArg: invalidArgs)
13370  m_context.reporter().reportInvalidArguments(invalidArg);
13371  }
13372 
13373  m_context.testGroupEnded(m_config->name(), totals, 1, 1);
13374  return totals;
13375  }
13376 
13377  private:
13378  using Tests = std::set<TestCase const*>;
13379 
13380  std::shared_ptr<Config> m_config;
13381  RunContext m_context;
13382  Tests m_tests;
13383  TestSpec::Matches m_matches;
13384  };
13385 
13386  void applyFilenamesAsTags(Catch::IConfig const& config) {
13387  auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
13388  for (auto& testCase : tests) {
13389  auto tags = testCase.tags;
13390 
13391  std::string filename = testCase.lineInfo.file;
13392  auto lastSlash = filename.find_last_of("\\/");
13393  if (lastSlash != std::string::npos) {
13394  filename.erase(0, lastSlash);
13395  filename[0] = '#';
13396  }
13397 
13398  auto lastDot = filename.find_last_of('.');
13399  if (lastDot != std::string::npos) {
13400  filename.erase(lastDot);
13401  }
13402 
13403  tags.push_back(std::move(filename));
13404  setTags(testCase, tags);
13405  }
13406  }
13407 
13408  } // anon namespace
13409 
13410  Session::Session() {
13411  static bool alreadyInstantiated = false;
13412  if( alreadyInstantiated ) {
13413  CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
13415  }
13416 
13417  // There cannot be exceptions at startup in no-exception mode.
13418 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13419  const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
13420  if ( !exceptions.empty() ) {
13421  config();
13422  getCurrentMutableContext().setConfig(m_config);
13423 
13424  m_startupExceptions = true;
13425  Colour colourGuard( Colour::Red );
13426  Catch::cerr() << "Errors occurred during startup!" << '\n';
13427  // iterate over all exceptions and notify user
13428  for ( const auto& ex_ptr : exceptions ) {
13429  try {
13430  std::rethrow_exception(ex_ptr);
13431  } catch ( std::exception const& ex ) {
13432  Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
13433  }
13434  }
13435  }
13436 #endif
13437 
13438  alreadyInstantiated = true;
13439  m_cli = makeCommandLineParser( m_configData );
13440  }
13441  Session::~Session() {
13442  Catch::cleanUp();
13443  }
13444 
13445  void Session::showHelp() const {
13446  Catch::cout()
13447  << "\nCatch v" << libraryVersion() << "\n"
13448  << m_cli << std::endl
13449  << "For more detailed usage please see the project docs\n" << std::endl;
13450  }
13451  void Session::libIdentify() {
13452  Catch::cout()
13453  << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
13454  << std::left << std::setw(16) << "category: " << "testframework\n"
13455  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
13456  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
13457  }
13458 
13459  int Session::applyCommandLine( int argc, char const * const * argv ) {
13460  if( m_startupExceptions )
13461  return 1;
13462 
13463  auto result = m_cli.parse( clara::Args( argc, argv ) );
13464  if( !result ) {
13465  config();
13466  getCurrentMutableContext().setConfig(m_config);
13467  Catch::cerr()
13468  << Colour( Colour::Red )
13469  << "\nError(s) in input:\n"
13470  << Column( result.errorMessage() ).indent( 2 )
13471  << "\n\n";
13472  Catch::cerr() << "Run with -? for usage\n" << std::endl;
13473  return MaxExitCode;
13474  }
13475 
13476  if( m_configData.showHelp )
13477  showHelp();
13478  if( m_configData.libIdentify )
13479  libIdentify();
13480  m_config.reset();
13481  return 0;
13482  }
13483 
13484 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13485  int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
13486 
13487  char **utf8Argv = new char *[ argc ];
13488 
13489  for ( int i = 0; i < argc; ++i ) {
13490  int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
13491 
13492  utf8Argv[ i ] = new char[ bufSize ];
13493 
13494  WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
13495  }
13496 
13497  int returnCode = applyCommandLine( argc, utf8Argv );
13498 
13499  for ( int i = 0; i < argc; ++i )
13500  delete [] utf8Argv[ i ];
13501 
13502  delete [] utf8Argv;
13503 
13504  return returnCode;
13505  }
13506 #endif
13507 
13508  void Session::useConfigData( ConfigData const& configData ) {
13509  m_configData = configData;
13510  m_config.reset();
13511  }
13512 
13513  int Session::run() {
13514  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
13515  Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
13516  static_cast<void>(std::getchar());
13517  }
13518  int exitCode = runInternal();
13519  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
13520  Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
13521  static_cast<void>(std::getchar());
13522  }
13523  return exitCode;
13524  }
13525 
13526  clara::Parser const& Session::cli() const {
13527  return m_cli;
13528  }
13529  void Session::cli( clara::Parser const& newParser ) {
13530  m_cli = newParser;
13531  }
13532  ConfigData& Session::configData() {
13533  return m_configData;
13534  }
13535  Config& Session::config() {
13536  if( !m_config )
13537  m_config = std::make_shared<Config>( m_configData );
13538  return *m_config;
13539  }
13540 
13541  int Session::runInternal() {
13542  if( m_startupExceptions )
13543  return 1;
13544 
13545  if (m_configData.showHelp || m_configData.libIdentify) {
13546  return 0;
13547  }
13548 
13549  CATCH_TRY {
13550  config(); // Force config to be constructed
13551 
13552  seedRng( *m_config );
13553 
13554  if( m_configData.filenamesAsTags )
13555  applyFilenamesAsTags( *m_config );
13556 
13557  // Handle list request
13558  if( Option<std::size_t> listed = list( m_config ) )
13559  return static_cast<int>( *listed );
13560 
13561  TestGroup tests { m_config };
13562  auto const totals = tests.execute();
13563 
13564  if( m_config->warnAboutNoTests() && totals.error == -1 )
13565  return 2;
13566 
13567  // Note that on unices only the lower 8 bits are usually used, clamping
13568  // the return value to 255 prevents false negative when some multiple
13569  // of 256 tests has failed
13570  return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
13571  }
13572 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13573  catch( std::exception& ex ) {
13574  Catch::cerr() << ex.what() << std::endl;
13575  return MaxExitCode;
13576  }
13577 #endif
13578  }
13579 
13580 } // end namespace Catch
13581 // end catch_session.cpp
13582 // start catch_singletons.cpp
13583 
13584 #include <vector>
13585 
13586 namespace Catch {
13587 
13588  namespace {
13589  static auto getSingletons() -> std::vector<ISingleton*>*& {
13590  static std::vector<ISingleton*>* g_singletons = nullptr;
13591  if( !g_singletons )
13592  g_singletons = new std::vector<ISingleton*>();
13593  return g_singletons;
13594  }
13595  }
13596 
13597  ISingleton::~ISingleton() {}
13598 
13599  void addSingleton(ISingleton* singleton ) {
13600  getSingletons()->push_back( singleton );
13601  }
13602  void cleanupSingletons() {
13603  auto& singletons = getSingletons();
13604  for( auto singleton : *singletons )
13605  delete singleton;
13606  delete singletons;
13607  singletons = nullptr;
13608  }
13609 
13610 } // namespace Catch
13611 // end catch_singletons.cpp
13612 // start catch_startup_exception_registry.cpp
13613 
13614 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13615 namespace Catch {
13616 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
13617  CATCH_TRY {
13618  m_exceptions.push_back(exception);
13619  } CATCH_CATCH_ALL {
13620  // If we run out of memory during start-up there's really not a lot more we can do about it
13621  std::terminate();
13622  }
13623  }
13624 
13625  std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
13626  return m_exceptions;
13627  }
13628 
13629 } // end namespace Catch
13630 #endif
13631 // end catch_startup_exception_registry.cpp
13632 // start catch_stream.cpp
13633 
13634 #include <cstdio>
13635 #include <iostream>
13636 #include <fstream>
13637 #include <sstream>
13638 #include <vector>
13639 #include <memory>
13640 
13641 namespace Catch {
13642 
13643  Catch::IStream::~IStream() = default;
13644 
13645  namespace Detail { namespace {
13646  template<typename WriterF, std::size_t bufferSize=256>
13647  class StreamBufImpl : public std::streambuf {
13648  char data[bufferSize];
13649  WriterF m_writer;
13650 
13651  public:
13652  StreamBufImpl() {
13653  setp( data, data + sizeof(data) );
13654  }
13655 
13656  ~StreamBufImpl() noexcept {
13657  StreamBufImpl::sync();
13658  }
13659 
13660  private:
13661  int overflow( int c ) override {
13662  sync();
13663 
13664  if( c != EOF ) {
13665  if( pbase() == epptr() )
13666  m_writer( std::string( 1, static_cast<char>( c ) ) );
13667  else
13668  sputc( static_cast<char>( c ) );
13669  }
13670  return 0;
13671  }
13672 
13673  int sync() override {
13674  if( pbase() != pptr() ) {
13675  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
13676  setp( pbase(), epptr() );
13677  }
13678  return 0;
13679  }
13680  };
13681 
13683 
13684  struct OutputDebugWriter {
13685 
13686  void operator()( std::string const&str ) {
13687  writeToDebugConsole( str );
13688  }
13689  };
13690 
13692 
13693  class FileStream : public IStream {
13694  mutable std::ofstream m_ofs;
13695  public:
13696  FileStream( StringRef filename ) {
13697  m_ofs.open( filename.c_str() );
13698  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
13699  }
13700  ~FileStream() override = default;
13701  public: // IStream
13702  std::ostream& stream() const override {
13703  return m_ofs;
13704  }
13705  };
13706 
13708 
13709  class CoutStream : public IStream {
13710  mutable std::ostream m_os;
13711  public:
13712  // Store the streambuf from cout up-front because
13713  // cout may get redirected when running tests
13714  CoutStream() : m_os( Catch::cout().rdbuf() ) {}
13715  ~CoutStream() override = default;
13716 
13717  public: // IStream
13718  std::ostream& stream() const override { return m_os; }
13719  };
13720 
13722 
13723  class DebugOutStream : public IStream {
13724  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
13725  mutable std::ostream m_os;
13726  public:
13727  DebugOutStream()
13728  : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
13729  m_os( m_streamBuf.get() )
13730  {}
13731 
13732  ~DebugOutStream() override = default;
13733 
13734  public: // IStream
13735  std::ostream& stream() const override { return m_os; }
13736  };
13737 
13738  }} // namespace anon::detail
13739 
13741 
13742  auto makeStream( StringRef const &filename ) -> IStream const* {
13743  if( filename.empty() )
13744  return new Detail::CoutStream();
13745  else if( filename[0] == '%' ) {
13746  if( filename == "%debug" )
13747  return new Detail::DebugOutStream();
13748  else
13749  CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
13750  }
13751  else
13752  return new Detail::FileStream( filename );
13753  }
13754 
13755  // This class encapsulates the idea of a pool of ostringstreams that can be reused.
13756  struct StringStreams {
13757  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
13758  std::vector<std::size_t> m_unused;
13759  std::ostringstream m_referenceStream; // Used for copy state/ flags from
13760 
13761  auto add() -> std::size_t {
13762  if( m_unused.empty() ) {
13763  m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
13764  return m_streams.size()-1;
13765  }
13766  else {
13767  auto index = m_unused.back();
13768  m_unused.pop_back();
13769  return index;
13770  }
13771  }
13772 
13773  void release( std::size_t index ) {
13774  m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
13775  m_unused.push_back(index);
13776  }
13777  };
13778 
13780  : m_index( Singleton<StringStreams>::getMutable().add() ),
13781  m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
13782  {}
13783 
13785  static_cast<std::ostringstream*>( m_oss )->str("");
13786  m_oss->clear();
13787  Singleton<StringStreams>::getMutable().release( m_index );
13788  }
13789 
13790  auto ReusableStringStream::str() const -> std::string {
13791  return static_cast<std::ostringstream*>( m_oss )->str();
13792  }
13793 
13795 
13796 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
13797  std::ostream& cout() { return std::cout; }
13798  std::ostream& cerr() { return std::cerr; }
13799  std::ostream& clog() { return std::clog; }
13800 #endif
13801 }
13802 // end catch_stream.cpp
13803 // start catch_string_manip.cpp
13804 
13805 #include <algorithm>
13806 #include <ostream>
13807 #include <cstring>
13808 #include <cctype>
13809 #include <vector>
13810 
13811 namespace Catch {
13812 
13813  namespace {
13814  char toLowerCh(char c) {
13815  return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
13816  }
13817  }
13818 
13819  bool startsWith( std::string const& s, std::string const& prefix ) {
13820  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
13821  }
13822  bool startsWith( std::string const& s, char prefix ) {
13823  return !s.empty() && s[0] == prefix;
13824  }
13825  bool endsWith( std::string const& s, std::string const& suffix ) {
13826  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
13827  }
13828  bool endsWith( std::string const& s, char suffix ) {
13829  return !s.empty() && s[s.size()-1] == suffix;
13830  }
13831  bool contains( std::string const& s, std::string const& infix ) {
13832  return s.find( infix ) != std::string::npos;
13833  }
13834  void toLowerInPlace( std::string& s ) {
13835  std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
13836  }
13837  std::string toLower( std::string const& s ) {
13838  std::string lc = s;
13839  toLowerInPlace( lc );
13840  return lc;
13841  }
13842  std::string trim( std::string const& str ) {
13843  static char const* whitespaceChars = "\n\r\t ";
13844  std::string::size_type start = str.find_first_not_of( whitespaceChars );
13845  std::string::size_type end = str.find_last_not_of( whitespaceChars );
13846 
13847  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
13848  }
13849 
13850  StringRef trim(StringRef ref) {
13851  const auto is_ws = [](char c) {
13852  return c == ' ' || c == '\t' || c == '\n' || c == '\r';
13853  };
13854  size_t real_begin = 0;
13855  while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
13856  size_t real_end = ref.size();
13857  while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
13858 
13859  return ref.substr(real_begin, real_end - real_begin);
13860  }
13861 
13862  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
13863  bool replaced = false;
13864  std::size_t i = str.find( replaceThis );
13865  while( i != std::string::npos ) {
13866  replaced = true;
13867  str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
13868  if( i < str.size()-withThis.size() )
13869  i = str.find( replaceThis, i+withThis.size() );
13870  else
13871  i = std::string::npos;
13872  }
13873  return replaced;
13874  }
13875 
13876  std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
13877  std::vector<StringRef> subStrings;
13878  std::size_t start = 0;
13879  for(std::size_t pos = 0; pos < str.size(); ++pos ) {
13880  if( str[pos] == delimiter ) {
13881  if( pos - start > 1 )
13882  subStrings.push_back( str.substr( start, pos-start ) );
13883  start = pos+1;
13884  }
13885  }
13886  if( start < str.size() )
13887  subStrings.push_back( str.substr( start, str.size()-start ) );
13888  return subStrings;
13889  }
13890 
13891  pluralise::pluralise( std::size_t count, std::string const& label )
13892  : m_count( count ),
13893  m_label( label )
13894  {}
13895 
13896  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
13897  os << pluraliser.m_count << ' ' << pluraliser.m_label;
13898  if( pluraliser.m_count != 1 )
13899  os << 's';
13900  return os;
13901  }
13902 
13903 }
13904 // end catch_string_manip.cpp
13905 // start catch_stringref.cpp
13906 
13907 #include <algorithm>
13908 #include <ostream>
13909 #include <cstring>
13910 #include <cstdint>
13911 
13912 namespace Catch {
13913  StringRef::StringRef( char const* rawChars ) noexcept
13914  : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
13915  {}
13916 
13917  auto StringRef::c_str() const -> char const* {
13918  CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
13919  return m_start;
13920  }
13921  auto StringRef::data() const noexcept -> char const* {
13922  return m_start;
13923  }
13924 
13925  auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
13926  if (start < m_size) {
13927  return StringRef(m_start + start, (std::min)(m_size - start, size));
13928  } else {
13929  return StringRef();
13930  }
13931  }
13932  auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
13933  return m_size == other.m_size
13934  && (std::memcmp( m_start, other.m_start, m_size ) == 0);
13935  }
13936 
13937  auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
13938  return os.write(str.data(), str.size());
13939  }
13940 
13941  auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
13942  lhs.append(rhs.data(), rhs.size());
13943  return lhs;
13944  }
13945 
13946 } // namespace Catch
13947 // end catch_stringref.cpp
13948 // start catch_tag_alias.cpp
13949 
13950 namespace Catch {
13951  TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
13952 }
13953 // end catch_tag_alias.cpp
13954 // start catch_tag_alias_autoregistrar.cpp
13955 
13956 namespace Catch {
13957 
13958  RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
13959  CATCH_TRY {
13960  getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
13961  } CATCH_CATCH_ALL {
13962  // Do not throw when constructing global objects, instead register the exception to be processed later
13964  }
13965  }
13966 
13967 }
13968 // end catch_tag_alias_autoregistrar.cpp
13969 // start catch_tag_alias_registry.cpp
13970 
13971 #include <sstream>
13972 
13973 namespace Catch {
13974 
13975  TagAliasRegistry::~TagAliasRegistry() {}
13976 
13977  TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
13978  auto it = m_registry.find( alias );
13979  if( it != m_registry.end() )
13980  return &(it->second);
13981  else
13982  return nullptr;
13983  }
13984 
13985  std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
13986  std::string expandedTestSpec = unexpandedTestSpec;
13987  for( auto const& registryKvp : m_registry ) {
13988  std::size_t pos = expandedTestSpec.find( registryKvp.first );
13989  if( pos != std::string::npos ) {
13990  expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
13991  registryKvp.second.tag +
13992  expandedTestSpec.substr( pos + registryKvp.first.size() );
13993  }
13994  }
13995  return expandedTestSpec;
13996  }
13997 
13998  void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
13999  CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
14000  "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
14001 
14002  CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
14003  "error: tag alias, '" << alias << "' already registered.\n"
14004  << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
14005  << "\tRedefined at: " << lineInfo );
14006  }
14007 
14008  ITagAliasRegistry::~ITagAliasRegistry() {}
14009 
14010  ITagAliasRegistry const& ITagAliasRegistry::get() {
14012  }
14013 
14014 } // end namespace Catch
14015 // end catch_tag_alias_registry.cpp
14016 // start catch_test_case_info.cpp
14017 
14018 #include <cctype>
14019 #include <exception>
14020 #include <algorithm>
14021 #include <sstream>
14022 
14023 namespace Catch {
14024 
14025  namespace {
14026  TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
14027  if( startsWith( tag, '.' ) ||
14028  tag == "!hide" )
14029  return TestCaseInfo::IsHidden;
14030  else if( tag == "!throws" )
14031  return TestCaseInfo::Throws;
14032  else if( tag == "!shouldfail" )
14033  return TestCaseInfo::ShouldFail;
14034  else if( tag == "!mayfail" )
14035  return TestCaseInfo::MayFail;
14036  else if( tag == "!nonportable" )
14038  else if( tag == "!benchmark" )
14040  else
14041  return TestCaseInfo::None;
14042  }
14043  bool isReservedTag( std::string const& tag ) {
14044  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
14045  }
14046  void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
14047  CATCH_ENFORCE( !isReservedTag(tag),
14048  "Tag name: [" << tag << "] is not allowed.\n"
14049  << "Tag names starting with non alphanumeric characters are reserved\n"
14050  << _lineInfo );
14051  }
14052  }
14053 
14054  TestCase makeTestCase( ITestInvoker* _testCase,
14055  std::string const& _className,
14056  NameAndTags const& nameAndTags,
14057  SourceLineInfo const& _lineInfo )
14058  {
14059  bool isHidden = false;
14060 
14061  // Parse out tags
14062  std::vector<std::string> tags;
14063  std::string desc, tag;
14064  bool inTag = false;
14065  for (char c : nameAndTags.tags) {
14066  if( !inTag ) {
14067  if( c == '[' )
14068  inTag = true;
14069  else
14070  desc += c;
14071  }
14072  else {
14073  if( c == ']' ) {
14074  TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
14075  if( ( prop & TestCaseInfo::IsHidden ) != 0 )
14076  isHidden = true;
14077  else if( prop == TestCaseInfo::None )
14078  enforceNotReservedTag( tag, _lineInfo );
14079 
14080  // Merged hide tags like `[.approvals]` should be added as
14081  // `[.][approvals]`. The `[.]` is added at later point, so
14082  // we only strip the prefix
14083  if (startsWith(tag, '.') && tag.size() > 1) {
14084  tag.erase(0, 1);
14085  }
14086  tags.push_back( tag );
14087  tag.clear();
14088  inTag = false;
14089  }
14090  else
14091  tag += c;
14092  }
14093  }
14094  if( isHidden ) {
14095  // Add all "hidden" tags to make them behave identically
14096  tags.insert( tags.end(), { ".", "!hide" } );
14097  }
14098 
14099  TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
14100  return TestCase( _testCase, std::move(info) );
14101  }
14102 
14103  void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
14104  std::sort(begin(tags), end(tags));
14105  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
14106  testCaseInfo.lcaseTags.clear();
14107 
14108  for( auto const& tag : tags ) {
14109  std::string lcaseTag = toLower( tag );
14110  testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
14111  testCaseInfo.lcaseTags.push_back( lcaseTag );
14112  }
14113  testCaseInfo.tags = std::move(tags);
14114  }
14115 
14117  std::string const& _className,
14118  std::string const& _description,
14119  std::vector<std::string> const& _tags,
14120  SourceLineInfo const& _lineInfo )
14121  : name( _name ),
14122  className( _className ),
14123  description( _description ),
14124  lineInfo( _lineInfo ),
14125  properties( None )
14126  {
14127  setTags( *this, _tags );
14128  }
14129 
14130  bool TestCaseInfo::isHidden() const {
14131  return ( properties & IsHidden ) != 0;
14132  }
14133  bool TestCaseInfo::throws() const {
14134  return ( properties & Throws ) != 0;
14135  }
14136  bool TestCaseInfo::okToFail() const {
14137  return ( properties & (ShouldFail | MayFail ) ) != 0;
14138  }
14139  bool TestCaseInfo::expectedToFail() const {
14140  return ( properties & (ShouldFail ) ) != 0;
14141  }
14142 
14144  std::string ret;
14145  // '[' and ']' per tag
14146  std::size_t full_size = 2 * tags.size();
14147  for (const auto& tag : tags) {
14148  full_size += tag.size();
14149  }
14150  ret.reserve(full_size);
14151  for (const auto& tag : tags) {
14152  ret.push_back('[');
14153  ret.append(tag);
14154  ret.push_back(']');
14155  }
14156 
14157  return ret;
14158  }
14159 
14160  TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
14161 
14162  TestCase TestCase::withName( std::string const& _newName ) const {
14163  TestCase other( *this );
14164  other.name = _newName;
14165  return other;
14166  }
14167 
14168  void TestCase::invoke() const {
14169  test->invoke();
14170  }
14171 
14172  bool TestCase::operator == ( TestCase const& other ) const {
14173  return test.get() == other.test.get() &&
14174  name == other.name &&
14175  className == other.className;
14176  }
14177 
14178  bool TestCase::operator < ( TestCase const& other ) const {
14179  return name < other.name;
14180  }
14181 
14182  TestCaseInfo const& TestCase::getTestCaseInfo() const
14183  {
14184  return *this;
14185  }
14186 
14187 } // end namespace Catch
14188 // end catch_test_case_info.cpp
14189 // start catch_test_case_registry_impl.cpp
14190 
14191 #include <algorithm>
14192 #include <sstream>
14193 
14194 namespace Catch {
14195 
14196  namespace {
14197  struct TestHasher {
14198  using hash_t = uint64_t;
14199 
14200  explicit TestHasher( hash_t hashSuffix ):
14201  m_hashSuffix{ hashSuffix } {}
14202 
14203  uint32_t operator()( TestCase const& t ) const {
14204  // FNV-1a hash with multiplication fold.
14205  const hash_t prime = 1099511628211u;
14206  hash_t hash = 14695981039346656037u;
14207  for ( const char c : t.name ) {
14208  hash ^= c;
14209  hash *= prime;
14210  }
14211  hash ^= m_hashSuffix;
14212  hash *= prime;
14213  const uint32_t low{ static_cast<uint32_t>( hash ) };
14214  const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };
14215  return low * high;
14216  }
14217 
14218  private:
14219  hash_t m_hashSuffix;
14220  };
14221  } // end unnamed namespace
14222 
14223  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
14224  switch( config.runOrder() ) {
14226  // already in declaration order
14227  break;
14228 
14230  std::vector<TestCase> sorted = unsortedTestCases;
14231  std::sort( sorted.begin(), sorted.end() );
14232  return sorted;
14233  }
14234 
14235  case RunTests::InRandomOrder: {
14236  seedRng( config );
14237  TestHasher h{ config.rngSeed() };
14238 
14239  using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
14240  std::vector<hashedTest> indexed_tests;
14241  indexed_tests.reserve( unsortedTestCases.size() );
14242 
14243  for (auto const& testCase : unsortedTestCases) {
14244  indexed_tests.emplace_back(h(testCase), &testCase);
14245  }
14246 
14247  std::sort(indexed_tests.begin(), indexed_tests.end(),
14248  [](hashedTest const& lhs, hashedTest const& rhs) {
14249  if (lhs.first == rhs.first) {
14250  return lhs.second->name < rhs.second->name;
14251  }
14252  return lhs.first < rhs.first;
14253  });
14254 
14255  std::vector<TestCase> sorted;
14256  sorted.reserve( indexed_tests.size() );
14257 
14258  for (auto const& hashed : indexed_tests) {
14259  sorted.emplace_back(*hashed.second);
14260  }
14261 
14262  return sorted;
14263  }
14264  }
14265  return unsortedTestCases;
14266  }
14267 
14268  bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
14269  return !testCase.throws() || config.allowThrows();
14270  }
14271 
14272  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
14273  return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
14274  }
14275 
14276  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
14277  std::set<TestCase> seenFunctions;
14278  for( auto const& function : functions ) {
14279  auto prev = seenFunctions.insert( function );
14280  CATCH_ENFORCE( prev.second,
14281  "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
14282  << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
14283  << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
14284  }
14285  }
14286 
14287  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
14288  std::vector<TestCase> filtered;
14289  filtered.reserve( testCases.size() );
14290  for (auto const& testCase : testCases) {
14291  if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
14292  (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
14293  filtered.push_back(testCase);
14294  }
14295  }
14296  return filtered;
14297  }
14298  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
14300  }
14301 
14302  void TestRegistry::registerTest( TestCase const& testCase ) {
14303  std::string name = testCase.getTestCaseInfo().name;
14304  if( name.empty() ) {
14305  ReusableStringStream rss;
14306  rss << "Anonymous test case " << ++m_unnamedCount;
14307  return registerTest( testCase.withName( rss.str() ) );
14308  }
14309  m_functions.push_back( testCase );
14310  }
14311 
14312  std::vector<TestCase> const& TestRegistry::getAllTests() const {
14313  return m_functions;
14314  }
14315  std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
14316  if( m_sortedFunctions.empty() )
14317  enforceNoDuplicateTestCases( m_functions );
14318 
14319  if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
14320  m_sortedFunctions = sortTests( config, m_functions );
14321  m_currentSortOrder = config.runOrder();
14322  }
14323  return m_sortedFunctions;
14324  }
14325 
14327  TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
14328 
14329  void TestInvokerAsFunction::invoke() const {
14330  m_testAsFunction();
14331  }
14332 
14333  std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
14334  std::string className(classOrQualifiedMethodName);
14335  if( startsWith( className, '&' ) )
14336  {
14337  std::size_t lastColons = className.rfind( "::" );
14338  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
14339  if( penultimateColons == std::string::npos )
14340  penultimateColons = 1;
14341  className = className.substr( penultimateColons, lastColons-penultimateColons );
14342  }
14343  return className;
14344  }
14345 
14346 } // end namespace Catch
14347 // end catch_test_case_registry_impl.cpp
14348 // start catch_test_case_tracker.cpp
14349 
14350 #include <algorithm>
14351 #include <cassert>
14352 #include <stdexcept>
14353 #include <memory>
14354 #include <sstream>
14355 
14356 #if defined(__clang__)
14357 # pragma clang diagnostic push
14358 # pragma clang diagnostic ignored "-Wexit-time-destructors"
14359 #endif
14360 
14361 namespace Catch {
14362 namespace TestCaseTracking {
14363 
14364  NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
14365  : name( _name ),
14366  location( _location )
14367  {}
14368 
14369  ITracker::~ITracker() = default;
14370 
14371  ITracker& TrackerContext::startRun() {
14372  m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
14373  m_currentTracker = nullptr;
14374  m_runState = Executing;
14375  return *m_rootTracker;
14376  }
14377 
14378  void TrackerContext::endRun() {
14379  m_rootTracker.reset();
14380  m_currentTracker = nullptr;
14381  m_runState = NotStarted;
14382  }
14383 
14384  void TrackerContext::startCycle() {
14385  m_currentTracker = m_rootTracker.get();
14386  m_runState = Executing;
14387  }
14388  void TrackerContext::completeCycle() {
14389  m_runState = CompletedCycle;
14390  }
14391 
14392  bool TrackerContext::completedCycle() const {
14393  return m_runState == CompletedCycle;
14394  }
14395  ITracker& TrackerContext::currentTracker() {
14396  return *m_currentTracker;
14397  }
14398  void TrackerContext::setCurrentTracker( ITracker* tracker ) {
14399  m_currentTracker = tracker;
14400  }
14401 
14402  TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
14403  ITracker(nameAndLocation),
14404  m_ctx( ctx ),
14405  m_parent( parent )
14406  {}
14407 
14408  bool TrackerBase::isComplete() const {
14409  return m_runState == CompletedSuccessfully || m_runState == Failed;
14410  }
14411  bool TrackerBase::isSuccessfullyCompleted() const {
14412  return m_runState == CompletedSuccessfully;
14413  }
14414  bool TrackerBase::isOpen() const {
14415  return m_runState != NotStarted && !isComplete();
14416  }
14417  bool TrackerBase::hasChildren() const {
14418  return !m_children.empty();
14419  }
14420 
14421  void TrackerBase::addChild( ITrackerPtr const& child ) {
14422  m_children.push_back( child );
14423  }
14424 
14425  ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
14426  auto it = std::find_if( m_children.begin(), m_children.end(),
14427  [&nameAndLocation]( ITrackerPtr const& tracker ){
14428  return
14429  tracker->nameAndLocation().location == nameAndLocation.location &&
14430  tracker->nameAndLocation().name == nameAndLocation.name;
14431  } );
14432  return( it != m_children.end() )
14433  ? *it
14434  : nullptr;
14435  }
14436  ITracker& TrackerBase::parent() {
14437  assert( m_parent ); // Should always be non-null except for root
14438  return *m_parent;
14439  }
14440 
14441  void TrackerBase::openChild() {
14442  if( m_runState != ExecutingChildren ) {
14443  m_runState = ExecutingChildren;
14444  if( m_parent )
14445  m_parent->openChild();
14446  }
14447  }
14448 
14449  bool TrackerBase::isSectionTracker() const { return false; }
14450  bool TrackerBase::isGeneratorTracker() const { return false; }
14451 
14452  void TrackerBase::open() {
14453  m_runState = Executing;
14454  moveToThis();
14455  if( m_parent )
14456  m_parent->openChild();
14457  }
14458 
14459  void TrackerBase::close() {
14460 
14461  // Close any still open children (e.g. generators)
14462  while( &m_ctx.currentTracker() != this )
14463  m_ctx.currentTracker().close();
14464 
14465  switch( m_runState ) {
14466  case NeedsAnotherRun:
14467  break;
14468 
14469  case Executing:
14470  m_runState = CompletedSuccessfully;
14471  break;
14472  case ExecutingChildren:
14473  if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
14474  m_runState = CompletedSuccessfully;
14475  break;
14476 
14477  case NotStarted:
14478  case CompletedSuccessfully:
14479  case Failed:
14480  CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
14481 
14482  default:
14483  CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
14484  }
14485  moveToParent();
14486  m_ctx.completeCycle();
14487  }
14488  void TrackerBase::fail() {
14489  m_runState = Failed;
14490  if( m_parent )
14491  m_parent->markAsNeedingAnotherRun();
14492  moveToParent();
14493  m_ctx.completeCycle();
14494  }
14495  void TrackerBase::markAsNeedingAnotherRun() {
14496  m_runState = NeedsAnotherRun;
14497  }
14498 
14499  void TrackerBase::moveToParent() {
14500  assert( m_parent );
14501  m_ctx.setCurrentTracker( m_parent );
14502  }
14503  void TrackerBase::moveToThis() {
14504  m_ctx.setCurrentTracker( this );
14505  }
14506 
14507  SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
14508  : TrackerBase( nameAndLocation, ctx, parent ),
14509  m_trimmed_name(trim(nameAndLocation.name))
14510  {
14511  if( parent ) {
14512  while( !parent->isSectionTracker() )
14513  parent = &parent->parent();
14514 
14515  SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
14516  addNextFilters( parentSection.m_filters );
14517  }
14518  }
14519 
14520  bool SectionTracker::isComplete() const {
14521  bool complete = true;
14522 
14523  if (m_filters.empty()
14524  || m_filters[0] == ""
14525  || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
14526  complete = TrackerBase::isComplete();
14527  }
14528  return complete;
14529  }
14530 
14531  bool SectionTracker::isSectionTracker() const { return true; }
14532 
14533  SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
14534  std::shared_ptr<SectionTracker> section;
14535 
14536  ITracker& currentTracker = ctx.currentTracker();
14537  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
14538  assert( childTracker );
14539  assert( childTracker->isSectionTracker() );
14540  section = std::static_pointer_cast<SectionTracker>( childTracker );
14541  }
14542  else {
14543  section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
14544  currentTracker.addChild( section );
14545  }
14546  if( !ctx.completedCycle() )
14547  section->tryOpen();
14548  return *section;
14549  }
14550 
14551  void SectionTracker::tryOpen() {
14552  if( !isComplete() )
14553  open();
14554  }
14555 
14556  void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
14557  if( !filters.empty() ) {
14558  m_filters.reserve( m_filters.size() + filters.size() + 2 );
14559  m_filters.emplace_back(""); // Root - should never be consulted
14560  m_filters.emplace_back(""); // Test Case - not a section filter
14561  m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
14562  }
14563  }
14564  void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
14565  if( filters.size() > 1 )
14566  m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
14567  }
14568 
14569  std::vector<std::string> const& SectionTracker::getFilters() const {
14570  return m_filters;
14571  }
14572 
14573  std::string const& SectionTracker::trimmedName() const {
14574  return m_trimmed_name;
14575  }
14576 
14577 } // namespace TestCaseTracking
14578 
14579 using TestCaseTracking::ITracker;
14580 using TestCaseTracking::TrackerContext;
14581 using TestCaseTracking::SectionTracker;
14582 
14583 } // namespace Catch
14584 
14585 #if defined(__clang__)
14586 # pragma clang diagnostic pop
14587 #endif
14588 // end catch_test_case_tracker.cpp
14589 // start catch_test_registry.cpp
14590 
14591 namespace Catch {
14592 
14593  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
14594  return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
14595  }
14596 
14597  NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
14598 
14599  AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
14600  CATCH_TRY {
14602  .registerTest(
14603  makeTestCase(
14604  invoker,
14605  extractClassName( classOrMethod ),
14606  nameAndTags,
14607  lineInfo));
14608  } CATCH_CATCH_ALL {
14609  // Do not throw when constructing global objects, instead register the exception to be processed later
14611  }
14612  }
14613 
14614  AutoReg::~AutoReg() = default;
14615 }
14616 // end catch_test_registry.cpp
14617 // start catch_test_spec.cpp
14618 
14619 #include <algorithm>
14620 #include <string>
14621 #include <vector>
14622 #include <memory>
14623 
14624 namespace Catch {
14625 
14626  TestSpec::Pattern::Pattern( std::string const& name )
14627  : m_name( name )
14628  {}
14629 
14630  TestSpec::Pattern::~Pattern() = default;
14631 
14632  std::string const& TestSpec::Pattern::name() const {
14633  return m_name;
14634  }
14635 
14636  TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
14637  : Pattern( filterString )
14638  , m_wildcardPattern( toLower( name ), CaseSensitive::No )
14639  {}
14640 
14641  bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
14642  return m_wildcardPattern.matches( testCase.name );
14643  }
14644 
14645  TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
14646  : Pattern( filterString )
14647  , m_tag( toLower( tag ) )
14648  {}
14649 
14650  bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
14651  return std::find(begin(testCase.lcaseTags),
14652  end(testCase.lcaseTags),
14653  m_tag) != end(testCase.lcaseTags);
14654  }
14655 
14656  TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
14657  : Pattern( underlyingPattern->name() )
14658  , m_underlyingPattern( underlyingPattern )
14659  {}
14660 
14661  bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
14662  return !m_underlyingPattern->matches( testCase );
14663  }
14664 
14665  bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
14666  return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
14667  }
14668 
14670  std::string name;
14671  for( auto const& p : m_patterns )
14672  name += p->name();
14673  return name;
14674  }
14675 
14676  bool TestSpec::hasFilters() const {
14677  return !m_filters.empty();
14678  }
14679 
14680  bool TestSpec::matches( TestCaseInfo const& testCase ) const {
14681  return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
14682  }
14683 
14684  TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
14685  {
14686  Matches matches( m_filters.size() );
14687  std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
14688  std::vector<TestCase const*> currentMatches;
14689  for( auto const& test : testCases )
14690  if( isThrowSafe( test, config ) && filter.matches( test ) )
14691  currentMatches.emplace_back( &test );
14692  return FilterMatch{ filter.name(), currentMatches };
14693  } );
14694  return matches;
14695  }
14696 
14697  const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
14698  return (m_invalidArgs);
14699  }
14700 
14701 }
14702 // end catch_test_spec.cpp
14703 // start catch_test_spec_parser.cpp
14704 
14705 namespace Catch {
14706 
14707  TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
14708 
14709  TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
14710  m_mode = None;
14711  m_exclusion = false;
14712  m_arg = m_tagAliases->expandAliases( arg );
14713  m_escapeChars.clear();
14714  m_substring.reserve(m_arg.size());
14715  m_patternName.reserve(m_arg.size());
14716  m_realPatternPos = 0;
14717 
14718  for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
14719  //if visitChar fails
14720  if( !visitChar( m_arg[m_pos] ) ){
14721  m_testSpec.m_invalidArgs.push_back(arg);
14722  break;
14723  }
14724  endMode();
14725  return *this;
14726  }
14727  TestSpec TestSpecParser::testSpec() {
14728  addFilter();
14729  return m_testSpec;
14730  }
14731  bool TestSpecParser::visitChar( char c ) {
14732  if( (m_mode != EscapedName) && (c == '\\') ) {
14733  escape();
14734  addCharToPattern(c);
14735  return true;
14736  }else if((m_mode != EscapedName) && (c == ',') ) {
14737  return separate();
14738  }
14739 
14740  switch( m_mode ) {
14741  case None:
14742  if( processNoneChar( c ) )
14743  return true;
14744  break;
14745  case Name:
14746  processNameChar( c );
14747  break;
14748  case EscapedName:
14749  endMode();
14750  addCharToPattern(c);
14751  return true;
14752  default:
14753  case Tag:
14754  case QuotedName:
14755  if( processOtherChar( c ) )
14756  return true;
14757  break;
14758  }
14759 
14760  m_substring += c;
14761  if( !isControlChar( c ) ) {
14762  m_patternName += c;
14763  m_realPatternPos++;
14764  }
14765  return true;
14766  }
14767  // Two of the processing methods return true to signal the caller to return
14768  // without adding the given character to the current pattern strings
14769  bool TestSpecParser::processNoneChar( char c ) {
14770  switch( c ) {
14771  case ' ':
14772  return true;
14773  case '~':
14774  m_exclusion = true;
14775  return false;
14776  case '[':
14777  startNewMode( Tag );
14778  return false;
14779  case '"':
14780  startNewMode( QuotedName );
14781  return false;
14782  default:
14783  startNewMode( Name );
14784  return false;
14785  }
14786  }
14787  void TestSpecParser::processNameChar( char c ) {
14788  if( c == '[' ) {
14789  if( m_substring == "exclude:" )
14790  m_exclusion = true;
14791  else
14792  endMode();
14793  startNewMode( Tag );
14794  }
14795  }
14796  bool TestSpecParser::processOtherChar( char c ) {
14797  if( !isControlChar( c ) )
14798  return false;
14799  m_substring += c;
14800  endMode();
14801  return true;
14802  }
14803  void TestSpecParser::startNewMode( Mode mode ) {
14804  m_mode = mode;
14805  }
14806  void TestSpecParser::endMode() {
14807  switch( m_mode ) {
14808  case Name:
14809  case QuotedName:
14810  return addNamePattern();
14811  case Tag:
14812  return addTagPattern();
14813  case EscapedName:
14814  revertBackToLastMode();
14815  return;
14816  case None:
14817  default:
14818  return startNewMode( None );
14819  }
14820  }
14821  void TestSpecParser::escape() {
14822  saveLastMode();
14823  m_mode = EscapedName;
14824  m_escapeChars.push_back(m_realPatternPos);
14825  }
14826  bool TestSpecParser::isControlChar( char c ) const {
14827  switch( m_mode ) {
14828  default:
14829  return false;
14830  case None:
14831  return c == '~';
14832  case Name:
14833  return c == '[';
14834  case EscapedName:
14835  return true;
14836  case QuotedName:
14837  return c == '"';
14838  case Tag:
14839  return c == '[' || c == ']';
14840  }
14841  }
14842 
14843  void TestSpecParser::addFilter() {
14844  if( !m_currentFilter.m_patterns.empty() ) {
14845  m_testSpec.m_filters.push_back( m_currentFilter );
14846  m_currentFilter = TestSpec::Filter();
14847  }
14848  }
14849 
14850  void TestSpecParser::saveLastMode() {
14851  lastMode = m_mode;
14852  }
14853 
14854  void TestSpecParser::revertBackToLastMode() {
14855  m_mode = lastMode;
14856  }
14857 
14858  bool TestSpecParser::separate() {
14859  if( (m_mode==QuotedName) || (m_mode==Tag) ){
14860  //invalid argument, signal failure to previous scope.
14861  m_mode = None;
14862  m_pos = m_arg.size();
14863  m_substring.clear();
14864  m_patternName.clear();
14865  m_realPatternPos = 0;
14866  return false;
14867  }
14868  endMode();
14869  addFilter();
14870  return true; //success
14871  }
14872 
14873  std::string TestSpecParser::preprocessPattern() {
14874  std::string token = m_patternName;
14875  for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
14876  token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
14877  m_escapeChars.clear();
14878  if (startsWith(token, "exclude:")) {
14879  m_exclusion = true;
14880  token = token.substr(8);
14881  }
14882 
14883  m_patternName.clear();
14884  m_realPatternPos = 0;
14885 
14886  return token;
14887  }
14888 
14889  void TestSpecParser::addNamePattern() {
14890  auto token = preprocessPattern();
14891 
14892  if (!token.empty()) {
14893  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
14894  if (m_exclusion)
14895  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14896  m_currentFilter.m_patterns.push_back(pattern);
14897  }
14898  m_substring.clear();
14899  m_exclusion = false;
14900  m_mode = None;
14901  }
14902 
14903  void TestSpecParser::addTagPattern() {
14904  auto token = preprocessPattern();
14905 
14906  if (!token.empty()) {
14907  // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
14908  // we have to create a separate hide tag and shorten the real one
14909  if (token.size() > 1 && token[0] == '.') {
14910  token.erase(token.begin());
14911  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
14912  if (m_exclusion) {
14913  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14914  }
14915  m_currentFilter.m_patterns.push_back(pattern);
14916  }
14917 
14918  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
14919 
14920  if (m_exclusion) {
14921  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14922  }
14923  m_currentFilter.m_patterns.push_back(pattern);
14924  }
14925  m_substring.clear();
14926  m_exclusion = false;
14927  m_mode = None;
14928  }
14929 
14930  TestSpec parseTestSpec( std::string const& arg ) {
14931  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
14932  }
14933 
14934 } // namespace Catch
14935 // end catch_test_spec_parser.cpp
14936 // start catch_timer.cpp
14937 
14938 #include <chrono>
14939 
14940 static const uint64_t nanosecondsInSecond = 1000000000;
14941 
14942 namespace Catch {
14943 
14944  auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
14945  return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
14946  }
14947 
14948  namespace {
14949  auto estimateClockResolution() -> uint64_t {
14950  uint64_t sum = 0;
14951  static const uint64_t iterations = 1000000;
14952 
14953  auto startTime = getCurrentNanosecondsSinceEpoch();
14954 
14955  for( std::size_t i = 0; i < iterations; ++i ) {
14956 
14957  uint64_t ticks;
14958  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
14959  do {
14961  } while( ticks == baseTicks );
14962 
14963  auto delta = ticks - baseTicks;
14964  sum += delta;
14965 
14966  // If we have been calibrating for over 3 seconds -- the clock
14967  // is terrible and we should move on.
14968  // TBD: How to signal that the measured resolution is probably wrong?
14969  if (ticks > startTime + 3 * nanosecondsInSecond) {
14970  return sum / ( i + 1u );
14971  }
14972  }
14973 
14974  // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
14975  // - and potentially do more iterations if there's a high variance.
14976  return sum/iterations;
14977  }
14978  }
14979  auto getEstimatedClockResolution() -> uint64_t {
14980  static auto s_resolution = estimateClockResolution();
14981  return s_resolution;
14982  }
14983 
14984  void Timer::start() {
14985  m_nanoseconds = getCurrentNanosecondsSinceEpoch();
14986  }
14987  auto Timer::getElapsedNanoseconds() const -> uint64_t {
14988  return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
14989  }
14990  auto Timer::getElapsedMicroseconds() const -> uint64_t {
14991  return getElapsedNanoseconds()/1000;
14992  }
14993  auto Timer::getElapsedMilliseconds() const -> unsigned int {
14994  return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
14995  }
14996  auto Timer::getElapsedSeconds() const -> double {
14997  return getElapsedMicroseconds()/1000000.0;
14998  }
14999 
15000 } // namespace Catch
15001 // end catch_timer.cpp
15002 // start catch_tostring.cpp
15003 
15004 #if defined(__clang__)
15005 # pragma clang diagnostic push
15006 # pragma clang diagnostic ignored "-Wexit-time-destructors"
15007 # pragma clang diagnostic ignored "-Wglobal-constructors"
15008 #endif
15009 
15010 // Enable specific decls locally
15011 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
15012 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
15013 #endif
15014 
15015 #include <cmath>
15016 #include <iomanip>
15017 
15018 namespace Catch {
15019 
15020 namespace Detail {
15021 
15022  const std::string unprintableString = "{?}";
15023 
15024  namespace {
15025  const int hexThreshold = 255;
15026 
15027  struct Endianness {
15028  enum Arch { Big, Little };
15029 
15030  static Arch which() {
15031  int one = 1;
15032  // If the lowest byte we read is non-zero, we can assume
15033  // that little endian format is used.
15034  auto value = *reinterpret_cast<char*>(&one);
15035  return value ? Little : Big;
15036  }
15037  };
15038  }
15039 
15040  std::string rawMemoryToString( const void *object, std::size_t size ) {
15041  // Reverse order for little endian architectures
15042  int i = 0, end = static_cast<int>( size ), inc = 1;
15043  if( Endianness::which() == Endianness::Little ) {
15044  i = end-1;
15045  end = inc = -1;
15046  }
15047 
15048  unsigned char const *bytes = static_cast<unsigned char const *>(object);
15049  ReusableStringStream rss;
15050  rss << "0x" << std::setfill('0') << std::hex;
15051  for( ; i != end; i += inc )
15052  rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
15053  return rss.str();
15054  }
15055 }
15056 
15057 template<typename T>
15058 std::string fpToString( T value, int precision ) {
15059  if (Catch::isnan(value)) {
15060  return "nan";
15061  }
15062 
15063  ReusableStringStream rss;
15064  rss << std::setprecision( precision )
15065  << std::fixed
15066  << value;
15067  std::string d = rss.str();
15068  std::size_t i = d.find_last_not_of( '0' );
15069  if( i != std::string::npos && i != d.size()-1 ) {
15070  if( d[i] == '.' )
15071  i++;
15072  d = d.substr( 0, i+1 );
15073  }
15074  return d;
15075 }
15076 
15078 //
15079 // Out-of-line defs for full specialization of StringMaker
15080 //
15082 
15084  if (!getCurrentContext().getConfig()->showInvisibles()) {
15085  return '"' + str + '"';
15086  }
15087 
15088  std::string s("\"");
15089  for (char c : str) {
15090  switch (c) {
15091  case '\n':
15092  s.append("\\n");
15093  break;
15094  case '\t':
15095  s.append("\\t");
15096  break;
15097  default:
15098  s.push_back(c);
15099  break;
15100  }
15101  }
15102  s.append("\"");
15103  return s;
15104 }
15105 
15106 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15109 }
15110 #endif
15111 
15113  if (str) {
15115  } else {
15116  return{ "{null string}" };
15117  }
15118 }
15120  if (str) {
15122  } else {
15123  return{ "{null string}" };
15124  }
15125 }
15126 
15127 #ifdef CATCH_CONFIG_WCHAR
15128 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
15129  std::string s;
15130  s.reserve(wstr.size());
15131  for (auto c : wstr) {
15132  s += (c <= 0xff) ? static_cast<char>(c) : '?';
15133  }
15135 }
15136 
15137 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15139  return StringMaker<std::wstring>::convert(std::wstring(str));
15140 }
15141 # endif
15142 
15144  if (str) {
15145  return ::Catch::Detail::stringify(std::wstring{ str });
15146  } else {
15147  return{ "{null string}" };
15148  }
15149 }
15151  if (str) {
15152  return ::Catch::Detail::stringify(std::wstring{ str });
15153  } else {
15154  return{ "{null string}" };
15155  }
15156 }
15157 #endif
15158 
15159 #if defined(CATCH_CONFIG_CPP17_BYTE)
15160 #include <cstddef>
15162  return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
15163 }
15164 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
15165 
15167  return ::Catch::Detail::stringify(static_cast<long long>(value));
15168 }
15170  return ::Catch::Detail::stringify(static_cast<long long>(value));
15171 }
15173  ReusableStringStream rss;
15174  rss << value;
15175  if (value > Detail::hexThreshold) {
15176  rss << " (0x" << std::hex << value << ')';
15177  }
15178  return rss.str();
15179 }
15180 
15182  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15183 }
15185  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15186 }
15188  ReusableStringStream rss;
15189  rss << value;
15190  if (value > Detail::hexThreshold) {
15191  rss << " (0x" << std::hex << value << ')';
15192  }
15193  return rss.str();
15194 }
15195 
15197  return b ? "true" : "false";
15198 }
15199 
15201  if (value == '\r') {
15202  return "'\\r'";
15203  } else if (value == '\f') {
15204  return "'\\f'";
15205  } else if (value == '\n') {
15206  return "'\\n'";
15207  } else if (value == '\t') {
15208  return "'\\t'";
15209  } else if ('\0' <= value && value < ' ') {
15210  return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
15211  } else {
15212  char chstr[] = "' '";
15213  chstr[1] = value;
15214  return chstr;
15215  }
15216 }
15218  return ::Catch::Detail::stringify(static_cast<signed char>(c));
15219 }
15221  return ::Catch::Detail::stringify(static_cast<char>(c));
15222 }
15223 
15225  return "nullptr";
15226 }
15227 
15229 
15231  return fpToString(value, precision) + 'f';
15232 }
15233 
15235 
15237  return fpToString(value, precision);
15238 }
15239 
15240 std::string ratio_string<std::atto>::symbol() { return "a"; }
15241 std::string ratio_string<std::femto>::symbol() { return "f"; }
15242 std::string ratio_string<std::pico>::symbol() { return "p"; }
15243 std::string ratio_string<std::nano>::symbol() { return "n"; }
15244 std::string ratio_string<std::micro>::symbol() { return "u"; }
15245 std::string ratio_string<std::milli>::symbol() { return "m"; }
15246 
15247 } // end namespace Catch
15248 
15249 #if defined(__clang__)
15250 # pragma clang diagnostic pop
15251 #endif
15252 
15253 // end catch_tostring.cpp
15254 // start catch_totals.cpp
15255 
15256 namespace Catch {
15257 
15258  Counts Counts::operator - ( Counts const& other ) const {
15259  Counts diff;
15260  diff.passed = passed - other.passed;
15261  diff.failed = failed - other.failed;
15262  diff.failedButOk = failedButOk - other.failedButOk;
15263  return diff;
15264  }
15265 
15266  Counts& Counts::operator += ( Counts const& other ) {
15267  passed += other.passed;
15268  failed += other.failed;
15270  return *this;
15271  }
15272 
15273  std::size_t Counts::total() const {
15274  return passed + failed + failedButOk;
15275  }
15276  bool Counts::allPassed() const {
15277  return failed == 0 && failedButOk == 0;
15278  }
15279  bool Counts::allOk() const {
15280  return failed == 0;
15281  }
15282 
15283  Totals Totals::operator - ( Totals const& other ) const {
15284  Totals diff;
15286  diff.testCases = testCases - other.testCases;
15287  return diff;
15288  }
15289 
15290  Totals& Totals::operator += ( Totals const& other ) {
15293  return *this;
15294  }
15295 
15296  Totals Totals::delta( Totals const& prevTotals ) const {
15297  Totals diff = *this - prevTotals;
15298  if( diff.assertions.failed > 0 )
15299  ++diff.testCases.failed;
15300  else if( diff.assertions.failedButOk > 0 )
15301  ++diff.testCases.failedButOk;
15302  else
15303  ++diff.testCases.passed;
15304  return diff;
15305  }
15306 
15307 }
15308 // end catch_totals.cpp
15309 // start catch_uncaught_exceptions.cpp
15310 
15311 // start catch_config_uncaught_exceptions.hpp
15312 
15313 // Copyright Catch2 Authors
15314 // Distributed under the Boost Software License, Version 1.0.
15315 // (See accompanying file LICENSE_1_0.txt or copy at
15316 // https://www.boost.org/LICENSE_1_0.txt)
15317 
15318 // SPDX-License-Identifier: BSL-1.0
15319 
15320 #ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15321 #define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15322 
15323 #if defined(_MSC_VER)
15324 # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
15325 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15326 # endif
15327 #endif
15328 
15329 #include <exception>
15330 
15331 #if defined(__cpp_lib_uncaught_exceptions) \
15332  && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15333 
15334 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15335 #endif // __cpp_lib_uncaught_exceptions
15336 
15337 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
15338  && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
15339  && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15340 
15341 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15342 #endif
15343 
15344 #endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15345 // end catch_config_uncaught_exceptions.hpp
15346 #include <exception>
15347 
15348 namespace Catch {
15349  bool uncaught_exceptions() {
15350 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
15351  return false;
15352 #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15353  return std::uncaught_exceptions() > 0;
15354 #else
15355  return std::uncaught_exception();
15356 #endif
15357  }
15358 } // end namespace Catch
15359 // end catch_uncaught_exceptions.cpp
15360 // start catch_version.cpp
15361 
15362 #include <ostream>
15363 
15364 namespace Catch {
15365 
15366  Version::Version
15367  ( unsigned int _majorVersion,
15368  unsigned int _minorVersion,
15369  unsigned int _patchNumber,
15370  char const * const _branchName,
15371  unsigned int _buildNumber )
15372  : majorVersion( _majorVersion ),
15373  minorVersion( _minorVersion ),
15374  patchNumber( _patchNumber ),
15375  branchName( _branchName ),
15376  buildNumber( _buildNumber )
15377  {}
15378 
15379  std::ostream& operator << ( std::ostream& os, Version const& version ) {
15380  os << version.majorVersion << '.'
15381  << version.minorVersion << '.'
15382  << version.patchNumber;
15383  // branchName is never null -> 0th char is \0 if it is empty
15384  if (version.branchName[0]) {
15385  os << '-' << version.branchName
15386  << '.' << version.buildNumber;
15387  }
15388  return os;
15389  }
15390 
15391  Version const& libraryVersion() {
15392  static Version version( 2, 13, 8, "", 0 );
15393  return version;
15394  }
15395 
15396 }
15397 // end catch_version.cpp
15398 // start catch_wildcard_pattern.cpp
15399 
15400 namespace Catch {
15401 
15402  WildcardPattern::WildcardPattern( std::string const& pattern,
15403  CaseSensitive::Choice caseSensitivity )
15404  : m_caseSensitivity( caseSensitivity ),
15405  m_pattern( normaliseString( pattern ) )
15406  {
15407  if( startsWith( m_pattern, '*' ) ) {
15408  m_pattern = m_pattern.substr( 1 );
15409  m_wildcard = WildcardAtStart;
15410  }
15411  if( endsWith( m_pattern, '*' ) ) {
15412  m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
15413  m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
15414  }
15415  }
15416 
15417  bool WildcardPattern::matches( std::string const& str ) const {
15418  switch( m_wildcard ) {
15419  case NoWildcard:
15420  return m_pattern == normaliseString( str );
15421  case WildcardAtStart:
15422  return endsWith( normaliseString( str ), m_pattern );
15423  case WildcardAtEnd:
15424  return startsWith( normaliseString( str ), m_pattern );
15425  case WildcardAtBothEnds:
15426  return contains( normaliseString( str ), m_pattern );
15427  default:
15428  CATCH_INTERNAL_ERROR( "Unknown enum" );
15429  }
15430  }
15431 
15432  std::string WildcardPattern::normaliseString( std::string const& str ) const {
15433  return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
15434  }
15435 }
15436 // end catch_wildcard_pattern.cpp
15437 // start catch_xmlwriter.cpp
15438 
15439 #include <iomanip>
15440 #include <type_traits>
15441 
15442 namespace Catch {
15443 
15444 namespace {
15445 
15446  size_t trailingBytes(unsigned char c) {
15447  if ((c & 0xE0) == 0xC0) {
15448  return 2;
15449  }
15450  if ((c & 0xF0) == 0xE0) {
15451  return 3;
15452  }
15453  if ((c & 0xF8) == 0xF0) {
15454  return 4;
15455  }
15456  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15457  }
15458 
15459  uint32_t headerValue(unsigned char c) {
15460  if ((c & 0xE0) == 0xC0) {
15461  return c & 0x1F;
15462  }
15463  if ((c & 0xF0) == 0xE0) {
15464  return c & 0x0F;
15465  }
15466  if ((c & 0xF8) == 0xF0) {
15467  return c & 0x07;
15468  }
15469  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15470  }
15471 
15472  void hexEscapeChar(std::ostream& os, unsigned char c) {
15473  std::ios_base::fmtflags f(os.flags());
15474  os << "\\x"
15475  << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
15476  << static_cast<int>(c);
15477  os.flags(f);
15478  }
15479 
15480  bool shouldNewline(XmlFormatting fmt) {
15481  return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
15482  }
15483 
15484  bool shouldIndent(XmlFormatting fmt) {
15485  return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
15486  }
15487 
15488 } // anonymous namespace
15489 
15490  XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
15491  return static_cast<XmlFormatting>(
15492  static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
15494  );
15495  }
15496 
15497  XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
15498  return static_cast<XmlFormatting>(
15499  static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
15501  );
15502  }
15503 
15504  XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
15505  : m_str( str ),
15506  m_forWhat( forWhat )
15507  {}
15508 
15509  void XmlEncode::encodeTo( std::ostream& os ) const {
15510  // Apostrophe escaping not necessary if we always use " to write attributes
15511  // (see: http://www.w3.org/TR/xml/#syntax)
15512 
15513  for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
15514  unsigned char c = m_str[idx];
15515  switch (c) {
15516  case '<': os << "&lt;"; break;
15517  case '&': os << "&amp;"; break;
15518 
15519  case '>':
15520  // See: http://www.w3.org/TR/xml/#syntax
15521  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
15522  os << "&gt;";
15523  else
15524  os << c;
15525  break;
15526 
15527  case '\"':
15528  if (m_forWhat == ForAttributes)
15529  os << "&quot;";
15530  else
15531  os << c;
15532  break;
15533 
15534  default:
15535  // Check for control characters and invalid utf-8
15536 
15537  // Escape control characters in standard ascii
15538  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
15539  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
15540  hexEscapeChar(os, c);
15541  break;
15542  }
15543 
15544  // Plain ASCII: Write it to stream
15545  if (c < 0x7F) {
15546  os << c;
15547  break;
15548  }
15549 
15550  // UTF-8 territory
15551  // Check if the encoding is valid and if it is not, hex escape bytes.
15552  // Important: We do not check the exact decoded values for validity, only the encoding format
15553  // First check that this bytes is a valid lead byte:
15554  // This means that it is not encoded as 1111 1XXX
15555  // Or as 10XX XXXX
15556  if (c < 0xC0 ||
15557  c >= 0xF8) {
15558  hexEscapeChar(os, c);
15559  break;
15560  }
15561 
15562  auto encBytes = trailingBytes(c);
15563  // Are there enough bytes left to avoid accessing out-of-bounds memory?
15564  if (idx + encBytes - 1 >= m_str.size()) {
15565  hexEscapeChar(os, c);
15566  break;
15567  }
15568  // The header is valid, check data
15569  // The next encBytes bytes must together be a valid utf-8
15570  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
15571  bool valid = true;
15572  uint32_t value = headerValue(c);
15573  for (std::size_t n = 1; n < encBytes; ++n) {
15574  unsigned char nc = m_str[idx + n];
15575  valid &= ((nc & 0xC0) == 0x80);
15576  value = (value << 6) | (nc & 0x3F);
15577  }
15578 
15579  if (
15580  // Wrong bit pattern of following bytes
15581  (!valid) ||
15582  // Overlong encodings
15583  (value < 0x80) ||
15584  (0x80 <= value && value < 0x800 && encBytes > 2) ||
15585  (0x800 < value && value < 0x10000 && encBytes > 3) ||
15586  // Encoded value out of range
15587  (value >= 0x110000)
15588  ) {
15589  hexEscapeChar(os, c);
15590  break;
15591  }
15592 
15593  // If we got here, this is in fact a valid(ish) utf-8 sequence
15594  for (std::size_t n = 0; n < encBytes; ++n) {
15595  os << m_str[idx + n];
15596  }
15597  idx += encBytes - 1;
15598  break;
15599  }
15600  }
15601  }
15602 
15603  std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
15604  xmlEncode.encodeTo( os );
15605  return os;
15606  }
15607 
15608  XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
15609  : m_writer( writer ),
15610  m_fmt(fmt)
15611  {}
15612 
15613  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
15614  : m_writer( other.m_writer ),
15615  m_fmt(other.m_fmt)
15616  {
15617  other.m_writer = nullptr;
15618  other.m_fmt = XmlFormatting::None;
15619  }
15620  XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
15621  if ( m_writer ) {
15622  m_writer->endElement();
15623  }
15624  m_writer = other.m_writer;
15625  other.m_writer = nullptr;
15626  m_fmt = other.m_fmt;
15627  other.m_fmt = XmlFormatting::None;
15628  return *this;
15629  }
15630 
15631  XmlWriter::ScopedElement::~ScopedElement() {
15632  if (m_writer) {
15633  m_writer->endElement(m_fmt);
15634  }
15635  }
15636 
15637  XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
15638  m_writer->writeText( text, fmt );
15639  return *this;
15640  }
15641 
15642  XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
15643  {
15644  writeDeclaration();
15645  }
15646 
15647  XmlWriter::~XmlWriter() {
15648  while (!m_tags.empty()) {
15649  endElement();
15650  }
15651  newlineIfNecessary();
15652  }
15653 
15654  XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
15655  ensureTagClosed();
15656  newlineIfNecessary();
15657  if (shouldIndent(fmt)) {
15658  m_os << m_indent;
15659  m_indent += " ";
15660  }
15661  m_os << '<' << name;
15662  m_tags.push_back( name );
15663  m_tagIsOpen = true;
15664  applyFormatting(fmt);
15665  return *this;
15666  }
15667 
15668  XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
15669  ScopedElement scoped( this, fmt );
15670  startElement( name, fmt );
15671  return scoped;
15672  }
15673 
15674  XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
15675  m_indent = m_indent.substr(0, m_indent.size() - 2);
15676 
15677  if( m_tagIsOpen ) {
15678  m_os << "/>";
15679  m_tagIsOpen = false;
15680  } else {
15681  newlineIfNecessary();
15682  if (shouldIndent(fmt)) {
15683  m_os << m_indent;
15684  }
15685  m_os << "</" << m_tags.back() << ">";
15686  }
15687  m_os << std::flush;
15688  applyFormatting(fmt);
15689  m_tags.pop_back();
15690  return *this;
15691  }
15692 
15693  XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
15694  if( !name.empty() && !attribute.empty() )
15695  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
15696  return *this;
15697  }
15698 
15699  XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
15700  m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
15701  return *this;
15702  }
15703 
15704  XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
15705  if( !text.empty() ){
15706  bool tagWasOpen = m_tagIsOpen;
15707  ensureTagClosed();
15708  if (tagWasOpen && shouldIndent(fmt)) {
15709  m_os << m_indent;
15710  }
15711  m_os << XmlEncode( text );
15712  applyFormatting(fmt);
15713  }
15714  return *this;
15715  }
15716 
15717  XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
15718  ensureTagClosed();
15719  if (shouldIndent(fmt)) {
15720  m_os << m_indent;
15721  }
15722  m_os << "<!--" << text << "-->";
15723  applyFormatting(fmt);
15724  return *this;
15725  }
15726 
15727  void XmlWriter::writeStylesheetRef( std::string const& url ) {
15728  m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
15729  }
15730 
15731  XmlWriter& XmlWriter::writeBlankLine() {
15732  ensureTagClosed();
15733  m_os << '\n';
15734  return *this;
15735  }
15736 
15737  void XmlWriter::ensureTagClosed() {
15738  if( m_tagIsOpen ) {
15739  m_os << '>' << std::flush;
15740  newlineIfNecessary();
15741  m_tagIsOpen = false;
15742  }
15743  }
15744 
15745  void XmlWriter::applyFormatting(XmlFormatting fmt) {
15746  m_needsNewline = shouldNewline(fmt);
15747  }
15748 
15749  void XmlWriter::writeDeclaration() {
15750  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
15751  }
15752 
15753  void XmlWriter::newlineIfNecessary() {
15754  if( m_needsNewline ) {
15755  m_os << std::endl;
15756  m_needsNewline = false;
15757  }
15758  }
15759 }
15760 // end catch_xmlwriter.cpp
15761 // start catch_reporter_bases.cpp
15762 
15763 #include <cstring>
15764 #include <cfloat>
15765 #include <cstdio>
15766 #include <cassert>
15767 #include <memory>
15768 
15769 namespace Catch {
15770  void prepareExpandedExpression(AssertionResult& result) {
15771  result.getExpandedExpression();
15772  }
15773 
15774  // Because formatting using c++ streams is stateful, drop down to C is required
15775  // Alternatively we could use stringstream, but its performance is... not good.
15776  std::string getFormattedDuration( double duration ) {
15777  // Max exponent + 1 is required to represent the whole part
15778  // + 1 for decimal point
15779  // + 3 for the 3 decimal places
15780  // + 1 for null terminator
15781  const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
15782  char buffer[maxDoubleSize];
15783 
15784  // Save previous errno, to prevent sprintf from overwriting it
15785  ErrnoGuard guard;
15786 #ifdef _MSC_VER
15787  sprintf_s(buffer, "%.3f", duration);
15788 #else
15789  std::sprintf(buffer, "%.3f", duration);
15790 #endif
15791  return std::string(buffer);
15792  }
15793 
15794  bool shouldShowDuration( IConfig const& config, double duration ) {
15795  if ( config.showDurations() == ShowDurations::Always ) {
15796  return true;
15797  }
15798  if ( config.showDurations() == ShowDurations::Never ) {
15799  return false;
15800  }
15801  const double min = config.minDuration();
15802  return min >= 0 && duration >= min;
15803  }
15804 
15805  std::string serializeFilters( std::vector<std::string> const& container ) {
15806  ReusableStringStream oss;
15807  bool first = true;
15808  for (auto&& filter : container)
15809  {
15810  if (!first)
15811  oss << ' ';
15812  else
15813  first = false;
15814 
15815  oss << filter;
15816  }
15817  return oss.str();
15818  }
15819 
15820  TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
15821  :StreamingReporterBase(_config) {}
15822 
15823  std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
15824  return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
15825  }
15826 
15827  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
15828 
15829  bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
15830  return false;
15831  }
15832 
15833 } // end namespace Catch
15834 // end catch_reporter_bases.cpp
15835 // start catch_reporter_compact.cpp
15836 
15837 namespace {
15838 
15839 #ifdef CATCH_PLATFORM_MAC
15840  const char* failedString() { return "FAILED"; }
15841  const char* passedString() { return "PASSED"; }
15842 #else
15843  const char* failedString() { return "failed"; }
15844  const char* passedString() { return "passed"; }
15845 #endif
15846 
15847  // Colour::LightGrey
15848  Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
15849 
15850  std::string bothOrAll( std::size_t count ) {
15851  return count == 1 ? std::string() :
15852  count == 2 ? "both " : "all " ;
15853  }
15854 
15855 } // anon namespace
15856 
15857 namespace Catch {
15858 namespace {
15859 // Colour, message variants:
15860 // - white: No tests ran.
15861 // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
15862 // - white: Passed [both/all] N test cases (no assertions).
15863 // - red: Failed N tests cases, failed M assertions.
15864 // - green: Passed [both/all] N tests cases with M assertions.
15865 void printTotals(std::ostream& out, const Totals& totals) {
15866  if (totals.testCases.total() == 0) {
15867  out << "No tests ran.";
15868  } else if (totals.testCases.failed == totals.testCases.total()) {
15869  Colour colour(Colour::ResultError);
15870  const std::string qualify_assertions_failed =
15871  totals.assertions.failed == totals.assertions.total() ?
15872  bothOrAll(totals.assertions.failed) : std::string();
15873  out <<
15874  "Failed " << bothOrAll(totals.testCases.failed)
15875  << pluralise(totals.testCases.failed, "test case") << ", "
15876  "failed " << qualify_assertions_failed <<
15877  pluralise(totals.assertions.failed, "assertion") << '.';
15878  } else if (totals.assertions.total() == 0) {
15879  out <<
15880  "Passed " << bothOrAll(totals.testCases.total())
15881  << pluralise(totals.testCases.total(), "test case")
15882  << " (no assertions).";
15883  } else if (totals.assertions.failed) {
15884  Colour colour(Colour::ResultError);
15885  out <<
15886  "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
15887  "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
15888  } else {
15889  Colour colour(Colour::ResultSuccess);
15890  out <<
15891  "Passed " << bothOrAll(totals.testCases.passed)
15892  << pluralise(totals.testCases.passed, "test case") <<
15893  " with " << pluralise(totals.assertions.passed, "assertion") << '.';
15894  }
15895 }
15896 
15897 // Implementation of CompactReporter formatting
15898 class AssertionPrinter {
15899 public:
15900  AssertionPrinter& operator= (AssertionPrinter const&) = delete;
15901  AssertionPrinter(AssertionPrinter const&) = delete;
15902  AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15903  : stream(_stream)
15904  , result(_stats.assertionResult)
15905  , messages(_stats.infoMessages)
15906  , itMessage(_stats.infoMessages.begin())
15907  , printInfoMessages(_printInfoMessages) {}
15908 
15909  void print() {
15910  printSourceInfo();
15911 
15912  itMessage = messages.begin();
15913 
15914  switch (result.getResultType()) {
15915  case ResultWas::Ok:
15916  printResultType(Colour::ResultSuccess, passedString());
15917  printOriginalExpression();
15918  printReconstructedExpression();
15919  if (!result.hasExpression())
15920  printRemainingMessages(Colour::None);
15921  else
15922  printRemainingMessages();
15923  break;
15924  case ResultWas::ExpressionFailed:
15925  if (result.isOk())
15926  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
15927  else
15928  printResultType(Colour::Error, failedString());
15929  printOriginalExpression();
15930  printReconstructedExpression();
15931  printRemainingMessages();
15932  break;
15933  case ResultWas::ThrewException:
15934  printResultType(Colour::Error, failedString());
15935  printIssue("unexpected exception with message:");
15936  printMessage();
15937  printExpressionWas();
15938  printRemainingMessages();
15939  break;
15940  case ResultWas::FatalErrorCondition:
15941  printResultType(Colour::Error, failedString());
15942  printIssue("fatal error condition with message:");
15943  printMessage();
15944  printExpressionWas();
15945  printRemainingMessages();
15946  break;
15947  case ResultWas::DidntThrowException:
15948  printResultType(Colour::Error, failedString());
15949  printIssue("expected exception, got none");
15950  printExpressionWas();
15951  printRemainingMessages();
15952  break;
15953  case ResultWas::Info:
15954  printResultType(Colour::None, "info");
15955  printMessage();
15956  printRemainingMessages();
15957  break;
15958  case ResultWas::Warning:
15959  printResultType(Colour::None, "warning");
15960  printMessage();
15961  printRemainingMessages();
15962  break;
15963  case ResultWas::ExplicitFailure:
15964  printResultType(Colour::Error, failedString());
15965  printIssue("explicitly");
15966  printRemainingMessages(Colour::None);
15967  break;
15968  // These cases are here to prevent compiler warnings
15969  case ResultWas::Unknown:
15970  case ResultWas::FailureBit:
15971  case ResultWas::Exception:
15972  printResultType(Colour::Error, "** internal error **");
15973  break;
15974  }
15975  }
15976 
15977 private:
15978  void printSourceInfo() const {
15979  Colour colourGuard(Colour::FileName);
15980  stream << result.getSourceInfo() << ':';
15981  }
15982 
15983  void printResultType(Colour::Code colour, std::string const& passOrFail) const {
15984  if (!passOrFail.empty()) {
15985  {
15986  Colour colourGuard(colour);
15987  stream << ' ' << passOrFail;
15988  }
15989  stream << ':';
15990  }
15991  }
15992 
15993  void printIssue(std::string const& issue) const {
15994  stream << ' ' << issue;
15995  }
15996 
15997  void printExpressionWas() {
15998  if (result.hasExpression()) {
15999  stream << ';';
16000  {
16001  Colour colour(dimColour());
16002  stream << " expression was:";
16003  }
16004  printOriginalExpression();
16005  }
16006  }
16007 
16008  void printOriginalExpression() const {
16009  if (result.hasExpression()) {
16010  stream << ' ' << result.getExpression();
16011  }
16012  }
16013 
16014  void printReconstructedExpression() const {
16015  if (result.hasExpandedExpression()) {
16016  {
16017  Colour colour(dimColour());
16018  stream << " for: ";
16019  }
16020  stream << result.getExpandedExpression();
16021  }
16022  }
16023 
16024  void printMessage() {
16025  if (itMessage != messages.end()) {
16026  stream << " '" << itMessage->message << '\'';
16027  ++itMessage;
16028  }
16029  }
16030 
16031  void printRemainingMessages(Colour::Code colour = dimColour()) {
16032  if (itMessage == messages.end())
16033  return;
16034 
16035  const auto itEnd = messages.cend();
16036  const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
16037 
16038  {
16039  Colour colourGuard(colour);
16040  stream << " with " << pluralise(N, "message") << ':';
16041  }
16042 
16043  while (itMessage != itEnd) {
16044  // If this assertion is a warning ignore any INFO messages
16045  if (printInfoMessages || itMessage->type != ResultWas::Info) {
16046  printMessage();
16047  if (itMessage != itEnd) {
16048  Colour colourGuard(dimColour());
16049  stream << " and";
16050  }
16051  continue;
16052  }
16053  ++itMessage;
16054  }
16055  }
16056 
16057 private:
16058  std::ostream& stream;
16059  AssertionResult const& result;
16060  std::vector<MessageInfo> messages;
16061  std::vector<MessageInfo>::const_iterator itMessage;
16062  bool printInfoMessages;
16063 };
16064 
16065 } // anon namespace
16066 
16067  std::string CompactReporter::getDescription() {
16068  return "Reports test results on a single line, suitable for IDEs";
16069  }
16070 
16071  void CompactReporter::noMatchingTestCases( std::string const& spec ) {
16072  stream << "No test cases matched '" << spec << '\'' << std::endl;
16073  }
16074 
16075  void CompactReporter::assertionStarting( AssertionInfo const& ) {}
16076 
16077  bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
16078  AssertionResult const& result = _assertionStats.assertionResult;
16079 
16080  bool printInfoMessages = true;
16081 
16082  // Drop out if result was successful and we're not printing those
16083  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
16084  if( result.getResultType() != ResultWas::Warning )
16085  return false;
16086  printInfoMessages = false;
16087  }
16088 
16089  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
16090  printer.print();
16091 
16092  stream << std::endl;
16093  return true;
16094  }
16095 
16096  void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
16097  double dur = _sectionStats.durationInSeconds;
16098  if ( shouldShowDuration( *m_config, dur ) ) {
16099  stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16100  }
16101  }
16102 
16103  void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
16104  printTotals( stream, _testRunStats.totals );
16105  stream << '\n' << std::endl;
16106  StreamingReporterBase::testRunEnded( _testRunStats );
16107  }
16108 
16109  CompactReporter::~CompactReporter() {}
16110 
16111  CATCH_REGISTER_REPORTER( "compact", CompactReporter )
16112 
16113 } // end namespace Catch
16114 // end catch_reporter_compact.cpp
16115 // start catch_reporter_console.cpp
16116 
16117 #include <cfloat>
16118 #include <cstdio>
16119 
16120 #if defined(_MSC_VER)
16121 #pragma warning(push)
16122 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
16123  // Note that 4062 (not all labels are handled and default is missing) is enabled
16124 #endif
16125 
16126 #if defined(__clang__)
16127 # pragma clang diagnostic push
16128 // For simplicity, benchmarking-only helpers are always enabled
16129 # pragma clang diagnostic ignored "-Wunused-function"
16130 #endif
16131 
16132 namespace Catch {
16133 
16134 namespace {
16135 
16136 // Formatter impl for ConsoleReporter
16137 class ConsoleAssertionPrinter {
16138 public:
16139  ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
16140  ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
16141  ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
16142  : stream(_stream),
16143  stats(_stats),
16144  result(_stats.assertionResult),
16145  colour(Colour::None),
16146  message(result.getMessage()),
16147  messages(_stats.infoMessages),
16148  printInfoMessages(_printInfoMessages) {
16149  switch (result.getResultType()) {
16150  case ResultWas::Ok:
16151  colour = Colour::Success;
16152  passOrFail = "PASSED";
16153  //if( result.hasMessage() )
16154  if (_stats.infoMessages.size() == 1)
16155  messageLabel = "with message";
16156  if (_stats.infoMessages.size() > 1)
16157  messageLabel = "with messages";
16158  break;
16160  if (result.isOk()) {
16161  colour = Colour::Success;
16162  passOrFail = "FAILED - but was ok";
16163  } else {
16164  colour = Colour::Error;
16165  passOrFail = "FAILED";
16166  }
16167  if (_stats.infoMessages.size() == 1)
16168  messageLabel = "with message";
16169  if (_stats.infoMessages.size() > 1)
16170  messageLabel = "with messages";
16171  break;
16173  colour = Colour::Error;
16174  passOrFail = "FAILED";
16175  messageLabel = "due to unexpected exception with ";
16176  if (_stats.infoMessages.size() == 1)
16177  messageLabel += "message";
16178  if (_stats.infoMessages.size() > 1)
16179  messageLabel += "messages";
16180  break;
16182  colour = Colour::Error;
16183  passOrFail = "FAILED";
16184  messageLabel = "due to a fatal error condition";
16185  break;
16187  colour = Colour::Error;
16188  passOrFail = "FAILED";
16189  messageLabel = "because no exception was thrown where one was expected";
16190  break;
16191  case ResultWas::Info:
16192  messageLabel = "info";
16193  break;
16194  case ResultWas::Warning:
16195  messageLabel = "warning";
16196  break;
16198  passOrFail = "FAILED";
16199  colour = Colour::Error;
16200  if (_stats.infoMessages.size() == 1)
16201  messageLabel = "explicitly with message";
16202  if (_stats.infoMessages.size() > 1)
16203  messageLabel = "explicitly with messages";
16204  break;
16205  // These cases are here to prevent compiler warnings
16206  case ResultWas::Unknown:
16207  case ResultWas::FailureBit:
16208  case ResultWas::Exception:
16209  passOrFail = "** internal error **";
16210  colour = Colour::Error;
16211  break;
16212  }
16213  }
16214 
16215  void print() const {
16216  printSourceInfo();
16217  if (stats.totals.assertions.total() > 0) {
16218  printResultType();
16219  printOriginalExpression();
16220  printReconstructedExpression();
16221  } else {
16222  stream << '\n';
16223  }
16224  printMessage();
16225  }
16226 
16227 private:
16228  void printResultType() const {
16229  if (!passOrFail.empty()) {
16230  Colour colourGuard(colour);
16231  stream << passOrFail << ":\n";
16232  }
16233  }
16234  void printOriginalExpression() const {
16235  if (result.hasExpression()) {
16236  Colour colourGuard(Colour::OriginalExpression);
16237  stream << " ";
16238  stream << result.getExpressionInMacro();
16239  stream << '\n';
16240  }
16241  }
16242  void printReconstructedExpression() const {
16243  if (result.hasExpandedExpression()) {
16244  stream << "with expansion:\n";
16245  Colour colourGuard(Colour::ReconstructedExpression);
16246  stream << Column(result.getExpandedExpression()).indent(2) << '\n';
16247  }
16248  }
16249  void printMessage() const {
16250  if (!messageLabel.empty())
16251  stream << messageLabel << ':' << '\n';
16252  for (auto const& msg : messages) {
16253  // If this assertion is a warning ignore any INFO messages
16254  if (printInfoMessages || msg.type != ResultWas::Info)
16255  stream << Column(msg.message).indent(2) << '\n';
16256  }
16257  }
16258  void printSourceInfo() const {
16259  Colour colourGuard(Colour::FileName);
16260  stream << result.getSourceInfo() << ": ";
16261  }
16262 
16263  std::ostream& stream;
16264  AssertionStats const& stats;
16265  AssertionResult const& result;
16266  Colour::Code colour;
16267  std::string passOrFail;
16268  std::string messageLabel;
16270  std::vector<MessageInfo> messages;
16271  bool printInfoMessages;
16272 };
16273 
16274 std::size_t makeRatio(std::size_t number, std::size_t total) {
16275  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
16276  return (ratio == 0 && number > 0) ? 1 : ratio;
16277 }
16278 
16279 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
16280  if (i > j && i > k)
16281  return i;
16282  else if (j > k)
16283  return j;
16284  else
16285  return k;
16286 }
16287 
16288 struct ColumnInfo {
16289  enum Justification { Left, Right };
16290  std::string name;
16291  int width;
16292  Justification justification;
16293 };
16294 struct ColumnBreak {};
16295 struct RowBreak {};
16296 
16297 class Duration {
16298  enum class Unit {
16299  Auto,
16300  Nanoseconds,
16301  Microseconds,
16302  Milliseconds,
16303  Seconds,
16304  Minutes
16305  };
16306  static const uint64_t s_nanosecondsInAMicrosecond = 1000;
16307  static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
16308  static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
16309  static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
16310 
16311  double m_inNanoseconds;
16312  Unit m_units;
16313 
16314 public:
16315  explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
16316  : m_inNanoseconds(inNanoseconds),
16317  m_units(units) {
16318  if (m_units == Unit::Auto) {
16319  if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
16320  m_units = Unit::Nanoseconds;
16321  else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
16322  m_units = Unit::Microseconds;
16323  else if (m_inNanoseconds < s_nanosecondsInASecond)
16324  m_units = Unit::Milliseconds;
16325  else if (m_inNanoseconds < s_nanosecondsInAMinute)
16326  m_units = Unit::Seconds;
16327  else
16328  m_units = Unit::Minutes;
16329  }
16330 
16331  }
16332 
16333  auto value() const -> double {
16334  switch (m_units) {
16335  case Unit::Microseconds:
16336  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
16337  case Unit::Milliseconds:
16338  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
16339  case Unit::Seconds:
16340  return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
16341  case Unit::Minutes:
16342  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
16343  default:
16344  return m_inNanoseconds;
16345  }
16346  }
16347  auto unitsAsString() const -> std::string {
16348  switch (m_units) {
16349  case Unit::Nanoseconds:
16350  return "ns";
16351  case Unit::Microseconds:
16352  return "us";
16353  case Unit::Milliseconds:
16354  return "ms";
16355  case Unit::Seconds:
16356  return "s";
16357  case Unit::Minutes:
16358  return "m";
16359  default:
16360  return "** internal error **";
16361  }
16362 
16363  }
16364  friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
16365  return os << duration.value() << ' ' << duration.unitsAsString();
16366  }
16367 };
16368 } // end anon namespace
16369 
16370 class TablePrinter {
16371  std::ostream& m_os;
16372  std::vector<ColumnInfo> m_columnInfos;
16373  std::ostringstream m_oss;
16374  int m_currentColumn = -1;
16375  bool m_isOpen = false;
16376 
16377 public:
16378  TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
16379  : m_os( os ),
16380  m_columnInfos( std::move( columnInfos ) ) {}
16381 
16382  auto columnInfos() const -> std::vector<ColumnInfo> const& {
16383  return m_columnInfos;
16384  }
16385 
16386  void open() {
16387  if (!m_isOpen) {
16388  m_isOpen = true;
16389  *this << RowBreak();
16390 
16391  Columns headerCols;
16392  Spacer spacer(2);
16393  for (auto const& info : m_columnInfos) {
16394  headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
16395  headerCols += spacer;
16396  }
16397  m_os << headerCols << '\n';
16398 
16399  m_os << Catch::getLineOfChars<'-'>() << '\n';
16400  }
16401  }
16402  void close() {
16403  if (m_isOpen) {
16404  *this << RowBreak();
16405  m_os << std::endl;
16406  m_isOpen = false;
16407  }
16408  }
16409 
16410  template<typename T>
16411  friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
16412  tp.m_oss << value;
16413  return tp;
16414  }
16415 
16416  friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
16417  auto colStr = tp.m_oss.str();
16418  const auto strSize = colStr.size();
16419  tp.m_oss.str("");
16420  tp.open();
16421  if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
16422  tp.m_currentColumn = -1;
16423  tp.m_os << '\n';
16424  }
16425  tp.m_currentColumn++;
16426 
16427  auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
16428  auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
16429  ? std::string(colInfo.width - (strSize + 1), ' ')
16430  : std::string();
16431  if (colInfo.justification == ColumnInfo::Left)
16432  tp.m_os << colStr << padding << ' ';
16433  else
16434  tp.m_os << padding << colStr << ' ';
16435  return tp;
16436  }
16437 
16438  friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
16439  if (tp.m_currentColumn > 0) {
16440  tp.m_os << '\n';
16441  tp.m_currentColumn = -1;
16442  }
16443  return tp;
16444  }
16445 };
16446 
16447 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
16448  : StreamingReporterBase(config),
16449  m_tablePrinter(new TablePrinter(config.stream(),
16450  [&config]() -> std::vector<ColumnInfo> {
16451  if (config.fullConfig()->benchmarkNoAnalysis())
16452  {
16453  return{
16454  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16455  { " samples", 14, ColumnInfo::Right },
16456  { " iterations", 14, ColumnInfo::Right },
16457  { " mean", 14, ColumnInfo::Right }
16458  };
16459  }
16460  else
16461  {
16462  return{
16463  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16464  { "samples mean std dev", 14, ColumnInfo::Right },
16465  { "iterations low mean low std dev", 14, ColumnInfo::Right },
16466  { "estimated high mean high std dev", 14, ColumnInfo::Right }
16467  };
16468  }
16469  }())) {}
16470 ConsoleReporter::~ConsoleReporter() = default;
16471 
16472 std::string ConsoleReporter::getDescription() {
16473  return "Reports test results as plain lines of text";
16474 }
16475 
16476 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
16477  stream << "No test cases matched '" << spec << '\'' << std::endl;
16478 }
16479 
16480 void ConsoleReporter::reportInvalidArguments(std::string const&arg){
16481  stream << "Invalid Filter: " << arg << std::endl;
16482 }
16483 
16484 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
16485 
16486 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
16487  AssertionResult const& result = _assertionStats.assertionResult;
16488 
16489  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16490 
16491  // Drop out if result was successful but we're not printing them.
16492  if (!includeResults && result.getResultType() != ResultWas::Warning)
16493  return false;
16494 
16495  lazyPrint();
16496 
16497  ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
16498  printer.print();
16499  stream << std::endl;
16500  return true;
16501 }
16502 
16503 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
16504  m_tablePrinter->close();
16505  m_headerPrinted = false;
16506  StreamingReporterBase::sectionStarting(_sectionInfo);
16507 }
16508 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
16509  m_tablePrinter->close();
16510  if (_sectionStats.missingAssertions) {
16511  lazyPrint();
16512  Colour colour(Colour::ResultError);
16513  if (m_sectionStack.size() > 1)
16514  stream << "\nNo assertions in section";
16515  else
16516  stream << "\nNo assertions in test case";
16517  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
16518  }
16519  double dur = _sectionStats.durationInSeconds;
16520  if (shouldShowDuration(*m_config, dur)) {
16521  stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16522  }
16523  if (m_headerPrinted) {
16524  m_headerPrinted = false;
16525  }
16526  StreamingReporterBase::sectionEnded(_sectionStats);
16527 }
16528 
16529 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16530 void ConsoleReporter::benchmarkPreparing(std::string const& name) {
16531  lazyPrintWithoutClosingBenchmarkTable();
16532 
16533  auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
16534 
16535  bool firstLine = true;
16536  for (auto line : nameCol) {
16537  if (!firstLine)
16538  (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
16539  else
16540  firstLine = false;
16541 
16542  (*m_tablePrinter) << line << ColumnBreak();
16543  }
16544 }
16545 
16546 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
16547  (*m_tablePrinter) << info.samples << ColumnBreak()
16548  << info.iterations << ColumnBreak();
16549  if (!m_config->benchmarkNoAnalysis())
16550  (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
16551 }
16552 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
16553  if (m_config->benchmarkNoAnalysis())
16554  {
16555  (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
16556  }
16557  else
16558  {
16559  (*m_tablePrinter) << ColumnBreak()
16560  << Duration(stats.mean.point.count()) << ColumnBreak()
16561  << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
16562  << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
16563  << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
16564  << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
16565  << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
16566  }
16567 }
16568 
16569 void ConsoleReporter::benchmarkFailed(std::string const& error) {
16570  Colour colour(Colour::Red);
16571  (*m_tablePrinter)
16572  << "Benchmark failed (" << error << ')'
16573  << ColumnBreak() << RowBreak();
16574 }
16575 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16576 
16577 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
16578  m_tablePrinter->close();
16579  StreamingReporterBase::testCaseEnded(_testCaseStats);
16580  m_headerPrinted = false;
16581 }
16582 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
16583  if (currentGroupInfo.used) {
16584  printSummaryDivider();
16585  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
16586  printTotals(_testGroupStats.totals);
16587  stream << '\n' << std::endl;
16588  }
16589  StreamingReporterBase::testGroupEnded(_testGroupStats);
16590 }
16591 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
16592  printTotalsDivider(_testRunStats.totals);
16593  printTotals(_testRunStats.totals);
16594  stream << std::endl;
16595  StreamingReporterBase::testRunEnded(_testRunStats);
16596 }
16597 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
16598  StreamingReporterBase::testRunStarting(_testInfo);
16599  printTestFilters();
16600 }
16601 
16602 void ConsoleReporter::lazyPrint() {
16603 
16604  m_tablePrinter->close();
16605  lazyPrintWithoutClosingBenchmarkTable();
16606 }
16607 
16608 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
16609 
16610  if (!currentTestRunInfo.used)
16611  lazyPrintRunInfo();
16612  if (!currentGroupInfo.used)
16613  lazyPrintGroupInfo();
16614 
16615  if (!m_headerPrinted) {
16616  printTestCaseAndSectionHeader();
16617  m_headerPrinted = true;
16618  }
16619 }
16620 void ConsoleReporter::lazyPrintRunInfo() {
16622  Colour colour(Colour::SecondaryText);
16623  stream << currentTestRunInfo->name
16624  << " is a Catch v" << libraryVersion() << " host application.\n"
16625  << "Run with -? for options\n\n";
16626 
16627  if (m_config->rngSeed() != 0)
16628  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
16629 
16630  currentTestRunInfo.used = true;
16631 }
16632 void ConsoleReporter::lazyPrintGroupInfo() {
16633  if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
16634  printClosedHeader("Group: " + currentGroupInfo->name);
16635  currentGroupInfo.used = true;
16636  }
16637 }
16638 void ConsoleReporter::printTestCaseAndSectionHeader() {
16639  assert(!m_sectionStack.empty());
16640  printOpenHeader(currentTestCaseInfo->name);
16641 
16642  if (m_sectionStack.size() > 1) {
16643  Colour colourGuard(Colour::Headers);
16644 
16645  auto
16646  it = m_sectionStack.begin() + 1, // Skip first section (test case)
16647  itEnd = m_sectionStack.end();
16648  for (; it != itEnd; ++it)
16649  printHeaderString(it->name, 2);
16650  }
16651 
16652  SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
16653 
16654  stream << getLineOfChars<'-'>() << '\n';
16655  Colour colourGuard(Colour::FileName);
16656  stream << lineInfo << '\n';
16657  stream << getLineOfChars<'.'>() << '\n' << std::endl;
16658 }
16659 
16660 void ConsoleReporter::printClosedHeader(std::string const& _name) {
16661  printOpenHeader(_name);
16662  stream << getLineOfChars<'.'>() << '\n';
16663 }
16664 void ConsoleReporter::printOpenHeader(std::string const& _name) {
16665  stream << getLineOfChars<'-'>() << '\n';
16666  {
16667  Colour colourGuard(Colour::Headers);
16668  printHeaderString(_name);
16669  }
16670 }
16671 
16672 // if string has a : in first line will set indent to follow it on
16673 // subsequent lines
16674 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
16675  std::size_t i = _string.find(": ");
16676  if (i != std::string::npos)
16677  i += 2;
16678  else
16679  i = 0;
16680  stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
16681 }
16682 
16683 struct SummaryColumn {
16684 
16685  SummaryColumn( std::string _label, Colour::Code _colour )
16686  : label( std::move( _label ) ),
16687  colour( _colour ) {}
16688  SummaryColumn addRow( std::size_t count ) {
16689  ReusableStringStream rss;
16690  rss << count;
16691  std::string row = rss.str();
16692  for (auto& oldRow : rows) {
16693  while (oldRow.size() < row.size())
16694  oldRow = ' ' + oldRow;
16695  while (oldRow.size() > row.size())
16696  row = ' ' + row;
16697  }
16698  rows.push_back(row);
16699  return *this;
16700  }
16701 
16703  Colour::Code colour;
16704  std::vector<std::string> rows;
16705 
16706 };
16707 
16708 void ConsoleReporter::printTotals( Totals const& totals ) {
16709  if (totals.testCases.total() == 0) {
16710  stream << Colour(Colour::Warning) << "No tests ran\n";
16711  } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
16712  stream << Colour(Colour::ResultSuccess) << "All tests passed";
16713  stream << " ("
16714  << pluralise(totals.assertions.passed, "assertion") << " in "
16715  << pluralise(totals.testCases.passed, "test case") << ')'
16716  << '\n';
16717  } else {
16718 
16719  std::vector<SummaryColumn> columns;
16720  columns.push_back(SummaryColumn("", Colour::None)
16721  .addRow(totals.testCases.total())
16722  .addRow(totals.assertions.total()));
16723  columns.push_back(SummaryColumn("passed", Colour::Success)
16724  .addRow(totals.testCases.passed)
16725  .addRow(totals.assertions.passed));
16726  columns.push_back(SummaryColumn("failed", Colour::ResultError)
16727  .addRow(totals.testCases.failed)
16728  .addRow(totals.assertions.failed));
16729  columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
16730  .addRow(totals.testCases.failedButOk)
16731  .addRow(totals.assertions.failedButOk));
16732 
16733  printSummaryRow("test cases", columns, 0);
16734  printSummaryRow("assertions", columns, 1);
16735  }
16736 }
16737 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
16738  for (auto col : cols) {
16739  std::string value = col.rows[row];
16740  if (col.label.empty()) {
16741  stream << label << ": ";
16742  if (value != "0")
16743  stream << value;
16744  else
16745  stream << Colour(Colour::Warning) << "- none -";
16746  } else if (value != "0") {
16747  stream << Colour(Colour::LightGrey) << " | ";
16748  stream << Colour(col.colour)
16749  << value << ' ' << col.label;
16750  }
16751  }
16752  stream << '\n';
16753 }
16754 
16755 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
16756  if (totals.testCases.total() > 0) {
16757  std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
16758  std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
16759  std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
16760  while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
16761  findMax(failedRatio, failedButOkRatio, passedRatio)++;
16762  while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
16763  findMax(failedRatio, failedButOkRatio, passedRatio)--;
16764 
16765  stream << Colour(Colour::Error) << std::string(failedRatio, '=');
16766  stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
16767  if (totals.testCases.allPassed())
16768  stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
16769  else
16770  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
16771  } else {
16772  stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
16773  }
16774  stream << '\n';
16775 }
16776 void ConsoleReporter::printSummaryDivider() {
16777  stream << getLineOfChars<'-'>() << '\n';
16778 }
16779 
16780 void ConsoleReporter::printTestFilters() {
16781  if (m_config->testSpec().hasFilters()) {
16782  Colour guard(Colour::BrightYellow);
16783  stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
16784  }
16785 }
16786 
16787 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
16788 
16789 } // end namespace Catch
16790 
16791 #if defined(_MSC_VER)
16792 #pragma warning(pop)
16793 #endif
16794 
16795 #if defined(__clang__)
16796 # pragma clang diagnostic pop
16797 #endif
16798 // end catch_reporter_console.cpp
16799 // start catch_reporter_junit.cpp
16800 
16801 #include <cassert>
16802 #include <sstream>
16803 #include <ctime>
16804 #include <algorithm>
16805 #include <iomanip>
16806 
16807 namespace Catch {
16808 
16809  namespace {
16810  std::string getCurrentTimestamp() {
16811  // Beware, this is not reentrant because of backward compatibility issues
16812  // Also, UTC only, again because of backward compatibility (%z is C++11)
16813  time_t rawtime;
16814  std::time(&rawtime);
16815  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
16816 
16817 #ifdef _MSC_VER
16818  std::tm timeInfo = {};
16819  gmtime_s(&timeInfo, &rawtime);
16820 #else
16821  std::tm* timeInfo;
16822  timeInfo = std::gmtime(&rawtime);
16823 #endif
16824 
16825  char timeStamp[timeStampSize];
16826  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
16827 
16828 #ifdef _MSC_VER
16829  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
16830 #else
16831  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
16832 #endif
16833  return std::string(timeStamp, timeStampSize-1);
16834  }
16835 
16836  std::string fileNameTag(const std::vector<std::string> &tags) {
16837  auto it = std::find_if(begin(tags),
16838  end(tags),
16839  [] (std::string const& tag) {return tag.front() == '#'; });
16840  if (it != tags.end())
16841  return it->substr(1);
16842  return std::string();
16843  }
16844 
16845  // Formats the duration in seconds to 3 decimal places.
16846  // This is done because some genius defined Maven Surefire schema
16847  // in a way that only accepts 3 decimal places, and tools like
16848  // Jenkins use that schema for validation JUnit reporter output.
16849  std::string formatDuration( double seconds ) {
16850  ReusableStringStream rss;
16851  rss << std::fixed << std::setprecision( 3 ) << seconds;
16852  return rss.str();
16853  }
16854 
16855  } // anonymous namespace
16856 
16857  JunitReporter::JunitReporter( ReporterConfig const& _config )
16858  : CumulativeReporterBase( _config ),
16859  xml( _config.stream() )
16860  {
16861  m_reporterPrefs.shouldRedirectStdOut = true;
16862  m_reporterPrefs.shouldReportAllAssertions = true;
16863  }
16864 
16865  JunitReporter::~JunitReporter() {}
16866 
16867  std::string JunitReporter::getDescription() {
16868  return "Reports test results in an XML format that looks like Ant's junitreport target";
16869  }
16870 
16871  void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
16872 
16873  void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
16874  CumulativeReporterBase::testRunStarting( runInfo );
16875  xml.startElement( "testsuites" );
16876  }
16877 
16878  void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16879  suiteTimer.start();
16880  stdOutForSuite.clear();
16881  stdErrForSuite.clear();
16882  unexpectedExceptions = 0;
16883  CumulativeReporterBase::testGroupStarting( groupInfo );
16884  }
16885 
16886  void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
16887  m_okToFail = testCaseInfo.okToFail();
16888  }
16889 
16890  bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
16891  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
16892  unexpectedExceptions++;
16893  return CumulativeReporterBase::assertionEnded( assertionStats );
16894  }
16895 
16896  void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
16897  stdOutForSuite += testCaseStats.stdOut;
16898  stdErrForSuite += testCaseStats.stdErr;
16899  CumulativeReporterBase::testCaseEnded( testCaseStats );
16900  }
16901 
16902  void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
16903  double suiteTime = suiteTimer.getElapsedSeconds();
16904  CumulativeReporterBase::testGroupEnded( testGroupStats );
16905  writeGroup( *m_testGroups.back(), suiteTime );
16906  }
16907 
16908  void JunitReporter::testRunEndedCumulative() {
16909  xml.endElement();
16910  }
16911 
16912  void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
16913  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
16914 
16915  TestGroupStats const& stats = groupNode.value;
16916  xml.writeAttribute( "name", stats.groupInfo.name );
16917  xml.writeAttribute( "errors", unexpectedExceptions );
16918  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
16919  xml.writeAttribute( "tests", stats.totals.assertions.total() );
16920  xml.writeAttribute( "hostname", "tbd" ); // !TBD
16921  if( m_config->showDurations() == ShowDurations::Never )
16922  xml.writeAttribute( "time", "" );
16923  else
16924  xml.writeAttribute( "time", formatDuration( suiteTime ) );
16925  xml.writeAttribute( "timestamp", getCurrentTimestamp() );
16926 
16927  // Write properties if there are any
16928  if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
16929  auto properties = xml.scopedElement("properties");
16930  if (m_config->hasTestFilters()) {
16931  xml.scopedElement("property")
16932  .writeAttribute("name", "filters")
16933  .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
16934  }
16935  if (m_config->rngSeed() != 0) {
16936  xml.scopedElement("property")
16937  .writeAttribute("name", "random-seed")
16938  .writeAttribute("value", m_config->rngSeed());
16939  }
16940  }
16941 
16942  // Write test cases
16943  for( auto const& child : groupNode.children )
16944  writeTestCase( *child );
16945 
16946  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
16947  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
16948  }
16949 
16950  void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
16951  TestCaseStats const& stats = testCaseNode.value;
16952 
16953  // All test cases have exactly one section - which represents the
16954  // test case itself. That section may have 0-n nested sections
16955  assert( testCaseNode.children.size() == 1 );
16956  SectionNode const& rootSection = *testCaseNode.children.front();
16957 
16958  std::string className = stats.testInfo.className;
16959 
16960  if( className.empty() ) {
16961  className = fileNameTag(stats.testInfo.tags);
16962  if ( className.empty() )
16963  className = "global";
16964  }
16965 
16966  if ( !m_config->name().empty() )
16967  className = m_config->name() + "." + className;
16968 
16969  writeSection( className, "", rootSection, stats.testInfo.okToFail() );
16970  }
16971 
16972  void JunitReporter::writeSection( std::string const& className,
16973  std::string const& rootName,
16974  SectionNode const& sectionNode,
16975  bool testOkToFail) {
16976  std::string name = trim( sectionNode.stats.sectionInfo.name );
16977  if( !rootName.empty() )
16978  name = rootName + '/' + name;
16979 
16980  if( !sectionNode.assertions.empty() ||
16981  !sectionNode.stdOut.empty() ||
16982  !sectionNode.stdErr.empty() ) {
16983  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
16984  if( className.empty() ) {
16985  xml.writeAttribute( "classname", name );
16986  xml.writeAttribute( "name", "root" );
16987  }
16988  else {
16989  xml.writeAttribute( "classname", className );
16990  xml.writeAttribute( "name", name );
16991  }
16992  xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) );
16993  // This is not ideal, but it should be enough to mimic gtest's
16994  // junit output.
16995  // Ideally the JUnit reporter would also handle `skipTest`
16996  // events and write those out appropriately.
16997  xml.writeAttribute( "status", "run" );
16998 
16999  if (sectionNode.stats.assertions.failedButOk) {
17000  xml.scopedElement("skipped")
17001  .writeAttribute("message", "TEST_CASE tagged with !mayfail");
17002  }
17003 
17004  writeAssertions( sectionNode );
17005 
17006  if( !sectionNode.stdOut.empty() )
17007  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
17008  if( !sectionNode.stdErr.empty() )
17009  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
17010  }
17011  for( auto const& childNode : sectionNode.childSections )
17012  if( className.empty() )
17013  writeSection( name, "", *childNode, testOkToFail );
17014  else
17015  writeSection( className, name, *childNode, testOkToFail );
17016  }
17017 
17018  void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
17019  for( auto const& assertion : sectionNode.assertions )
17020  writeAssertion( assertion );
17021  }
17022 
17023  void JunitReporter::writeAssertion( AssertionStats const& stats ) {
17024  AssertionResult const& result = stats.assertionResult;
17025  if( !result.isOk() ) {
17026  std::string elementName;
17027  switch( result.getResultType() ) {
17030  elementName = "error";
17031  break;
17035  elementName = "failure";
17036  break;
17037 
17038  // We should never see these here:
17039  case ResultWas::Info:
17040  case ResultWas::Warning:
17041  case ResultWas::Ok:
17042  case ResultWas::Unknown:
17043  case ResultWas::FailureBit:
17044  case ResultWas::Exception:
17045  elementName = "internalError";
17046  break;
17047  }
17048 
17049  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
17050 
17051  xml.writeAttribute( "message", result.getExpression() );
17052  xml.writeAttribute( "type", result.getTestMacroName() );
17053 
17054  ReusableStringStream rss;
17055  if (stats.totals.assertions.total() > 0) {
17056  rss << "FAILED" << ":\n";
17057  if (result.hasExpression()) {
17058  rss << " ";
17059  rss << result.getExpressionInMacro();
17060  rss << '\n';
17061  }
17062  if (result.hasExpandedExpression()) {
17063  rss << "with expansion:\n";
17064  rss << Column(result.getExpandedExpression()).indent(2) << '\n';
17065  }
17066  } else {
17067  rss << '\n';
17068  }
17069 
17070  if( !result.getMessage().empty() )
17071  rss << result.getMessage() << '\n';
17072  for( auto const& msg : stats.infoMessages )
17073  if( msg.type == ResultWas::Info )
17074  rss << msg.message << '\n';
17075 
17076  rss << "at " << result.getSourceInfo();
17077  xml.writeText( rss.str(), XmlFormatting::Newline );
17078  }
17079  }
17080 
17081  CATCH_REGISTER_REPORTER( "junit", JunitReporter )
17082 
17083 } // end namespace Catch
17084 // end catch_reporter_junit.cpp
17085 // start catch_reporter_listening.cpp
17086 
17087 #include <cassert>
17088 
17089 namespace Catch {
17090 
17091  ListeningReporter::ListeningReporter() {
17092  // We will assume that listeners will always want all assertions
17093  m_preferences.shouldReportAllAssertions = true;
17094  }
17095 
17096  void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
17097  m_listeners.push_back( std::move( listener ) );
17098  }
17099 
17100  void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
17101  assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
17102  m_reporter = std::move( reporter );
17103  m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
17104  }
17105 
17106  ReporterPreferences ListeningReporter::getPreferences() const {
17107  return m_preferences;
17108  }
17109 
17110  std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
17111  return std::set<Verbosity>{ };
17112  }
17113 
17114  void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
17115  for ( auto const& listener : m_listeners ) {
17116  listener->noMatchingTestCases( spec );
17117  }
17118  m_reporter->noMatchingTestCases( spec );
17119  }
17120 
17121  void ListeningReporter::reportInvalidArguments(std::string const&arg){
17122  for ( auto const& listener : m_listeners ) {
17123  listener->reportInvalidArguments( arg );
17124  }
17125  m_reporter->reportInvalidArguments( arg );
17126  }
17127 
17128 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17129  void ListeningReporter::benchmarkPreparing( std::string const& name ) {
17130  for (auto const& listener : m_listeners) {
17131  listener->benchmarkPreparing(name);
17132  }
17133  m_reporter->benchmarkPreparing(name);
17134  }
17135  void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
17136  for ( auto const& listener : m_listeners ) {
17137  listener->benchmarkStarting( benchmarkInfo );
17138  }
17139  m_reporter->benchmarkStarting( benchmarkInfo );
17140  }
17141  void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
17142  for ( auto const& listener : m_listeners ) {
17143  listener->benchmarkEnded( benchmarkStats );
17144  }
17145  m_reporter->benchmarkEnded( benchmarkStats );
17146  }
17147 
17148  void ListeningReporter::benchmarkFailed( std::string const& error ) {
17149  for (auto const& listener : m_listeners) {
17150  listener->benchmarkFailed(error);
17151  }
17152  m_reporter->benchmarkFailed(error);
17153  }
17154 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17155 
17156  void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
17157  for ( auto const& listener : m_listeners ) {
17158  listener->testRunStarting( testRunInfo );
17159  }
17160  m_reporter->testRunStarting( testRunInfo );
17161  }
17162 
17163  void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
17164  for ( auto const& listener : m_listeners ) {
17165  listener->testGroupStarting( groupInfo );
17166  }
17167  m_reporter->testGroupStarting( groupInfo );
17168  }
17169 
17170  void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
17171  for ( auto const& listener : m_listeners ) {
17172  listener->testCaseStarting( testInfo );
17173  }
17174  m_reporter->testCaseStarting( testInfo );
17175  }
17176 
17177  void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
17178  for ( auto const& listener : m_listeners ) {
17179  listener->sectionStarting( sectionInfo );
17180  }
17181  m_reporter->sectionStarting( sectionInfo );
17182  }
17183 
17184  void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
17185  for ( auto const& listener : m_listeners ) {
17186  listener->assertionStarting( assertionInfo );
17187  }
17188  m_reporter->assertionStarting( assertionInfo );
17189  }
17190 
17191  // The return value indicates if the messages buffer should be cleared:
17192  bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
17193  for( auto const& listener : m_listeners ) {
17194  static_cast<void>( listener->assertionEnded( assertionStats ) );
17195  }
17196  return m_reporter->assertionEnded( assertionStats );
17197  }
17198 
17199  void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
17200  for ( auto const& listener : m_listeners ) {
17201  listener->sectionEnded( sectionStats );
17202  }
17203  m_reporter->sectionEnded( sectionStats );
17204  }
17205 
17206  void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
17207  for ( auto const& listener : m_listeners ) {
17208  listener->testCaseEnded( testCaseStats );
17209  }
17210  m_reporter->testCaseEnded( testCaseStats );
17211  }
17212 
17213  void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17214  for ( auto const& listener : m_listeners ) {
17215  listener->testGroupEnded( testGroupStats );
17216  }
17217  m_reporter->testGroupEnded( testGroupStats );
17218  }
17219 
17220  void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
17221  for ( auto const& listener : m_listeners ) {
17222  listener->testRunEnded( testRunStats );
17223  }
17224  m_reporter->testRunEnded( testRunStats );
17225  }
17226 
17227  void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
17228  for ( auto const& listener : m_listeners ) {
17229  listener->skipTest( testInfo );
17230  }
17231  m_reporter->skipTest( testInfo );
17232  }
17233 
17234  bool ListeningReporter::isMulti() const {
17235  return true;
17236  }
17237 
17238 } // end namespace Catch
17239 // end catch_reporter_listening.cpp
17240 // start catch_reporter_xml.cpp
17241 
17242 #if defined(_MSC_VER)
17243 #pragma warning(push)
17244 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
17245  // Note that 4062 (not all labels are handled
17246  // and default is missing) is enabled
17247 #endif
17248 
17249 namespace Catch {
17250  XmlReporter::XmlReporter( ReporterConfig const& _config )
17251  : StreamingReporterBase( _config ),
17252  m_xml(_config.stream())
17253  {
17254  m_reporterPrefs.shouldRedirectStdOut = true;
17255  m_reporterPrefs.shouldReportAllAssertions = true;
17256  }
17257 
17258  XmlReporter::~XmlReporter() = default;
17259 
17260  std::string XmlReporter::getDescription() {
17261  return "Reports test results as an XML document";
17262  }
17263 
17264  std::string XmlReporter::getStylesheetRef() const {
17265  return std::string();
17266  }
17267 
17268  void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
17269  m_xml
17270  .writeAttribute( "filename", sourceInfo.file )
17271  .writeAttribute( "line", sourceInfo.line );
17272  }
17273 
17274  void XmlReporter::noMatchingTestCases( std::string const& s ) {
17275  StreamingReporterBase::noMatchingTestCases( s );
17276  }
17277 
17278  void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
17279  StreamingReporterBase::testRunStarting( testInfo );
17280  std::string stylesheetRef = getStylesheetRef();
17281  if( !stylesheetRef.empty() )
17282  m_xml.writeStylesheetRef( stylesheetRef );
17283  m_xml.startElement( "Catch" );
17284  if( !m_config->name().empty() )
17285  m_xml.writeAttribute( "name", m_config->name() );
17286  if (m_config->testSpec().hasFilters())
17287  m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
17288  if( m_config->rngSeed() != 0 )
17289  m_xml.scopedElement( "Randomness" )
17290  .writeAttribute( "seed", m_config->rngSeed() );
17291  }
17292 
17293  void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
17294  StreamingReporterBase::testGroupStarting( groupInfo );
17295  m_xml.startElement( "Group" )
17296  .writeAttribute( "name", groupInfo.name );
17297  }
17298 
17299  void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
17300  StreamingReporterBase::testCaseStarting(testInfo);
17301  m_xml.startElement( "TestCase" )
17302  .writeAttribute( "name", trim( testInfo.name ) )
17303  .writeAttribute( "description", testInfo.description )
17304  .writeAttribute( "tags", testInfo.tagsAsString() );
17305 
17306  writeSourceInfo( testInfo.lineInfo );
17307 
17308  if ( m_config->showDurations() == ShowDurations::Always )
17309  m_testCaseTimer.start();
17310  m_xml.ensureTagClosed();
17311  }
17312 
17313  void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
17314  StreamingReporterBase::sectionStarting( sectionInfo );
17315  if( m_sectionDepth++ > 0 ) {
17316  m_xml.startElement( "Section" )
17317  .writeAttribute( "name", trim( sectionInfo.name ) );
17318  writeSourceInfo( sectionInfo.lineInfo );
17319  m_xml.ensureTagClosed();
17320  }
17321  }
17322 
17323  void XmlReporter::assertionStarting( AssertionInfo const& ) { }
17324 
17325  bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
17326 
17327  AssertionResult const& result = assertionStats.assertionResult;
17328 
17329  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
17330 
17331  if( includeResults || result.getResultType() == ResultWas::Warning ) {
17332  // Print any info messages in <Info> tags.
17333  for( auto const& msg : assertionStats.infoMessages ) {
17334  if( msg.type == ResultWas::Info && includeResults ) {
17335  m_xml.scopedElement( "Info" )
17336  .writeText( msg.message );
17337  } else if ( msg.type == ResultWas::Warning ) {
17338  m_xml.scopedElement( "Warning" )
17339  .writeText( msg.message );
17340  }
17341  }
17342  }
17343 
17344  // Drop out if result was successful but we're not printing them.
17345  if( !includeResults && result.getResultType() != ResultWas::Warning )
17346  return true;
17347 
17348  // Print the expression if there is one.
17349  if( result.hasExpression() ) {
17350  m_xml.startElement( "Expression" )
17351  .writeAttribute( "success", result.succeeded() )
17352  .writeAttribute( "type", result.getTestMacroName() );
17353 
17354  writeSourceInfo( result.getSourceInfo() );
17355 
17356  m_xml.scopedElement( "Original" )
17357  .writeText( result.getExpression() );
17358  m_xml.scopedElement( "Expanded" )
17359  .writeText( result.getExpandedExpression() );
17360  }
17361 
17362  // And... Print a result applicable to each result type.
17363  switch( result.getResultType() ) {
17365  m_xml.startElement( "Exception" );
17366  writeSourceInfo( result.getSourceInfo() );
17367  m_xml.writeText( result.getMessage() );
17368  m_xml.endElement();
17369  break;
17371  m_xml.startElement( "FatalErrorCondition" );
17372  writeSourceInfo( result.getSourceInfo() );
17373  m_xml.writeText( result.getMessage() );
17374  m_xml.endElement();
17375  break;
17376  case ResultWas::Info:
17377  m_xml.scopedElement( "Info" )
17378  .writeText( result.getMessage() );
17379  break;
17380  case ResultWas::Warning:
17381  // Warning will already have been written
17382  break;
17384  m_xml.startElement( "Failure" );
17385  writeSourceInfo( result.getSourceInfo() );
17386  m_xml.writeText( result.getMessage() );
17387  m_xml.endElement();
17388  break;
17389  default:
17390  break;
17391  }
17392 
17393  if( result.hasExpression() )
17394  m_xml.endElement();
17395 
17396  return true;
17397  }
17398 
17399  void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
17400  StreamingReporterBase::sectionEnded( sectionStats );
17401  if( --m_sectionDepth > 0 ) {
17402  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
17403  e.writeAttribute( "successes", sectionStats.assertions.passed );
17404  e.writeAttribute( "failures", sectionStats.assertions.failed );
17405  e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
17406 
17407  if ( m_config->showDurations() == ShowDurations::Always )
17408  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
17409 
17410  m_xml.endElement();
17411  }
17412  }
17413 
17414  void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
17415  StreamingReporterBase::testCaseEnded( testCaseStats );
17416  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
17417  e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
17418 
17419  if ( m_config->showDurations() == ShowDurations::Always )
17420  e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
17421 
17422  if( !testCaseStats.stdOut.empty() )
17423  m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
17424  if( !testCaseStats.stdErr.empty() )
17425  m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
17426 
17427  m_xml.endElement();
17428  }
17429 
17430  void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17431  StreamingReporterBase::testGroupEnded( testGroupStats );
17432  // TODO: Check testGroupStats.aborting and act accordingly.
17433  m_xml.scopedElement( "OverallResults" )
17434  .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
17435  .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
17436  .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
17437  m_xml.scopedElement( "OverallResultsCases")
17438  .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
17439  .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
17440  .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
17441  m_xml.endElement();
17442  }
17443 
17444  void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
17445  StreamingReporterBase::testRunEnded( testRunStats );
17446  m_xml.scopedElement( "OverallResults" )
17447  .writeAttribute( "successes", testRunStats.totals.assertions.passed )
17448  .writeAttribute( "failures", testRunStats.totals.assertions.failed )
17449  .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
17450  m_xml.scopedElement( "OverallResultsCases")
17451  .writeAttribute( "successes", testRunStats.totals.testCases.passed )
17452  .writeAttribute( "failures", testRunStats.totals.testCases.failed )
17453  .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
17454  m_xml.endElement();
17455  }
17456 
17457 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17458  void XmlReporter::benchmarkPreparing(std::string const& name) {
17459  m_xml.startElement("BenchmarkResults")
17460  .writeAttribute("name", name);
17461  }
17462 
17463  void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
17464  m_xml.writeAttribute("samples", info.samples)
17465  .writeAttribute("resamples", info.resamples)
17466  .writeAttribute("iterations", info.iterations)
17467  .writeAttribute("clockResolution", info.clockResolution)
17468  .writeAttribute("estimatedDuration", info.estimatedDuration)
17469  .writeComment("All values in nano seconds");
17470  }
17471 
17472  void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
17473  m_xml.startElement("mean")
17474  .writeAttribute("value", benchmarkStats.mean.point.count())
17475  .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
17476  .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
17477  .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
17478  m_xml.endElement();
17479  m_xml.startElement("standardDeviation")
17480  .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
17481  .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
17482  .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
17483  .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
17484  m_xml.endElement();
17485  m_xml.startElement("outliers")
17486  .writeAttribute("variance", benchmarkStats.outlierVariance)
17487  .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
17488  .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
17489  .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
17490  .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
17491  m_xml.endElement();
17492  m_xml.endElement();
17493  }
17494 
17495  void XmlReporter::benchmarkFailed(std::string const &error) {
17496  m_xml.scopedElement("failed").
17497  writeAttribute("message", error);
17498  m_xml.endElement();
17499  }
17500 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17501 
17502  CATCH_REGISTER_REPORTER( "xml", XmlReporter )
17503 
17504 } // end namespace Catch
17505 
17506 #if defined(_MSC_VER)
17507 #pragma warning(pop)
17508 #endif
17509 // end catch_reporter_xml.cpp
17510 
17511 namespace Catch {
17512  LeakDetector leakDetector;
17513 }
17514 
17515 #ifdef __clang__
17516 #pragma clang diagnostic pop
17517 #endif
17518 
17519 // end catch_impl.hpp
17520 #endif
17521 
17522 #ifdef CATCH_CONFIG_MAIN
17523 // start catch_default_main.hpp
17524 
17525 #ifndef __OBJC__
17526 
17527 #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
17528 // Standard C/C++ Win32 Unicode wmain entry point
17529 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
17530 #else
17531 // Standard C/C++ main entry point
17532 int main (int argc, char * argv[]) {
17533 #endif
17534 
17535  return Catch::Session().run( argc, argv );
17536 }
17537 
17538 #else // __OBJC__
17539 
17540 // Objective-C entry point
17541 int main (int argc, char * const argv[]) {
17542 #if !CATCH_ARC_ENABLED
17543  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
17544 #endif
17545 
17546  Catch::registerTestMethods();
17547  int result = Catch::Session().run( argc, (char**)argv );
17548 
17549 #if !CATCH_ARC_ENABLED
17550  [pool drain];
17551 #endif
17552 
17553  return result;
17554 }
17555 
17556 #endif // __OBJC__
17557 
17558 // end catch_default_main.hpp
17559 #endif
17560 
17561 #if !defined(CATCH_CONFIG_IMPL_ONLY)
17562 
17563 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
17564 # undef CLARA_CONFIG_MAIN
17565 #endif
17566 
17567 #if !defined(CATCH_CONFIG_DISABLE)
17569 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17570 #ifdef CATCH_CONFIG_PREFIX_ALL
17571 
17572 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17573 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17574 
17575 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17576 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17577 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17578 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17579 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17580 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17581 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17582 
17583 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17584 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17585 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17586 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17587 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17588 
17589 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17590 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17591 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17592 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17593 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17594 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17595 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17596 
17597 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17598 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17599 
17600 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17601 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17602 
17603 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
17604 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
17605 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17606 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
17607 
17608 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17609 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17610 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17611 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17612 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17613 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17614 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17615 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17616 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17617 
17618 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17619 
17620 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17621 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17622 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17623 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17624 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17625 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17626 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17627 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17628 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17629 #else
17630 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17631 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17632 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17633 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17634 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17635 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17636 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17637 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17638 #endif
17639 
17640 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17641 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
17642 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
17643 #else
17644 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
17645 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
17646 #endif
17647 
17648 // "BDD-style" convenience wrappers
17649 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
17650 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17651 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
17652 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17653 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
17654 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17655 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
17656 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
17657 
17658 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17659 #define CATCH_BENCHMARK(...) \
17660  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__,,))
17661 #define CATCH_BENCHMARK_ADVANCED(name) \
17662  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
17663 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17664 
17665 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17666 #else
17667 
17668 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17669 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17670 
17671 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17672 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17673 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17674 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17675 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17676 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17677 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17678 
17679 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17680 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17681 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17682 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17683 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17684 
17685 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17686 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17687 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17688 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17689 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17690 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17691 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17692 
17693 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17694 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17695 
17696 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17697 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17698 
17699 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
17700 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
17701 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17702 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
17703 
17704 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17705 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17706 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17707 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17708 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17709 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17710 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17711 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17712 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17713 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17714 
17715 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17716 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17717 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17718 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17719 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17720 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17721 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17722 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17723 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17724 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
17725 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
17726 #else
17727 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17728 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17729 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17730 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17731 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17732 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17733 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17734 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17735 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
17736 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17737 #endif
17738 
17739 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17740 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
17741 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
17742 #else
17743 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
17744 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
17745 #endif
17746 
17747 #endif
17748 
17749 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
17750 
17751 // "BDD-style" convenience wrappers
17752 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
17753 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17754 
17755 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
17756 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17757 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
17758 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17759 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
17760 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
17761 
17762 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17763 #define BENCHMARK(...) \
17764  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__,,))
17765 #define BENCHMARK_ADVANCED(name) \
17766  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
17767 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17768 
17769 using Catch::Detail::Approx;
17770 
17771 #else // CATCH_CONFIG_DISABLE
17772 
17774 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17775 #ifdef CATCH_CONFIG_PREFIX_ALL
17776 
17777 #define CATCH_REQUIRE( ... ) (void)(0)
17778 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
17779 
17780 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
17781 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17782 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
17783 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17784 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17785 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17786 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
17787 
17788 #define CATCH_CHECK( ... ) (void)(0)
17789 #define CATCH_CHECK_FALSE( ... ) (void)(0)
17790 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
17791 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
17792 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
17793 
17794 #define CATCH_CHECK_THROWS( ... ) (void)(0)
17795 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17796 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
17797 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17798 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17799 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17800 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
17801 
17802 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17803 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
17804 
17805 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
17806 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17807 
17808 #define CATCH_INFO( msg ) (void)(0)
17809 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
17810 #define CATCH_WARN( msg ) (void)(0)
17811 #define CATCH_CAPTURE( msg ) (void)(0)
17812 
17813 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17814 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17815 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
17816 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
17817 #define CATCH_SECTION( ... )
17818 #define CATCH_DYNAMIC_SECTION( ... )
17819 #define CATCH_FAIL( ... ) (void)(0)
17820 #define CATCH_FAIL_CHECK( ... ) (void)(0)
17821 #define CATCH_SUCCEED( ... ) (void)(0)
17822 
17823 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17824 
17825 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17826 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17827 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17828 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17829 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17830 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17831 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17832 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17833 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17834 #else
17835 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17836 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17837 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17838 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17839 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17840 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17841 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17842 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17843 #endif
17844 
17845 // "BDD-style" convenience wrappers
17846 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17847 #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 )
17848 #define CATCH_GIVEN( desc )
17849 #define CATCH_AND_GIVEN( desc )
17850 #define CATCH_WHEN( desc )
17851 #define CATCH_AND_WHEN( desc )
17852 #define CATCH_THEN( desc )
17853 #define CATCH_AND_THEN( desc )
17854 
17855 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
17856 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
17857 
17858 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17859 #else
17860 
17861 #define REQUIRE( ... ) (void)(0)
17862 #define REQUIRE_FALSE( ... ) (void)(0)
17863 
17864 #define REQUIRE_THROWS( ... ) (void)(0)
17865 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17866 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
17867 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17868 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17869 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17870 #define REQUIRE_NOTHROW( ... ) (void)(0)
17871 
17872 #define CHECK( ... ) (void)(0)
17873 #define CHECK_FALSE( ... ) (void)(0)
17874 #define CHECKED_IF( ... ) if (__VA_ARGS__)
17875 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
17876 #define CHECK_NOFAIL( ... ) (void)(0)
17877 
17878 #define CHECK_THROWS( ... ) (void)(0)
17879 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17880 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
17881 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17882 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17883 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17884 #define CHECK_NOTHROW( ... ) (void)(0)
17885 
17886 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17887 #define CHECK_THAT( arg, matcher ) (void)(0)
17888 
17889 #define REQUIRE_THAT( arg, matcher ) (void)(0)
17890 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17891 
17892 #define INFO( msg ) (void)(0)
17893 #define UNSCOPED_INFO( msg ) (void)(0)
17894 #define WARN( msg ) (void)(0)
17895 #define CAPTURE( msg ) (void)(0)
17896 
17897 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17898 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17899 #define METHOD_AS_TEST_CASE( method, ... )
17900 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
17901 #define SECTION( ... )
17902 #define DYNAMIC_SECTION( ... )
17903 #define FAIL( ... ) (void)(0)
17904 #define FAIL_CHECK( ... ) (void)(0)
17905 #define SUCCEED( ... ) (void)(0)
17906 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
17907 
17908 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17909 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17910 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17911 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17912 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17913 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17914 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17915 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17916 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17917 #else
17918 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17919 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17920 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17921 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17922 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17923 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17924 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17925 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17926 #endif
17927 
17928 #define STATIC_REQUIRE( ... ) (void)(0)
17929 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
17930 
17931 #endif
17932 
17933 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
17934 
17935 // "BDD-style" convenience wrappers
17936 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )
17937 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
17938 
17939 #define GIVEN( desc )
17940 #define AND_GIVEN( desc )
17941 #define WHEN( desc )
17942 #define AND_WHEN( desc )
17943 #define THEN( desc )
17944 #define AND_THEN( desc )
17945 
17946 using Catch::Detail::Approx;
17947 
17948 #endif
17949 
17950 #endif // ! CATCH_CONFIG_IMPL_ONLY
17951 
17952 // start catch_reenable_warnings.h
17953 
17954 
17955 #ifdef __clang__
17956 # ifdef __ICC // icpc defines the __clang__ macro
17957 # pragma warning(pop)
17958 # else
17959 # pragma clang diagnostic pop
17960 # endif
17961 #elif defined __GNUC__
17962 # pragma GCC diagnostic pop
17963 #endif
17964 
17965 // end catch_reenable_warnings.h
17966 // end catch.hpp
17967 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
17968 
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
sizeof(AF_ModuleRec)
#define EOF
Definition: afmparse.c:59
struct NameRec_ * Name
const char msg[]
Definition: arch.cpp:46
#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH
Definition: catch.cpp:41
#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
Definition: catch_p_p.h:419
#define CATCH_CATCH_ANON(type)
Definition: catch_p_p.h:456
#define CATCH_RUNTIME_ERROR(...)
Definition: catch_p_p.h:3903
#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
Definition: catch_p_p.h:428
#define CATCH_TRY
Definition: catch_p_p.h:454
#define CATCH_ENFORCE(condition,...)
Definition: catch_p_p.h:3906
#define CATCH_INTERNAL_LINEINFO
Definition: catch_p_p.h:543
#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
Definition: catch_p_p.h:422
#define CATCH_ERROR(...)
Definition: catch_p_p.h:3900
#define CATCH_INTERNAL_ERROR(...)
Definition: catch_p_p.h:3897
#define CATCH_CATCH_ALL
Definition: catch_p_p.h:455
@ Float
@ Double
FT_UInt idx
Definition: cffcmap.c:135
FT_Error error
Definition: cffdrivr.c:657
auto allowThrows() const -> bool
void handleExpr(ExprLhs< T > const &expr)
Definition: catch_p_p.h:2567
AssertionHandler(StringRef const &macroName, SourceLineInfo const &lineInfo, StringRef capturedExpression, ResultDisposition::Flags resultDisposition)
void handleExceptionNotThrownAsExpected()
void handleUnexpectedExceptionNotThrown()
void handleUnexpectedInflightException()
void handleExceptionThrownAsExpected()
void handleMessage(ResultWas::OfType resultType, StringRef const &message)
void handleExpr(ITransientExpression const &expr)
auto operator==(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2257
auto operator||(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2250
auto operator<=(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2292
BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
Definition: catch_p_p.h:2235
auto operator>=(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2285
auto operator<(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2278
auto operator>(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2271
auto operator!=(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2264
auto operator&&(T) const -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2243
void captureValue(size_t index, std::string const &value)
void captureValues(size_t index, T const &value)
Definition: catch_p_p.h:2663
void captureValues(size_t index, T const &value, Ts const &... values)
Definition: catch_p_p.h:2668
Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names)
Approx operator()(T const &value) const
Definition: catch_p_p.h:3096
Approx(double value)
Approx & margin(T const &newMargin)
Definition: catch_p_p.h:3157
Approx & scale(T const &newScale)
Definition: catch_p_p.h:3164
std::string toString() const
Approx operator-() const
static Approx custom()
Approx(T const &value)
Definition: catch_p_p.h:3105
Approx & epsilon(T const &newEpsilon)
Definition: catch_p_p.h:3150
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
Definition: catch_p_p.h:3052
auto operator!=(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2352
auto operator&(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2380
auto operator|(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2376
auto operator>=(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2368
auto operator>(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2360
auto operator^(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2384
auto operator<=(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2372
auto makeUnaryExpr() const -> UnaryExpr< LhsT >
Definition: catch_p_p.h:2402
ExprLhs(LhsT lhs)
Definition: catch_p_p.h:2341
auto operator&&(RhsT const &) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2389
auto operator||(RhsT const &) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2396
auto operator==(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2344
auto operator<(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
Definition: catch_p_p.h:2364
GeneratorException(const char *msg)
Definition: catch_p_p.h:3923
const char * what() const noexcept override final
ChunkGenerator(size_t size, GeneratorWrapper< T > generator)
Definition: catch_p_p.h:4303
std::vector< T > const & get() const override
Definition: catch_p_p.h:4317
FilterGenerator(P &&pred, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4161
T const & get() const override
Definition: catch_p_p.h:4175
FixedValuesGenerator(std::initializer_list< T > values)
Definition: catch_p_p.h:3974
T const & get() const override
Definition: catch_p_p.h:3976
GeneratorWrapper(std::unique_ptr< IGenerator< T >> generator)
Definition: catch_p_p.h:3989
Generators(Gs &&... moreGenerators)
Definition: catch_p_p.h:4032
T const & get() const override
Definition: catch_p_p.h:4037
IteratorGenerator(InputIterator first, InputSentinel last)
Definition: catch_p_p.h:4721
T const & get() const override
Definition: catch_p_p.h:4727
T const & get() const override
Definition: catch_p_p.h:4270
MapGenerator(F2 &&function, GeneratorWrapper< U > &&generator)
Definition: catch_p_p.h:4264
Float const & get() const override
Definition: catch_p_p.h:4615
RandomIntegerGenerator(Integer a, Integer b)
Definition: catch_p_p.h:4631
Integer const & get() const override
Definition: catch_p_p.h:4637
T const & get() const override
Definition: catch_p_p.h:4689
RangeGenerator(T const &start, T const &end, T const &step)
Definition: catch_p_p.h:4674
RangeGenerator(T const &start, T const &end)
Definition: catch_p_p.h:4685
RepeatGenerator(size_t repeats, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4210
T const & get() const override
Definition: catch_p_p.h:4217
T const & get() const override
Definition: catch_p_p.h:3958
T const & get() const override
Definition: catch_p_p.h:4131
TakeGenerator(size_t target, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4125
LazyExpression(bool isNegated)
friend struct AssertionStats
Definition: catch_p_p.h:2528
friend auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream &
LazyExpression(LazyExpression const &other)
LazyExpression & operator=(LazyExpression const &)=delete
friend class RunContext
Definition: catch_p_p.h:2529
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch_p_p.h:3782
MatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString)
Definition: catch_p_p.h:3775
bool match(std::exception const &ex) const override
ExceptionMessageMatcher(std::string const &message)
Definition: catch_p_p.h:3403
bool match(T const &item) const override
Definition: catch_p_p.h:3505
PredicateMatcher(std::function< bool(T const &)> const &elem, std::string const &descr)
Definition: catch_p_p.h:3500
std::string describe() const override
Definition: catch_p_p.h:3509
virtual std::string describe() const =0
MatcherUntypedBase(MatcherUntypedBase const &)=default
virtual ~NonCopyable()
void reset()
Definition: catch_p_p.h:4437
Option(T const &_value)
Definition: catch_p_p.h:4412
T const & operator*() const
Definition: catch_p_p.h:4444
Option & operator=(Option const &_other)
Definition: catch_p_p.h:4423
bool none() const
Definition: catch_p_p.h:4453
T valueOr(T const &defaultValue) const
Definition: catch_p_p.h:4448
bool some() const
Definition: catch_p_p.h:4452
T * operator->()
Definition: catch_p_p.h:4445
const T * operator->() const
Definition: catch_p_p.h:4446
Option(Option const &_other)
Definition: catch_p_p.h:4415
T & operator*()
Definition: catch_p_p.h:4443
auto str() const -> std::string
auto get() -> std::ostream &
Definition: catch_p_p.h:1454
ScopedMessage(MessageBuilder const &builder)
ScopedMessage(ScopedMessage &duplicate)=delete
ScopedMessage(ScopedMessage &&old)
MessageInfo m_info
Definition: catch_p_p.h:2648
Section(SectionInfo const &info)
void seed(result_type seed_)
std::uint32_t result_type
Definition: catch_p_p.h:4561
friend bool operator==(SimplePcg32 const &lhs, SimplePcg32 const &rhs)
friend bool operator!=(SimplePcg32 const &lhs, SimplePcg32 const &rhs)
void discard(uint64_t skip)
SimplePcg32(result_type seed_)
result_type operator()()
std::size_t size_type
Definition: catch_p_p.h:608
constexpr auto empty() const noexcept -> bool
Definition: catch_p_p.h:648
auto c_str() const -> char const *
constexpr const_iterator end() const
Definition: catch_p_p.h:674
auto operator[](size_type index) const noexcept -> char
Definition: catch_p_p.h:642
auto substr(size_type start, size_type length) const noexcept -> StringRef
constexpr StringRef() noexcept=default
constexpr auto isNullTerminated() const noexcept -> bool
Definition: catch_p_p.h:668
StringRef(std::string const &stdString) noexcept
Definition: catch_p_p.h:627
auto operator!=(StringRef const &other) const noexcept -> bool
Definition: catch_p_p.h:638
auto operator==(StringRef const &other) const noexcept -> bool
constexpr const_iterator begin() const
Definition: catch_p_p.h:673
auto data() const noexcept -> char const *
const char * const_iterator
Definition: catch_p_p.h:609
constexpr auto size() const noexcept -> size_type
Definition: catch_p_p.h:651
bool operator<(TestCase const &other) const
TestCase withName(std::string const &_newName) const
TestCaseInfo const & getTestCaseInfo() const
void invoke() const
bool operator==(TestCase const &other) const
TestCase(ITestInvoker *testCase, TestCaseInfo &&info)
TestInvokerAsMethod(void(C::*testAsMethod)()) noexcept
Definition: catch_p_p.h:965
void invoke() const override
Definition: catch_p_p.h:967
auto getElapsedSeconds() const -> double
auto getElapsedNanoseconds() const -> uint64_t
UnaryExpr(LhsT lhs)
Definition: catch_p_p.h:2308
[0]
Definition: node.h:62
Definition: parser.h:39
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
template< typename Enum > bool operator!=(Enum lhs, QFlags< Enum > rhs)
template< typename Enum > bool operator==(Enum lhs, QFlags< Enum > rhs)
void push_back(parameter_type t)
Definition: qlist.h:687
void reserve(qsizetype size)
Definition: qlist.h:757
void swap(QPainterPath &other) noexcept
Definition: qpainterpath.h:98
qsizetype size() const
Definition: qstring.h:413
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition: qstring.cpp:6263
QChar * data()
Definition: qstring.h:1228
qsizetype length() const
Definition: qstring.h:415
void start(int msec)
Definition: qtimer.cpp:259
XmlWriter(QTextDocument *document)
Definition: xmlwriter.h:62
float step
#define T(x)
Definition: main.cpp:42
struct config_s config
#define Code
Definition: deflate.h:80
#define this
Definition: dialogs.cpp:56
QHash< int, QWidget * > hash
[35multi]
QString str
[2]
QString text
[meta data]
double e
const auto predicate
direction
QStyleOptionButton opt
bool parse()
int const char * version
Definition: zlib.h:814
int flush
Definition: zlib.h:309
FT_Vector * vec
Definition: ftbbox.c:469
#define true
Definition: ftrandom.c:51
constexpr T & operator()(T &v) const
Definition: hb-algs.hh:2
auto it unsigned count const
Definition: hb-iter.hh:848
#define _(S, M)
backing_store_ptr info
[4]
Definition: jmemsys.h:161
short next
Definition: keywords.cpp:454
Token token
Definition: keywords.cpp:453
#define SZ
Definition: md4c.c:124
#define F2(x, y, z)
Definition: md5.cpp:148
QT_BEGIN_NAMESPACE bool operator<(const QMimeType &t1, const QMimeType &t2)
triState operator!(const triState &rhs)
std::string convertUnknownEnumToString(E e)
Definition: catch_p_p.h:1649
std::string rawMemoryToString(const T &object)
Definition: catch_p_p.h:1559
const std::string unprintableString
std::enable_if< !std::is_enum< T >::value &&!std::is_base_of< std::exception, T >::value, std::string >::type convertUnstreamable(T const &)
Definition: catch_p_p.h:1582
std::string rawMemoryToString(const void *object, std::size_t size)
std::string rangeToString(InputIterator first, Sentinel last)
Definition: catch_p_p.h:1829
std::string stringify(const T &e)
Definition: catch_p_p.h:1644
std::unique_ptr< T > make_unique(Args &&... args)
Definition: catch_p_p.h:3935
GeneratorWrapper< std::vector< T > > chunk(size_t size, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4333
std::unique_ptr< GeneratorUntypedBase > GeneratorBasePtr
Definition: catch_p_p.h:3855
GeneratorWrapper< T > repeat(size_t repeats, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4251
auto generate(StringRef generatorName, SourceLineInfo const &lineInfo, L const &generatorExpression) -> decltype(std::declval< decltype(generatorExpression())>().get())
Definition: catch_p_p.h:4085
GeneratorWrapper< T > value(T &&value)
Definition: catch_p_p.h:4001
GeneratorWrapper< T > values(std::initializer_list< T > values)
Definition: catch_p_p.h:4005
std::enable_if< std::is_floating_point< T >::value, GeneratorWrapper< T > >::type random(T a, T b)
Definition: catch_p_p.h:4660
GeneratorWrapper< T > range(T const &start, T const &end)
Definition: catch_p_p.h:4706
GeneratorWrapper< T > take(size_t target, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4151
auto makeGenerators(as< T >, U &&val, Gs &&... moreGenerators) -> Generators< T >
Definition: catch_p_p.h:4075
auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker &
GeneratorWrapper< ResultType > from_range(Container const &cnt)
Definition: catch_p_p.h:4746
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< U > &&generator)
Definition: catch_p_p.h:4283
GeneratorWrapper< T > filter(Predicate &&pred, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4195
std::string finalizeDescription(const std::string &desc)
Generic::PredicateMatcher< T > Predicate(std::function< bool(T const &)> const &predicate, std::string const &description="")
Definition: catch_p_p.h:3521
Exception::ExceptionMessageMatcher Message(std::string const &message)
Floating::WithinRelMatcher WithinRel(float target)
Vector::EqualsMatcher< T, AllocComp, AllocMatch > Equals(std::vector< T, AllocComp > const &comparator)
Definition: catch_p_p.h:3749
Floating::WithinAbsMatcher WithinAbs(double target, double margin)
Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff)
Vector::ContainsMatcher< T, AllocComp, AllocMatch > Contains(std::vector< T, AllocComp > const &comparator)
Definition: catch_p_p.h:3739
StdString::RegexMatcher Matches(std::string const &regex, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
Vector::ContainsElementMatcher< T, Alloc > VectorContains(T const &comparator)
Definition: catch_p_p.h:3744
StdString::StartsWithMatcher StartsWith(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
Vector::UnorderedEqualsMatcher< T, AllocComp, AllocMatch > UnorderedEquals(std::vector< T, AllocComp > const &target)
Definition: catch_p_p.h:3759
StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
Vector::ApproxMatcher< T, AllocComp, AllocMatch > Approx(std::vector< T, AllocComp > const &comparator)
Definition: catch_p_p.h:3754
StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
void toLowerInPlace(std::string &s)
std::string trim(std::string const &str)
Returns a new string without whitespace at the start/end.
void cleanUp()
std::vector< TestCase > const & getAllTestCasesSorted(IConfig const &config)
auto makeMatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString) -> MatchExpr< ArgT, MatcherT >
Definition: catch_p_p.h:3797
typename std::remove_reference< typename std::remove_cv< typename std::result_of< Func(U...)>::type >::type >::type FunctionReturnType
Definition: catch_p_p.h:949
std::vector< StringRef > splitStringRef(StringRef str, char delimiter)
void throw_exception(std::exception const &e)
void throw_runtime_error(std::string const &msg)
std::ostream & cerr()
std::ostream & cout()
void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs)
bool isOk(ResultWas::OfType resultType)
bool isJustInfo(int flags)
std::ostream & clog()
TestCase makeTestCase(ITestInvoker *testCase, std::string const &className, NameAndTags const &nameAndTags, SourceLineInfo const &lineInfo)
T const & operator+(T const &value, StreamEndStop)
Definition: catch_p_p.h:538
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
IRegistryHub const & getRegistryHub()
void handleExpression(ITransientExpression const &expr)
bool startsWith(std::string const &s, std::string const &prefix)
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
void throw_logic_error(std::string const &msg)
std::vector< std::unique_ptr< IExceptionTranslator const > > ExceptionTranslators
Definition: catch_p_p.h:3008
bool shouldContinueOnFailure(int flags)
auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool
Definition: catch_p_p.h:2327
bool isFalseTest(int flags)
Definition: catch_p_p.h:1388
auto getCurrentNanosecondsSinceEpoch() -> uint64_t
SimplePcg32 & rng()
bool contains(std::string const &s, std::string const &infix)
bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config)
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
auto makeTestInvoker(void(*testAsFunction)()) noexcept -> ITestInvoker *
std::vector< TestCase > filterTests(std::vector< TestCase > const &testCases, TestSpec const &testSpec, IConfig const &config)
bool shouldSuppressFailure(int flags)
Matchers::Impl::MatcherBase< std::string > StringMatcher
Definition: catch_p_p.h:3792
std::string toLower(std::string const &s)
auto getEstimatedClockResolution() -> uint64_t
IMutableRegistryHub & getMutableRegistryHub()
bool startsWith(std::string const &s, char prefix)
unsigned int rngSeed()
std::shared_ptr< IReporterFactory > IReporterFactoryPtr
Definition: catch_p_p.h:2963
IContext & getCurrentContext()
Definition: catch_p_p.h:4389
bool endsWith(std::string const &s, std::string const &suffix)
std::string translateActiveException()
std::string rangeToString(std::vector< bool, Allocator > const &v)
Definition: catch_p_p.h:2024
void cleanUpContext()
void throw_domain_error(std::string const &msg)
std::string(*)() exceptionTranslateFunction
Definition: catch_p_p.h:3005
void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef const &matcherString)
std::string rangeToString(Range const &range)
Definition: catch_p_p.h:2018
bool isThrowSafe(TestCase const &testCase, IConfig const &config)
auto makeStream(StringRef const &filename) -> IStream const *
IMutableContext & getCurrentMutableContext()
Definition: catch_p_p.h:4381
auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool
Definition: catch_p_p.h:2316
std::shared_ptr< IConfig const > IConfigPtr
Definition: catch_p_p.h:4356
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis)
IResultCapture & getResultCapture()
QPainterPath node()
Definition: paths.cpp:574
constexpr QColor Red
Definition: qcolor.h:320
constexpr QColor Blue
Definition: qcolor.h:322
constexpr QColor White
Definition: qcolor.h:316
constexpr QColor Cyan
Definition: qcolor.h:323
constexpr QColor Green
Definition: qcolor.h:321
constexpr QColor Yellow
Definition: qcolor.h:325
typename C::value_type value_type
typename C::const_iterator const_iterator
typename C::iterator iterator
void toString(QString &appendTo, IPv4Address address)
Definition: qipaddress.cpp:131
@ Auto
Definition: qprint_p.h:119
@ Error
Definition: qprint_p.h:94
Q_TESTLIB_EXPORT QTestData & addRow(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
Definition: qtestcase.cpp:2690
Q_DECL_CONST_FUNCTION Q_CORE_EXPORT const Properties *QT_FASTCALL properties(char32_t ucs4) noexcept
QFuture< typename std::decay_t< Sequence >::value_type > filtered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep)
QTextStream & fixed(QTextStream &stream)
void * HANDLE
Definition: qnamespace.h:1561
@ CaseSensitive
Definition: qnamespace.h:1284
QTextStream & endl(QTextStream &stream)
QTextStream & scientific(QTextStream &stream)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QByteArrayView trimmed(QByteArrayView s) noexcept
void wrapper()
Definition: brush.cpp:53
typing.Tuple[int, int] test(str binary_directory, *debug=False)
parser
Definition: devices.py:74
default
Definition: devices.py:76
required
Definition: devices.py:75
QString enumValue(const QString &value)
Definition: language.cpp:492
constexpr struct q20::ranges::@309 any_of
constexpr struct q20::ranges::@310 all_of
Definition: qfloat16.h:381
Definition: __init__.py:1
int PRIV() strcmp(PCRE2_SPTR str1, PCRE2_SPTR str2)
PCRE2_SIZE PRIV() strlen(PCRE2_SPTR str)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
[3]
set set set set set set set macro pixldst1 op
void
Definition: png.h:1080
#define None
@ Ok
Definition: qbezier.cpp:209
Q_CORE_EXPORT QBitArray operator&(const QBitArray &, const QBitArray &)
#define assert
Definition: qcborcommon_p.h:63
SharedPointerFileDialogOptions m_options
constexpr bool operator!=(const timespec &t1, const timespec &t2)
Definition: qcore_unix_p.h:124
constexpr timespec operator*(const timespec &t1, int mul)
Definition: qcore_unix_p.h:146
constexpr timespec operator-(const timespec &t1, const timespec &t2)
Definition: qcore_unix_p.h:139
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
EGLOutputLayerEXT EGLint attribute
bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two)
@ Required
Definition: qmetaobject_p.h:82
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLenum GLuint id
[6]
Definition: qopengl.h:270
GLenum type
Definition: qopengl.h:270
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: qopengl.h:270
GLint location
GLenum GLsizei GLsizei GLint * values
[16]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLsizei samples
GLenum mode
const GLfloat * m
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLenum GLenum GLsizei count
GLuint object
[3]
GLdouble GLdouble right
GLfloat GLfloat f
GLsizei range
GLenum GLuint buffer
GLint GLsizei width
GLint reference
GLint left
GLuint GLsizei const GLchar * label
[43]
GLenum target
GLbitfield flags
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLfloat units
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLboolean GLboolean g
GLint ref
GLuint name
GLint first
GLsizei bufSize
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLfloat n
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLenum GLenum GLsizei void GLsizei void * column
Definition: qopenglext.h:2747
GLuint GLenum GLenum transform
Definition: qopenglext.h:11564
GLhandleARB obj
[2]
Definition: qopenglext.h:4164
GLboolean reset
Definition: qopenglext.h:2748
GLenum func
Definition: qopenglext.h:663
const GLubyte * c
Definition: qopenglext.h:12701
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLuint GLuint * names
Definition: qopenglext.h:5654
GLfloat bias
Definition: qopenglext.h:7943
GLenum GLsizei len
Definition: qopenglext.h:3292
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint in
Definition: qopenglext.h:8870
GLsizei const void * pointer
Definition: qopenglext.h:384
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLenum GLenum GLsizei void * row
Definition: qopenglext.h:2747
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLuint num
Definition: qopenglext.h:5654
GLfixed GLfixed GLint GLint order
Definition: qopenglext.h:5206
GLubyte * pattern
Definition: qopenglext.h:2744
GLenum GLenum GLsizei void * table
Definition: qopenglext.h:2745
GLenum GLint GLint * precision
Definition: qopenglext.h:1890
GLsizei const GLchar *const * string
[0]
Definition: qopenglext.h:694
@ Left
@ Right
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
SSL_CTX int(*) void arg)
Q_ALWAYS_INLINE QString to_string(QLatin1String s) noexcept
Definition: qstring.cpp:8697
#define k0
#define a2
#define k1
#define a1
Tag
Definition: qtranslator.cpp:78
@ desc
QUrl::FormattingOptions & operator|=(QUrl::FormattingOptions &i, QUrl::ComponentFormattingOptions f)
Definition: qurl.h:327
bool operator<=(const QUuid &lhs, const QUuid &rhs) noexcept
Definition: quuid.h:216
bool operator>=(const QUuid &lhs, const QUuid &rhs) noexcept
Definition: quuid.h:218
double accumulate
Definition: outofline.cpp:34
const char className[16]
[1]
Definition: qwizard.cpp:135
QSqlQueryModel * model
[16]
#define isOpen(pFd)
Definition: sqlite3.c:53456
struct Column Column
Definition: sqlite3.c:14264
QStringView el
@ Success
Definition: main.cpp:3134
QList< int > results
QFuture< int > sum
QFuture< QSet< QChar > > set
[10]
QList< int > vector
[14]
QThreadPool pool
QRandomGenerator generator(sseq)
std::uniform_real_distribution dist(1, 2.5)
[2]
QFile file
[0]
file open(QIODevice::ReadOnly)
QFileSelector selector
[1]
gzip write("uncompressed data")
settings remove("monkey")
QStorageInfo storage
[1]
QTextStream out(stdout)
[7]
QUrl url("http://www.example.com/List of holidays.xml")
[0]
QObject::connect nullptr
QTimer * timer
[3]
sem acquire()
sem release()
Definition: main.cpp:48
QVariant variant
[1]
QTime time
[5]
QSharedPointer< T > other(t)
[5]
QXmlStreamReader xml
[0]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
QGraphicsItem * item
QItemEditorFactory * factory
QLayoutItem * child
[0]
QAction * at
header setValue("Host", "qt-project.org")
http get(QUrl::toPercentEncoding("/index.html"))
view create()
QDBusVariant Type
QStringList::Iterator it
QStringList list
[0]
Definition: main.cpp:58
SourceLineInfo lineInfo
Definition: catch_p_p.h:1399
ResultDisposition::Flags resultDisposition
Definition: catch_p_p.h:1401
StringRef capturedExpression
Definition: catch_p_p.h:1400
AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags) noexcept
std::size_t failed
Definition: catch_p_p.h:2838
Counts & operator+=(Counts const &other)
bool allOk() const
bool allPassed() const
std::size_t total() const
Counts operator-(Counts const &other) const
std::size_t failedButOk
Definition: catch_p_p.h:2839
std::size_t passed
Definition: catch_p_p.h:2837
auto operator<=(T const &lhs) -> ExprLhs< T const & >
Definition: catch_p_p.h:2416
StringRef lookup(int value) const
std::vector< std::pair< int, StringRef > > m_values
Definition: catch_p_p.h:1468
virtual T const & get() const =0
virtual ~IGenerator()=default
virtual TestSpec const & testSpec() const =0
virtual RunTests::InWhatOrder runOrder() const =0
virtual double minDuration() const =0
virtual std::vector< std::string > const & getTestsOrTags() const =0
virtual bool includeSuccessfulResults() const =0
virtual bool warnAboutNoTests() const =0
virtual int abortAfter() const =0
virtual unsigned int benchmarkResamples() const =0
virtual bool hasTestFilters() const =0
virtual std::chrono::milliseconds benchmarkWarmupTime() const =0
virtual Verbosity verbosity() const =0
virtual int benchmarkSamples() const =0
virtual bool shouldDebugBreak() const =0
virtual bool warnAboutMissingAssertions() const =0
virtual UseColour::YesOrNo useColour() const =0
virtual std::string name() const =0
virtual bool showInvisibles() const =0
virtual std::ostream & stream() const =0
virtual bool benchmarkNoAnalysis() const =0
virtual bool allowThrows() const =0
virtual ShowDurations::OrNot showDurations() const =0
virtual ~IConfig()
virtual unsigned int rngSeed() const =0
virtual double benchmarkConfidenceInterval() const =0
virtual std::vector< std::string > const & getSectionsToRun() const =0
virtual IResultCapture * getResultCapture()=0
virtual IConfigPtr const & getConfig() const =0
virtual ~IContext()
virtual IRunner * getRunner()=0
virtual std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const =0
virtual std::string translateActiveException() const =0
virtual auto getGenerator() const -> Generators::GeneratorBasePtr const &=0
virtual void setGenerator(Generators::GeneratorBasePtr &&generator)=0
virtual auto hasGenerator() const -> bool=0
virtual void setResultCapture(IResultCapture *resultCapture)=0
virtual void setConfig(IConfigPtr const &config)=0
friend void cleanUpContext()
virtual void setRunner(IRunner *runner)=0
Detail::EnumInfo const & registerEnum(StringRef enumName, StringRef allEnums, std::initializer_list< E > values)
Definition: catch_p_p.h:1482
virtual Detail::EnumInfo const & registerEnum(StringRef enumName, StringRef allEnums, std::vector< int > const &values)=0
virtual void registerTest(TestCase const &testInfo)=0
virtual void registerReporter(std::string const &name, IReporterFactoryPtr const &factory)=0
virtual void registerStartupException() noexcept=0
virtual void registerListener(IReporterFactoryPtr const &factory)=0
virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo)=0
virtual void registerTranslator(const IExceptionTranslator *translator)=0
virtual StartupExceptionRegistry const & getStartupExceptionRegistry() const =0
virtual ~IRegistryHub()
virtual ITagAliasRegistry const & getTagAliasRegistry() const =0
virtual IExceptionTranslatorRegistry const & getExceptionTranslatorRegistry() const =0
virtual IReporterRegistry const & getReporterRegistry() const =0
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
virtual void handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, AssertionReaction &reaction)=0
virtual void popScopedMessage(MessageInfo const &message)=0
virtual void handleFatalErrorCondition(StringRef message)=0
virtual void emplaceUnscopedMessage(MessageBuilder const &builder)=0
virtual void sectionEnded(SectionEndInfo const &endInfo)=0
virtual void handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction)=0
virtual bool sectionStarted(SectionInfo const &sectionInfo, Counts &assertions)=0
virtual void handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction)=0
virtual void handleIncomplete(AssertionInfo const &info)=0
virtual auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker &=0
virtual void pushScopedMessage(MessageInfo const &message)=0
virtual bool lastAssertionPassed()=0
virtual void assertionPassed()=0
virtual const AssertionResult * getLastResult() const =0
virtual void handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction)=0
virtual void exceptionEarlyReported()=0
virtual std::string getCurrentTestName() const =0
virtual void handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, AssertionReaction &reaction)=0
virtual void sectionEndedEarly(SectionEndInfo const &endInfo)=0
virtual bool aborting() const =0
virtual ~IRunner()
virtual ~IStream()
virtual std::ostream & stream() const =0
virtual std::vector< TestCase > const & getAllTestsSorted(IConfig const &config) const =0
virtual std::vector< TestCase > const & getAllTests() const =0
virtual ~ITestInvoker()
virtual void invoke() const =0
auto getResult() const -> bool
Definition: catch_p_p.h:2204
auto isBinaryExpression() const -> bool
Definition: catch_p_p.h:2203
virtual void streamReconstructedExpression(std::ostream &os) const =0
ITransientExpression(bool isBinaryExpression, bool result)
Definition: catch_p_p.h:2207
std::string describe() const override
WithinAbsMatcher(double target, double margin)
bool match(double const &matchee) const override
WithinRelMatcher(double target, double epsilon)
bool match(double const &matchee) const override
std::string describe() const override
WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
bool match(double const &matchee) const override
std::string describe() const override
std::vector< MatcherBase< ArgT > const * > m_matchers
Definition: catch_p_p.h:3318
std::string describe() const override
Definition: catch_p_p.h:3296
bool match(ArgT const &arg) const override
Definition: catch_p_p.h:3289
std::vector< MatcherBase< ArgT > const * > m_matchers
Definition: catch_p_p.h:3352
std::string describe() const override
Definition: catch_p_p.h:3330
bool match(ArgT const &arg) const override
Definition: catch_p_p.h:3323
bool match(ArgT const &arg) const override
Definition: catch_p_p.h:3360
MatchNotOf(MatcherBase< ArgT > const &underlyingMatcher)
Definition: catch_p_p.h:3358
std::string describe() const override
Definition: catch_p_p.h:3364
MatcherBase< ArgT > const & m_underlyingMatcher
Definition: catch_p_p.h:3367
MatchNotOf< T > operator!() const
Definition: catch_p_p.h:3379
MatchAnyOf< T > operator||(MatcherBase const &other) const
Definition: catch_p_p.h:3375
MatchAllOf< T > operator&&(MatcherBase const &other) const
Definition: catch_p_p.h:3371
virtual bool match(ObjectT const &arg) const =0
std::string adjustString(std::string const &str) const
CasedString(std::string const &str, CaseSensitive::Choice caseSensitivity)
CaseSensitive::Choice m_caseSensitivity
Definition: catch_p_p.h:3544
bool match(std::string const &source) const override
ContainsMatcher(CasedString const &comparator)
EndsWithMatcher(CasedString const &comparator)
bool match(std::string const &source) const override
bool match(std::string const &source) const override
EqualsMatcher(CasedString const &comparator)
std::string describe() const override
bool match(std::string const &matchee) const override
RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity)
StartsWithMatcher(CasedString const &comparator)
bool match(std::string const &source) const override
StringMatcherBase(std::string const &operation, CasedString const &comparator)
std::string describe() const override
ApproxMatcher(std::vector< T, AllocComp > const &comparator)
Definition: catch_p_p.h:3683
ApproxMatcher & epsilon(T const &newEpsilon)
Definition: catch_p_p.h:3697
std::vector< T, AllocComp > const & m_comparator
Definition: catch_p_p.h:3712
ApproxMatcher & margin(T const &newMargin)
Definition: catch_p_p.h:3702
ApproxMatcher & scale(T const &newScale)
Definition: catch_p_p.h:3707
std::string describe() const override
Definition: catch_p_p.h:3693
bool match(std::vector< T, AllocMatch > const &v) const override
Definition: catch_p_p.h:3685
std::string describe() const override
Definition: catch_p_p.h:3620
bool match(std::vector< T, Alloc > const &v) const override
Definition: catch_p_p.h:3611
bool match(std::vector< T, AllocMatch > const &v) const override
Definition: catch_p_p.h:3632
ContainsMatcher(std::vector< T, AllocComp > const &comparator)
Definition: catch_p_p.h:3630
std::vector< T, AllocComp > const & m_comparator
Definition: catch_p_p.h:3654
std::string describe() const override
Definition: catch_p_p.h:3650
std::string describe() const override
Definition: catch_p_p.h:3674
bool match(std::vector< T, AllocMatch > const &v) const override
Definition: catch_p_p.h:3662
std::vector< T, AllocComp > const & m_comparator
Definition: catch_p_p.h:3677
EqualsMatcher(std::vector< T, AllocComp > const &comparator)
Definition: catch_p_p.h:3660
std::string describe() const override
Definition: catch_p_p.h:3726
UnorderedEqualsMatcher(std::vector< T, AllocComp > const &target)
Definition: catch_p_p.h:3718
bool match(std::vector< T, AllocMatch > const &vec) const override
Definition: catch_p_p.h:3719
MessageInfo m_info
Definition: catch_p_p.h:2638
MessageBuilder(StringRef const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
StringRef macroName
Definition: catch_p_p.h:2604
unsigned int sequence
Definition: catch_p_p.h:2608
bool operator<(MessageInfo const &other) const
SourceLineInfo lineInfo
Definition: catch_p_p.h:2606
std::string message
Definition: catch_p_p.h:2605
ResultWas::OfType type
Definition: catch_p_p.h:2607
bool operator==(MessageInfo const &other) const
MessageInfo(StringRef const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
ReusableStringStream m_stream
Definition: catch_p_p.h:2624
StringRef tags
Definition: catch_p_p.h:983
NameAndTags(StringRef const &name_=StringRef(), StringRef const &tags_=StringRef()) noexcept
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
SectionInfo sectionInfo
Definition: catch_p_p.h:2877
std::string description
Definition: catch_p_p.h:2872
SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name, std::string const &)
Definition: catch_p_p.h:2867
SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name)
std::string name
Definition: catch_p_p.h:2871
SourceLineInfo lineInfo
Definition: catch_p_p.h:2873
bool empty() const noexcept
Definition: catch_p_p.h:515
SourceLineInfo & operator=(SourceLineInfo const &)=default
SourceLineInfo(char const *_file, std::size_t _line) noexcept
Definition: catch_p_p.h:505
SourceLineInfo(SourceLineInfo &&) noexcept=default
SourceLineInfo(SourceLineInfo const &other)=default
std::size_t line
Definition: catch_p_p.h:520
char const * file
Definition: catch_p_p.h:519
bool operator==(SourceLineInfo const &other) const noexcept
bool operator<(SourceLineInfo const &other) const noexcept
std::string operator+() const
static std::string convert(Catch::Detail::Approx const &value)
static std::string convert(R C::*p)
Definition: catch_p_p.h:1809
static std::string convert(U *p)
Definition: catch_p_p.h:1798
static std::string convert(T const(&arr)[SZ])
Definition: catch_p_p.h:2048
static std::string convert(bool b)
static std::string convert(char c)
static std::string convert(char *str)
static std::string convert(char const *str)
static std::string convert(char const *str)
Definition: catch_p_p.h:1712
static std::string convert(double value)
static std::string convert(float value)
static std::string convert(int value)
static std::string convert(long value)
static std::string convert(long long value)
static std::string convert(signed char c)
static std::string convert(signed char const *str)
Definition: catch_p_p.h:1718
static std::string convert(std::nullptr_t)
static std::string convert(const std::string &str)
static std::string convert(const std::wstring &wstr)
static std::string convert(unsigned char c)
static std::string convert(unsigned char const *str)
Definition: catch_p_p.h:1724
static std::string convert(unsigned int value)
static std::string convert(unsigned long value)
static std::string convert(unsigned long long value)
static std::string convert(wchar_t *str)
static std::string convert(wchar_t const *str)
static std::enable_if<!::Catch::Detail::IsStreamInsertable< Fake >::value, std::string >::type convert(const Fake &value)
Definition: catch_p_p.h:1630
static std::enable_if<::Catch::Detail::IsStreamInsertable< Fake >::value, std::string >::type convert(const Fake &value)
Definition: catch_p_p.h:1619
friend void setTags(TestCaseInfo &testCaseInfo, std::vector< std::string > tags)
std::vector< std::string > tags
Definition: catch_p_p.h:4801
std::string tagsAsString() const
std::string className
Definition: catch_p_p.h:4799
std::string description
Definition: catch_p_p.h:4800
std::string name
Definition: catch_p_p.h:4798
bool okToFail() const
std::vector< std::string > lcaseTags
Definition: catch_p_p.h:4802
bool isHidden() const
SourceLineInfo lineInfo
Definition: catch_p_p.h:4803
bool expectedToFail() const
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::vector< std::string > const &_tags, SourceLineInfo const &_lineInfo)
SpecialProperties properties
Definition: catch_p_p.h:4804
bool throws() const
Totals delta(Totals const &prevTotals) const
Totals & operator+=(Totals const &other)
Counts assertions
Definition: catch_p_p.h:2850
Totals operator-(Totals const &other) const
Counts testCases
Definition: catch_p_p.h:2851
static true_given< decltype(std::declval< Fun >)(std::declval< Args >)...))> test(int)
static std::false_type test(...)
std::size_t m_count
Definition: catch_p_p.h:3221
pluralise(std::size_t count, std::string const &label)
std::string m_label
Definition: catch_p_p.h:3222
Definition: global.h:89
Config()
Definition: global.h:90
Definition: main.cpp:38
Definition: data.cpp:95
TempFile(QString filename)
Definition: tst_qmake.cpp:512
Definition: moc.h:48
#define private
Definition: main.cpp:37
#define main
[0]
QString escape(const QString &s)
void populate(Container &)
bool run(const QString &name, QString *errorMessage)
#define STDOUT_FILENO
Definition: tst_qfile.cpp:111
int(* fun)()
const qreal epsilon
Definition: tst_qline.cpp:63
LockFileUsageInGlobalDtor s_instance
U convert(const T &t)
constexpr const auto messages
#define rhs
Str make(const QString &s)
C sorted(C c)
QAtomicInt iterations
int fn(int &i)
void add(int &result, const int &sum)
void runTest(const QString &test, const TestLoggers &requestedLoggers)
Catch::Generators::GeneratorWrapper< T > enums()
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent
QDomElement find(const QString &tagName, const QDomElement &e)
Definition: main.cpp:39
#define CALLBACK
Definition: wintab.h:609
XmlOutput::xml_output tag(const QString &name)
Definition: xmloutput.h:154