arduino-emulator
catch.hpp
1 /*
2  * Catch v2.13.1
3  * Generated: 2020-09-07 12:12:38.090364
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
7  *
8  * Distributed under the Boost Software License, Version 1.0. (See accompanying
9  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 // start catch.hpp
14 
15 
16 #define CATCH_VERSION_MAJOR 2
17 #define CATCH_VERSION_MINOR 13
18 #define CATCH_VERSION_PATCH 1
19 
20 #ifdef __clang__
21 # pragma clang system_header
22 #elif defined __GNUC__
23 # pragma GCC system_header
24 #endif
25 
26 // start catch_suppress_warnings.h
27 
28 #ifdef __clang__
29 # ifdef __ICC // icpc defines the __clang__ macro
30 # pragma warning(push)
31 # pragma warning(disable: 161 1682)
32 # else // __ICC
33 # pragma clang diagnostic push
34 # pragma clang diagnostic ignored "-Wpadded"
35 # pragma clang diagnostic ignored "-Wswitch-enum"
36 # pragma clang diagnostic ignored "-Wcovered-switch-default"
37 # endif
38 #elif defined __GNUC__
39  // Because REQUIREs trigger GCC's -Wparentheses, and because still
40  // supported version of g++ have only buggy support for _Pragmas,
41  // Wparentheses have to be suppressed globally.
42 # pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
43 
44 # pragma GCC diagnostic push
45 # pragma GCC diagnostic ignored "-Wunused-variable"
46 # pragma GCC diagnostic ignored "-Wpadded"
47 #endif
48 // end catch_suppress_warnings.h
49 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
50 # define CATCH_IMPL
51 # define CATCH_CONFIG_ALL_PARTS
52 #endif
53 
54 // In the impl file, we want to have access to all parts of the headers
55 // Can also be used to sanely support PCHs
56 #if defined(CATCH_CONFIG_ALL_PARTS)
57 # define CATCH_CONFIG_EXTERNAL_INTERFACES
58 # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
59 # undef CATCH_CONFIG_DISABLE_MATCHERS
60 # endif
61 # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
62 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
63 # endif
64 #endif
65 
66 #if !defined(CATCH_CONFIG_IMPL_ONLY)
67 // start catch_platform.h
68 
69 #ifdef __APPLE__
70 # include <TargetConditionals.h>
71 # if TARGET_OS_OSX == 1
72 # define CATCH_PLATFORM_MAC
73 # elif TARGET_OS_IPHONE == 1
74 # define CATCH_PLATFORM_IPHONE
75 # endif
76 
77 #elif defined(linux) || defined(__linux) || defined(__linux__)
78 # define CATCH_PLATFORM_LINUX
79 
80 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
81 # define CATCH_PLATFORM_WINDOWS
82 #endif
83 
84 // end catch_platform.h
85 
86 #ifdef CATCH_IMPL
87 # ifndef CLARA_CONFIG_MAIN
88 # define CLARA_CONFIG_MAIN_NOT_DEFINED
89 # define CLARA_CONFIG_MAIN
90 # endif
91 #endif
92 
93 // start catch_user_interfaces.h
94 
95 namespace Catch {
96  unsigned int rngSeed();
97 }
98 
99 // end catch_user_interfaces.h
100 // start catch_tag_alias_autoregistrar.h
101 
102 // start catch_common.h
103 
104 // start catch_compiler_capabilities.h
105 
106 // Detect a number of compiler features - by compiler
107 // The following features are defined:
108 //
109 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
110 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
111 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
112 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
113 // ****************
114 // Note to maintainers: if new toggles are added please document them
115 // in configuration.md, too
116 // ****************
117 
118 // In general each macro has a _NO_<feature name> form
119 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
120 // Many features, at point of detection, define an _INTERNAL_ macro, so they
121 // can be combined, en-mass, with the _NO_ forms later.
122 
123 #ifdef __cplusplus
124 
125 # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
126 # define CATCH_CPP14_OR_GREATER
127 # endif
128 
129 # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
130 # define CATCH_CPP17_OR_GREATER
131 # endif
132 
133 #endif
134 
135 #if defined(__cpp_lib_uncaught_exceptions)
136 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
137 #endif
138 
139 // We have to avoid both ICC and Clang, because they try to mask themselves
140 // as gcc, and we want only GCC in this block
141 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
142 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
143 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
144 
145 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
146 
147 #endif
148 
149 #if defined(__clang__)
150 
151 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
152 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
153 
154 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
155 // which results in calls to destructors being emitted for each temporary,
156 // without a matching initialization. In practice, this can result in something
157 // like `std::string::~string` being called on an uninitialized value.
158 //
159 // For example, this code will likely segfault under IBM XL:
160 // ```
161 // REQUIRE(std::string("12") + "34" == "1234")
162 // ```
163 //
164 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
165 # if !defined(__ibmxl__)
166 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
167 # endif
168 
169 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
170  _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
171  _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
172 
173 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
174  _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
175 
176 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
177  _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
178 
179 # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
180  _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
181 
182 # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
183  _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
184 
185 #endif // __clang__
186 
188 // Assume that non-Windows platforms support posix signals by default
189 #if !defined(CATCH_PLATFORM_WINDOWS)
190  #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
191 #endif
192 
194 // We know some environments not to support full POSIX signals
195 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
196  #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
197 #endif
198 
199 #ifdef __OS400__
200 # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
201 # define CATCH_CONFIG_COLOUR_NONE
202 #endif
203 
205 // Android somehow still does not support std::to_string
206 #if defined(__ANDROID__)
207 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
208 # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
209 #endif
210 
212 // Not all Windows environments support SEH properly
213 #if defined(__MINGW32__)
214 # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
215 #endif
216 
218 // PS4
219 #if defined(__ORBIS__)
220 # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
221 #endif
222 
224 // Cygwin
225 #ifdef __CYGWIN__
226 
227 // Required for some versions of Cygwin to declare gettimeofday
228 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
229 # define _BSD_SOURCE
230 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
231 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
232 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
233  && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
234 
235 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
236 
237 # endif
238 #endif // __CYGWIN__
239 
241 // Visual C++
242 #if defined(_MSC_VER)
243 
244 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
245 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
246 
247 # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
248 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
249 # endif
250 
251 // Universal Windows platform does not support SEH
252 // Or console colours (or console at all...)
253 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
254 # define CATCH_CONFIG_COLOUR_NONE
255 # else
256 # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
257 # endif
258 
259 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
260 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
261 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
262 # if !defined(__clang__) // Handle Clang masquerading for msvc
263 # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
264 # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
265 # endif // MSVC_TRADITIONAL
266 # endif // __clang__
267 
268 #endif // _MSC_VER
269 
270 #if defined(_REENTRANT) || defined(_MSC_VER)
271 // Enable async processing, as -pthread is specified or no additional linking is required
272 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
273 #endif // _MSC_VER
274 
276 // Check if we are compiled with -fno-exceptions or equivalent
277 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
278 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
279 #endif
280 
282 // DJGPP
283 #ifdef __DJGPP__
284 # define CATCH_INTERNAL_CONFIG_NO_WCHAR
285 #endif // __DJGPP__
286 
288 // Embarcadero C++Build
289 #if defined(__BORLANDC__)
290  #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
291 #endif
292 
294 
295 // Use of __COUNTER__ is suppressed during code analysis in
296 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
297 // handled by it.
298 // Otherwise all supported compilers support COUNTER macro,
299 // but user still might want to turn it off
300 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
301  #define CATCH_INTERNAL_CONFIG_COUNTER
302 #endif
303 
305 
306 // RTX is a special version of Windows that is real time.
307 // This means that it is detected as Windows, but does not provide
308 // the same set of capabilities as real Windows does.
309 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
310  #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
311  #define CATCH_INTERNAL_CONFIG_NO_ASYNC
312  #define CATCH_CONFIG_COLOUR_NONE
313 #endif
314 
315 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
316 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
317 #endif
318 
319 // Various stdlib support checks that require __has_include
320 #if defined(__has_include)
321  // Check if string_view is available and usable
322  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
323  # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
324  #endif
325 
326  // Check if optional is available and usable
327  # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
328  # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
329  # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
330 
331  // Check if byte is available and usable
332  # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
333  # include <cstddef>
334  # if __cpp_lib_byte > 0
335  # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
336  # endif
337  # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
338 
339  // Check if variant is available and usable
340  # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
341  # if defined(__clang__) && (__clang_major__ < 8)
342  // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
343  // fix should be in clang 8, workaround in libstdc++ 8.2
344  # include <ciso646>
345  # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
346  # define CATCH_CONFIG_NO_CPP17_VARIANT
347  # else
348  # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
349  # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
350  # else
351  # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
352  # endif // defined(__clang__) && (__clang_major__ < 8)
353  # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
354 #endif // defined(__has_include)
355 
356 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
357 # define CATCH_CONFIG_COUNTER
358 #endif
359 #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)
360 # define CATCH_CONFIG_WINDOWS_SEH
361 #endif
362 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
363 #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)
364 # define CATCH_CONFIG_POSIX_SIGNALS
365 #endif
366 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
367 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
368 # define CATCH_CONFIG_WCHAR
369 #endif
370 
371 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
372 # define CATCH_CONFIG_CPP11_TO_STRING
373 #endif
374 
375 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
376 # define CATCH_CONFIG_CPP17_OPTIONAL
377 #endif
378 
379 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
380 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
381 #endif
382 
383 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
384 # define CATCH_CONFIG_CPP17_STRING_VIEW
385 #endif
386 
387 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
388 # define CATCH_CONFIG_CPP17_VARIANT
389 #endif
390 
391 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
392 # define CATCH_CONFIG_CPP17_BYTE
393 #endif
394 
395 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
396 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
397 #endif
398 
399 #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)
400 # define CATCH_CONFIG_NEW_CAPTURE
401 #endif
402 
403 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
404 # define CATCH_CONFIG_DISABLE_EXCEPTIONS
405 #endif
406 
407 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
408 # define CATCH_CONFIG_POLYFILL_ISNAN
409 #endif
410 
411 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
412 # define CATCH_CONFIG_USE_ASYNC
413 #endif
414 
415 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
416 # define CATCH_CONFIG_ANDROID_LOGWRITE
417 #endif
418 
419 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
420 # define CATCH_CONFIG_GLOBAL_NEXTAFTER
421 #endif
422 
423 // Even if we do not think the compiler has that warning, we still have
424 // to provide a macro that can be used by the code.
425 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
426 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
427 #endif
428 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
429 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
430 #endif
431 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
432 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
433 #endif
434 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
435 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
436 #endif
437 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
438 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
439 #endif
440 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
441 # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
442 #endif
443 
444 // The goal of this macro is to avoid evaluation of the arguments, but
445 // still have the compiler warn on problems inside...
446 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
447 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
448 #endif
449 
450 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
451 # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
452 #elif defined(__clang__) && (__clang_major__ < 5)
453 # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
454 #endif
455 
456 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
457 # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
458 #endif
459 
460 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
461 #define CATCH_TRY if ((true))
462 #define CATCH_CATCH_ALL if ((false))
463 #define CATCH_CATCH_ANON(type) if ((false))
464 #else
465 #define CATCH_TRY try
466 #define CATCH_CATCH_ALL catch (...)
467 #define CATCH_CATCH_ANON(type) catch (type)
468 #endif
469 
470 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
471 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
472 #endif
473 
474 // end catch_compiler_capabilities.h
475 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
476 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
477 #ifdef CATCH_CONFIG_COUNTER
478 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
479 #else
480 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
481 #endif
482 
483 #include <iosfwd>
484 #include <string>
485 #include <cstdint>
486 
487 // We need a dummy global operator<< so we can bring it into Catch namespace later
489 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
490 
491 namespace Catch {
492 
493  struct CaseSensitive { enum Choice {
494  Yes,
495  No
496  }; };
497 
498  class NonCopyable {
499  NonCopyable( NonCopyable const& ) = delete;
500  NonCopyable( NonCopyable && ) = delete;
501  NonCopyable& operator = ( NonCopyable const& ) = delete;
502  NonCopyable& operator = ( NonCopyable && ) = delete;
503 
504  protected:
505  NonCopyable();
506  virtual ~NonCopyable();
507  };
508 
509  struct SourceLineInfo {
510 
511  SourceLineInfo() = delete;
512  SourceLineInfo( char const* _file, std::size_t _line ) noexcept
513  : file( _file ),
514  line( _line )
515  {}
516 
517  SourceLineInfo( SourceLineInfo const& other ) = default;
518  SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
519  SourceLineInfo( SourceLineInfo&& ) noexcept = default;
520  SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
521 
522  bool empty() const noexcept { return file[0] == '\0'; }
523  bool operator == ( SourceLineInfo const& other ) const noexcept;
524  bool operator < ( SourceLineInfo const& other ) const noexcept;
525 
526  char const* file;
527  std::size_t line;
528  };
529 
530  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
531 
532  // Bring in operator<< from global namespace into Catch namespace
533  // This is necessary because the overload of operator<< above makes
534  // lookup stop at namespace Catch
535  using ::operator<<;
536 
537  // Use this in variadic streaming macros to allow
538  // >> +StreamEndStop
539  // as well as
540  // >> stuff +StreamEndStop
541  struct StreamEndStop {
542  std::string operator+() const;
543  };
544  template<typename T>
545  T const& operator + ( T const& value, StreamEndStop ) {
546  return value;
547  }
548 }
549 
550 #define CATCH_INTERNAL_LINEINFO \
551  ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
552 
553 // end catch_common.h
554 namespace Catch {
555 
557  RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
558  };
559 
560 } // end namespace Catch
561 
562 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
563  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
564  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
565  namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
566  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
567 
568 // end catch_tag_alias_autoregistrar.h
569 // start catch_test_registry.h
570 
571 // start catch_interfaces_testcase.h
572 
573 #include <vector>
574 
575 namespace Catch {
576 
577  class TestSpec;
578 
579  struct ITestInvoker {
580  virtual void invoke () const = 0;
581  virtual ~ITestInvoker();
582  };
583 
584  class TestCase;
585  struct IConfig;
586 
588  virtual ~ITestCaseRegistry();
589  virtual std::vector<TestCase> const& getAllTests() const = 0;
590  virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
591  };
592 
593  bool isThrowSafe( TestCase const& testCase, IConfig const& config );
594  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
595  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
596  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
597 
598 }
599 
600 // end catch_interfaces_testcase.h
601 // start catch_stringref.h
602 
603 #include <cstddef>
604 #include <string>
605 #include <iosfwd>
606 #include <cassert>
607 
608 namespace Catch {
609 
613  class StringRef {
614  public:
615  using size_type = std::size_t;
616  using const_iterator = const char*;
617 
618  private:
619  static constexpr char const* const s_empty = "";
620 
621  char const* m_start = s_empty;
622  size_type m_size = 0;
623 
624  public: // construction
625  constexpr StringRef() noexcept = default;
626 
627  StringRef( char const* rawChars ) noexcept;
628 
629  constexpr StringRef( char const* rawChars, size_type size ) noexcept
630  : m_start( rawChars ),
631  m_size( size )
632  {}
633 
634  StringRef( std::string const& stdString ) noexcept
635  : m_start( stdString.c_str() ),
636  m_size( stdString.size() )
637  {}
638 
639  explicit operator std::string() const {
640  return std::string(m_start, m_size);
641  }
642 
643  public: // operators
644  auto operator == ( StringRef const& other ) const noexcept -> bool;
645  auto operator != (StringRef const& other) const noexcept -> bool {
646  return !(*this == other);
647  }
648 
649  auto operator[] ( size_type index ) const noexcept -> char {
650  assert(index < m_size);
651  return m_start[index];
652  }
653 
654  public: // named queries
655  constexpr auto empty() const noexcept -> bool {
656  return m_size == 0;
657  }
658  constexpr auto size() const noexcept -> size_type {
659  return m_size;
660  }
661 
662  // Returns the current start pointer. If the StringRef is not
663  // null-terminated, throws std::domain_exception
664  auto c_str() const -> char const*;
665 
666  public: // substrings and searches
667  // Returns a substring of [start, start + length).
668  // If start + length > size(), then the substring is [start, size()).
669  // If start > size(), then the substring is empty.
670  auto substr( size_type start, size_type length ) const noexcept -> StringRef;
671 
672  // Returns the current start pointer. May not be null-terminated.
673  auto data() const noexcept -> char const*;
674 
675  constexpr auto isNullTerminated() const noexcept -> bool {
676  return m_start[m_size] == '\0';
677  }
678 
679  public: // iterators
680  constexpr const_iterator begin() const { return m_start; }
681  constexpr const_iterator end() const { return m_start + m_size; }
682  };
683 
684  auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
685  auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
686 
687  constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
688  return StringRef( rawChars, size );
689  }
690 } // namespace Catch
691 
692 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
693  return Catch::StringRef( rawChars, size );
694 }
695 
696 // end catch_stringref.h
697 // start catch_preprocessor.hpp
698 
699 
700 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
701 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
702 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
703 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
704 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
705 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
706 
707 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
708 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
709 // MSVC needs more evaluations
710 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
711 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
712 #else
713 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
714 #endif
715 
716 #define CATCH_REC_END(...)
717 #define CATCH_REC_OUT
718 
719 #define CATCH_EMPTY()
720 #define CATCH_DEFER(id) id CATCH_EMPTY()
721 
722 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
723 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
724 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
725 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
726 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
727 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
728 
729 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
730 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
731 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
732 
733 #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__ )
734 #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__ )
735 #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__ )
736 
737 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
738 // and passes userdata as the first parameter to each invocation,
739 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
740 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
741 
742 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
743 
744 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
745 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
746 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
747 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
748 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
749 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
750 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
751 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
752 #else
753 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
754 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
755 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
756 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
757 #endif
758 
759 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
760 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
761 
762 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
763 
764 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
765 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
766 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
767 #else
768 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
769 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
770 #endif
771 
772 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
773  CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
774 
775 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
776 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
777 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
778 #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)
779 #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)
780 #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)
781 #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)
782 #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)
783 #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)
784 #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)
785 #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)
786 
787 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
788 
789 #define INTERNAL_CATCH_TYPE_GEN\
790  template<typename...> struct TypeList {};\
791  template<typename...Ts>\
792  constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
793  template<template<typename...> class...> struct TemplateTypeList{};\
794  template<template<typename...> class...Cs>\
795  constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
796  template<typename...>\
797  struct append;\
798  template<typename...>\
799  struct rewrap;\
800  template<template<typename...> class, typename...>\
801  struct create;\
802  template<template<typename...> class, typename>\
803  struct convert;\
804  \
805  template<typename T> \
806  struct append<T> { using type = T; };\
807  template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
808  struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
809  template< template<typename...> class L1, typename...E1, typename...Rest>\
810  struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
811  \
812  template< template<typename...> class Container, template<typename...> class List, typename...elems>\
813  struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
814  template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
815  struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
816  \
817  template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
818  struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
819  template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
820  struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
821 
822 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
823  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
824  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
825  constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
826  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
827  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
828  constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
829  \
830  template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
831  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
832  template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
833  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
834  template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
835  struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
836 
837 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
838 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
839  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
840  static void TestName()
841 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
842  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
843  static void TestName()
844 
845 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
846 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
847  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
848  static void TestName()
849 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
850  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
851  static void TestName()
852 
853 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
854  template<typename Type>\
855  void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
856  {\
857  Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
858  }
859 
860 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
861  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
862  void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
863  {\
864  Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
865  }
866 
867 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
868  template<typename Type>\
869  void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
870  {\
871  Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
872  }
873 
874 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
875  template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
876  void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
877  {\
878  Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
879  }
880 
881 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
882 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
883  template<typename TestType> \
884  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
885  void test();\
886  }
887 
888 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
889  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
890  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
891  void test();\
892  }
893 
894 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
895 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
896  template<typename TestType> \
897  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
898 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
899  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
900  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
901 
902 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
903 #define INTERNAL_CATCH_NTTP_0
904 #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)
905 #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__)
906 #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__)
907 #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__)
908 #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__)
909 #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__)
910 #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__)
911 #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__)
912 #else
913 #define INTERNAL_CATCH_NTTP_0(signature)
914 #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__))
915 #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__))
916 #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__))
917 #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__))
918 #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__))
919 #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__))
920 #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__))
921 #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__))
922 #endif
923 
924 // end catch_preprocessor.hpp
925 // start catch_meta.hpp
926 
927 
928 #include <type_traits>
929 
930 namespace Catch {
931  template<typename T>
932  struct always_false : std::false_type {};
933 
934  template <typename> struct true_given : std::true_type {};
936  template <typename Fun, typename... Args>
937  true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
938  template <typename...>
939  std::false_type static test(...);
940  };
941 
942  template <typename T>
943  struct is_callable;
944 
945  template <typename Fun, typename... Args>
946  struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
947 
948 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
949  // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
950  // replaced with std::invoke_result here.
951  template <typename Func, typename... U>
952  using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
953 #else
954  // Keep ::type here because we still support C++11
955  template <typename Func, typename... U>
956  using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
957 #endif
958 
959 } // namespace Catch
960 
961 namespace mpl_{
962  struct na;
963 }
964 
965 // end catch_meta.hpp
966 namespace Catch {
967 
968 template<typename C>
970  void (C::*m_testAsMethod)();
971 public:
972  TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
973 
974  void invoke() const override {
975  C obj;
976  (obj.*m_testAsMethod)();
977  }
978 };
979 
980 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
981 
982 template<typename C>
983 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
984  return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
985 }
986 
987 struct NameAndTags {
988  NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
989  StringRef name;
990  StringRef tags;
991 };
992 
994  AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
995  ~AutoReg();
996 };
997 
998 } // end namespace Catch
999 
1000 #if defined(CATCH_CONFIG_DISABLE)
1001  #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
1002  static void TestName()
1003  #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
1004  namespace{ \
1005  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1006  void test(); \
1007  }; \
1008  } \
1009  void TestName::test()
1010  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
1011  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1012  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1013  namespace{ \
1014  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1015  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1016  } \
1017  } \
1018  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1019 
1020  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1021  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1022  INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
1023  #else
1024  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1025  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__ ) )
1026  #endif
1027 
1028  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1029  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1030  INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
1031  #else
1032  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1033  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__ ) )
1034  #endif
1035 
1036  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1037  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1038  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
1039  #else
1040  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1041  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__ ) )
1042  #endif
1043 
1044  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1045  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1046  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
1047  #else
1048  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1049  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__ ) )
1050  #endif
1051 #endif
1052 
1054  #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
1055  static void TestName(); \
1056  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1057  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1058  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1059  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1060  static void TestName()
1061  #define INTERNAL_CATCH_TESTCASE( ... ) \
1062  INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
1063 
1065  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
1066  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1067  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1068  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1069  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1070 
1072  #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
1073  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1074  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1075  namespace{ \
1076  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1077  void test(); \
1078  }; \
1079  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1080  } \
1081  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1082  void TestName::test()
1083  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
1084  INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
1085 
1087  #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
1088  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1089  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1090  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1091  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1092 
1094  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
1095  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1096  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1097  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1098  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1099  INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1100  namespace {\
1101  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1102  INTERNAL_CATCH_TYPE_GEN\
1103  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1104  INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1105  template<typename...Types> \
1106  struct TestName{\
1107  TestName(){\
1108  int index = 0; \
1109  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1110  using expander = int[];\
1111  (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
1112  }\
1113  };\
1114  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1115  TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1116  return 0;\
1117  }();\
1118  }\
1119  }\
1120  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1121  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
1122 
1123 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1124  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1125  INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
1126 #else
1127  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1128  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__ ) )
1129 #endif
1130 
1131 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1132  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1133  INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
1134 #else
1135  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1136  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__ ) )
1137 #endif
1138 
1139  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
1140  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1141  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1142  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1143  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1144  template<typename TestType> static void TestFuncName(); \
1145  namespace {\
1146  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1147  INTERNAL_CATCH_TYPE_GEN \
1148  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1149  template<typename... Types> \
1150  struct TestName { \
1151  void reg_tests() { \
1152  int index = 0; \
1153  using expander = int[]; \
1154  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1155  constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1156  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1157  (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 */\
1158  } \
1159  }; \
1160  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1161  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; \
1162  TestInit t; \
1163  t.reg_tests(); \
1164  return 0; \
1165  }(); \
1166  } \
1167  } \
1168  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1169  template<typename TestType> \
1170  static void TestFuncName()
1171 
1172 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1173  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1174  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
1175 #else
1176  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1177  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__ ) )
1178 #endif
1179 
1180 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1181  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1182  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
1183 #else
1184  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1185  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__ ) )
1186 #endif
1187 
1188  #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
1189  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1190  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1191  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1192  template<typename TestType> static void TestFunc(); \
1193  namespace {\
1194  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1195  INTERNAL_CATCH_TYPE_GEN\
1196  template<typename... Types> \
1197  struct TestName { \
1198  void reg_tests() { \
1199  int index = 0; \
1200  using expander = int[]; \
1201  (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 */\
1202  } \
1203  };\
1204  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1205  using TestInit = typename convert<TestName, TmplList>::type; \
1206  TestInit t; \
1207  t.reg_tests(); \
1208  return 0; \
1209  }(); \
1210  }}\
1211  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1212  template<typename TestType> \
1213  static void TestFunc()
1214 
1215  #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
1216  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 )
1217 
1218  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1219  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1220  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1221  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1222  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1223  namespace {\
1224  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1225  INTERNAL_CATCH_TYPE_GEN\
1226  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1227  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1228  INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1229  template<typename...Types> \
1230  struct TestNameClass{\
1231  TestNameClass(){\
1232  int index = 0; \
1233  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1234  using expander = int[];\
1235  (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
1236  }\
1237  };\
1238  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1239  TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1240  return 0;\
1241  }();\
1242  }\
1243  }\
1244  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1245  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1246 
1247 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1248  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1249  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
1250 #else
1251  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1252  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__ ) )
1253 #endif
1254 
1255 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1256  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1257  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
1258 #else
1259  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1260  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__ ) )
1261 #endif
1262 
1263  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
1264  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1265  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1266  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1267  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1268  template<typename TestType> \
1269  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1270  void test();\
1271  };\
1272  namespace {\
1273  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
1274  INTERNAL_CATCH_TYPE_GEN \
1275  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1276  template<typename...Types>\
1277  struct TestNameClass{\
1278  void reg_tests(){\
1279  int index = 0;\
1280  using expander = int[];\
1281  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1282  constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1283  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1284  (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 */ \
1285  }\
1286  };\
1287  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1288  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;\
1289  TestInit t;\
1290  t.reg_tests();\
1291  return 0;\
1292  }(); \
1293  }\
1294  }\
1295  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1296  template<typename TestType> \
1297  void TestName<TestType>::test()
1298 
1299 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1300  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1301  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
1302 #else
1303  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1304  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__ ) )
1305 #endif
1306 
1307 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1308  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1309  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
1310 #else
1311  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1312  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__ ) )
1313 #endif
1314 
1315  #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
1316  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1317  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1318  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1319  template<typename TestType> \
1320  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1321  void test();\
1322  };\
1323  namespace {\
1324  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1325  INTERNAL_CATCH_TYPE_GEN\
1326  template<typename...Types>\
1327  struct TestNameClass{\
1328  void reg_tests(){\
1329  int index = 0;\
1330  using expander = int[];\
1331  (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 */ \
1332  }\
1333  };\
1334  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1335  using TestInit = typename convert<TestNameClass, TmplList>::type;\
1336  TestInit t;\
1337  t.reg_tests();\
1338  return 0;\
1339  }(); \
1340  }}\
1341  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1342  template<typename TestType> \
1343  void TestName<TestType>::test()
1344 
1345 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
1346  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 )
1347 
1348 // end catch_test_registry.h
1349 // start catch_capture.hpp
1350 
1351 // start catch_assertionhandler.h
1352 
1353 // start catch_assertioninfo.h
1354 
1355 // start catch_result_type.h
1356 
1357 namespace Catch {
1358 
1359  // ResultWas::OfType enum
1360  struct ResultWas { enum OfType {
1361  Unknown = -1,
1362  Ok = 0,
1363  Info = 1,
1364  Warning = 2,
1365 
1366  FailureBit = 0x10,
1367 
1368  ExpressionFailed = FailureBit | 1,
1369  ExplicitFailure = FailureBit | 2,
1370 
1371  Exception = 0x100 | FailureBit,
1372 
1373  ThrewException = Exception | 1,
1374  DidntThrowException = Exception | 2,
1375 
1376  FatalErrorCondition = 0x200 | FailureBit
1377 
1378  }; };
1379 
1380  bool isOk( ResultWas::OfType resultType );
1381  bool isJustInfo( int flags );
1382 
1383  // ResultDisposition::Flags enum
1384  struct ResultDisposition { enum Flags {
1385  Normal = 0x01,
1386 
1387  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
1388  FalseTest = 0x04, // Prefix expression with !
1389  SuppressFail = 0x08 // Failures are reported but do not fail the test
1390  }; };
1391 
1392  ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
1393 
1394  bool shouldContinueOnFailure( int flags );
1395  inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
1396  bool shouldSuppressFailure( int flags );
1397 
1398 } // end namespace Catch
1399 
1400 // end catch_result_type.h
1401 namespace Catch {
1402 
1404  {
1405  StringRef macroName;
1406  SourceLineInfo lineInfo;
1407  StringRef capturedExpression;
1408  ResultDisposition::Flags resultDisposition;
1409 
1410  // We want to delete this constructor but a compiler bug in 4.8 means
1411  // the struct is then treated as non-aggregate
1412  //AssertionInfo() = delete;
1413  };
1414 
1415 } // end namespace Catch
1416 
1417 // end catch_assertioninfo.h
1418 // start catch_decomposer.h
1419 
1420 // start catch_tostring.h
1421 
1422 #include <vector>
1423 #include <cstddef>
1424 #include <type_traits>
1425 #include <string>
1426 // start catch_stream.h
1427 
1428 #include <iosfwd>
1429 #include <cstddef>
1430 #include <ostream>
1431 
1432 namespace Catch {
1433 
1434  std::ostream& cout();
1435  std::ostream& cerr();
1436  std::ostream& clog();
1437 
1438  class StringRef;
1439 
1440  struct IStream {
1441  virtual ~IStream();
1442  virtual std::ostream& stream() const = 0;
1443  };
1444 
1445  auto makeStream( StringRef const &filename ) -> IStream const*;
1446 
1448  std::size_t m_index;
1449  std::ostream* m_oss;
1450  public:
1453 
1454  auto str() const -> std::string;
1455 
1456  template<typename T>
1457  auto operator << ( T const& value ) -> ReusableStringStream& {
1458  *m_oss << value;
1459  return *this;
1460  }
1461  auto get() -> std::ostream& { return *m_oss; }
1462  };
1463 }
1464 
1465 // end catch_stream.h
1466 // start catch_interfaces_enum_values_registry.h
1467 
1468 #include <vector>
1469 
1470 namespace Catch {
1471 
1472  namespace Detail {
1473  struct EnumInfo {
1474  StringRef m_name;
1475  std::vector<std::pair<int, StringRef>> m_values;
1476 
1477  ~EnumInfo();
1478 
1479  StringRef lookup( int value ) const;
1480  };
1481  } // namespace Detail
1482 
1484  virtual ~IMutableEnumValuesRegistry();
1485 
1486  virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
1487 
1488  template<typename E>
1489  Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
1490  static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1491  std::vector<int> intValues;
1492  intValues.reserve( values.size() );
1493  for( auto enumValue : values )
1494  intValues.push_back( static_cast<int>( enumValue ) );
1495  return registerEnum( enumName, allEnums, intValues );
1496  }
1497  };
1498 
1499 } // Catch
1500 
1501 // end catch_interfaces_enum_values_registry.h
1502 
1503 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1504 #include <string_view>
1505 #endif
1506 
1507 #ifdef __OBJC__
1508 // start catch_objc_arc.hpp
1509 
1510 #import <Foundation/Foundation.h>
1511 
1512 #ifdef __has_feature
1513 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1514 #else
1515 #define CATCH_ARC_ENABLED 0
1516 #endif
1517 
1518 void arcSafeRelease( NSObject* obj );
1519 id performOptionalSelector( id obj, SEL sel );
1520 
1521 #if !CATCH_ARC_ENABLED
1522 inline void arcSafeRelease( NSObject* obj ) {
1523  [obj release];
1524 }
1525 inline id performOptionalSelector( id obj, SEL sel ) {
1526  if( [obj respondsToSelector: sel] )
1527  return [obj performSelector: sel];
1528  return nil;
1529 }
1530 #define CATCH_UNSAFE_UNRETAINED
1531 #define CATCH_ARC_STRONG
1532 #else
1533 inline void arcSafeRelease( NSObject* ){}
1534 inline id performOptionalSelector( id obj, SEL sel ) {
1535 #ifdef __clang__
1536 #pragma clang diagnostic push
1537 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1538 #endif
1539  if( [obj respondsToSelector: sel] )
1540  return [obj performSelector: sel];
1541 #ifdef __clang__
1542 #pragma clang diagnostic pop
1543 #endif
1544  return nil;
1545 }
1546 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1547 #define CATCH_ARC_STRONG __strong
1548 #endif
1549 
1550 // end catch_objc_arc.hpp
1551 #endif
1552 
1553 #ifdef _MSC_VER
1554 #pragma warning(push)
1555 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1556 #endif
1557 
1558 namespace Catch {
1559  namespace Detail {
1560 
1561  extern const std::string unprintableString;
1562 
1563  std::string rawMemoryToString( const void *object, std::size_t size );
1564 
1565  template<typename T>
1566  std::string rawMemoryToString( const T& object ) {
1567  return rawMemoryToString( &object, sizeof(object) );
1568  }
1569 
1570  template<typename T>
1572  template<typename Stream, typename U>
1573  static auto test(int)
1574  -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
1575 
1576  template<typename, typename>
1577  static auto test(...)->std::false_type;
1578 
1579  public:
1580  static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1581  };
1582 
1583  template<typename E>
1584  std::string convertUnknownEnumToString( E e );
1585 
1586  template<typename T>
1587  typename std::enable_if<
1588  !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
1589  std::string>::type convertUnstreamable( T const& ) {
1590  return Detail::unprintableString;
1591  }
1592  template<typename T>
1593  typename std::enable_if<
1594  !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
1595  std::string>::type convertUnstreamable(T const& ex) {
1596  return ex.what();
1597  }
1598 
1599  template<typename T>
1600  typename std::enable_if<
1601  std::is_enum<T>::value
1602  , std::string>::type convertUnstreamable( T const& value ) {
1603  return convertUnknownEnumToString( value );
1604  }
1605 
1606 #if defined(_MANAGED)
1608  template<typename T>
1609  std::string clrReferenceToString( T^ ref ) {
1610  if (ref == nullptr)
1611  return std::string("null");
1612  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1613  cli::pin_ptr<System::Byte> p = &bytes[0];
1614  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1615  }
1616 #endif
1617 
1618  } // namespace Detail
1619 
1620  // If we decide for C++14, change these to enable_if_ts
1621  template <typename T, typename = void>
1622  struct StringMaker {
1623  template <typename Fake = T>
1624  static
1625  typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1626  convert(const Fake& value) {
1628  // NB: call using the function-like syntax to avoid ambiguity with
1629  // user-defined templated operator<< under clang.
1630  rss.operator<<(value);
1631  return rss.str();
1632  }
1633 
1634  template <typename Fake = T>
1635  static
1636  typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1637  convert( const Fake& value ) {
1638 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1639  return Detail::convertUnstreamable(value);
1640 #else
1641  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1642 #endif
1643  }
1644  };
1645 
1646  namespace Detail {
1647 
1648  // This function dispatches all stringification requests inside of Catch.
1649  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1650  template <typename T>
1651  std::string stringify(const T& e) {
1652  return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1653  }
1654 
1655  template<typename E>
1656  std::string convertUnknownEnumToString( E e ) {
1657  return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1658  }
1659 
1660 #if defined(_MANAGED)
1661  template <typename T>
1662  std::string stringify( T^ e ) {
1663  return ::Catch::StringMaker<T^>::convert(e);
1664  }
1665 #endif
1666 
1667  } // namespace Detail
1668 
1669  // Some predefined specializations
1670 
1671  template<>
1672  struct StringMaker<std::string> {
1673  static std::string convert(const std::string& str);
1674  };
1675 
1676 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1677  template<>
1678  struct StringMaker<std::string_view> {
1679  static std::string convert(std::string_view str);
1680  };
1681 #endif
1682 
1683  template<>
1684  struct StringMaker<char const *> {
1685  static std::string convert(char const * str);
1686  };
1687  template<>
1688  struct StringMaker<char *> {
1689  static std::string convert(char * str);
1690  };
1691 
1692 #ifdef CATCH_CONFIG_WCHAR
1693  template<>
1694  struct StringMaker<std::wstring> {
1695  static std::string convert(const std::wstring& wstr);
1696  };
1697 
1698 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1699  template<>
1700  struct StringMaker<std::wstring_view> {
1701  static std::string convert(std::wstring_view str);
1702  };
1703 # endif
1704 
1705  template<>
1706  struct StringMaker<wchar_t const *> {
1707  static std::string convert(wchar_t const * str);
1708  };
1709  template<>
1710  struct StringMaker<wchar_t *> {
1711  static std::string convert(wchar_t * str);
1712  };
1713 #endif
1714 
1715  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1716  // while keeping string semantics?
1717  template<int SZ>
1718  struct StringMaker<char[SZ]> {
1719  static std::string convert(char const* str) {
1720  return ::Catch::Detail::stringify(std::string{ str });
1721  }
1722  };
1723  template<int SZ>
1724  struct StringMaker<signed char[SZ]> {
1725  static std::string convert(signed char const* str) {
1726  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1727  }
1728  };
1729  template<int SZ>
1730  struct StringMaker<unsigned char[SZ]> {
1731  static std::string convert(unsigned char const* str) {
1732  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1733  }
1734  };
1735 
1736 #if defined(CATCH_CONFIG_CPP17_BYTE)
1737  template<>
1738  struct StringMaker<std::byte> {
1739  static std::string convert(std::byte value);
1740  };
1741 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
1742  template<>
1743  struct StringMaker<int> {
1744  static std::string convert(int value);
1745  };
1746  template<>
1747  struct StringMaker<long> {
1748  static std::string convert(long value);
1749  };
1750  template<>
1751  struct StringMaker<long long> {
1752  static std::string convert(long long value);
1753  };
1754  template<>
1755  struct StringMaker<unsigned int> {
1756  static std::string convert(unsigned int value);
1757  };
1758  template<>
1759  struct StringMaker<unsigned long> {
1760  static std::string convert(unsigned long value);
1761  };
1762  template<>
1763  struct StringMaker<unsigned long long> {
1764  static std::string convert(unsigned long long value);
1765  };
1766 
1767  template<>
1768  struct StringMaker<bool> {
1769  static std::string convert(bool b);
1770  };
1771 
1772  template<>
1773  struct StringMaker<char> {
1774  static std::string convert(char c);
1775  };
1776  template<>
1777  struct StringMaker<signed char> {
1778  static std::string convert(signed char c);
1779  };
1780  template<>
1781  struct StringMaker<unsigned char> {
1782  static std::string convert(unsigned char c);
1783  };
1784 
1785  template<>
1786  struct StringMaker<std::nullptr_t> {
1787  static std::string convert(std::nullptr_t);
1788  };
1789 
1790  template<>
1791  struct StringMaker<float> {
1792  static std::string convert(float value);
1793  static int precision;
1794  };
1795 
1796  template<>
1797  struct StringMaker<double> {
1798  static std::string convert(double value);
1799  static int precision;
1800  };
1801 
1802  template <typename T>
1803  struct StringMaker<T*> {
1804  template <typename U>
1805  static std::string convert(U* p) {
1806  if (p) {
1807  return ::Catch::Detail::rawMemoryToString(p);
1808  } else {
1809  return "nullptr";
1810  }
1811  }
1812  };
1813 
1814  template <typename R, typename C>
1815  struct StringMaker<R C::*> {
1816  static std::string convert(R C::* p) {
1817  if (p) {
1818  return ::Catch::Detail::rawMemoryToString(p);
1819  } else {
1820  return "nullptr";
1821  }
1822  }
1823  };
1824 
1825 #if defined(_MANAGED)
1826  template <typename T>
1827  struct StringMaker<T^> {
1828  static std::string convert( T^ ref ) {
1829  return ::Catch::Detail::clrReferenceToString(ref);
1830  }
1831  };
1832 #endif
1833 
1834  namespace Detail {
1835  template<typename InputIterator, typename Sentinel = InputIterator>
1836  std::string rangeToString(InputIterator first, Sentinel last) {
1838  rss << "{ ";
1839  if (first != last) {
1840  rss << ::Catch::Detail::stringify(*first);
1841  for (++first; first != last; ++first)
1842  rss << ", " << ::Catch::Detail::stringify(*first);
1843  }
1844  rss << " }";
1845  return rss.str();
1846  }
1847  }
1848 
1849 #ifdef __OBJC__
1850  template<>
1851  struct StringMaker<NSString*> {
1852  static std::string convert(NSString * nsstring) {
1853  if (!nsstring)
1854  return "nil";
1855  return std::string("@") + [nsstring UTF8String];
1856  }
1857  };
1858  template<>
1859  struct StringMaker<NSObject*> {
1860  static std::string convert(NSObject* nsObject) {
1861  return ::Catch::Detail::stringify([nsObject description]);
1862  }
1863 
1864  };
1865  namespace Detail {
1866  inline std::string stringify( NSString* nsstring ) {
1867  return StringMaker<NSString*>::convert( nsstring );
1868  }
1869 
1870  } // namespace Detail
1871 #endif // __OBJC__
1872 
1873 } // namespace Catch
1874 
1876 // Separate std-lib types stringification, so it can be selectively enabled
1877 // This means that we do not bring in
1878 
1879 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1880 # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1881 # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1882 # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1883 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1884 # define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1885 #endif
1886 
1887 // Separate std::pair specialization
1888 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1889 #include <utility>
1890 namespace Catch {
1891  template<typename T1, typename T2>
1892  struct StringMaker<std::pair<T1, T2> > {
1893  static std::string convert(const std::pair<T1, T2>& pair) {
1895  rss << "{ "
1896  << ::Catch::Detail::stringify(pair.first)
1897  << ", "
1898  << ::Catch::Detail::stringify(pair.second)
1899  << " }";
1900  return rss.str();
1901  }
1902  };
1903 }
1904 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1905 
1906 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
1907 #include <optional>
1908 namespace Catch {
1909  template<typename T>
1910  struct StringMaker<std::optional<T> > {
1911  static std::string convert(const std::optional<T>& optional) {
1913  if (optional.has_value()) {
1914  rss << ::Catch::Detail::stringify(*optional);
1915  } else {
1916  rss << "{ }";
1917  }
1918  return rss.str();
1919  }
1920  };
1921 }
1922 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1923 
1924 // Separate std::tuple specialization
1925 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1926 #include <tuple>
1927 namespace Catch {
1928  namespace Detail {
1929  template<
1930  typename Tuple,
1931  std::size_t N = 0,
1932  bool = (N < std::tuple_size<Tuple>::value)
1933  >
1935  static void print(const Tuple& tuple, std::ostream& os) {
1936  os << (N ? ", " : " ")
1937  << ::Catch::Detail::stringify(std::get<N>(tuple));
1939  }
1940  };
1941 
1942  template<
1943  typename Tuple,
1944  std::size_t N
1945  >
1946  struct TupleElementPrinter<Tuple, N, false> {
1947  static void print(const Tuple&, std::ostream&) {}
1948  };
1949 
1950  }
1951 
1952  template<typename ...Types>
1953  struct StringMaker<std::tuple<Types...>> {
1954  static std::string convert(const std::tuple<Types...>& tuple) {
1956  rss << '{';
1957  Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1958  rss << " }";
1959  return rss.str();
1960  }
1961  };
1962 }
1963 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1964 
1965 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1966 #include <variant>
1967 namespace Catch {
1968  template<>
1969  struct StringMaker<std::monostate> {
1970  static std::string convert(const std::monostate&) {
1971  return "{ }";
1972  }
1973  };
1974 
1975  template<typename... Elements>
1976  struct StringMaker<std::variant<Elements...>> {
1977  static std::string convert(const std::variant<Elements...>& variant) {
1978  if (variant.valueless_by_exception()) {
1979  return "{valueless variant}";
1980  } else {
1981  return std::visit(
1982  [](const auto& value) {
1983  return ::Catch::Detail::stringify(value);
1984  },
1985  variant
1986  );
1987  }
1988  }
1989  };
1990 }
1991 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1992 
1993 namespace Catch {
1994  // Import begin/ end from std here
1995  using std::begin;
1996  using std::end;
1997 
1998  namespace detail {
1999  template <typename...>
2000  struct void_type {
2001  using type = void;
2002  };
2003 
2004  template <typename T, typename = void>
2005  struct is_range_impl : std::false_type {
2006  };
2007 
2008  template <typename T>
2010  };
2011  } // namespace detail
2012 
2013  template <typename T>
2015  };
2016 
2017 #if defined(_MANAGED) // Managed types are never ranges
2018  template <typename T>
2019  struct is_range<T^> {
2020  static const bool value = false;
2021  };
2022 #endif
2023 
2024  template<typename Range>
2025  std::string rangeToString( Range const& range ) {
2026  return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
2027  }
2028 
2029  // Handle vector<bool> specially
2030  template<typename Allocator>
2031  std::string rangeToString( std::vector<bool, Allocator> const& v ) {
2032  ReusableStringStream rss;
2033  rss << "{ ";
2034  bool first = true;
2035  for( bool b : v ) {
2036  if( first )
2037  first = false;
2038  else
2039  rss << ", ";
2040  rss << ::Catch::Detail::stringify( b );
2041  }
2042  rss << " }";
2043  return rss.str();
2044  }
2045 
2046  template<typename R>
2047  struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
2048  static std::string convert( R const& range ) {
2049  return rangeToString( range );
2050  }
2051  };
2052 
2053  template <typename T, int SZ>
2054  struct StringMaker<T[SZ]> {
2055  static std::string convert(T const(&arr)[SZ]) {
2056  return rangeToString(arr);
2057  }
2058  };
2059 
2060 } // namespace Catch
2061 
2062 // Separate std::chrono::duration specialization
2063 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2064 #include <ctime>
2065 #include <ratio>
2066 #include <chrono>
2067 
2068 namespace Catch {
2069 
2070 template <class Ratio>
2072  static std::string symbol();
2073 };
2074 
2075 template <class Ratio>
2076 std::string ratio_string<Ratio>::symbol() {
2078  rss << '[' << Ratio::num << '/'
2079  << Ratio::den << ']';
2080  return rss.str();
2081 }
2082 template <>
2083 struct ratio_string<std::atto> {
2084  static std::string symbol();
2085 };
2086 template <>
2087 struct ratio_string<std::femto> {
2088  static std::string symbol();
2089 };
2090 template <>
2091 struct ratio_string<std::pico> {
2092  static std::string symbol();
2093 };
2094 template <>
2095 struct ratio_string<std::nano> {
2096  static std::string symbol();
2097 };
2098 template <>
2099 struct ratio_string<std::micro> {
2100  static std::string symbol();
2101 };
2102 template <>
2103 struct ratio_string<std::milli> {
2104  static std::string symbol();
2105 };
2106 
2108  // std::chrono::duration specializations
2109  template<typename Value, typename Ratio>
2110  struct StringMaker<std::chrono::duration<Value, Ratio>> {
2111  static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
2113  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2114  return rss.str();
2115  }
2116  };
2117  template<typename Value>
2118  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2119  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
2121  rss << duration.count() << " s";
2122  return rss.str();
2123  }
2124  };
2125  template<typename Value>
2126  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2127  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
2129  rss << duration.count() << " m";
2130  return rss.str();
2131  }
2132  };
2133  template<typename Value>
2134  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2135  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
2137  rss << duration.count() << " h";
2138  return rss.str();
2139  }
2140  };
2141 
2143  // std::chrono::time_point specialization
2144  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2145  template<typename Clock, typename Duration>
2146  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2147  static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
2148  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2149  }
2150  };
2151  // std::chrono::time_point<system_clock> specialization
2152  template<typename Duration>
2153  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
2154  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
2155  auto converted = std::chrono::system_clock::to_time_t(time_point);
2156 
2157 #ifdef _MSC_VER
2158  std::tm timeInfo = {};
2159  gmtime_s(&timeInfo, &converted);
2160 #else
2161  std::tm* timeInfo = std::gmtime(&converted);
2162 #endif
2163 
2164  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2165  char timeStamp[timeStampSize];
2166  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
2167 
2168 #ifdef _MSC_VER
2169  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2170 #else
2171  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2172 #endif
2173  return std::string(timeStamp);
2174  }
2175  };
2176 }
2177 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2178 
2179 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
2180 namespace Catch { \
2181  template<> struct StringMaker<enumName> { \
2182  static std::string convert( enumName value ) { \
2183  static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
2184  return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
2185  } \
2186  }; \
2187 }
2188 
2189 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
2190 
2191 #ifdef _MSC_VER
2192 #pragma warning(pop)
2193 #endif
2194 
2195 // end catch_tostring.h
2196 #include <iosfwd>
2197 
2198 #ifdef _MSC_VER
2199 #pragma warning(push)
2200 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
2201 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
2202 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2203 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
2204 #pragma warning(disable:4800) // Forcing result to true or false
2205 #endif
2206 
2207 namespace Catch {
2208 
2210  auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
2211  auto getResult() const -> bool { return m_result; }
2212  virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
2213 
2214  ITransientExpression( bool isBinaryExpression, bool result )
2215  : m_isBinaryExpression( isBinaryExpression ),
2216  m_result( result )
2217  {}
2218 
2219  // We don't actually need a virtual destructor, but many static analysers
2220  // complain if it's not here :-(
2221  virtual ~ITransientExpression();
2222 
2223  bool m_isBinaryExpression;
2224  bool m_result;
2225 
2226  };
2227 
2228  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
2229 
2230  template<typename LhsT, typename RhsT>
2232  LhsT m_lhs;
2233  StringRef m_op;
2234  RhsT m_rhs;
2235 
2236  void streamReconstructedExpression( std::ostream &os ) const override {
2237  formatReconstructedExpression
2238  ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
2239  }
2240 
2241  public:
2242  BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
2243  : ITransientExpression{ true, comparisonResult },
2244  m_lhs( lhs ),
2245  m_op( op ),
2246  m_rhs( rhs )
2247  {}
2248 
2249  template<typename T>
2250  auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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>
2257  auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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>
2264  auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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>
2271  auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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>
2278  auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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>
2285  auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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>
2292  auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
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  template<typename T>
2299  auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2300  static_assert(always_false<T>::value,
2301  "chained comparisons are not supported inside assertions, "
2302  "wrap the expression inside parentheses, or decompose it");
2303  }
2304  };
2305 
2306  template<typename LhsT>
2308  LhsT m_lhs;
2309 
2310  void streamReconstructedExpression( std::ostream &os ) const override {
2311  os << Catch::Detail::stringify( m_lhs );
2312  }
2313 
2314  public:
2315  explicit UnaryExpr( LhsT lhs )
2316  : ITransientExpression{ false, static_cast<bool>(lhs) },
2317  m_lhs( lhs )
2318  {}
2319  };
2320 
2321  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2322  template<typename LhsT, typename RhsT>
2323  auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
2324  template<typename T>
2325  auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2326  template<typename T>
2327  auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2328  template<typename T>
2329  auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2330  template<typename T>
2331  auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2332 
2333  template<typename LhsT, typename RhsT>
2334  auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
2335  template<typename T>
2336  auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2337  template<typename T>
2338  auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2339  template<typename T>
2340  auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2341  template<typename T>
2342  auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2343 
2344  template<typename LhsT>
2345  class ExprLhs {
2346  LhsT m_lhs;
2347  public:
2348  explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
2349 
2350  template<typename RhsT>
2351  auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2352  return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
2353  }
2354  auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2355  return { m_lhs == rhs, m_lhs, "==", rhs };
2356  }
2357 
2358  template<typename RhsT>
2359  auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2360  return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
2361  }
2362  auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2363  return { m_lhs != rhs, m_lhs, "!=", rhs };
2364  }
2365 
2366  template<typename RhsT>
2367  auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2368  return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
2369  }
2370  template<typename RhsT>
2371  auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2372  return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
2373  }
2374  template<typename RhsT>
2375  auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2376  return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
2377  }
2378  template<typename RhsT>
2379  auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2380  return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
2381  }
2382  template <typename RhsT>
2383  auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2384  return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
2385  }
2386  template <typename RhsT>
2387  auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2388  return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
2389  }
2390  template <typename RhsT>
2391  auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
2392  return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
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  template<typename RhsT>
2403  auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2404  static_assert(always_false<RhsT>::value,
2405  "operator|| is not supported inside assertions, "
2406  "wrap the expression inside parentheses, or decompose it");
2407  }
2408 
2409  auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
2410  return UnaryExpr<LhsT>{ m_lhs };
2411  }
2412  };
2413 
2414  void handleExpression( ITransientExpression const& expr );
2415 
2416  template<typename T>
2417  void handleExpression( ExprLhs<T> const& expr ) {
2418  handleExpression( expr.makeUnaryExpr() );
2419  }
2420 
2421  struct Decomposer {
2422  template<typename T>
2423  auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
2424  return ExprLhs<T const&>{ lhs };
2425  }
2426 
2427  auto operator <=( bool value ) -> ExprLhs<bool> {
2428  return ExprLhs<bool>{ value };
2429  }
2430  };
2431 
2432 } // end namespace Catch
2433 
2434 #ifdef _MSC_VER
2435 #pragma warning(pop)
2436 #endif
2437 
2438 // end catch_decomposer.h
2439 // start catch_interfaces_capture.h
2440 
2441 #include <string>
2442 #include <chrono>
2443 
2444 namespace Catch {
2445 
2446  class AssertionResult;
2447  struct AssertionInfo;
2448  struct SectionInfo;
2449  struct SectionEndInfo;
2450  struct MessageInfo;
2451  struct MessageBuilder;
2452  struct Counts;
2453  struct AssertionReaction;
2454  struct SourceLineInfo;
2455 
2456  struct ITransientExpression;
2457  struct IGeneratorTracker;
2458 
2459 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2460  struct BenchmarkInfo;
2461  template <typename Duration = std::chrono::duration<double, std::nano>>
2462  struct BenchmarkStats;
2463 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2464 
2466 
2467  virtual ~IResultCapture();
2468 
2469  virtual bool sectionStarted( SectionInfo const& sectionInfo,
2470  Counts& assertions ) = 0;
2471  virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2472  virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2473 
2474  virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
2475 
2476 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2477  virtual void benchmarkPreparing( std::string const& name ) = 0;
2478  virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
2479  virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
2480  virtual void benchmarkFailed( std::string const& error ) = 0;
2481 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2482 
2483  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2484  virtual void popScopedMessage( MessageInfo const& message ) = 0;
2485 
2486  virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
2487 
2488  virtual void handleFatalErrorCondition( StringRef message ) = 0;
2489 
2490  virtual void handleExpr
2491  ( AssertionInfo const& info,
2492  ITransientExpression const& expr,
2493  AssertionReaction& reaction ) = 0;
2494  virtual void handleMessage
2495  ( AssertionInfo const& info,
2496  ResultWas::OfType resultType,
2497  StringRef const& message,
2498  AssertionReaction& reaction ) = 0;
2499  virtual void handleUnexpectedExceptionNotThrown
2500  ( AssertionInfo const& info,
2501  AssertionReaction& reaction ) = 0;
2502  virtual void handleUnexpectedInflightException
2503  ( AssertionInfo const& info,
2504  std::string const& message,
2505  AssertionReaction& reaction ) = 0;
2506  virtual void handleIncomplete
2507  ( AssertionInfo const& info ) = 0;
2508  virtual void handleNonExpr
2509  ( AssertionInfo const &info,
2510  ResultWas::OfType resultType,
2511  AssertionReaction &reaction ) = 0;
2512 
2513  virtual bool lastAssertionPassed() = 0;
2514  virtual void assertionPassed() = 0;
2515 
2516  // Deprecated, do not use:
2517  virtual std::string getCurrentTestName() const = 0;
2518  virtual const AssertionResult* getLastResult() const = 0;
2519  virtual void exceptionEarlyReported() = 0;
2520  };
2521 
2522  IResultCapture& getResultCapture();
2523 }
2524 
2525 // end catch_interfaces_capture.h
2526 namespace Catch {
2527 
2529  struct AssertionResultData;
2530  struct IResultCapture;
2531  class RunContext;
2532 
2534  friend class AssertionHandler;
2535  friend struct AssertionStats;
2536  friend class RunContext;
2537 
2538  ITransientExpression const* m_transientExpression = nullptr;
2539  bool m_isNegated;
2540  public:
2541  LazyExpression( bool isNegated );
2542  LazyExpression( LazyExpression const& other );
2543  LazyExpression& operator = ( LazyExpression const& ) = delete;
2544 
2545  explicit operator bool() const;
2546 
2547  friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
2548  };
2549 
2551  bool shouldDebugBreak = false;
2552  bool shouldThrow = false;
2553  };
2554 
2556  AssertionInfo m_assertionInfo;
2557  AssertionReaction m_reaction;
2558  bool m_completed = false;
2559  IResultCapture& m_resultCapture;
2560 
2561  public:
2563  ( StringRef const& macroName,
2564  SourceLineInfo const& lineInfo,
2565  StringRef capturedExpression,
2566  ResultDisposition::Flags resultDisposition );
2567  ~AssertionHandler() {
2568  if ( !m_completed ) {
2569  m_resultCapture.handleIncomplete( m_assertionInfo );
2570  }
2571  }
2572 
2573  template<typename T>
2574  void handleExpr( ExprLhs<T> const& expr ) {
2575  handleExpr( expr.makeUnaryExpr() );
2576  }
2577  void handleExpr( ITransientExpression const& expr );
2578 
2579  void handleMessage(ResultWas::OfType resultType, StringRef const& message);
2580 
2581  void handleExceptionThrownAsExpected();
2582  void handleUnexpectedExceptionNotThrown();
2583  void handleExceptionNotThrownAsExpected();
2584  void handleThrowingCallSkipped();
2585  void handleUnexpectedInflightException();
2586 
2587  void complete();
2588  void setCompleted();
2589 
2590  // query
2591  auto allowThrows() const -> bool;
2592  };
2593 
2594  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
2595 
2596 } // namespace Catch
2597 
2598 // end catch_assertionhandler.h
2599 // start catch_message.h
2600 
2601 #include <string>
2602 #include <vector>
2603 
2604 namespace Catch {
2605 
2606  struct MessageInfo {
2607  MessageInfo( StringRef const& _macroName,
2608  SourceLineInfo const& _lineInfo,
2609  ResultWas::OfType _type );
2610 
2611  StringRef macroName;
2612  std::string message;
2613  SourceLineInfo lineInfo;
2614  ResultWas::OfType type;
2615  unsigned int sequence;
2616 
2617  bool operator == ( MessageInfo const& other ) const;
2618  bool operator < ( MessageInfo const& other ) const;
2619  private:
2620  static unsigned int globalCount;
2621  };
2622 
2623  struct MessageStream {
2624 
2625  template<typename T>
2626  MessageStream& operator << ( T const& value ) {
2627  m_stream << value;
2628  return *this;
2629  }
2630 
2631  ReusableStringStream m_stream;
2632  };
2633 
2635  MessageBuilder( StringRef const& macroName,
2636  SourceLineInfo const& lineInfo,
2637  ResultWas::OfType type );
2638 
2639  template<typename T>
2640  MessageBuilder& operator << ( T const& value ) {
2641  m_stream << value;
2642  return *this;
2643  }
2644 
2645  MessageInfo m_info;
2646  };
2647 
2649  public:
2650  explicit ScopedMessage( MessageBuilder const& builder );
2651  ScopedMessage( ScopedMessage& duplicate ) = delete;
2652  ScopedMessage( ScopedMessage&& old );
2653  ~ScopedMessage();
2654 
2655  MessageInfo m_info;
2656  bool m_moved;
2657  };
2658 
2659  class Capturer {
2660  std::vector<MessageInfo> m_messages;
2661  IResultCapture& m_resultCapture = getResultCapture();
2662  size_t m_captured = 0;
2663  public:
2664  Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
2665  ~Capturer();
2666 
2667  void captureValue( size_t index, std::string const& value );
2668 
2669  template<typename T>
2670  void captureValues( size_t index, T const& value ) {
2671  captureValue( index, Catch::Detail::stringify( value ) );
2672  }
2673 
2674  template<typename T, typename... Ts>
2675  void captureValues( size_t index, T const& value, Ts const&... values ) {
2676  captureValue( index, Catch::Detail::stringify(value) );
2677  captureValues( index+1, values... );
2678  }
2679  };
2680 
2681 } // end namespace Catch
2682 
2683 // end catch_message.h
2684 #if !defined(CATCH_CONFIG_DISABLE)
2685 
2686 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2687  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2688 #else
2689  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2690 #endif
2691 
2692 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2693 
2695 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2696 // macros.
2697 #define INTERNAL_CATCH_TRY
2698 #define INTERNAL_CATCH_CATCH( capturer )
2699 
2700 #else // CATCH_CONFIG_FAST_COMPILE
2701 
2702 #define INTERNAL_CATCH_TRY try
2703 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
2704 
2705 #endif
2706 
2707 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
2708 
2710 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2711  do { \
2712  CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
2713  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2714  INTERNAL_CATCH_TRY { \
2715  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2716  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2717  catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
2718  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
2719  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2720  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2721  } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
2722 
2724 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
2725  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2726  if( Catch::getResultCapture().lastAssertionPassed() )
2727 
2729 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
2730  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2731  if( !Catch::getResultCapture().lastAssertionPassed() )
2732 
2734 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2735  do { \
2736  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2737  try { \
2738  static_cast<void>(__VA_ARGS__); \
2739  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
2740  } \
2741  catch( ... ) { \
2742  catchAssertionHandler.handleUnexpectedInflightException(); \
2743  } \
2744  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2745  } while( false )
2746 
2748 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2749  do { \
2750  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
2751  if( catchAssertionHandler.allowThrows() ) \
2752  try { \
2753  static_cast<void>(__VA_ARGS__); \
2754  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2755  } \
2756  catch( ... ) { \
2757  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2758  } \
2759  else \
2760  catchAssertionHandler.handleThrowingCallSkipped(); \
2761  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2762  } while( false )
2763 
2765 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2766  do { \
2767  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2768  if( catchAssertionHandler.allowThrows() ) \
2769  try { \
2770  static_cast<void>(expr); \
2771  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2772  } \
2773  catch( exceptionType const& ) { \
2774  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2775  } \
2776  catch( ... ) { \
2777  catchAssertionHandler.handleUnexpectedInflightException(); \
2778  } \
2779  else \
2780  catchAssertionHandler.handleThrowingCallSkipped(); \
2781  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2782  } while( false )
2783 
2785 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2786  do { \
2787  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
2788  catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
2789  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2790  } while( false )
2791 
2793 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
2794  auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
2795  varName.captureValues( 0, __VA_ARGS__ )
2796 
2798 #define INTERNAL_CATCH_INFO( macroName, log ) \
2799  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
2800 
2802 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
2803  Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
2804 
2806 // Although this is matcher-based, it can be used with just a string
2807 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
2808  do { \
2809  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2810  if( catchAssertionHandler.allowThrows() ) \
2811  try { \
2812  static_cast<void>(__VA_ARGS__); \
2813  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2814  } \
2815  catch( ... ) { \
2816  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
2817  } \
2818  else \
2819  catchAssertionHandler.handleThrowingCallSkipped(); \
2820  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2821  } while( false )
2822 
2823 #endif // CATCH_CONFIG_DISABLE
2824 
2825 // end catch_capture.hpp
2826 // start catch_section.h
2827 
2828 // start catch_section_info.h
2829 
2830 // start catch_totals.h
2831 
2832 #include <cstddef>
2833 
2834 namespace Catch {
2835 
2836  struct Counts {
2837  Counts operator - ( Counts const& other ) const;
2838  Counts& operator += ( Counts const& other );
2839 
2840  std::size_t total() const;
2841  bool allPassed() const;
2842  bool allOk() const;
2843 
2844  std::size_t passed = 0;
2845  std::size_t failed = 0;
2846  std::size_t failedButOk = 0;
2847  };
2848 
2849  struct Totals {
2850 
2851  Totals operator - ( Totals const& other ) const;
2852  Totals& operator += ( Totals const& other );
2853 
2854  Totals delta( Totals const& prevTotals ) const;
2855 
2856  int error = 0;
2857  Counts assertions;
2858  Counts testCases;
2859  };
2860 }
2861 
2862 // end catch_totals.h
2863 #include <string>
2864 
2865 namespace Catch {
2866 
2867  struct SectionInfo {
2868  SectionInfo
2869  ( SourceLineInfo const& _lineInfo,
2870  std::string const& _name );
2871 
2872  // Deprecated
2873  SectionInfo
2874  ( SourceLineInfo const& _lineInfo,
2875  std::string const& _name,
2876  std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2877 
2878  std::string name;
2879  std::string description; // !Deprecated: this will always be empty
2880  SourceLineInfo lineInfo;
2881  };
2882 
2884  SectionInfo sectionInfo;
2885  Counts prevAssertions;
2886  double durationInSeconds;
2887  };
2888 
2889 } // end namespace Catch
2890 
2891 // end catch_section_info.h
2892 // start catch_timer.h
2893 
2894 #include <cstdint>
2895 
2896 namespace Catch {
2897 
2898  auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
2899  auto getEstimatedClockResolution() -> uint64_t;
2900 
2901  class Timer {
2902  uint64_t m_nanoseconds = 0;
2903  public:
2904  void start();
2905  auto getElapsedNanoseconds() const -> uint64_t;
2906  auto getElapsedMicroseconds() const -> uint64_t;
2907  auto getElapsedMilliseconds() const -> unsigned int;
2908  auto getElapsedSeconds() const -> double;
2909  };
2910 
2911 } // namespace Catch
2912 
2913 // end catch_timer.h
2914 #include <string>
2915 
2916 namespace Catch {
2917 
2919  public:
2920  Section( SectionInfo const& info );
2921  ~Section();
2922 
2923  // This indicates whether the section should be executed or not
2924  explicit operator bool() const;
2925 
2926  private:
2927  SectionInfo m_info;
2928 
2929  std::string m_name;
2930  Counts m_assertions;
2931  bool m_sectionIncluded;
2932  Timer m_timer;
2933  };
2934 
2935 } // end namespace Catch
2936 
2937 #define INTERNAL_CATCH_SECTION( ... ) \
2938  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2939  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2940  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2941  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2942 
2943 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2944  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
2945  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2946  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2947  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
2948 
2949 // end catch_section.h
2950 // start catch_interfaces_exception.h
2951 
2952 // start catch_interfaces_registry_hub.h
2953 
2954 #include <string>
2955 #include <memory>
2956 
2957 namespace Catch {
2958 
2959  class TestCase;
2960  struct ITestCaseRegistry;
2961  struct IExceptionTranslatorRegistry;
2962  struct IExceptionTranslator;
2963  struct IReporterRegistry;
2964  struct IReporterFactory;
2965  struct ITagAliasRegistry;
2966  struct IMutableEnumValuesRegistry;
2967 
2968  class StartupExceptionRegistry;
2969 
2970  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2971 
2972  struct IRegistryHub {
2973  virtual ~IRegistryHub();
2974 
2975  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2976  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2977  virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2978  virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2979 
2980  virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2981  };
2982 
2984  virtual ~IMutableRegistryHub();
2985  virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2986  virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2987  virtual void registerTest( TestCase const& testInfo ) = 0;
2988  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2989  virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2990  virtual void registerStartupException() noexcept = 0;
2991  virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
2992  };
2993 
2994  IRegistryHub const& getRegistryHub();
2995  IMutableRegistryHub& getMutableRegistryHub();
2996  void cleanUp();
2997  std::string translateActiveException();
2998 
2999 }
3000 
3001 // end catch_interfaces_registry_hub.h
3002 #if defined(CATCH_CONFIG_DISABLE)
3003  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
3004  static std::string translatorName( signature )
3005 #endif
3006 
3007 #include <exception>
3008 #include <string>
3009 #include <vector>
3010 
3011 namespace Catch {
3012  using exceptionTranslateFunction = std::string(*)();
3013 
3014  struct IExceptionTranslator;
3015  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
3016 
3018  virtual ~IExceptionTranslator();
3019  virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
3020  };
3021 
3023  virtual ~IExceptionTranslatorRegistry();
3024 
3025  virtual std::string translateActiveException() const = 0;
3026  };
3027 
3029  template<typename T>
3030  class ExceptionTranslator : public IExceptionTranslator {
3031  public:
3032 
3033  ExceptionTranslator( std::string(*translateFunction)( T& ) )
3034  : m_translateFunction( translateFunction )
3035  {}
3036 
3037  std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
3038 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3039  return "";
3040 #else
3041  try {
3042  if( it == itEnd )
3043  std::rethrow_exception(std::current_exception());
3044  else
3045  return (*it)->translate( it+1, itEnd );
3046  }
3047  catch( T& ex ) {
3048  return m_translateFunction( ex );
3049  }
3050 #endif
3051  }
3052 
3053  protected:
3054  std::string(*m_translateFunction)( T& );
3055  };
3056 
3057  public:
3058  template<typename T>
3059  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
3060  getMutableRegistryHub().registerTranslator
3061  ( new ExceptionTranslator<T>( translateFunction ) );
3062  }
3063  };
3064 }
3065 
3067 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
3068  static std::string translatorName( signature ); \
3069  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3070  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
3071  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
3072  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
3073  static std::string translatorName( signature )
3074 
3075 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
3076 
3077 // end catch_interfaces_exception.h
3078 // start catch_approx.h
3079 
3080 #include <type_traits>
3081 
3082 namespace Catch {
3083 namespace Detail {
3084 
3085  class Approx {
3086  private:
3087  bool equalityComparisonImpl(double other) const;
3088  // Validates the new margin (margin >= 0)
3089  // out-of-line to avoid including stdexcept in the header
3090  void setMargin(double margin);
3091  // Validates the new epsilon (0 < epsilon < 1)
3092  // out-of-line to avoid including stdexcept in the header
3093  void setEpsilon(double epsilon);
3094 
3095  public:
3096  explicit Approx ( double value );
3097 
3098  static Approx custom();
3099 
3100  Approx operator-() const;
3101 
3102  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3103  Approx operator()( T const& value ) {
3104  Approx approx( static_cast<double>(value) );
3105  approx.m_epsilon = m_epsilon;
3106  approx.m_margin = m_margin;
3107  approx.m_scale = m_scale;
3108  return approx;
3109  }
3110 
3111  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3112  explicit Approx( T const& value ): Approx(static_cast<double>(value))
3113  {}
3114 
3115  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3116  friend bool operator == ( const T& lhs, Approx const& rhs ) {
3117  auto lhs_v = static_cast<double>(lhs);
3118  return rhs.equalityComparisonImpl(lhs_v);
3119  }
3120 
3121  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3122  friend bool operator == ( Approx const& lhs, const T& rhs ) {
3123  return operator==( rhs, lhs );
3124  }
3125 
3126  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3127  friend bool operator != ( T const& lhs, Approx const& rhs ) {
3128  return !operator==( lhs, rhs );
3129  }
3130 
3131  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3132  friend bool operator != ( Approx const& lhs, T const& rhs ) {
3133  return !operator==( rhs, lhs );
3134  }
3135 
3136  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3137  friend bool operator <= ( T const& lhs, Approx const& rhs ) {
3138  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3139  }
3140 
3141  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3142  friend bool operator <= ( Approx const& lhs, T const& rhs ) {
3143  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3144  }
3145 
3146  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3147  friend bool operator >= ( T const& lhs, Approx const& rhs ) {
3148  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3149  }
3150 
3151  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3152  friend bool operator >= ( Approx const& lhs, T const& rhs ) {
3153  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3154  }
3155 
3156  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3157  Approx& epsilon( T const& newEpsilon ) {
3158  double epsilonAsDouble = static_cast<double>(newEpsilon);
3159  setEpsilon(epsilonAsDouble);
3160  return *this;
3161  }
3162 
3163  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3164  Approx& margin( T const& newMargin ) {
3165  double marginAsDouble = static_cast<double>(newMargin);
3166  setMargin(marginAsDouble);
3167  return *this;
3168  }
3169 
3170  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3171  Approx& scale( T const& newScale ) {
3172  m_scale = static_cast<double>(newScale);
3173  return *this;
3174  }
3175 
3176  std::string toString() const;
3177 
3178  private:
3179  double m_epsilon;
3180  double m_margin;
3181  double m_scale;
3182  double m_value;
3183  };
3184 } // end namespace Detail
3185 
3186 namespace literals {
3187  Detail::Approx operator "" _a(long double val);
3188  Detail::Approx operator "" _a(unsigned long long val);
3189 } // end namespace literals
3190 
3191 template<>
3192 struct StringMaker<Catch::Detail::Approx> {
3193  static std::string convert(Catch::Detail::Approx const& value);
3194 };
3195 
3196 } // end namespace Catch
3197 
3198 // end catch_approx.h
3199 // start catch_string_manip.h
3200 
3201 #include <string>
3202 #include <iosfwd>
3203 #include <vector>
3204 
3205 namespace Catch {
3206 
3207  bool startsWith( std::string const& s, std::string const& prefix );
3208  bool startsWith( std::string const& s, char prefix );
3209  bool endsWith( std::string const& s, std::string const& suffix );
3210  bool endsWith( std::string const& s, char suffix );
3211  bool contains( std::string const& s, std::string const& infix );
3212  void toLowerInPlace( std::string& s );
3213  std::string toLower( std::string const& s );
3215  std::string trim( std::string const& str );
3217  StringRef trim(StringRef ref);
3218 
3219  // !!! Be aware, returns refs into original string - make sure original string outlives them
3220  std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
3221  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
3222 
3223  struct pluralise {
3224  pluralise( std::size_t count, std::string const& label );
3225 
3226  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
3227 
3228  std::size_t m_count;
3229  std::string m_label;
3230  };
3231 }
3232 
3233 // end catch_string_manip.h
3234 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
3235 // start catch_capture_matchers.h
3236 
3237 // start catch_matchers.h
3238 
3239 #include <string>
3240 #include <vector>
3241 
3242 namespace Catch {
3243 namespace Matchers {
3244  namespace Impl {
3245 
3246  template<typename ArgT> struct MatchAllOf;
3247  template<typename ArgT> struct MatchAnyOf;
3248  template<typename ArgT> struct MatchNotOf;
3249 
3251  public:
3252  MatcherUntypedBase() = default;
3253  MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
3254  MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
3255  std::string toString() const;
3256 
3257  protected:
3258  virtual ~MatcherUntypedBase();
3259  virtual std::string describe() const = 0;
3260  mutable std::string m_cachedToString;
3261  };
3262 
3263 #ifdef __clang__
3264 # pragma clang diagnostic push
3265 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
3266 #endif
3267 
3268  template<typename ObjectT>
3269  struct MatcherMethod {
3270  virtual bool match( ObjectT const& arg ) const = 0;
3271  };
3272 
3273 #if defined(__OBJC__)
3274  // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
3275  // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
3276  template<>
3277  struct MatcherMethod<NSString*> {
3278  virtual bool match( NSString* arg ) const = 0;
3279  };
3280 #endif
3281 
3282 #ifdef __clang__
3283 # pragma clang diagnostic pop
3284 #endif
3285 
3286  template<typename T>
3288 
3289  MatchAllOf<T> operator && ( MatcherBase const& other ) const;
3290  MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
3291  MatchNotOf<T> operator ! () const;
3292  };
3293 
3294  template<typename ArgT>
3295  struct MatchAllOf : MatcherBase<ArgT> {
3296  bool match( ArgT const& arg ) const override {
3297  for( auto matcher : m_matchers ) {
3298  if (!matcher->match(arg))
3299  return false;
3300  }
3301  return true;
3302  }
3303  std::string describe() const override {
3304  std::string description;
3305  description.reserve( 4 + m_matchers.size()*32 );
3306  description += "( ";
3307  bool first = true;
3308  for( auto matcher : m_matchers ) {
3309  if( first )
3310  first = false;
3311  else
3312  description += " and ";
3313  description += matcher->toString();
3314  }
3315  description += " )";
3316  return description;
3317  }
3318 
3319  MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
3320  auto copy(*this);
3321  copy.m_matchers.push_back( &other );
3322  return copy;
3323  }
3324 
3325  std::vector<MatcherBase<ArgT> const*> m_matchers;
3326  };
3327  template<typename ArgT>
3328  struct MatchAnyOf : MatcherBase<ArgT> {
3329 
3330  bool match( ArgT const& arg ) const override {
3331  for( auto matcher : m_matchers ) {
3332  if (matcher->match(arg))
3333  return true;
3334  }
3335  return false;
3336  }
3337  std::string describe() const override {
3338  std::string description;
3339  description.reserve( 4 + m_matchers.size()*32 );
3340  description += "( ";
3341  bool first = true;
3342  for( auto matcher : m_matchers ) {
3343  if( first )
3344  first = false;
3345  else
3346  description += " or ";
3347  description += matcher->toString();
3348  }
3349  description += " )";
3350  return description;
3351  }
3352 
3353  MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
3354  auto copy(*this);
3355  copy.m_matchers.push_back( &other );
3356  return copy;
3357  }
3358 
3359  std::vector<MatcherBase<ArgT> const*> m_matchers;
3360  };
3361 
3362  template<typename ArgT>
3363  struct MatchNotOf : MatcherBase<ArgT> {
3364 
3365  MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
3366 
3367  bool match( ArgT const& arg ) const override {
3368  return !m_underlyingMatcher.match( arg );
3369  }
3370 
3371  std::string describe() const override {
3372  return "not " + m_underlyingMatcher.toString();
3373  }
3374  MatcherBase<ArgT> const& m_underlyingMatcher;
3375  };
3376 
3377  template<typename T>
3379  return MatchAllOf<T>() && *this && other;
3380  }
3381  template<typename T>
3382  MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
3383  return MatchAnyOf<T>() || *this || other;
3384  }
3385  template<typename T>
3386  MatchNotOf<T> MatcherBase<T>::operator ! () const {
3387  return MatchNotOf<T>( *this );
3388  }
3389 
3390  } // namespace Impl
3391 
3392 } // namespace Matchers
3393 
3394 using namespace Matchers;
3395 using Matchers::Impl::MatcherBase;
3396 
3397 } // namespace Catch
3398 
3399 // end catch_matchers.h
3400 // start catch_matchers_exception.hpp
3401 
3402 namespace Catch {
3403 namespace Matchers {
3404 namespace Exception {
3405 
3406 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
3407  std::string m_message;
3408 public:
3409 
3410  ExceptionMessageMatcher(std::string const& message):
3411  m_message(message)
3412  {}
3413 
3414  bool match(std::exception const& ex) const override;
3415 
3416  std::string describe() const override;
3417 };
3418 
3419 } // namespace Exception
3420 
3421 Exception::ExceptionMessageMatcher Message(std::string const& message);
3422 
3423 } // namespace Matchers
3424 } // namespace Catch
3425 
3426 // end catch_matchers_exception.hpp
3427 // start catch_matchers_floating.h
3428 
3429 namespace Catch {
3430 namespace Matchers {
3431 
3432  namespace Floating {
3433 
3434  enum class FloatingPointKind : uint8_t;
3435 
3436  struct WithinAbsMatcher : MatcherBase<double> {
3437  WithinAbsMatcher(double target, double margin);
3438  bool match(double const& matchee) const override;
3439  std::string describe() const override;
3440  private:
3441  double m_target;
3442  double m_margin;
3443  };
3444 
3445  struct WithinUlpsMatcher : MatcherBase<double> {
3446  WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
3447  bool match(double const& matchee) const override;
3448  std::string describe() const override;
3449  private:
3450  double m_target;
3451  uint64_t m_ulps;
3452  FloatingPointKind m_type;
3453  };
3454 
3455  // Given IEEE-754 format for floats and doubles, we can assume
3456  // that float -> double promotion is lossless. Given this, we can
3457  // assume that if we do the standard relative comparison of
3458  // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
3459  // the same result if we do this for floats, as if we do this for
3460  // doubles that were promoted from floats.
3461  struct WithinRelMatcher : MatcherBase<double> {
3462  WithinRelMatcher(double target, double epsilon);
3463  bool match(double const& matchee) const override;
3464  std::string describe() const override;
3465  private:
3466  double m_target;
3467  double m_epsilon;
3468  };
3469 
3470  } // namespace Floating
3471 
3472  // The following functions create the actual matcher objects.
3473  // This allows the types to be inferred
3474  Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
3475  Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
3476  Floating::WithinAbsMatcher WithinAbs(double target, double margin);
3477  Floating::WithinRelMatcher WithinRel(double target, double eps);
3478  // defaults epsilon to 100*numeric_limits<double>::epsilon()
3479  Floating::WithinRelMatcher WithinRel(double target);
3480  Floating::WithinRelMatcher WithinRel(float target, float eps);
3481  // defaults epsilon to 100*numeric_limits<float>::epsilon()
3482  Floating::WithinRelMatcher WithinRel(float target);
3483 
3484 } // namespace Matchers
3485 } // namespace Catch
3486 
3487 // end catch_matchers_floating.h
3488 // start catch_matchers_generic.hpp
3489 
3490 #include <functional>
3491 #include <string>
3492 
3493 namespace Catch {
3494 namespace Matchers {
3495 namespace Generic {
3496 
3497 namespace Detail {
3498  std::string finalizeDescription(const std::string& desc);
3499 }
3500 
3501 template <typename T>
3502 class PredicateMatcher : public MatcherBase<T> {
3503  std::function<bool(T const&)> m_predicate;
3504  std::string m_description;
3505 public:
3506 
3507  PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
3508  :m_predicate(std::move(elem)),
3509  m_description(Detail::finalizeDescription(descr))
3510  {}
3511 
3512  bool match( T const& item ) const override {
3513  return m_predicate(item);
3514  }
3515 
3516  std::string describe() const override {
3517  return m_description;
3518  }
3519 };
3520 
3521 } // namespace Generic
3522 
3523  // The following functions create the actual matcher objects.
3524  // The user has to explicitly specify type to the function, because
3525  // inferring std::function<bool(T const&)> is hard (but possible) and
3526  // requires a lot of TMP.
3527  template<typename T>
3528  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
3529  return Generic::PredicateMatcher<T>(predicate, description);
3530  }
3531 
3532 } // namespace Matchers
3533 } // namespace Catch
3534 
3535 // end catch_matchers_generic.hpp
3536 // start catch_matchers_string.h
3537 
3538 #include <string>
3539 
3540 namespace Catch {
3541 namespace Matchers {
3542 
3543  namespace StdString {
3544 
3546  {
3547  CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
3548  std::string adjustString( std::string const& str ) const;
3549  std::string caseSensitivitySuffix() const;
3550 
3551  CaseSensitive::Choice m_caseSensitivity;
3552  std::string m_str;
3553  };
3554 
3555  struct StringMatcherBase : MatcherBase<std::string> {
3556  StringMatcherBase( std::string const& operation, CasedString const& comparator );
3557  std::string describe() const override;
3558 
3559  CasedString m_comparator;
3560  std::string m_operation;
3561  };
3562 
3564  EqualsMatcher( CasedString const& comparator );
3565  bool match( std::string const& source ) const override;
3566  };
3568  ContainsMatcher( CasedString const& comparator );
3569  bool match( std::string const& source ) const override;
3570  };
3572  StartsWithMatcher( CasedString const& comparator );
3573  bool match( std::string const& source ) const override;
3574  };
3576  EndsWithMatcher( CasedString const& comparator );
3577  bool match( std::string const& source ) const override;
3578  };
3579 
3580  struct RegexMatcher : MatcherBase<std::string> {
3581  RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
3582  bool match( std::string const& matchee ) const override;
3583  std::string describe() const override;
3584 
3585  private:
3586  std::string m_regex;
3587  CaseSensitive::Choice m_caseSensitivity;
3588  };
3589 
3590  } // namespace StdString
3591 
3592  // The following functions create the actual matcher objects.
3593  // This allows the types to be inferred
3594 
3595  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3596  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3597  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3598  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3599  StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3600 
3601 } // namespace Matchers
3602 } // namespace Catch
3603 
3604 // end catch_matchers_string.h
3605 // start catch_matchers_vector.h
3606 
3607 #include <algorithm>
3608 
3609 namespace Catch {
3610 namespace Matchers {
3611 
3612  namespace Vector {
3613  template<typename T, typename Alloc>
3614  struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
3615 
3616  ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3617 
3618  bool match(std::vector<T, Alloc> const &v) const override {
3619  for (auto const& el : v) {
3620  if (el == m_comparator) {
3621  return true;
3622  }
3623  }
3624  return false;
3625  }
3626 
3627  std::string describe() const override {
3628  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3629  }
3630 
3631  T const& m_comparator;
3632  };
3633 
3634  template<typename T, typename AllocComp, typename AllocMatch>
3635  struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3636 
3637  ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
3638 
3639  bool match(std::vector<T, AllocMatch> const &v) const override {
3640  // !TBD: see note in EqualsMatcher
3641  if (m_comparator.size() > v.size())
3642  return false;
3643  for (auto const& comparator : m_comparator) {
3644  auto present = false;
3645  for (const auto& el : v) {
3646  if (el == comparator) {
3647  present = true;
3648  break;
3649  }
3650  }
3651  if (!present) {
3652  return false;
3653  }
3654  }
3655  return true;
3656  }
3657  std::string describe() const override {
3658  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3659  }
3660 
3661  std::vector<T, AllocComp> const& m_comparator;
3662  };
3663 
3664  template<typename T, typename AllocComp, typename AllocMatch>
3665  struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3666 
3667  EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
3668 
3669  bool match(std::vector<T, AllocMatch> const &v) const override {
3670  // !TBD: This currently works if all elements can be compared using !=
3671  // - a more general approach would be via a compare template that defaults
3672  // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
3673  // - then just call that directly
3674  if (m_comparator.size() != v.size())
3675  return false;
3676  for (std::size_t i = 0; i < v.size(); ++i)
3677  if (m_comparator[i] != v[i])
3678  return false;
3679  return true;
3680  }
3681  std::string describe() const override {
3682  return "Equals: " + ::Catch::Detail::stringify( m_comparator );
3683  }
3684  std::vector<T, AllocComp> const& m_comparator;
3685  };
3686 
3687  template<typename T, typename AllocComp, typename AllocMatch>
3688  struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3689 
3690  ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
3691 
3692  bool match(std::vector<T, AllocMatch> const &v) const override {
3693  if (m_comparator.size() != v.size())
3694  return false;
3695  for (std::size_t i = 0; i < v.size(); ++i)
3696  if (m_comparator[i] != approx(v[i]))
3697  return false;
3698  return true;
3699  }
3700  std::string describe() const override {
3701  return "is approx: " + ::Catch::Detail::stringify( m_comparator );
3702  }
3703  template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3704  ApproxMatcher& epsilon( T const& newEpsilon ) {
3705  approx.epsilon(newEpsilon);
3706  return *this;
3707  }
3708  template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3709  ApproxMatcher& margin( T const& newMargin ) {
3710  approx.margin(newMargin);
3711  return *this;
3712  }
3713  template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3714  ApproxMatcher& scale( T const& newScale ) {
3715  approx.scale(newScale);
3716  return *this;
3717  }
3718 
3719  std::vector<T, AllocComp> const& m_comparator;
3720  mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
3721  };
3722 
3723  template<typename T, typename AllocComp, typename AllocMatch>
3724  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
3725  UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
3726  bool match(std::vector<T, AllocMatch> const& vec) const override {
3727  if (m_target.size() != vec.size()) {
3728  return false;
3729  }
3730  return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
3731  }
3732 
3733  std::string describe() const override {
3734  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
3735  }
3736  private:
3737  std::vector<T, AllocComp> const& m_target;
3738  };
3739 
3740  } // namespace Vector
3741 
3742  // The following functions create the actual matcher objects.
3743  // This allows the types to be inferred
3744 
3745  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3746  Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
3748  }
3749 
3750  template<typename T, typename Alloc = std::allocator<T>>
3751  Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
3752  return Vector::ContainsElementMatcher<T, Alloc>( comparator );
3753  }
3754 
3755  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3756  Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
3757  return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );
3758  }
3759 
3760  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3761  Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
3762  return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );
3763  }
3764 
3765  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
3766  Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
3767  return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );
3768  }
3769 
3770 } // namespace Matchers
3771 } // namespace Catch
3772 
3773 // end catch_matchers_vector.h
3774 namespace Catch {
3775 
3776  template<typename ArgT, typename MatcherT>
3778  ArgT const& m_arg;
3779  MatcherT m_matcher;
3780  StringRef m_matcherString;
3781  public:
3782  MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
3783  : ITransientExpression{ true, matcher.match( arg ) },
3784  m_arg( arg ),
3785  m_matcher( matcher ),
3786  m_matcherString( matcherString )
3787  {}
3788 
3789  void streamReconstructedExpression( std::ostream &os ) const override {
3790  auto matcherAsString = m_matcher.toString();
3791  os << Catch::Detail::stringify( m_arg ) << ' ';
3792  if( matcherAsString == Detail::unprintableString )
3793  os << m_matcherString;
3794  else
3795  os << matcherAsString;
3796  }
3797  };
3798 
3800 
3801  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
3802 
3803  template<typename ArgT, typename MatcherT>
3804  auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
3805  return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
3806  }
3807 
3808 } // namespace Catch
3809 
3811 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
3812  do { \
3813  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3814  INTERNAL_CATCH_TRY { \
3815  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
3816  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
3817  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3818  } while( false )
3819 
3821 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
3822  do { \
3823  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3824  if( catchAssertionHandler.allowThrows() ) \
3825  try { \
3826  static_cast<void>(__VA_ARGS__ ); \
3827  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3828  } \
3829  catch( exceptionType const& ex ) { \
3830  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
3831  } \
3832  catch( ... ) { \
3833  catchAssertionHandler.handleUnexpectedInflightException(); \
3834  } \
3835  else \
3836  catchAssertionHandler.handleThrowingCallSkipped(); \
3837  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3838  } while( false )
3839 
3840 // end catch_capture_matchers.h
3841 #endif
3842 // start catch_generators.hpp
3843 
3844 // start catch_interfaces_generatortracker.h
3845 
3846 
3847 #include <memory>
3848 
3849 namespace Catch {
3850 
3851  namespace Generators {
3853  public:
3854  GeneratorUntypedBase() = default;
3855  virtual ~GeneratorUntypedBase();
3856  // Attempts to move the generator to the next element
3857  //
3858  // Returns true iff the move succeeded (and a valid element
3859  // can be retrieved).
3860  virtual bool next() = 0;
3861  };
3862  using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
3863 
3864  } // namespace Generators
3865 
3867  virtual ~IGeneratorTracker();
3868  virtual auto hasGenerator() const -> bool = 0;
3869  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3870  virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3871  };
3872 
3873 } // namespace Catch
3874 
3875 // end catch_interfaces_generatortracker.h
3876 // start catch_enforce.h
3877 
3878 #include <exception>
3879 
3880 namespace Catch {
3881 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3882  template <typename Ex>
3883  [[noreturn]]
3884  void throw_exception(Ex const& e) {
3885  throw e;
3886  }
3887 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
3888  [[noreturn]]
3889  void throw_exception(std::exception const& e);
3890 #endif
3891 
3892  [[noreturn]]
3893  void throw_logic_error(std::string const& msg);
3894  [[noreturn]]
3895  void throw_domain_error(std::string const& msg);
3896  [[noreturn]]
3897  void throw_runtime_error(std::string const& msg);
3898 
3899 } // namespace Catch;
3900 
3901 #define CATCH_MAKE_MSG(...) \
3902  (Catch::ReusableStringStream() << __VA_ARGS__).str()
3903 
3904 #define CATCH_INTERNAL_ERROR(...) \
3905  Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
3906 
3907 #define CATCH_ERROR(...) \
3908  Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3909 
3910 #define CATCH_RUNTIME_ERROR(...) \
3911  Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
3912 
3913 #define CATCH_ENFORCE( condition, ... ) \
3914  do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
3915 
3916 // end catch_enforce.h
3917 #include <memory>
3918 #include <vector>
3919 #include <cassert>
3920 
3921 #include <utility>
3922 #include <exception>
3923 
3924 namespace Catch {
3925 
3926 class GeneratorException : public std::exception {
3927  const char* const m_msg = "";
3928 
3929 public:
3930  GeneratorException(const char* msg):
3931  m_msg(msg)
3932  {}
3933 
3934  const char* what() const noexcept override final;
3935 };
3936 
3937 namespace Generators {
3938 
3939  // !TBD move this into its own location?
3940  namespace pf{
3941  template<typename T, typename... Args>
3942  std::unique_ptr<T> make_unique( Args&&... args ) {
3943  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3944  }
3945  }
3946 
3947  template<typename T>
3949  virtual ~IGenerator() = default;
3950 
3951  // Returns the current element of the generator
3952  //
3953  // \Precondition The generator is either freshly constructed,
3954  // or the last call to `next()` returned true
3955  virtual T const& get() const = 0;
3956  using type = T;
3957  };
3958 
3959  template<typename T>
3960  class SingleValueGenerator final : public IGenerator<T> {
3961  T m_value;
3962  public:
3963  SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
3964 
3965  T const& get() const override {
3966  return m_value;
3967  }
3968  bool next() override {
3969  return false;
3970  }
3971  };
3972 
3973  template<typename T>
3974  class FixedValuesGenerator final : public IGenerator<T> {
3975  static_assert(!std::is_same<T, bool>::value,
3976  "FixedValuesGenerator does not support bools because of std::vector<bool>"
3977  "specialization, use SingleValue Generator instead.");
3978  std::vector<T> m_values;
3979  size_t m_idx = 0;
3980  public:
3981  FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3982 
3983  T const& get() const override {
3984  return m_values[m_idx];
3985  }
3986  bool next() override {
3987  ++m_idx;
3988  return m_idx < m_values.size();
3989  }
3990  };
3991 
3992  template <typename T>
3993  class GeneratorWrapper final {
3994  std::unique_ptr<IGenerator<T>> m_generator;
3995  public:
3996  GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
3997  m_generator(std::move(generator))
3998  {}
3999  T const& get() const {
4000  return m_generator->get();
4001  }
4002  bool next() {
4003  return m_generator->next();
4004  }
4005  };
4006 
4007  template <typename T>
4008  GeneratorWrapper<T> value(T&& value) {
4009  return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
4010  }
4011  template <typename T>
4012  GeneratorWrapper<T> values(std::initializer_list<T> values) {
4013  return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
4014  }
4015 
4016  template<typename T>
4017  class Generators : public IGenerator<T> {
4018  std::vector<GeneratorWrapper<T>> m_generators;
4019  size_t m_current = 0;
4020 
4021  void populate(GeneratorWrapper<T>&& generator) {
4022  m_generators.emplace_back(std::move(generator));
4023  }
4024  void populate(T&& val) {
4025  m_generators.emplace_back(value(std::forward<T>(val)));
4026  }
4027  template<typename U>
4028  void populate(U&& val) {
4029  populate(T(std::forward<U>(val)));
4030  }
4031  template<typename U, typename... Gs>
4032  void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
4033  populate(std::forward<U>(valueOrGenerator));
4034  populate(std::forward<Gs>(moreGenerators)...);
4035  }
4036 
4037  public:
4038  template <typename... Gs>
4039  Generators(Gs &&... moreGenerators) {
4040  m_generators.reserve(sizeof...(Gs));
4041  populate(std::forward<Gs>(moreGenerators)...);
4042  }
4043 
4044  T const& get() const override {
4045  return m_generators[m_current].get();
4046  }
4047 
4048  bool next() override {
4049  if (m_current >= m_generators.size()) {
4050  return false;
4051  }
4052  const bool current_status = m_generators[m_current].next();
4053  if (!current_status) {
4054  ++m_current;
4055  }
4056  return m_current < m_generators.size();
4057  }
4058  };
4059 
4060  template<typename... Ts>
4061  GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
4062  return values<std::tuple<Ts...>>( tuples );
4063  }
4064 
4065  // Tag type to signal that a generator sequence should convert arguments to a specific type
4066  template <typename T>
4067  struct as {};
4068 
4069  template<typename T, typename... Gs>
4070  auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
4071  return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
4072  }
4073  template<typename T>
4074  auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
4075  return Generators<T>(std::move(generator));
4076  }
4077  template<typename T, typename... Gs>
4078  auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
4079  return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
4080  }
4081  template<typename T, typename U, typename... Gs>
4082  auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
4083  return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
4084  }
4085 
4086  auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
4087 
4088  template<typename L>
4089  // Note: The type after -> is weird, because VS2015 cannot parse
4090  // the expression used in the typedef inside, when it is in
4091  // return type. Yeah.
4092  auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
4093  using UnderlyingType = typename decltype(generatorExpression())::type;
4094 
4095  IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
4096  if (!tracker.hasGenerator()) {
4097  tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
4098  }
4099 
4100  auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
4101  return generator.get();
4102  }
4103 
4104 } // namespace Generators
4105 } // namespace Catch
4106 
4107 #define GENERATE( ... ) \
4108  Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4109  CATCH_INTERNAL_LINEINFO, \
4110  [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4111 #define GENERATE_COPY( ... ) \
4112  Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4113  CATCH_INTERNAL_LINEINFO, \
4114  [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4115 #define GENERATE_REF( ... ) \
4116  Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
4117  CATCH_INTERNAL_LINEINFO, \
4118  [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
4119 
4120 // end catch_generators.hpp
4121 // start catch_generators_generic.hpp
4122 
4123 namespace Catch {
4124 namespace Generators {
4125 
4126  template <typename T>
4127  class TakeGenerator : public IGenerator<T> {
4128  GeneratorWrapper<T> m_generator;
4129  size_t m_returned = 0;
4130  size_t m_target;
4131  public:
4132  TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
4133  m_generator(std::move(generator)),
4134  m_target(target)
4135  {
4136  assert(target != 0 && "Empty generators are not allowed");
4137  }
4138  T const& get() const override {
4139  return m_generator.get();
4140  }
4141  bool next() override {
4142  ++m_returned;
4143  if (m_returned >= m_target) {
4144  return false;
4145  }
4146 
4147  const auto success = m_generator.next();
4148  // If the underlying generator does not contain enough values
4149  // then we cut short as well
4150  if (!success) {
4151  m_returned = m_target;
4152  }
4153  return success;
4154  }
4155  };
4156 
4157  template <typename T>
4158  GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
4159  return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
4160  }
4161 
4162  template <typename T, typename Predicate>
4163  class FilterGenerator : public IGenerator<T> {
4164  GeneratorWrapper<T> m_generator;
4165  Predicate m_predicate;
4166  public:
4167  template <typename P = Predicate>
4168  FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
4169  m_generator(std::move(generator)),
4170  m_predicate(std::forward<P>(pred))
4171  {
4172  if (!m_predicate(m_generator.get())) {
4173  // It might happen that there are no values that pass the
4174  // filter. In that case we throw an exception.
4175  auto has_initial_value = next();
4176  if (!has_initial_value) {
4177  Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
4178  }
4179  }
4180  }
4181 
4182  T const& get() const override {
4183  return m_generator.get();
4184  }
4185 
4186  bool next() override {
4187  bool success = m_generator.next();
4188  if (!success) {
4189  return false;
4190  }
4191  while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
4192  return success;
4193  }
4194  };
4195 
4196  template <typename T, typename Predicate>
4197  GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
4198  return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
4199  }
4200 
4201  template <typename T>
4202  class RepeatGenerator : public IGenerator<T> {
4203  static_assert(!std::is_same<T, bool>::value,
4204  "RepeatGenerator currently does not support bools"
4205  "because of std::vector<bool> specialization");
4206  GeneratorWrapper<T> m_generator;
4207  mutable std::vector<T> m_returned;
4208  size_t m_target_repeats;
4209  size_t m_current_repeat = 0;
4210  size_t m_repeat_index = 0;
4211  public:
4212  RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
4213  m_generator(std::move(generator)),
4214  m_target_repeats(repeats)
4215  {
4216  assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
4217  }
4218 
4219  T const& get() const override {
4220  if (m_current_repeat == 0) {
4221  m_returned.push_back(m_generator.get());
4222  return m_returned.back();
4223  }
4224  return m_returned[m_repeat_index];
4225  }
4226 
4227  bool next() override {
4228  // There are 2 basic cases:
4229  // 1) We are still reading the generator
4230  // 2) We are reading our own cache
4231 
4232  // In the first case, we need to poke the underlying generator.
4233  // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
4234  if (m_current_repeat == 0) {
4235  const auto success = m_generator.next();
4236  if (!success) {
4237  ++m_current_repeat;
4238  }
4239  return m_current_repeat < m_target_repeats;
4240  }
4241 
4242  // In the second case, we need to move indices forward and check that we haven't run up against the end
4243  ++m_repeat_index;
4244  if (m_repeat_index == m_returned.size()) {
4245  m_repeat_index = 0;
4246  ++m_current_repeat;
4247  }
4248  return m_current_repeat < m_target_repeats;
4249  }
4250  };
4251 
4252  template <typename T>
4253  GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
4254  return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
4255  }
4256 
4257  template <typename T, typename U, typename Func>
4258  class MapGenerator : public IGenerator<T> {
4259  // TBD: provide static assert for mapping function, for friendly error message
4260  GeneratorWrapper<U> m_generator;
4261  Func m_function;
4262  // To avoid returning dangling reference, we have to save the values
4263  T m_cache;
4264  public:
4265  template <typename F2 = Func>
4266  MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
4267  m_generator(std::move(generator)),
4268  m_function(std::forward<F2>(function)),
4269  m_cache(m_function(m_generator.get()))
4270  {}
4271 
4272  T const& get() const override {
4273  return m_cache;
4274  }
4275  bool next() override {
4276  const auto success = m_generator.next();
4277  if (success) {
4278  m_cache = m_function(m_generator.get());
4279  }
4280  return success;
4281  }
4282  };
4283 
4284  template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
4285  GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4286  return GeneratorWrapper<T>(
4287  pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4288  );
4289  }
4290 
4291  template <typename T, typename U, typename Func>
4292  GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
4293  return GeneratorWrapper<T>(
4294  pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
4295  );
4296  }
4297 
4298  template <typename T>
4299  class ChunkGenerator final : public IGenerator<std::vector<T>> {
4300  std::vector<T> m_chunk;
4301  size_t m_chunk_size;
4302  GeneratorWrapper<T> m_generator;
4303  bool m_used_up = false;
4304  public:
4305  ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
4306  m_chunk_size(size), m_generator(std::move(generator))
4307  {
4308  m_chunk.reserve(m_chunk_size);
4309  if (m_chunk_size != 0) {
4310  m_chunk.push_back(m_generator.get());
4311  for (size_t i = 1; i < m_chunk_size; ++i) {
4312  if (!m_generator.next()) {
4313  Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
4314  }
4315  m_chunk.push_back(m_generator.get());
4316  }
4317  }
4318  }
4319  std::vector<T> const& get() const override {
4320  return m_chunk;
4321  }
4322  bool next() override {
4323  m_chunk.clear();
4324  for (size_t idx = 0; idx < m_chunk_size; ++idx) {
4325  if (!m_generator.next()) {
4326  return false;
4327  }
4328  m_chunk.push_back(m_generator.get());
4329  }
4330  return true;
4331  }
4332  };
4333 
4334  template <typename T>
4335  GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
4337  pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
4338  );
4339  }
4340 
4341 } // namespace Generators
4342 } // namespace Catch
4343 
4344 // end catch_generators_generic.hpp
4345 // start catch_generators_specific.hpp
4346 
4347 // start catch_context.h
4348 
4349 #include <memory>
4350 
4351 namespace Catch {
4352 
4353  struct IResultCapture;
4354  struct IRunner;
4355  struct IConfig;
4356  struct IMutableContext;
4357 
4358  using IConfigPtr = std::shared_ptr<IConfig const>;
4359 
4360  struct IContext
4361  {
4362  virtual ~IContext();
4363 
4364  virtual IResultCapture* getResultCapture() = 0;
4365  virtual IRunner* getRunner() = 0;
4366  virtual IConfigPtr const& getConfig() const = 0;
4367  };
4368 
4370  {
4371  virtual ~IMutableContext();
4372  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
4373  virtual void setRunner( IRunner* runner ) = 0;
4374  virtual void setConfig( IConfigPtr const& config ) = 0;
4375 
4376  private:
4377  static IMutableContext *currentContext;
4378  friend IMutableContext& getCurrentMutableContext();
4379  friend void cleanUpContext();
4380  static void createContext();
4381  };
4382 
4383  inline IMutableContext& getCurrentMutableContext()
4384  {
4385  if( !IMutableContext::currentContext )
4386  IMutableContext::createContext();
4387  // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
4388  return *IMutableContext::currentContext;
4389  }
4390 
4391  inline IContext& getCurrentContext()
4392  {
4393  return getCurrentMutableContext();
4394  }
4395 
4396  void cleanUpContext();
4397 
4398  class SimplePcg32;
4399  SimplePcg32& rng();
4400 }
4401 
4402 // end catch_context.h
4403 // start catch_interfaces_config.h
4404 
4405 // start catch_option.hpp
4406 
4407 namespace Catch {
4408 
4409  // An optional type
4410  template<typename T>
4411  class Option {
4412  public:
4413  Option() : nullableValue( nullptr ) {}
4414  Option( T const& _value )
4415  : nullableValue( new( storage ) T( _value ) )
4416  {}
4417  Option( Option const& _other )
4418  : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4419  {}
4420 
4421  ~Option() {
4422  reset();
4423  }
4424 
4425  Option& operator= ( Option const& _other ) {
4426  if( &_other != this ) {
4427  reset();
4428  if( _other )
4429  nullableValue = new( storage ) T( *_other );
4430  }
4431  return *this;
4432  }
4433  Option& operator = ( T const& _value ) {
4434  reset();
4435  nullableValue = new( storage ) T( _value );
4436  return *this;
4437  }
4438 
4439  void reset() {
4440  if( nullableValue )
4441  nullableValue->~T();
4442  nullableValue = nullptr;
4443  }
4444 
4445  T& operator*() { return *nullableValue; }
4446  T const& operator*() const { return *nullableValue; }
4447  T* operator->() { return nullableValue; }
4448  const T* operator->() const { return nullableValue; }
4449 
4450  T valueOr( T const& defaultValue ) const {
4451  return nullableValue ? *nullableValue : defaultValue;
4452  }
4453 
4454  bool some() const { return nullableValue != nullptr; }
4455  bool none() const { return nullableValue == nullptr; }
4456 
4457  bool operator !() const { return nullableValue == nullptr; }
4458  explicit operator bool() const {
4459  return some();
4460  }
4461 
4462  private:
4463  T *nullableValue;
4464  alignas(alignof(T)) char storage[sizeof(T)];
4465  };
4466 
4467 } // end namespace Catch
4468 
4469 // end catch_option.hpp
4470 #include <chrono>
4471 #include <iosfwd>
4472 #include <string>
4473 #include <vector>
4474 #include <memory>
4475 
4476 namespace Catch {
4477 
4478  enum class Verbosity {
4479  Quiet = 0,
4480  Normal,
4481  High
4482  };
4483 
4484  struct WarnAbout { enum What {
4485  Nothing = 0x00,
4486  NoAssertions = 0x01,
4487  NoTests = 0x02
4488  }; };
4489 
4490  struct ShowDurations { enum OrNot {
4491  DefaultForReporter,
4492  Always,
4493  Never
4494  }; };
4495  struct RunTests { enum InWhatOrder {
4496  InDeclarationOrder,
4497  InLexicographicalOrder,
4498  InRandomOrder
4499  }; };
4500  struct UseColour { enum YesOrNo {
4501  Auto,
4502  Yes,
4503  No
4504  }; };
4505  struct WaitForKeypress { enum When {
4506  Never,
4507  BeforeStart = 1,
4508  BeforeExit = 2,
4509  BeforeStartAndExit = BeforeStart | BeforeExit
4510  }; };
4511 
4512  class TestSpec;
4513 
4515 
4516  virtual ~IConfig();
4517 
4518  virtual bool allowThrows() const = 0;
4519  virtual std::ostream& stream() const = 0;
4520  virtual std::string name() const = 0;
4521  virtual bool includeSuccessfulResults() const = 0;
4522  virtual bool shouldDebugBreak() const = 0;
4523  virtual bool warnAboutMissingAssertions() const = 0;
4524  virtual bool warnAboutNoTests() const = 0;
4525  virtual int abortAfter() const = 0;
4526  virtual bool showInvisibles() const = 0;
4527  virtual ShowDurations::OrNot showDurations() const = 0;
4528  virtual double minDuration() const = 0;
4529  virtual TestSpec const& testSpec() const = 0;
4530  virtual bool hasTestFilters() const = 0;
4531  virtual std::vector<std::string> const& getTestsOrTags() const = 0;
4532  virtual RunTests::InWhatOrder runOrder() const = 0;
4533  virtual unsigned int rngSeed() const = 0;
4534  virtual UseColour::YesOrNo useColour() const = 0;
4535  virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4536  virtual Verbosity verbosity() const = 0;
4537 
4538  virtual bool benchmarkNoAnalysis() const = 0;
4539  virtual int benchmarkSamples() const = 0;
4540  virtual double benchmarkConfidenceInterval() const = 0;
4541  virtual unsigned int benchmarkResamples() const = 0;
4542  virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
4543  };
4544 
4545  using IConfigPtr = std::shared_ptr<IConfig const>;
4546 }
4547 
4548 // end catch_interfaces_config.h
4549 // start catch_random_number_generator.h
4550 
4551 #include <cstdint>
4552 
4553 namespace Catch {
4554 
4555  // This is a simple implementation of C++11 Uniform Random Number
4556  // Generator. It does not provide all operators, because Catch2
4557  // does not use it, but it should behave as expected inside stdlib's
4558  // distributions.
4559  // The implementation is based on the PCG family (http://pcg-random.org)
4560  class SimplePcg32 {
4561  using state_type = std::uint64_t;
4562  public:
4563  using result_type = std::uint32_t;
4564  static constexpr result_type (min)() {
4565  return 0;
4566  }
4567  static constexpr result_type (max)() {
4568  return static_cast<result_type>(-1);
4569  }
4570 
4571  // Provide some default initial state for the default constructor
4572  SimplePcg32():SimplePcg32(0xed743cc4U) {}
4573 
4574  explicit SimplePcg32(result_type seed_);
4575 
4576  void seed(result_type seed_);
4577  void discard(uint64_t skip);
4578 
4579  result_type operator()();
4580 
4581  private:
4582  friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4583  friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
4584 
4585  // In theory we also need operator<< and operator>>
4586  // In practice we do not use them, so we will skip them for now
4587 
4588  std::uint64_t m_state;
4589  // This part of the state determines which "stream" of the numbers
4590  // is chosen -- we take it as a constant for Catch2, so we only
4591  // need to deal with seeding the main state.
4592  // Picked by reading 8 bytes from `/dev/random` :-)
4593  static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
4594  };
4595 
4596 } // end namespace Catch
4597 
4598 // end catch_random_number_generator.h
4599 #include <random>
4600 
4601 namespace Catch {
4602 namespace Generators {
4603 
4604 template <typename Float>
4605 class RandomFloatingGenerator final : public IGenerator<Float> {
4606  Catch::SimplePcg32& m_rng;
4607  std::uniform_real_distribution<Float> m_dist;
4608  Float m_current_number;
4609 public:
4610 
4611  RandomFloatingGenerator(Float a, Float b):
4612  m_rng(rng()),
4613  m_dist(a, b) {
4614  static_cast<void>(next());
4615  }
4616 
4617  Float const& get() const override {
4618  return m_current_number;
4619  }
4620  bool next() override {
4621  m_current_number = m_dist(m_rng);
4622  return true;
4623  }
4624 };
4625 
4626 template <typename Integer>
4627 class RandomIntegerGenerator final : public IGenerator<Integer> {
4628  Catch::SimplePcg32& m_rng;
4629  std::uniform_int_distribution<Integer> m_dist;
4630  Integer m_current_number;
4631 public:
4632 
4633  RandomIntegerGenerator(Integer a, Integer b):
4634  m_rng(rng()),
4635  m_dist(a, b) {
4636  static_cast<void>(next());
4637  }
4638 
4639  Integer const& get() const override {
4640  return m_current_number;
4641  }
4642  bool next() override {
4643  m_current_number = m_dist(m_rng);
4644  return true;
4645  }
4646 };
4647 
4648 // TODO: Ideally this would be also constrained against the various char types,
4649 // but I don't expect users to run into that in practice.
4650 template <typename T>
4651 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
4652 GeneratorWrapper<T>>::type
4653 random(T a, T b) {
4654  return GeneratorWrapper<T>(
4655  pf::make_unique<RandomIntegerGenerator<T>>(a, b)
4656  );
4657 }
4658 
4659 template <typename T>
4660 typename std::enable_if<std::is_floating_point<T>::value,
4661 GeneratorWrapper<T>>::type
4662 random(T a, T b) {
4663  return GeneratorWrapper<T>(
4664  pf::make_unique<RandomFloatingGenerator<T>>(a, b)
4665  );
4666 }
4667 
4668 template <typename T>
4669 class RangeGenerator final : public IGenerator<T> {
4670  T m_current;
4671  T m_end;
4672  T m_step;
4673  bool m_positive;
4674 
4675 public:
4676  RangeGenerator(T const& start, T const& end, T const& step):
4677  m_current(start),
4678  m_end(end),
4679  m_step(step),
4680  m_positive(m_step > T(0))
4681  {
4682  assert(m_current != m_end && "Range start and end cannot be equal");
4683  assert(m_step != T(0) && "Step size cannot be zero");
4684  assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
4685  }
4686 
4687  RangeGenerator(T const& start, T const& end):
4688  RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
4689  {}
4690 
4691  T const& get() const override {
4692  return m_current;
4693  }
4694 
4695  bool next() override {
4696  m_current += m_step;
4697  return (m_positive) ? (m_current < m_end) : (m_current > m_end);
4698  }
4699 };
4700 
4701 template <typename T>
4702 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
4703  static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
4704  return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
4705 }
4706 
4707 template <typename T>
4708 GeneratorWrapper<T> range(T const& start, T const& end) {
4709  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4710  return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
4711 }
4712 
4713 template <typename T>
4714 class IteratorGenerator final : public IGenerator<T> {
4715  static_assert(!std::is_same<T, bool>::value,
4716  "IteratorGenerator currently does not support bools"
4717  "because of std::vector<bool> specialization");
4718 
4719  std::vector<T> m_elems;
4720  size_t m_current = 0;
4721 public:
4722  template <typename InputIterator, typename InputSentinel>
4723  IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
4724  if (m_elems.empty()) {
4725  Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
4726  }
4727  }
4728 
4729  T const& get() const override {
4730  return m_elems[m_current];
4731  }
4732 
4733  bool next() override {
4734  ++m_current;
4735  return m_current != m_elems.size();
4736  }
4737 };
4738 
4739 template <typename InputIterator,
4740  typename InputSentinel,
4741  typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
4742 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
4743  return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
4744 }
4745 
4746 template <typename Container,
4747  typename ResultType = typename Container::value_type>
4748 GeneratorWrapper<ResultType> from_range(Container const& cnt) {
4749  return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
4750 }
4751 
4752 } // namespace Generators
4753 } // namespace Catch
4754 
4755 // end catch_generators_specific.hpp
4756 
4757 // These files are included here so the single_include script doesn't put them
4758 // in the conditionally compiled sections
4759 // start catch_test_case_info.h
4760 
4761 #include <string>
4762 #include <vector>
4763 #include <memory>
4764 
4765 #ifdef __clang__
4766 #pragma clang diagnostic push
4767 #pragma clang diagnostic ignored "-Wpadded"
4768 #endif
4769 
4770 namespace Catch {
4771 
4772  struct ITestInvoker;
4773 
4774  struct TestCaseInfo {
4775  enum SpecialProperties{
4776  None = 0,
4777  IsHidden = 1 << 1,
4778  ShouldFail = 1 << 2,
4779  MayFail = 1 << 3,
4780  Throws = 1 << 4,
4781  NonPortable = 1 << 5,
4782  Benchmark = 1 << 6
4783  };
4784 
4785  TestCaseInfo( std::string const& _name,
4786  std::string const& _className,
4787  std::string const& _description,
4788  std::vector<std::string> const& _tags,
4789  SourceLineInfo const& _lineInfo );
4790 
4791  friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
4792 
4793  bool isHidden() const;
4794  bool throws() const;
4795  bool okToFail() const;
4796  bool expectedToFail() const;
4797 
4798  std::string tagsAsString() const;
4799 
4800  std::string name;
4801  std::string className;
4802  std::string description;
4803  std::vector<std::string> tags;
4804  std::vector<std::string> lcaseTags;
4805  SourceLineInfo lineInfo;
4806  SpecialProperties properties;
4807  };
4808 
4809  class TestCase : public TestCaseInfo {
4810  public:
4811 
4812  TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
4813 
4814  TestCase withName( std::string const& _newName ) const;
4815 
4816  void invoke() const;
4817 
4818  TestCaseInfo const& getTestCaseInfo() const;
4819 
4820  bool operator == ( TestCase const& other ) const;
4821  bool operator < ( TestCase const& other ) const;
4822 
4823  private:
4824  std::shared_ptr<ITestInvoker> test;
4825  };
4826 
4827  TestCase makeTestCase( ITestInvoker* testCase,
4828  std::string const& className,
4829  NameAndTags const& nameAndTags,
4830  SourceLineInfo const& lineInfo );
4831 }
4832 
4833 #ifdef __clang__
4834 #pragma clang diagnostic pop
4835 #endif
4836 
4837 // end catch_test_case_info.h
4838 // start catch_interfaces_runner.h
4839 
4840 namespace Catch {
4841 
4842  struct IRunner {
4843  virtual ~IRunner();
4844  virtual bool aborting() const = 0;
4845  };
4846 }
4847 
4848 // end catch_interfaces_runner.h
4849 
4850 #ifdef __OBJC__
4851 // start catch_objc.hpp
4852 
4853 #import <objc/runtime.h>
4854 
4855 #include <string>
4856 
4857 // NB. Any general catch headers included here must be included
4858 // in catch.hpp first to make sure they are included by the single
4859 // header for non obj-usage
4860 
4862 // This protocol is really only here for (self) documenting purposes, since
4863 // all its methods are optional.
4864 @protocol OcFixture
4865 
4866 @optional
4867 
4868 -(void) setUp;
4869 -(void) tearDown;
4870 
4871 @end
4872 
4873 namespace Catch {
4874 
4875  class OcMethod : public ITestInvoker {
4876 
4877  public:
4878  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
4879 
4880  virtual void invoke() const {
4881  id obj = [[m_cls alloc] init];
4882 
4883  performOptionalSelector( obj, @selector(setUp) );
4884  performOptionalSelector( obj, m_sel );
4885  performOptionalSelector( obj, @selector(tearDown) );
4886 
4887  arcSafeRelease( obj );
4888  }
4889  private:
4890  virtual ~OcMethod() {}
4891 
4892  Class m_cls;
4893  SEL m_sel;
4894  };
4895 
4896  namespace Detail{
4897 
4898  inline std::string getAnnotation( Class cls,
4899  std::string const& annotationName,
4900  std::string const& testCaseName ) {
4901  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
4902  SEL sel = NSSelectorFromString( selStr );
4903  arcSafeRelease( selStr );
4904  id value = performOptionalSelector( cls, sel );
4905  if( value )
4906  return [(NSString*)value UTF8String];
4907  return "";
4908  }
4909  }
4910 
4911  inline std::size_t registerTestMethods() {
4912  std::size_t noTestMethods = 0;
4913  int noClasses = objc_getClassList( nullptr, 0 );
4914 
4915  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
4916  objc_getClassList( classes, noClasses );
4917 
4918  for( int c = 0; c < noClasses; c++ ) {
4919  Class cls = classes[c];
4920  {
4921  u_int count;
4922  Method* methods = class_copyMethodList( cls, &count );
4923  for( u_int m = 0; m < count ; m++ ) {
4924  SEL selector = method_getName(methods[m]);
4925  std::string methodName = sel_getName(selector);
4926  if( startsWith( methodName, "Catch_TestCase_" ) ) {
4927  std::string testCaseName = methodName.substr( 15 );
4928  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
4929  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
4930  const char* className = class_getName( cls );
4931 
4932  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
4933  noTestMethods++;
4934  }
4935  }
4936  free(methods);
4937  }
4938  }
4939  return noTestMethods;
4940  }
4941 
4942 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
4943 
4944  namespace Matchers {
4945  namespace Impl {
4946  namespace NSStringMatchers {
4947 
4948  struct StringHolder : MatcherBase<NSString*>{
4949  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
4950  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
4951  StringHolder() {
4952  arcSafeRelease( m_substr );
4953  }
4954 
4955  bool match( NSString* str ) const override {
4956  return false;
4957  }
4958 
4959  NSString* CATCH_ARC_STRONG m_substr;
4960  };
4961 
4962  struct Equals : StringHolder {
4963  Equals( NSString* substr ) : StringHolder( substr ){}
4964 
4965  bool match( NSString* str ) const override {
4966  return (str != nil || m_substr == nil ) &&
4967  [str isEqualToString:m_substr];
4968  }
4969 
4970  std::string describe() const override {
4971  return "equals string: " + Catch::Detail::stringify( m_substr );
4972  }
4973  };
4974 
4975  struct Contains : StringHolder {
4976  Contains( NSString* substr ) : StringHolder( substr ){}
4977 
4978  bool match( NSString* str ) const override {
4979  return (str != nil || m_substr == nil ) &&
4980  [str rangeOfString:m_substr].location != NSNotFound;
4981  }
4982 
4983  std::string describe() const override {
4984  return "contains string: " + Catch::Detail::stringify( m_substr );
4985  }
4986  };
4987 
4988  struct StartsWith : StringHolder {
4989  StartsWith( NSString* substr ) : StringHolder( substr ){}
4990 
4991  bool match( NSString* str ) const override {
4992  return (str != nil || m_substr == nil ) &&
4993  [str rangeOfString:m_substr].location == 0;
4994  }
4995 
4996  std::string describe() const override {
4997  return "starts with: " + Catch::Detail::stringify( m_substr );
4998  }
4999  };
5000  struct EndsWith : StringHolder {
5001  EndsWith( NSString* substr ) : StringHolder( substr ){}
5002 
5003  bool match( NSString* str ) const override {
5004  return (str != nil || m_substr == nil ) &&
5005  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
5006  }
5007 
5008  std::string describe() const override {
5009  return "ends with: " + Catch::Detail::stringify( m_substr );
5010  }
5011  };
5012 
5013  } // namespace NSStringMatchers
5014  } // namespace Impl
5015 
5016  inline Impl::NSStringMatchers::Equals
5017  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
5018 
5019  inline Impl::NSStringMatchers::Contains
5020  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
5021 
5022  inline Impl::NSStringMatchers::StartsWith
5023  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
5024 
5025  inline Impl::NSStringMatchers::EndsWith
5026  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
5027 
5028  } // namespace Matchers
5029 
5030  using namespace Matchers;
5031 
5032 #endif // CATCH_CONFIG_DISABLE_MATCHERS
5033 
5034 } // namespace Catch
5035 
5037 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
5038 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
5039 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
5040 { \
5041 return @ name; \
5042 } \
5043 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
5044 { \
5045 return @ desc; \
5046 } \
5047 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
5048 
5049 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
5050 
5051 // end catch_objc.hpp
5052 #endif
5053 
5054 // Benchmarking needs the externally-facing parts of reporters to work
5055 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5056 // start catch_external_interfaces.h
5057 
5058 // start catch_reporter_bases.hpp
5059 
5060 // start catch_interfaces_reporter.h
5061 
5062 // start catch_config.hpp
5063 
5064 // start catch_test_spec_parser.h
5065 
5066 #ifdef __clang__
5067 #pragma clang diagnostic push
5068 #pragma clang diagnostic ignored "-Wpadded"
5069 #endif
5070 
5071 // start catch_test_spec.h
5072 
5073 #ifdef __clang__
5074 #pragma clang diagnostic push
5075 #pragma clang diagnostic ignored "-Wpadded"
5076 #endif
5077 
5078 // start catch_wildcard_pattern.h
5079 
5080 namespace Catch
5081 {
5083  enum WildcardPosition {
5084  NoWildcard = 0,
5085  WildcardAtStart = 1,
5086  WildcardAtEnd = 2,
5087  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
5088  };
5089 
5090  public:
5091 
5092  WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
5093  virtual ~WildcardPattern() = default;
5094  virtual bool matches( std::string const& str ) const;
5095 
5096  private:
5097  std::string normaliseString( std::string const& str ) const;
5098  CaseSensitive::Choice m_caseSensitivity;
5099  WildcardPosition m_wildcard = NoWildcard;
5100  std::string m_pattern;
5101  };
5102 }
5103 
5104 // end catch_wildcard_pattern.h
5105 #include <string>
5106 #include <vector>
5107 #include <memory>
5108 
5109 namespace Catch {
5110 
5111  struct IConfig;
5112 
5113  class TestSpec {
5114  class Pattern {
5115  public:
5116  explicit Pattern( std::string const& name );
5117  virtual ~Pattern();
5118  virtual bool matches( TestCaseInfo const& testCase ) const = 0;
5119  std::string const& name() const;
5120  private:
5121  std::string const m_name;
5122  };
5123  using PatternPtr = std::shared_ptr<Pattern>;
5124 
5125  class NamePattern : public Pattern {
5126  public:
5127  explicit NamePattern( std::string const& name, std::string const& filterString );
5128  bool matches( TestCaseInfo const& testCase ) const override;
5129  private:
5130  WildcardPattern m_wildcardPattern;
5131  };
5132 
5133  class TagPattern : public Pattern {
5134  public:
5135  explicit TagPattern( std::string const& tag, std::string const& filterString );
5136  bool matches( TestCaseInfo const& testCase ) const override;
5137  private:
5138  std::string m_tag;
5139  };
5140 
5141  class ExcludedPattern : public Pattern {
5142  public:
5143  explicit ExcludedPattern( PatternPtr const& underlyingPattern );
5144  bool matches( TestCaseInfo const& testCase ) const override;
5145  private:
5146  PatternPtr m_underlyingPattern;
5147  };
5148 
5149  struct Filter {
5150  std::vector<PatternPtr> m_patterns;
5151 
5152  bool matches( TestCaseInfo const& testCase ) const;
5153  std::string name() const;
5154  };
5155 
5156  public:
5157  struct FilterMatch {
5158  std::string name;
5159  std::vector<TestCase const*> tests;
5160  };
5161  using Matches = std::vector<FilterMatch>;
5162  using vectorStrings = std::vector<std::string>;
5163 
5164  bool hasFilters() const;
5165  bool matches( TestCaseInfo const& testCase ) const;
5166  Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
5167  const vectorStrings & getInvalidArgs() const;
5168 
5169  private:
5170  std::vector<Filter> m_filters;
5171  std::vector<std::string> m_invalidArgs;
5172  friend class TestSpecParser;
5173  };
5174 }
5175 
5176 #ifdef __clang__
5177 #pragma clang diagnostic pop
5178 #endif
5179 
5180 // end catch_test_spec.h
5181 // start catch_interfaces_tag_alias_registry.h
5182 
5183 #include <string>
5184 
5185 namespace Catch {
5186 
5187  struct TagAlias;
5188 
5190  virtual ~ITagAliasRegistry();
5191  // Nullptr if not present
5192  virtual TagAlias const* find( std::string const& alias ) const = 0;
5193  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
5194 
5195  static ITagAliasRegistry const& get();
5196  };
5197 
5198 } // end namespace Catch
5199 
5200 // end catch_interfaces_tag_alias_registry.h
5201 namespace Catch {
5202 
5204  enum Mode{ None, Name, QuotedName, Tag, EscapedName };
5205  Mode m_mode = None;
5206  Mode lastMode = None;
5207  bool m_exclusion = false;
5208  std::size_t m_pos = 0;
5209  std::size_t m_realPatternPos = 0;
5210  std::string m_arg;
5211  std::string m_substring;
5212  std::string m_patternName;
5213  std::vector<std::size_t> m_escapeChars;
5214  TestSpec::Filter m_currentFilter;
5215  TestSpec m_testSpec;
5216  ITagAliasRegistry const* m_tagAliases = nullptr;
5217 
5218  public:
5219  TestSpecParser( ITagAliasRegistry const& tagAliases );
5220 
5221  TestSpecParser& parse( std::string const& arg );
5222  TestSpec testSpec();
5223 
5224  private:
5225  bool visitChar( char c );
5226  void startNewMode( Mode mode );
5227  bool processNoneChar( char c );
5228  void processNameChar( char c );
5229  bool processOtherChar( char c );
5230  void endMode();
5231  void escape();
5232  bool isControlChar( char c ) const;
5233  void saveLastMode();
5234  void revertBackToLastMode();
5235  void addFilter();
5236  bool separate();
5237 
5238  // Handles common preprocessing of the pattern for name/tag patterns
5239  std::string preprocessPattern();
5240  // Adds the current pattern as a test name
5241  void addNamePattern();
5242  // Adds the current pattern as a tag
5243  void addTagPattern();
5244 
5245  inline void addCharToPattern(char c) {
5246  m_substring += c;
5247  m_patternName += c;
5248  m_realPatternPos++;
5249  }
5250 
5251  };
5252  TestSpec parseTestSpec( std::string const& arg );
5253 
5254 } // namespace Catch
5255 
5256 #ifdef __clang__
5257 #pragma clang diagnostic pop
5258 #endif
5259 
5260 // end catch_test_spec_parser.h
5261 // Libstdc++ doesn't like incomplete classes for unique_ptr
5262 
5263 #include <memory>
5264 #include <vector>
5265 #include <string>
5266 
5267 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
5268 #define CATCH_CONFIG_CONSOLE_WIDTH 80
5269 #endif
5270 
5271 namespace Catch {
5272 
5273  struct IStream;
5274 
5275  struct ConfigData {
5276  bool listTests = false;
5277  bool listTags = false;
5278  bool listReporters = false;
5279  bool listTestNamesOnly = false;
5280 
5281  bool showSuccessfulTests = false;
5282  bool shouldDebugBreak = false;
5283  bool noThrow = false;
5284  bool showHelp = false;
5285  bool showInvisibles = false;
5286  bool filenamesAsTags = false;
5287  bool libIdentify = false;
5288 
5289  int abortAfter = -1;
5290  unsigned int rngSeed = 0;
5291 
5292  bool benchmarkNoAnalysis = false;
5293  unsigned int benchmarkSamples = 100;
5294  double benchmarkConfidenceInterval = 0.95;
5295  unsigned int benchmarkResamples = 100000;
5296  std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
5297 
5298  Verbosity verbosity = Verbosity::Normal;
5299  WarnAbout::What warnings = WarnAbout::Nothing;
5300  ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
5301  double minDuration = -1;
5302  RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
5303  UseColour::YesOrNo useColour = UseColour::Auto;
5304  WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
5305 
5306  std::string outputFilename;
5307  std::string name;
5308  std::string processName;
5309 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
5310 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
5311 #endif
5312  std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
5313 #undef CATCH_CONFIG_DEFAULT_REPORTER
5314 
5315  std::vector<std::string> testsOrTags;
5316  std::vector<std::string> sectionsToRun;
5317  };
5318 
5319  class Config : public IConfig {
5320  public:
5321 
5322  Config() = default;
5323  Config( ConfigData const& data );
5324  virtual ~Config() = default;
5325 
5326  std::string const& getFilename() const;
5327 
5328  bool listTests() const;
5329  bool listTestNamesOnly() const;
5330  bool listTags() const;
5331  bool listReporters() const;
5332 
5333  std::string getProcessName() const;
5334  std::string const& getReporterName() const;
5335 
5336  std::vector<std::string> const& getTestsOrTags() const override;
5337  std::vector<std::string> const& getSectionsToRun() const override;
5338 
5339  TestSpec const& testSpec() const override;
5340  bool hasTestFilters() const override;
5341 
5342  bool showHelp() const;
5343 
5344  // IConfig interface
5345  bool allowThrows() const override;
5346  std::ostream& stream() const override;
5347  std::string name() const override;
5348  bool includeSuccessfulResults() const override;
5349  bool warnAboutMissingAssertions() const override;
5350  bool warnAboutNoTests() const override;
5351  ShowDurations::OrNot showDurations() const override;
5352  double minDuration() const override;
5353  RunTests::InWhatOrder runOrder() const override;
5354  unsigned int rngSeed() const override;
5355  UseColour::YesOrNo useColour() const override;
5356  bool shouldDebugBreak() const override;
5357  int abortAfter() const override;
5358  bool showInvisibles() const override;
5359  Verbosity verbosity() const override;
5360  bool benchmarkNoAnalysis() const override;
5361  int benchmarkSamples() const override;
5362  double benchmarkConfidenceInterval() const override;
5363  unsigned int benchmarkResamples() const override;
5364  std::chrono::milliseconds benchmarkWarmupTime() const override;
5365 
5366  private:
5367 
5368  IStream const* openStream();
5369  ConfigData m_data;
5370 
5371  std::unique_ptr<IStream const> m_stream;
5372  TestSpec m_testSpec;
5373  bool m_hasTestFilters = false;
5374  };
5375 
5376 } // end namespace Catch
5377 
5378 // end catch_config.hpp
5379 // start catch_assertionresult.h
5380 
5381 #include <string>
5382 
5383 namespace Catch {
5384 
5386  {
5387  AssertionResultData() = delete;
5388 
5389  AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
5390 
5391  std::string message;
5392  mutable std::string reconstructedExpression;
5393  LazyExpression lazyExpression;
5394  ResultWas::OfType resultType;
5395 
5396  std::string reconstructExpression() const;
5397  };
5398 
5400  public:
5401  AssertionResult() = delete;
5402  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
5403 
5404  bool isOk() const;
5405  bool succeeded() const;
5406  ResultWas::OfType getResultType() const;
5407  bool hasExpression() const;
5408  bool hasMessage() const;
5409  std::string getExpression() const;
5410  std::string getExpressionInMacro() const;
5411  bool hasExpandedExpression() const;
5412  std::string getExpandedExpression() const;
5413  std::string getMessage() const;
5414  SourceLineInfo getSourceInfo() const;
5415  StringRef getTestMacroName() const;
5416 
5417  //protected:
5418  AssertionInfo m_info;
5419  AssertionResultData m_resultData;
5420  };
5421 
5422 } // end namespace Catch
5423 
5424 // end catch_assertionresult.h
5425 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5426 // start catch_estimate.hpp
5427 
5428  // Statistics estimates
5429 
5430 
5431 namespace Catch {
5432  namespace Benchmark {
5433  template <typename Duration>
5434  struct Estimate {
5435  Duration point;
5436  Duration lower_bound;
5437  Duration upper_bound;
5438  double confidence_interval;
5439 
5440  template <typename Duration2>
5441  operator Estimate<Duration2>() const {
5442  return { point, lower_bound, upper_bound, confidence_interval };
5443  }
5444  };
5445  } // namespace Benchmark
5446 } // namespace Catch
5447 
5448 // end catch_estimate.hpp
5449 // start catch_outlier_classification.hpp
5450 
5451 // Outlier information
5452 
5453 namespace Catch {
5454  namespace Benchmark {
5456  int samples_seen = 0;
5457  int low_severe = 0; // more than 3 times IQR below Q1
5458  int low_mild = 0; // 1.5 to 3 times IQR below Q1
5459  int high_mild = 0; // 1.5 to 3 times IQR above Q3
5460  int high_severe = 0; // more than 3 times IQR above Q3
5461 
5462  int total() const {
5463  return low_severe + low_mild + high_mild + high_severe;
5464  }
5465  };
5466  } // namespace Benchmark
5467 } // namespace Catch
5468 
5469 // end catch_outlier_classification.hpp
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 
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 
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 
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 
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>
5626  BenchmarkInfo info;
5627 
5628  std::vector<Duration> samples;
5630  Benchmark::Estimate<Duration> standardDeviation;
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 
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 
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 
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>
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>
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 
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>
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>
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 
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 ) {
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 
6358  void writeAssertions(SectionNode const& sectionNode);
6359  void writeAssertion(AssertionStats const& stats);
6360 
6361  XmlWriter xml;
6362  Timer suiteTimer;
6363  std::string stdOutForSuite;
6364  std::string stdErrForSuite;
6365  unsigned int unexpectedExceptions = 0;
6366  bool m_okToFail = false;
6367  };
6368 
6369 } // end namespace Catch
6370 
6371 // end catch_reporter_junit.h
6372 // start catch_reporter_xml.h
6373 
6374 namespace Catch {
6375  class XmlReporter : public StreamingReporterBase<XmlReporter> {
6376  public:
6377  XmlReporter(ReporterConfig const& _config);
6378 
6379  ~XmlReporter() override;
6380 
6381  static std::string getDescription();
6382 
6383  virtual std::string getStylesheetRef() const;
6384 
6385  void writeSourceInfo(SourceLineInfo const& sourceInfo);
6386 
6387  public: // StreamingReporterBase
6388 
6389  void noMatchingTestCases(std::string const& s) override;
6390 
6391  void testRunStarting(TestRunInfo const& testInfo) override;
6392 
6393  void testGroupStarting(GroupInfo const& groupInfo) override;
6394 
6395  void testCaseStarting(TestCaseInfo const& testInfo) override;
6396 
6397  void sectionStarting(SectionInfo const& sectionInfo) override;
6398 
6399  void assertionStarting(AssertionInfo const&) override;
6400 
6401  bool assertionEnded(AssertionStats const& assertionStats) override;
6402 
6403  void sectionEnded(SectionStats const& sectionStats) override;
6404 
6405  void testCaseEnded(TestCaseStats const& testCaseStats) override;
6406 
6407  void testGroupEnded(TestGroupStats const& testGroupStats) override;
6408 
6409  void testRunEnded(TestRunStats const& testRunStats) override;
6410 
6411 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6412  void benchmarkPreparing(std::string const& name) override;
6413  void benchmarkStarting(BenchmarkInfo const&) override;
6414  void benchmarkEnded(BenchmarkStats<> const&) override;
6415  void benchmarkFailed(std::string const&) override;
6416 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6417 
6418  private:
6419  Timer m_testCaseTimer;
6420  XmlWriter m_xml;
6421  int m_sectionDepth = 0;
6422  };
6423 
6424 } // end namespace Catch
6425 
6426 // end catch_reporter_xml.h
6427 
6428 // end catch_external_interfaces.h
6429 #endif
6430 
6431 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6432 // start catch_benchmarking_all.hpp
6433 
6434 // A proxy header that includes all of the benchmarking headers to allow
6435 // concise include of the benchmarking features. You should prefer the
6436 // individual includes in standard use.
6437 
6438 // start catch_benchmark.hpp
6439 
6440  // Benchmark
6441 
6442 // start catch_chronometer.hpp
6443 
6444 // User-facing chronometer
6445 
6446 
6447 // start catch_clock.hpp
6448 
6449 // Clocks
6450 
6451 
6452 #include <chrono>
6453 #include <ratio>
6454 
6455 namespace Catch {
6456  namespace Benchmark {
6457  template <typename Clock>
6458  using ClockDuration = typename Clock::duration;
6459  template <typename Clock>
6460  using FloatDuration = std::chrono::duration<double, typename Clock::period>;
6461 
6462  template <typename Clock>
6463  using TimePoint = typename Clock::time_point;
6464 
6465  using default_clock = std::chrono::steady_clock;
6466 
6467  template <typename Clock>
6468  struct now {
6469  TimePoint<Clock> operator()() const {
6470  return Clock::now();
6471  }
6472  };
6473 
6474  using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
6475  } // namespace Benchmark
6476 } // namespace Catch
6477 
6478 // end catch_clock.hpp
6479 // start catch_optimizer.hpp
6480 
6481  // Hinting the optimizer
6482 
6483 
6484 #if defined(_MSC_VER)
6485 # include <atomic> // atomic_thread_fence
6486 #endif
6487 
6488 namespace Catch {
6489  namespace Benchmark {
6490 #if defined(__GNUC__) || defined(__clang__)
6491  template <typename T>
6492  inline void keep_memory(T* p) {
6493  asm volatile("" : : "g"(p) : "memory");
6494  }
6495  inline void keep_memory() {
6496  asm volatile("" : : : "memory");
6497  }
6498 
6499  namespace Detail {
6500  inline void optimizer_barrier() { keep_memory(); }
6501  } // namespace Detail
6502 #elif defined(_MSC_VER)
6503 
6504 #pragma optimize("", off)
6505  template <typename T>
6506  inline void keep_memory(T* p) {
6507  // thanks @milleniumbug
6508  *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
6509  }
6510  // TODO equivalent keep_memory()
6511 #pragma optimize("", on)
6512 
6513  namespace Detail {
6514  inline void optimizer_barrier() {
6515  std::atomic_thread_fence(std::memory_order_seq_cst);
6516  }
6517  } // namespace Detail
6518 
6519 #endif
6520 
6521  template <typename T>
6522  inline void deoptimize_value(T&& x) {
6523  keep_memory(&x);
6524  }
6525 
6526  template <typename Fn, typename... Args>
6527  inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
6528  deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
6529  }
6530 
6531  template <typename Fn, typename... Args>
6532  inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
6533  std::forward<Fn>(fn) (std::forward<Args...>(args...));
6534  }
6535  } // namespace Benchmark
6536 } // namespace Catch
6537 
6538 // end catch_optimizer.hpp
6539 // start catch_complete_invoke.hpp
6540 
6541 // Invoke with a special case for void
6542 
6543 
6544 #include <type_traits>
6545 #include <utility>
6546 
6547 namespace Catch {
6548  namespace Benchmark {
6549  namespace Detail {
6550  template <typename T>
6551  struct CompleteType { using type = T; };
6552  template <>
6553  struct CompleteType<void> { struct type {}; };
6554 
6555  template <typename T>
6556  using CompleteType_t = typename CompleteType<T>::type;
6557 
6558  template <typename Result>
6559  struct CompleteInvoker {
6560  template <typename Fun, typename... Args>
6561  static Result invoke(Fun&& fun, Args&&... args) {
6562  return std::forward<Fun>(fun)(std::forward<Args>(args)...);
6563  }
6564  };
6565  template <>
6566  struct CompleteInvoker<void> {
6567  template <typename Fun, typename... Args>
6568  static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
6569  std::forward<Fun>(fun)(std::forward<Args>(args)...);
6570  return {};
6571  }
6572  };
6573 
6574  // invoke and not return void :(
6575  template <typename Fun, typename... Args>
6576  CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
6577  return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
6578  }
6579 
6580  const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
6581  } // namespace Detail
6582 
6583  template <typename Fun>
6584  Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
6585  CATCH_TRY{
6586  return Detail::complete_invoke(std::forward<Fun>(fun));
6587  } CATCH_CATCH_ALL{
6588  getResultCapture().benchmarkFailed(translateActiveException());
6589  CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
6590  }
6591  }
6592  } // namespace Benchmark
6593 } // namespace Catch
6594 
6595 // end catch_complete_invoke.hpp
6596 namespace Catch {
6597  namespace Benchmark {
6598  namespace Detail {
6600  virtual void start() = 0;
6601  virtual void finish() = 0;
6602  virtual ~ChronometerConcept() = default;
6603  };
6604  template <typename Clock>
6605  struct ChronometerModel final : public ChronometerConcept {
6606  void start() override { started = Clock::now(); }
6607  void finish() override { finished = Clock::now(); }
6608 
6609  ClockDuration<Clock> elapsed() const { return finished - started; }
6610 
6611  TimePoint<Clock> started;
6612  TimePoint<Clock> finished;
6613  };
6614  } // namespace Detail
6615 
6616  struct Chronometer {
6617  public:
6618  template <typename Fun>
6619  void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
6620 
6621  int runs() const { return k; }
6622 
6624  : impl(&meter)
6625  , k(k) {}
6626 
6627  private:
6628  template <typename Fun>
6629  void measure(Fun&& fun, std::false_type) {
6630  measure([&fun](int) { return fun(); }, std::true_type());
6631  }
6632 
6633  template <typename Fun>
6634  void measure(Fun&& fun, std::true_type) {
6635  Detail::optimizer_barrier();
6636  impl->start();
6637  for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
6638  impl->finish();
6639  Detail::optimizer_barrier();
6640  }
6641 
6643  int k;
6644  };
6645  } // namespace Benchmark
6646 } // namespace Catch
6647 
6648 // end catch_chronometer.hpp
6649 // start catch_environment.hpp
6650 
6651 // Environment information
6652 
6653 
6654 namespace Catch {
6655  namespace Benchmark {
6656  template <typename Duration>
6658  Duration mean;
6659  OutlierClassification outliers;
6660 
6661  template <typename Duration2>
6662  operator EnvironmentEstimate<Duration2>() const {
6663  return { mean, outliers };
6664  }
6665  };
6666  template <typename Clock>
6667  struct Environment {
6668  using clock_type = Clock;
6669  EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
6671  };
6672  } // namespace Benchmark
6673 } // namespace Catch
6674 
6675 // end catch_environment.hpp
6676 // start catch_execution_plan.hpp
6677 
6678  // Execution plan
6679 
6680 
6681 // start catch_benchmark_function.hpp
6682 
6683  // Dumb std::function implementation for consistent call overhead
6684 
6685 
6686 #include <cassert>
6687 #include <type_traits>
6688 #include <utility>
6689 #include <memory>
6690 
6691 namespace Catch {
6692  namespace Benchmark {
6693  namespace Detail {
6694  template <typename T>
6695  using Decay = typename std::decay<T>::type;
6696  template <typename T, typename U>
6697  struct is_related
6698  : std::is_same<Decay<T>, Decay<U>> {};
6699 
6707  struct BenchmarkFunction {
6708  private:
6709  struct callable {
6710  virtual void call(Chronometer meter) const = 0;
6711  virtual callable* clone() const = 0;
6712  virtual ~callable() = default;
6713  };
6714  template <typename Fun>
6715  struct model : public callable {
6716  model(Fun&& fun) : fun(std::move(fun)) {}
6717  model(Fun const& fun) : fun(fun) {}
6718 
6719  model<Fun>* clone() const override { return new model<Fun>(*this); }
6720 
6721  void call(Chronometer meter) const override {
6722  call(meter, is_callable<Fun(Chronometer)>());
6723  }
6724  void call(Chronometer meter, std::true_type) const {
6725  fun(meter);
6726  }
6727  void call(Chronometer meter, std::false_type) const {
6728  meter.measure(fun);
6729  }
6730 
6731  Fun fun;
6732  };
6733 
6734  struct do_nothing { void operator()() const {} };
6735 
6736  template <typename T>
6737  BenchmarkFunction(model<T>* c) : f(c) {}
6738 
6739  public:
6740  BenchmarkFunction()
6741  : f(new model<do_nothing>{ {} }) {}
6742 
6743  template <typename Fun,
6744  typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
6745  BenchmarkFunction(Fun&& fun)
6746  : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
6747 
6748  BenchmarkFunction(BenchmarkFunction&& that)
6749  : f(std::move(that.f)) {}
6750 
6751  BenchmarkFunction(BenchmarkFunction const& that)
6752  : f(that.f->clone()) {}
6753 
6754  BenchmarkFunction& operator=(BenchmarkFunction&& that) {
6755  f = std::move(that.f);
6756  return *this;
6757  }
6758 
6759  BenchmarkFunction& operator=(BenchmarkFunction const& that) {
6760  f.reset(that.f->clone());
6761  return *this;
6762  }
6763 
6764  void operator()(Chronometer meter) const { f->call(meter); }
6765 
6766  private:
6767  std::unique_ptr<callable> f;
6768  };
6769  } // namespace Detail
6770  } // namespace Benchmark
6771 } // namespace Catch
6772 
6773 // end catch_benchmark_function.hpp
6774 // start catch_repeat.hpp
6775 
6776 // repeat algorithm
6777 
6778 
6779 #include <type_traits>
6780 #include <utility>
6781 
6782 namespace Catch {
6783  namespace Benchmark {
6784  namespace Detail {
6785  template <typename Fun>
6786  struct repeater {
6787  void operator()(int k) const {
6788  for (int i = 0; i < k; ++i) {
6789  fun();
6790  }
6791  }
6792  Fun fun;
6793  };
6794  template <typename Fun>
6795  repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
6796  return { std::forward<Fun>(fun) };
6797  }
6798  } // namespace Detail
6799  } // namespace Benchmark
6800 } // namespace Catch
6801 
6802 // end catch_repeat.hpp
6803 // start catch_run_for_at_least.hpp
6804 
6805 // Run a function for a minimum amount of time
6806 
6807 
6808 // start catch_measure.hpp
6809 
6810 // Measure
6811 
6812 
6813 // start catch_timing.hpp
6814 
6815 // Timing
6816 
6817 
6818 #include <tuple>
6819 #include <type_traits>
6820 
6821 namespace Catch {
6822  namespace Benchmark {
6823  template <typename Duration, typename Result>
6824  struct Timing {
6825  Duration elapsed;
6826  Result result;
6827  int iterations;
6828  };
6829  template <typename Clock, typename Func, typename... Args>
6830  using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
6831  } // namespace Benchmark
6832 } // namespace Catch
6833 
6834 // end catch_timing.hpp
6835 #include <utility>
6836 
6837 namespace Catch {
6838  namespace Benchmark {
6839  namespace Detail {
6840  template <typename Clock, typename Fun, typename... Args>
6841  TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
6842  auto start = Clock::now();
6843  auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
6844  auto end = Clock::now();
6845  auto delta = end - start;
6846  return { delta, std::forward<decltype(r)>(r), 1 };
6847  }
6848  } // namespace Detail
6849  } // namespace Benchmark
6850 } // namespace Catch
6851 
6852 // end catch_measure.hpp
6853 #include <utility>
6854 #include <type_traits>
6855 
6856 namespace Catch {
6857  namespace Benchmark {
6858  namespace Detail {
6859  template <typename Clock, typename Fun>
6860  TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
6861  return Detail::measure<Clock>(fun, iters);
6862  }
6863  template <typename Clock, typename Fun>
6864  TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
6865  Detail::ChronometerModel<Clock> meter;
6866  auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
6867 
6868  return { meter.elapsed(), std::move(result), iters };
6869  }
6870 
6871  template <typename Clock, typename Fun>
6872  using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
6873 
6874  struct optimized_away_error : std::exception {
6875  const char* what() const noexcept override {
6876  return "could not measure benchmark, maybe it was optimized away";
6877  }
6878  };
6879 
6880  template <typename Clock, typename Fun>
6881  TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
6882  auto iters = seed;
6883  while (iters < (1 << 30)) {
6884  auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
6885 
6886  if (Timing.elapsed >= how_long) {
6887  return { Timing.elapsed, std::move(Timing.result), iters };
6888  }
6889  iters *= 2;
6890  }
6891  throw optimized_away_error{};
6892  }
6893  } // namespace Detail
6894  } // namespace Benchmark
6895 } // namespace Catch
6896 
6897 // end catch_run_for_at_least.hpp
6898 #include <algorithm>
6899 
6900 namespace Catch {
6901  namespace Benchmark {
6902  template <typename Duration>
6903  struct ExecutionPlan {
6904  int iterations_per_sample;
6905  Duration estimated_duration;
6906  Detail::BenchmarkFunction benchmark;
6907  Duration warmup_time;
6908  int warmup_iterations;
6909 
6910  template <typename Duration2>
6911  operator ExecutionPlan<Duration2>() const {
6912  return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
6913  }
6914 
6915  template <typename Clock>
6916  std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
6917  // warmup a bit
6918  Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
6919 
6920  std::vector<FloatDuration<Clock>> times;
6921  times.reserve(cfg.benchmarkSamples());
6922  std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
6923  Detail::ChronometerModel<Clock> model;
6924  this->benchmark(Chronometer(model, iterations_per_sample));
6925  auto sample_time = model.elapsed() - env.clock_cost.mean;
6926  if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
6927  return sample_time / iterations_per_sample;
6928  });
6929  return times;
6930  }
6931  };
6932  } // namespace Benchmark
6933 } // namespace Catch
6934 
6935 // end catch_execution_plan.hpp
6936 // start catch_estimate_clock.hpp
6937 
6938  // Environment measurement
6939 
6940 
6941 // start catch_stats.hpp
6942 
6943 // Statistical analysis tools
6944 
6945 
6946 #include <algorithm>
6947 #include <functional>
6948 #include <vector>
6949 #include <iterator>
6950 #include <numeric>
6951 #include <tuple>
6952 #include <cmath>
6953 #include <utility>
6954 #include <cstddef>
6955 #include <random>
6956 
6957 namespace Catch {
6958  namespace Benchmark {
6959  namespace Detail {
6960  using sample = std::vector<double>;
6961 
6962  double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
6963 
6964  template <typename Iterator>
6965  OutlierClassification classify_outliers(Iterator first, Iterator last) {
6966  std::vector<double> copy(first, last);
6967 
6968  auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
6969  auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
6970  auto iqr = q3 - q1;
6971  auto los = q1 - (iqr * 3.);
6972  auto lom = q1 - (iqr * 1.5);
6973  auto him = q3 + (iqr * 1.5);
6974  auto his = q3 + (iqr * 3.);
6975 
6976  OutlierClassification o;
6977  for (; first != last; ++first) {
6978  auto&& t = *first;
6979  if (t < los) ++o.low_severe;
6980  else if (t < lom) ++o.low_mild;
6981  else if (t > his) ++o.high_severe;
6982  else if (t > him) ++o.high_mild;
6983  ++o.samples_seen;
6984  }
6985  return o;
6986  }
6987 
6988  template <typename Iterator>
6989  double mean(Iterator first, Iterator last) {
6990  auto count = last - first;
6991  double sum = std::accumulate(first, last, 0.);
6992  return sum / count;
6993  }
6994 
6995  template <typename URng, typename Iterator, typename Estimator>
6996  sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
6997  auto n = last - first;
6998  std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
6999 
7000  sample out;
7001  out.reserve(resamples);
7002  std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
7003  std::vector<double> resampled;
7004  resampled.reserve(n);
7005  std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
7006  return estimator(resampled.begin(), resampled.end());
7007  });
7008  std::sort(out.begin(), out.end());
7009  return out;
7010  }
7011 
7012  template <typename Estimator, typename Iterator>
7013  sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
7014  auto n = last - first;
7015  auto second = std::next(first);
7016  sample results;
7017  results.reserve(n);
7018 
7019  for (auto it = first; it != last; ++it) {
7020  std::iter_swap(it, first);
7021  results.push_back(estimator(second, last));
7022  }
7023 
7024  return results;
7025  }
7026 
7027  inline double normal_cdf(double x) {
7028  return std::erfc(-x / std::sqrt(2.0)) / 2.0;
7029  }
7030 
7031  double erfc_inv(double x);
7032 
7033  double normal_quantile(double p);
7034 
7035  template <typename Iterator, typename Estimator>
7036  Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
7037  auto n_samples = last - first;
7038 
7039  double point = estimator(first, last);
7040  // Degenerate case with a single sample
7041  if (n_samples == 1) return { point, point, point, confidence_level };
7042 
7043  sample jack = jackknife(estimator, first, last);
7044  double jack_mean = mean(jack.begin(), jack.end());
7045  double sum_squares, sum_cubes;
7046  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> {
7047  auto d = jack_mean - x;
7048  auto d2 = d * d;
7049  auto d3 = d2 * d;
7050  return { sqcb.first + d2, sqcb.second + d3 };
7051  });
7052 
7053  double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
7054  int n = static_cast<int>(resample.size());
7055  double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
7056  // degenerate case with uniform samples
7057  if (prob_n == 0) return { point, point, point, confidence_level };
7058 
7059  double bias = normal_quantile(prob_n);
7060  double z1 = normal_quantile((1. - confidence_level) / 2.);
7061 
7062  auto cumn = [n](double x) -> int {
7063  return std::lround(normal_cdf(x) * n); };
7064  auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
7065  double b1 = bias + z1;
7066  double b2 = bias - z1;
7067  double a1 = a(b1);
7068  double a2 = a(b2);
7069  auto lo = std::max(cumn(a1), 0);
7070  auto hi = std::min(cumn(a2), n - 1);
7071 
7072  return { point, resample[lo], resample[hi], confidence_level };
7073  }
7074 
7075  double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
7076 
7078  Estimate<double> mean;
7079  Estimate<double> standard_deviation;
7080  double outlier_variance;
7081  };
7082 
7083  bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
7084  } // namespace Detail
7085  } // namespace Benchmark
7086 } // namespace Catch
7087 
7088 // end catch_stats.hpp
7089 #include <algorithm>
7090 #include <iterator>
7091 #include <tuple>
7092 #include <vector>
7093 #include <cmath>
7094 
7095 namespace Catch {
7096  namespace Benchmark {
7097  namespace Detail {
7098  template <typename Clock>
7099  std::vector<double> resolution(int k) {
7100  std::vector<TimePoint<Clock>> times;
7101  times.reserve(k + 1);
7102  std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
7103 
7104  std::vector<double> deltas;
7105  deltas.reserve(k);
7106  std::transform(std::next(times.begin()), times.end(), times.begin(),
7107  std::back_inserter(deltas),
7108  [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
7109 
7110  return deltas;
7111  }
7112 
7113  const auto warmup_iterations = 10000;
7114  const auto warmup_time = std::chrono::milliseconds(100);
7115  const auto minimum_ticks = 1000;
7116  const auto warmup_seed = 10000;
7117  const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
7118  const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
7119  const auto clock_cost_estimation_tick_limit = 100000;
7120  const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
7121  const auto clock_cost_estimation_iterations = 10000;
7122 
7123  template <typename Clock>
7124  int warmup() {
7125  return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
7126  .iterations;
7127  }
7128  template <typename Clock>
7129  EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
7130  auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
7131  .result;
7132  return {
7133  FloatDuration<Clock>(mean(r.begin(), r.end())),
7134  classify_outliers(r.begin(), r.end()),
7135  };
7136  }
7137  template <typename Clock>
7138  EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
7139  auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
7140  auto time_clock = [](int k) {
7141  return Detail::measure<Clock>([k] {
7142  for (int i = 0; i < k; ++i) {
7143  volatile auto ignored = Clock::now();
7144  (void)ignored;
7145  }
7146  }).elapsed;
7147  };
7148  time_clock(1);
7149  int iters = clock_cost_estimation_iterations;
7150  auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
7151  std::vector<double> times;
7152  int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
7153  times.reserve(nsamples);
7154  std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
7155  return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
7156  });
7157  return {
7158  FloatDuration<Clock>(mean(times.begin(), times.end())),
7159  classify_outliers(times.begin(), times.end()),
7160  };
7161  }
7162 
7163  template <typename Clock>
7164  Environment<FloatDuration<Clock>> measure_environment() {
7165  static Environment<FloatDuration<Clock>>* env = nullptr;
7166  if (env) {
7167  return *env;
7168  }
7169 
7170  auto iters = Detail::warmup<Clock>();
7171  auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
7172  auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
7173 
7174  env = new Environment<FloatDuration<Clock>>{ resolution, cost };
7175  return *env;
7176  }
7177  } // namespace Detail
7178  } // namespace Benchmark
7179 } // namespace Catch
7180 
7181 // end catch_estimate_clock.hpp
7182 // start catch_analyse.hpp
7183 
7184  // Run and analyse one benchmark
7185 
7186 
7187 // start catch_sample_analysis.hpp
7188 
7189 // Benchmark results
7190 
7191 
7192 #include <algorithm>
7193 #include <vector>
7194 #include <string>
7195 #include <iterator>
7196 
7197 namespace Catch {
7198  namespace Benchmark {
7199  template <typename Duration>
7201  std::vector<Duration> samples;
7202  Estimate<Duration> mean;
7203  Estimate<Duration> standard_deviation;
7204  OutlierClassification outliers;
7205  double outlier_variance;
7206 
7207  template <typename Duration2>
7208  operator SampleAnalysis<Duration2>() const {
7209  std::vector<Duration2> samples2;
7210  samples2.reserve(samples.size());
7211  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
7212  return {
7213  std::move(samples2),
7214  mean,
7215  standard_deviation,
7216  outliers,
7217  outlier_variance,
7218  };
7219  }
7220  };
7221  } // namespace Benchmark
7222 } // namespace Catch
7223 
7224 // end catch_sample_analysis.hpp
7225 #include <algorithm>
7226 #include <iterator>
7227 #include <vector>
7228 
7229 namespace Catch {
7230  namespace Benchmark {
7231  namespace Detail {
7232  template <typename Duration, typename Iterator>
7233  SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
7234  if (!cfg.benchmarkNoAnalysis()) {
7235  std::vector<double> samples;
7236  samples.reserve(last - first);
7237  std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
7238 
7239  auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
7240  auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
7241 
7242  auto wrap_estimate = [](Estimate<double> e) {
7243  return Estimate<Duration> {
7244  Duration(e.point),
7245  Duration(e.lower_bound),
7246  Duration(e.upper_bound),
7247  e.confidence_interval,
7248  };
7249  };
7250  std::vector<Duration> samples2;
7251  samples2.reserve(samples.size());
7252  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
7253  return {
7254  std::move(samples2),
7255  wrap_estimate(analysis.mean),
7256  wrap_estimate(analysis.standard_deviation),
7257  outliers,
7258  analysis.outlier_variance,
7259  };
7260  } else {
7261  std::vector<Duration> samples;
7262  samples.reserve(last - first);
7263 
7264  Duration mean = Duration(0);
7265  int i = 0;
7266  for (auto it = first; it < last; ++it, ++i) {
7267  samples.push_back(Duration(*it));
7268  mean += Duration(*it);
7269  }
7270  mean /= i;
7271 
7272  return {
7273  std::move(samples),
7274  Estimate<Duration>{mean, mean, mean, 0.0},
7275  Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
7276  OutlierClassification{},
7277  0.0
7278  };
7279  }
7280  }
7281  } // namespace Detail
7282  } // namespace Benchmark
7283 } // namespace Catch
7284 
7285 // end catch_analyse.hpp
7286 #include <algorithm>
7287 #include <functional>
7288 #include <string>
7289 #include <vector>
7290 #include <cmath>
7291 
7292 namespace Catch {
7293  namespace Benchmark {
7294  struct Benchmark {
7295  Benchmark(std::string &&name)
7296  : name(std::move(name)) {}
7297 
7298  template <class FUN>
7299  Benchmark(std::string &&name, FUN &&func)
7300  : fun(std::move(func)), name(std::move(name)) {}
7301 
7302  template <typename Clock>
7303  ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
7304  auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
7305  auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
7306  auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
7307  int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
7308  return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
7309  }
7310 
7311  template <typename Clock = default_clock>
7312  void run() {
7313  IConfigPtr cfg = getCurrentContext().getConfig();
7314 
7315  auto env = Detail::measure_environment<Clock>();
7316 
7317  getResultCapture().benchmarkPreparing(name);
7318  CATCH_TRY{
7319  auto plan = user_code([&] {
7320  return prepare<Clock>(*cfg, env);
7321  });
7322 
7323  BenchmarkInfo info {
7324  name,
7325  plan.estimated_duration.count(),
7326  plan.iterations_per_sample,
7327  cfg->benchmarkSamples(),
7328  cfg->benchmarkResamples(),
7329  env.clock_resolution.mean.count(),
7330  env.clock_cost.mean.count()
7331  };
7332 
7333  getResultCapture().benchmarkStarting(info);
7334 
7335  auto samples = user_code([&] {
7336  return plan.template run<Clock>(*cfg, env);
7337  });
7338 
7339  auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
7340  BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
7341  getResultCapture().benchmarkEnded(stats);
7342 
7343  } CATCH_CATCH_ALL{
7344  if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
7345  std::rethrow_exception(std::current_exception());
7346  }
7347  }
7348 
7349  // sets lambda to be used in fun *and* executes benchmark!
7350  template <typename Fun,
7351  typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
7352  Benchmark & operator=(Fun func) {
7353  fun = Detail::BenchmarkFunction(func);
7354  run();
7355  return *this;
7356  }
7357 
7358  explicit operator bool() {
7359  return true;
7360  }
7361 
7362  private:
7363  Detail::BenchmarkFunction fun;
7364  std::string name;
7365  };
7366  }
7367 } // namespace Catch
7368 
7369 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
7370 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
7371 
7372 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
7373  if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7374  BenchmarkName = [&](int benchmarkIndex)
7375 
7376 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
7377  if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
7378  BenchmarkName = [&]
7379 
7380 // end catch_benchmark.hpp
7381 // start catch_constructor.hpp
7382 
7383 // Constructor and destructor helpers
7384 
7385 
7386 #include <type_traits>
7387 
7388 namespace Catch {
7389  namespace Benchmark {
7390  namespace Detail {
7391  template <typename T, bool Destruct>
7393  {
7394  using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
7395 
7396  ObjectStorage() : data() {}
7397 
7398  ObjectStorage(const ObjectStorage& other)
7399  {
7400  new(&data) T(other.stored_object());
7401  }
7402 
7403  ObjectStorage(ObjectStorage&& other)
7404  {
7405  new(&data) T(std::move(other.stored_object()));
7406  }
7407 
7408  ~ObjectStorage() { destruct_on_exit<T>(); }
7409 
7410  template <typename... Args>
7411  void construct(Args&&... args)
7412  {
7413  new (&data) T(std::forward<Args>(args)...);
7414  }
7415 
7416  template <bool AllowManualDestruction = !Destruct>
7417  typename std::enable_if<AllowManualDestruction>::type destruct()
7418  {
7419  stored_object().~T();
7420  }
7421 
7422  private:
7423  // If this is a constructor benchmark, destruct the underlying object
7424  template <typename U>
7425  void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
7426  // Otherwise, don't
7427  template <typename U>
7428  void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
7429 
7430  T& stored_object() {
7431  return *static_cast<T*>(static_cast<void*>(&data));
7432  }
7433 
7434  T const& stored_object() const {
7435  return *static_cast<T*>(static_cast<void*>(&data));
7436  }
7437 
7438  TStorage data;
7439  };
7440  }
7441 
7442  template <typename T>
7444 
7445  template <typename T>
7447  }
7448 }
7449 
7450 // end catch_constructor.hpp
7451 // end catch_benchmarking_all.hpp
7452 #endif
7453 
7454 #endif // ! CATCH_CONFIG_IMPL_ONLY
7455 
7456 #ifdef CATCH_IMPL
7457 // start catch_impl.hpp
7458 
7459 #ifdef __clang__
7460 #pragma clang diagnostic push
7461 #pragma clang diagnostic ignored "-Wweak-vtables"
7462 #endif
7463 
7464 // Keep these here for external reporters
7465 // start catch_test_case_tracker.h
7466 
7467 #include <string>
7468 #include <vector>
7469 #include <memory>
7470 
7471 namespace Catch {
7472 namespace TestCaseTracking {
7473 
7475  std::string name;
7476  SourceLineInfo location;
7477 
7478  NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
7479  friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
7480  return lhs.name == rhs.name
7481  && lhs.location == rhs.location;
7482  }
7483  };
7484 
7485  class ITracker;
7486 
7487  using ITrackerPtr = std::shared_ptr<ITracker>;
7488 
7489  class ITracker {
7490  NameAndLocation m_nameAndLocation;
7491 
7492  public:
7493  ITracker(NameAndLocation const& nameAndLoc) :
7494  m_nameAndLocation(nameAndLoc)
7495  {}
7496 
7497  // static queries
7498  NameAndLocation const& nameAndLocation() const {
7499  return m_nameAndLocation;
7500  }
7501 
7502  virtual ~ITracker();
7503 
7504  // dynamic queries
7505  virtual bool isComplete() const = 0; // Successfully completed or failed
7506  virtual bool isSuccessfullyCompleted() const = 0;
7507  virtual bool isOpen() const = 0; // Started but not complete
7508  virtual bool hasChildren() const = 0;
7509  virtual bool hasStarted() const = 0;
7510 
7511  virtual ITracker& parent() = 0;
7512 
7513  // actions
7514  virtual void close() = 0; // Successfully complete
7515  virtual void fail() = 0;
7516  virtual void markAsNeedingAnotherRun() = 0;
7517 
7518  virtual void addChild( ITrackerPtr const& child ) = 0;
7519  virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
7520  virtual void openChild() = 0;
7521 
7522  // Debug/ checking
7523  virtual bool isSectionTracker() const = 0;
7524  virtual bool isGeneratorTracker() const = 0;
7525  };
7526 
7528 
7529  enum RunState {
7530  NotStarted,
7531  Executing,
7532  CompletedCycle
7533  };
7534 
7535  ITrackerPtr m_rootTracker;
7536  ITracker* m_currentTracker = nullptr;
7537  RunState m_runState = NotStarted;
7538 
7539  public:
7540 
7541  ITracker& startRun();
7542  void endRun();
7543 
7544  void startCycle();
7545  void completeCycle();
7546 
7547  bool completedCycle() const;
7548  ITracker& currentTracker();
7549  void setCurrentTracker( ITracker* tracker );
7550  };
7551 
7552  class TrackerBase : public ITracker {
7553  protected:
7554  enum CycleState {
7555  NotStarted,
7556  Executing,
7557  ExecutingChildren,
7558  NeedsAnotherRun,
7559  CompletedSuccessfully,
7560  Failed
7561  };
7562 
7563  using Children = std::vector<ITrackerPtr>;
7564  TrackerContext& m_ctx;
7565  ITracker* m_parent;
7566  Children m_children;
7567  CycleState m_runState = NotStarted;
7568 
7569  public:
7570  TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7571 
7572  bool isComplete() const override;
7573  bool isSuccessfullyCompleted() const override;
7574  bool isOpen() const override;
7575  bool hasChildren() const override;
7576  bool hasStarted() const override {
7577  return m_runState != NotStarted;
7578  }
7579 
7580  void addChild( ITrackerPtr const& child ) override;
7581 
7582  ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
7583  ITracker& parent() override;
7584 
7585  void openChild() override;
7586 
7587  bool isSectionTracker() const override;
7588  bool isGeneratorTracker() const override;
7589 
7590  void open();
7591 
7592  void close() override;
7593  void fail() override;
7594  void markAsNeedingAnotherRun() override;
7595 
7596  private:
7597  void moveToParent();
7598  void moveToThis();
7599  };
7600 
7601  class SectionTracker : public TrackerBase {
7602  std::vector<std::string> m_filters;
7603  std::string m_trimmed_name;
7604  public:
7605  SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
7606 
7607  bool isSectionTracker() const override;
7608 
7609  bool isComplete() const override;
7610 
7611  static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
7612 
7613  void tryOpen();
7614 
7615  void addInitialFilters( std::vector<std::string> const& filters );
7616  void addNextFilters( std::vector<std::string> const& filters );
7617  };
7618 
7619 } // namespace TestCaseTracking
7620 
7624 
7625 } // namespace Catch
7626 
7627 // end catch_test_case_tracker.h
7628 
7629 // start catch_leak_detector.h
7630 
7631 namespace Catch {
7632 
7633  struct LeakDetector {
7634  LeakDetector();
7635  ~LeakDetector();
7636  };
7637 
7638 }
7639 // end catch_leak_detector.h
7640 // Cpp files will be included in the single-header file here
7641 // start catch_stats.cpp
7642 
7643 // Statistical analysis tools
7644 
7645 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
7646 
7647 #include <cassert>
7648 #include <random>
7649 
7650 #if defined(CATCH_CONFIG_USE_ASYNC)
7651 #include <future>
7652 #endif
7653 
7654 namespace {
7655  double erf_inv(double x) {
7656  // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
7657  double w, p;
7658 
7659  w = -log((1.0 - x) * (1.0 + x));
7660 
7661  if (w < 6.250000) {
7662  w = w - 3.125000;
7663  p = -3.6444120640178196996e-21;
7664  p = -1.685059138182016589e-19 + p * w;
7665  p = 1.2858480715256400167e-18 + p * w;
7666  p = 1.115787767802518096e-17 + p * w;
7667  p = -1.333171662854620906e-16 + p * w;
7668  p = 2.0972767875968561637e-17 + p * w;
7669  p = 6.6376381343583238325e-15 + p * w;
7670  p = -4.0545662729752068639e-14 + p * w;
7671  p = -8.1519341976054721522e-14 + p * w;
7672  p = 2.6335093153082322977e-12 + p * w;
7673  p = -1.2975133253453532498e-11 + p * w;
7674  p = -5.4154120542946279317e-11 + p * w;
7675  p = 1.051212273321532285e-09 + p * w;
7676  p = -4.1126339803469836976e-09 + p * w;
7677  p = -2.9070369957882005086e-08 + p * w;
7678  p = 4.2347877827932403518e-07 + p * w;
7679  p = -1.3654692000834678645e-06 + p * w;
7680  p = -1.3882523362786468719e-05 + p * w;
7681  p = 0.0001867342080340571352 + p * w;
7682  p = -0.00074070253416626697512 + p * w;
7683  p = -0.0060336708714301490533 + p * w;
7684  p = 0.24015818242558961693 + p * w;
7685  p = 1.6536545626831027356 + p * w;
7686  } else if (w < 16.000000) {
7687  w = sqrt(w) - 3.250000;
7688  p = 2.2137376921775787049e-09;
7689  p = 9.0756561938885390979e-08 + p * w;
7690  p = -2.7517406297064545428e-07 + p * w;
7691  p = 1.8239629214389227755e-08 + p * w;
7692  p = 1.5027403968909827627e-06 + p * w;
7693  p = -4.013867526981545969e-06 + p * w;
7694  p = 2.9234449089955446044e-06 + p * w;
7695  p = 1.2475304481671778723e-05 + p * w;
7696  p = -4.7318229009055733981e-05 + p * w;
7697  p = 6.8284851459573175448e-05 + p * w;
7698  p = 2.4031110387097893999e-05 + p * w;
7699  p = -0.0003550375203628474796 + p * w;
7700  p = 0.00095328937973738049703 + p * w;
7701  p = -0.0016882755560235047313 + p * w;
7702  p = 0.0024914420961078508066 + p * w;
7703  p = -0.0037512085075692412107 + p * w;
7704  p = 0.005370914553590063617 + p * w;
7705  p = 1.0052589676941592334 + p * w;
7706  p = 3.0838856104922207635 + p * w;
7707  } else {
7708  w = sqrt(w) - 5.000000;
7709  p = -2.7109920616438573243e-11;
7710  p = -2.5556418169965252055e-10 + p * w;
7711  p = 1.5076572693500548083e-09 + p * w;
7712  p = -3.7894654401267369937e-09 + p * w;
7713  p = 7.6157012080783393804e-09 + p * w;
7714  p = -1.4960026627149240478e-08 + p * w;
7715  p = 2.9147953450901080826e-08 + p * w;
7716  p = -6.7711997758452339498e-08 + p * w;
7717  p = 2.2900482228026654717e-07 + p * w;
7718  p = -9.9298272942317002539e-07 + p * w;
7719  p = 4.5260625972231537039e-06 + p * w;
7720  p = -1.9681778105531670567e-05 + p * w;
7721  p = 7.5995277030017761139e-05 + p * w;
7722  p = -0.00021503011930044477347 + p * w;
7723  p = -0.00013871931833623122026 + p * w;
7724  p = 1.0103004648645343977 + p * w;
7725  p = 4.8499064014085844221 + p * w;
7726  }
7727  return p * x;
7728  }
7729 
7730  double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
7731  auto m = Catch::Benchmark::Detail::mean(first, last);
7732  double variance = std::accumulate(first, last, 0., [m](double a, double b) {
7733  double diff = b - m;
7734  return a + diff * diff;
7735  }) / (last - first);
7736  return std::sqrt(variance);
7737  }
7738 
7739 }
7740 
7741 namespace Catch {
7742  namespace Benchmark {
7743  namespace Detail {
7744 
7745  double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7746  auto count = last - first;
7747  double idx = (count - 1) * k / static_cast<double>(q);
7748  int j = static_cast<int>(idx);
7749  double g = idx - j;
7750  std::nth_element(first, first + j, last);
7751  auto xj = first[j];
7752  if (g == 0) return xj;
7753 
7754  auto xj1 = *std::min_element(first + (j + 1), last);
7755  return xj + g * (xj1 - xj);
7756  }
7757 
7758  double erfc_inv(double x) {
7759  return erf_inv(1.0 - x);
7760  }
7761 
7762  double normal_quantile(double p) {
7763  static const double ROOT_TWO = std::sqrt(2.0);
7764 
7765  double result = 0.0;
7766  assert(p >= 0 && p <= 1);
7767  if (p < 0 || p > 1) {
7768  return result;
7769  }
7770 
7771  result = -erfc_inv(2.0 * p);
7772  // result *= normal distribution standard deviation (1.0) * sqrt(2)
7773  result *= /*sd * */ ROOT_TWO;
7774  // result += normal disttribution mean (0)
7775  return result;
7776  }
7777 
7778  double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
7779  double sb = stddev.point;
7780  double mn = mean.point / n;
7781  double mg_min = mn / 2.;
7782  double sg = std::min(mg_min / 4., sb / std::sqrt(n));
7783  double sg2 = sg * sg;
7784  double sb2 = sb * sb;
7785 
7786  auto c_max = [n, mn, sb2, sg2](double x) -> double {
7787  double k = mn - x;
7788  double d = k * k;
7789  double nd = n * d;
7790  double k0 = -n * nd;
7791  double k1 = sb2 - n * sg2 + nd;
7792  double det = k1 * k1 - 4 * sg2 * k0;
7793  return (int)(-2. * k0 / (k1 + std::sqrt(det)));
7794  };
7795 
7796  auto var_out = [n, sb2, sg2](double c) {
7797  double nc = n - c;
7798  return (nc / n) * (sb2 - nc * sg2);
7799  };
7800 
7801  return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
7802  }
7803 
7804  bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
7805  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
7806  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
7807  static std::random_device entropy;
7808  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
7809 
7810  auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
7811 
7812  auto mean = &Detail::mean<std::vector<double>::iterator>;
7813  auto stddev = &standard_deviation;
7814 
7815 #if defined(CATCH_CONFIG_USE_ASYNC)
7816  auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7817  auto seed = entropy();
7818  return std::async(std::launch::async, [=] {
7819  std::mt19937 rng(seed);
7820  auto resampled = resample(rng, n_resamples, first, last, f);
7821  return bootstrap(confidence_level, first, last, resampled, f);
7822  });
7823  };
7824 
7825  auto mean_future = Estimate(mean);
7826  auto stddev_future = Estimate(stddev);
7827 
7828  auto mean_estimate = mean_future.get();
7829  auto stddev_estimate = stddev_future.get();
7830 #else
7831  auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
7832  auto seed = entropy();
7833  std::mt19937 rng(seed);
7834  auto resampled = resample(rng, n_resamples, first, last, f);
7835  return bootstrap(confidence_level, first, last, resampled, f);
7836  };
7837 
7838  auto mean_estimate = Estimate(mean);
7839  auto stddev_estimate = Estimate(stddev);
7840 #endif // CATCH_USE_ASYNC
7841 
7842  double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
7843 
7844  return { mean_estimate, stddev_estimate, outlier_variance };
7845  }
7846  } // namespace Detail
7847  } // namespace Benchmark
7848 } // namespace Catch
7849 
7850 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
7851 // end catch_stats.cpp
7852 // start catch_approx.cpp
7853 
7854 #include <cmath>
7855 #include <limits>
7856 
7857 namespace {
7858 
7859 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
7860 // But without the subtraction to allow for INFINITY in comparison
7861 bool marginComparison(double lhs, double rhs, double margin) {
7862  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
7863 }
7864 
7865 }
7866 
7867 namespace Catch {
7868 namespace Detail {
7869 
7870  Approx::Approx ( double value )
7871  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
7872  m_margin( 0.0 ),
7873  m_scale( 0.0 ),
7874  m_value( value )
7875  {}
7876 
7877  Approx Approx::custom() {
7878  return Approx( 0 );
7879  }
7880 
7881  Approx Approx::operator-() const {
7882  auto temp(*this);
7883  temp.m_value = -temp.m_value;
7884  return temp;
7885  }
7886 
7887  std::string Approx::toString() const {
7888  ReusableStringStream rss;
7889  rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
7890  return rss.str();
7891  }
7892 
7893  bool Approx::equalityComparisonImpl(const double other) const {
7894  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
7895  // Thanks to Richard Harris for his help refining the scaled margin value
7896  return marginComparison(m_value, other, m_margin)
7897  || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
7898  }
7899 
7900  void Approx::setMargin(double newMargin) {
7901  CATCH_ENFORCE(newMargin >= 0,
7902  "Invalid Approx::margin: " << newMargin << '.'
7903  << " Approx::Margin has to be non-negative.");
7904  m_margin = newMargin;
7905  }
7906 
7907  void Approx::setEpsilon(double newEpsilon) {
7908  CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
7909  "Invalid Approx::epsilon: " << newEpsilon << '.'
7910  << " Approx::epsilon has to be in [0, 1]");
7911  m_epsilon = newEpsilon;
7912  }
7913 
7914 } // end namespace Detail
7915 
7916 namespace literals {
7917  Detail::Approx operator "" _a(long double val) {
7918  return Detail::Approx(val);
7919  }
7920  Detail::Approx operator "" _a(unsigned long long val) {
7921  return Detail::Approx(val);
7922  }
7923 } // end namespace literals
7924 
7925 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
7926  return value.toString();
7927 }
7928 
7929 } // end namespace Catch
7930 // end catch_approx.cpp
7931 // start catch_assertionhandler.cpp
7932 
7933 // start catch_debugger.h
7934 
7935 namespace Catch {
7936  bool isDebuggerActive();
7937 }
7938 
7939 #ifdef CATCH_PLATFORM_MAC
7940 
7941  #if defined(__i386__) || defined(__x86_64__)
7942  #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
7943  #elif defined(__aarch64__)
7944  #define CATCH_TRAP() __asm__(".inst 0xd4200000")
7945  #endif
7946 
7947 #elif defined(CATCH_PLATFORM_IPHONE)
7948 
7949  // use inline assembler
7950  #if defined(__i386__) || defined(__x86_64__)
7951  #define CATCH_TRAP() __asm__("int $3")
7952  #elif defined(__aarch64__)
7953  #define CATCH_TRAP() __asm__(".inst 0xd4200000")
7954  #elif defined(__arm__) && !defined(__thumb__)
7955  #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
7956  #elif defined(__arm__) && defined(__thumb__)
7957  #define CATCH_TRAP() __asm__(".inst 0xde01")
7958  #endif
7959 
7960 #elif defined(CATCH_PLATFORM_LINUX)
7961  // If we can use inline assembler, do it because this allows us to break
7962  // directly at the location of the failing check instead of breaking inside
7963  // raise() called from it, i.e. one stack frame below.
7964  #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
7965  #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
7966  #else // Fall back to the generic way.
7967  #include <signal.h>
7968 
7969  #define CATCH_TRAP() raise(SIGTRAP)
7970  #endif
7971 #elif defined(_MSC_VER)
7972  #define CATCH_TRAP() __debugbreak()
7973 #elif defined(__MINGW32__)
7974  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
7975  #define CATCH_TRAP() DebugBreak()
7976 #endif
7977 
7978 #ifndef CATCH_BREAK_INTO_DEBUGGER
7979  #ifdef CATCH_TRAP
7980  #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
7981  #else
7982  #define CATCH_BREAK_INTO_DEBUGGER() []{}()
7983  #endif
7984 #endif
7985 
7986 // end catch_debugger.h
7987 // start catch_run_context.h
7988 
7989 // start catch_fatal_condition.h
7990 
7991 // start catch_windows_h_proxy.h
7992 
7993 
7994 #if defined(CATCH_PLATFORM_WINDOWS)
7995 
7996 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
7997 # define CATCH_DEFINED_NOMINMAX
7998 # define NOMINMAX
7999 #endif
8000 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
8001 # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
8002 # define WIN32_LEAN_AND_MEAN
8003 #endif
8004 
8005 #ifdef __AFXDLL
8006 #include <AfxWin.h>
8007 #else
8008 #include <windows.h>
8009 #endif
8010 
8011 #ifdef CATCH_DEFINED_NOMINMAX
8012 # undef NOMINMAX
8013 #endif
8014 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
8015 # undef WIN32_LEAN_AND_MEAN
8016 #endif
8017 
8018 #endif // defined(CATCH_PLATFORM_WINDOWS)
8019 
8020 // end catch_windows_h_proxy.h
8021 #if defined( CATCH_CONFIG_WINDOWS_SEH )
8022 
8023 namespace Catch {
8024 
8026 
8027  static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
8029  static void reset();
8031 
8032  private:
8033  static bool isSet;
8034  static ULONG guaranteeSize;
8035  static PVOID exceptionHandlerHandle;
8036  };
8037 
8038 } // namespace Catch
8039 
8040 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
8041 
8042 #include <signal.h>
8043 
8044 namespace Catch {
8045 
8046  struct FatalConditionHandler {
8047 
8048  static bool isSet;
8049  static struct sigaction oldSigActions[];
8050  static stack_t oldSigStack;
8051  static char altStackMem[];
8052 
8053  static void handleSignal( int sig );
8054 
8055  FatalConditionHandler();
8056  ~FatalConditionHandler();
8057  static void reset();
8058  };
8059 
8060 } // namespace Catch
8061 
8062 #else
8063 
8064 namespace Catch {
8065  struct FatalConditionHandler {
8066  void reset();
8067  };
8068 }
8069 
8070 #endif
8071 
8072 // end catch_fatal_condition.h
8073 #include <string>
8074 
8075 namespace Catch {
8076 
8077  struct IMutableContext;
8078 
8080 
8081  class RunContext : public IResultCapture, public IRunner {
8082 
8083  public:
8084  RunContext( RunContext const& ) = delete;
8085  RunContext& operator =( RunContext const& ) = delete;
8086 
8087  explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
8088 
8089  ~RunContext() override;
8090 
8091  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
8092  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
8093 
8094  Totals runTest(TestCase const& testCase);
8095 
8096  IConfigPtr config() const;
8097  IStreamingReporter& reporter() const;
8098 
8099  public: // IResultCapture
8100 
8101  // Assertion handlers
8102  void handleExpr
8103  ( AssertionInfo const& info,
8104  ITransientExpression const& expr,
8105  AssertionReaction& reaction ) override;
8106  void handleMessage
8107  ( AssertionInfo const& info,
8108  ResultWas::OfType resultType,
8109  StringRef const& message,
8110  AssertionReaction& reaction ) override;
8111  void handleUnexpectedExceptionNotThrown
8112  ( AssertionInfo const& info,
8113  AssertionReaction& reaction ) override;
8114  void handleUnexpectedInflightException
8115  ( AssertionInfo const& info,
8116  std::string const& message,
8117  AssertionReaction& reaction ) override;
8118  void handleIncomplete
8119  ( AssertionInfo const& info ) override;
8120  void handleNonExpr
8121  ( AssertionInfo const &info,
8122  ResultWas::OfType resultType,
8123  AssertionReaction &reaction ) override;
8124 
8125  bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
8126 
8127  void sectionEnded( SectionEndInfo const& endInfo ) override;
8128  void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
8129 
8130  auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
8131 
8132 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
8133  void benchmarkPreparing( std::string const& name ) override;
8134  void benchmarkStarting( BenchmarkInfo const& info ) override;
8135  void benchmarkEnded( BenchmarkStats<> const& stats ) override;
8136  void benchmarkFailed( std::string const& error ) override;
8137 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
8138 
8139  void pushScopedMessage( MessageInfo const& message ) override;
8140  void popScopedMessage( MessageInfo const& message ) override;
8141 
8142  void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
8143 
8144  std::string getCurrentTestName() const override;
8145 
8146  const AssertionResult* getLastResult() const override;
8147 
8148  void exceptionEarlyReported() override;
8149 
8150  void handleFatalErrorCondition( StringRef message ) override;
8151 
8152  bool lastAssertionPassed() override;
8153 
8154  void assertionPassed() override;
8155 
8156  public:
8157  // !TBD We need to do this another way!
8158  bool aborting() const final;
8159 
8160  private:
8161 
8162  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
8163  void invokeActiveTestCase();
8164 
8165  void resetAssertionInfo();
8166  bool testForMissingAssertions( Counts& assertions );
8167 
8168  void assertionEnded( AssertionResult const& result );
8169  void reportExpr
8170  ( AssertionInfo const &info,
8171  ResultWas::OfType resultType,
8172  ITransientExpression const *expr,
8173  bool negated );
8174 
8175  void populateReaction( AssertionReaction& reaction );
8176 
8177  private:
8178 
8179  void handleUnfinishedSections();
8180 
8181  TestRunInfo m_runInfo;
8182  IMutableContext& m_context;
8183  TestCase const* m_activeTestCase = nullptr;
8184  ITracker* m_testCaseTracker = nullptr;
8185  Option<AssertionResult> m_lastResult;
8186 
8187  IConfigPtr m_config;
8188  Totals m_totals;
8189  IStreamingReporterPtr m_reporter;
8190  std::vector<MessageInfo> m_messages;
8191  std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
8192  AssertionInfo m_lastAssertionInfo;
8193  std::vector<SectionEndInfo> m_unfinishedSections;
8194  std::vector<ITracker*> m_activeSections;
8195  TrackerContext m_trackerContext;
8196  bool m_lastAssertionPassed = false;
8197  bool m_shouldReportUnexpected = true;
8198  bool m_includeSuccessfulResults;
8199  };
8200 
8201  void seedRng(IConfig const& config);
8202  unsigned int rngSeed();
8203 } // end namespace Catch
8204 
8205 // end catch_run_context.h
8206 namespace Catch {
8207 
8208  namespace {
8209  auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
8210  expr.streamReconstructedExpression( os );
8211  return os;
8212  }
8213  }
8214 
8215  LazyExpression::LazyExpression( bool isNegated )
8216  : m_isNegated( isNegated )
8217  {}
8218 
8219  LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
8220 
8221  LazyExpression::operator bool() const {
8222  return m_transientExpression != nullptr;
8223  }
8224 
8225  auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
8226  if( lazyExpr.m_isNegated )
8227  os << "!";
8228 
8229  if( lazyExpr ) {
8230  if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
8231  os << "(" << *lazyExpr.m_transientExpression << ")";
8232  else
8233  os << *lazyExpr.m_transientExpression;
8234  }
8235  else {
8236  os << "{** error - unchecked empty expression requested **}";
8237  }
8238  return os;
8239  }
8240 
8241  AssertionHandler::AssertionHandler
8242  ( StringRef const& macroName,
8243  SourceLineInfo const& lineInfo,
8244  StringRef capturedExpression,
8245  ResultDisposition::Flags resultDisposition )
8246  : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
8247  m_resultCapture( getResultCapture() )
8248  {}
8249 
8250  void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
8251  m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
8252  }
8253  void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
8254  m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
8255  }
8256 
8257  auto AssertionHandler::allowThrows() const -> bool {
8258  return getCurrentContext().getConfig()->allowThrows();
8259  }
8260 
8261  void AssertionHandler::complete() {
8262  setCompleted();
8263  if( m_reaction.shouldDebugBreak ) {
8264 
8265  // If you find your debugger stopping you here then go one level up on the
8266  // call-stack for the code that caused it (typically a failed assertion)
8267 
8268  // (To go back to the test and change execution, jump over the throw, next)
8269  CATCH_BREAK_INTO_DEBUGGER();
8270  }
8271  if (m_reaction.shouldThrow) {
8272 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8274 #else
8275  CATCH_ERROR( "Test failure requires aborting test!" );
8276 #endif
8277  }
8278  }
8279  void AssertionHandler::setCompleted() {
8280  m_completed = true;
8281  }
8282 
8283  void AssertionHandler::handleUnexpectedInflightException() {
8284  m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
8285  }
8286 
8287  void AssertionHandler::handleExceptionThrownAsExpected() {
8288  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8289  }
8290  void AssertionHandler::handleExceptionNotThrownAsExpected() {
8291  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8292  }
8293 
8294  void AssertionHandler::handleUnexpectedExceptionNotThrown() {
8295  m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
8296  }
8297 
8298  void AssertionHandler::handleThrowingCallSkipped() {
8299  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8300  }
8301 
8302  // This is the overload that takes a string and infers the Equals matcher from it
8303  // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
8304  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
8305  handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
8306  }
8307 
8308 } // namespace Catch
8309 // end catch_assertionhandler.cpp
8310 // start catch_assertionresult.cpp
8311 
8312 namespace Catch {
8313  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
8314  lazyExpression(_lazyExpression),
8315  resultType(_resultType) {}
8316 
8317  std::string AssertionResultData::reconstructExpression() const {
8318 
8319  if( reconstructedExpression.empty() ) {
8320  if( lazyExpression ) {
8321  ReusableStringStream rss;
8322  rss << lazyExpression;
8323  reconstructedExpression = rss.str();
8324  }
8325  }
8326  return reconstructedExpression;
8327  }
8328 
8329  AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
8330  : m_info( info ),
8331  m_resultData( data )
8332  {}
8333 
8334  // Result was a success
8335  bool AssertionResult::succeeded() const {
8336  return Catch::isOk( m_resultData.resultType );
8337  }
8338 
8339  // Result was a success, or failure is suppressed
8340  bool AssertionResult::isOk() const {
8341  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
8342  }
8343 
8344  ResultWas::OfType AssertionResult::getResultType() const {
8345  return m_resultData.resultType;
8346  }
8347 
8348  bool AssertionResult::hasExpression() const {
8349  return !m_info.capturedExpression.empty();
8350  }
8351 
8352  bool AssertionResult::hasMessage() const {
8353  return !m_resultData.message.empty();
8354  }
8355 
8356  std::string AssertionResult::getExpression() const {
8357  // Possibly overallocating by 3 characters should be basically free
8358  std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
8359  if (isFalseTest(m_info.resultDisposition)) {
8360  expr += "!(";
8361  }
8362  expr += m_info.capturedExpression;
8363  if (isFalseTest(m_info.resultDisposition)) {
8364  expr += ')';
8365  }
8366  return expr;
8367  }
8368 
8369  std::string AssertionResult::getExpressionInMacro() const {
8370  std::string expr;
8371  if( m_info.macroName.empty() )
8372  expr = static_cast<std::string>(m_info.capturedExpression);
8373  else {
8374  expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
8375  expr += m_info.macroName;
8376  expr += "( ";
8377  expr += m_info.capturedExpression;
8378  expr += " )";
8379  }
8380  return expr;
8381  }
8382 
8383  bool AssertionResult::hasExpandedExpression() const {
8384  return hasExpression() && getExpandedExpression() != getExpression();
8385  }
8386 
8387  std::string AssertionResult::getExpandedExpression() const {
8388  std::string expr = m_resultData.reconstructExpression();
8389  return expr.empty()
8390  ? getExpression()
8391  : expr;
8392  }
8393 
8394  std::string AssertionResult::getMessage() const {
8395  return m_resultData.message;
8396  }
8397  SourceLineInfo AssertionResult::getSourceInfo() const {
8398  return m_info.lineInfo;
8399  }
8400 
8401  StringRef AssertionResult::getTestMacroName() const {
8402  return m_info.macroName;
8403  }
8404 
8405 } // end namespace Catch
8406 // end catch_assertionresult.cpp
8407 // start catch_capture_matchers.cpp
8408 
8409 namespace Catch {
8410 
8411  using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
8412 
8413  // This is the general overload that takes a any string matcher
8414  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
8415  // the Equals matcher (so the header does not mention matchers)
8416  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
8417  std::string exceptionMessage = Catch::translateActiveException();
8418  MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
8419  handler.handleExpr( expr );
8420  }
8421 
8422 } // namespace Catch
8423 // end catch_capture_matchers.cpp
8424 // start catch_commandline.cpp
8425 
8426 // start catch_commandline.h
8427 
8428 // start catch_clara.h
8429 
8430 // Use Catch's value for console width (store Clara's off to the side, if present)
8431 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
8432 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8433 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8434 #endif
8435 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
8436 
8437 #ifdef __clang__
8438 #pragma clang diagnostic push
8439 #pragma clang diagnostic ignored "-Wweak-vtables"
8440 #pragma clang diagnostic ignored "-Wexit-time-destructors"
8441 #pragma clang diagnostic ignored "-Wshadow"
8442 #endif
8443 
8444 // start clara.hpp
8445 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
8446 //
8447 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8448 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8449 //
8450 // See https://github.com/philsquared/Clara for more details
8451 
8452 // Clara v1.1.5
8453 
8454 
8455 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8456 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
8457 #endif
8458 
8459 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8460 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8461 #endif
8462 
8463 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
8464 #ifdef __has_include
8465 #if __has_include(<optional>) && __cplusplus >= 201703L
8466 #include <optional>
8467 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
8468 #endif
8469 #endif
8470 #endif
8471 
8472 // ----------- #included from clara_textflow.hpp -----------
8473 
8474 // TextFlowCpp
8475 //
8476 // A single-header library for wrapping and laying out basic text, by Phil Nash
8477 //
8478 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8479 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8480 //
8481 // This project is hosted at https://github.com/philsquared/textflowcpp
8482 
8483 
8484 #include <cassert>
8485 #include <ostream>
8486 #include <sstream>
8487 #include <vector>
8488 
8489 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8490 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
8491 #endif
8492 
8493 namespace Catch {
8494 namespace clara {
8495 namespace TextFlow {
8496 
8497 inline auto isWhitespace(char c) -> bool {
8498  static std::string chars = " \t\n\r";
8499  return chars.find(c) != std::string::npos;
8500 }
8501 inline auto isBreakableBefore(char c) -> bool {
8502  static std::string chars = "[({<|";
8503  return chars.find(c) != std::string::npos;
8504 }
8505 inline auto isBreakableAfter(char c) -> bool {
8506  static std::string chars = "])}>.,:;*+-=&/\\";
8507  return chars.find(c) != std::string::npos;
8508 }
8509 
8510 class Columns;
8511 
8512 class Column {
8513  std::vector<std::string> m_strings;
8514  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
8515  size_t m_indent = 0;
8516  size_t m_initialIndent = std::string::npos;
8517 
8518 public:
8519  class iterator {
8520  friend Column;
8521 
8522  Column const& m_column;
8523  size_t m_stringIndex = 0;
8524  size_t m_pos = 0;
8525 
8526  size_t m_len = 0;
8527  size_t m_end = 0;
8528  bool m_suffix = false;
8529 
8530  iterator(Column const& column, size_t stringIndex)
8531  : m_column(column),
8532  m_stringIndex(stringIndex) {}
8533 
8534  auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
8535 
8536  auto isBoundary(size_t at) const -> bool {
8537  assert(at > 0);
8538  assert(at <= line().size());
8539 
8540  return at == line().size() ||
8541  (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
8542  isBreakableBefore(line()[at]) ||
8543  isBreakableAfter(line()[at - 1]);
8544  }
8545 
8546  void calcLength() {
8547  assert(m_stringIndex < m_column.m_strings.size());
8548 
8549  m_suffix = false;
8550  auto width = m_column.m_width - indent();
8551  m_end = m_pos;
8552  if (line()[m_pos] == '\n') {
8553  ++m_end;
8554  }
8555  while (m_end < line().size() && line()[m_end] != '\n')
8556  ++m_end;
8557 
8558  if (m_end < m_pos + width) {
8559  m_len = m_end - m_pos;
8560  } else {
8561  size_t len = width;
8562  while (len > 0 && !isBoundary(m_pos + len))
8563  --len;
8564  while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
8565  --len;
8566 
8567  if (len > 0) {
8568  m_len = len;
8569  } else {
8570  m_suffix = true;
8571  m_len = width - 1;
8572  }
8573  }
8574  }
8575 
8576  auto indent() const -> size_t {
8577  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
8578  return initial == std::string::npos ? m_column.m_indent : initial;
8579  }
8580 
8581  auto addIndentAndSuffix(std::string const &plain) const -> std::string {
8582  return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
8583  }
8584 
8585  public:
8586  using difference_type = std::ptrdiff_t;
8587  using value_type = std::string;
8588  using pointer = value_type * ;
8589  using reference = value_type & ;
8590  using iterator_category = std::forward_iterator_tag;
8591 
8592  explicit iterator(Column const& column) : m_column(column) {
8593  assert(m_column.m_width > m_column.m_indent);
8594  assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
8595  calcLength();
8596  if (m_len == 0)
8597  m_stringIndex++; // Empty string
8598  }
8599 
8600  auto operator *() const -> std::string {
8601  assert(m_stringIndex < m_column.m_strings.size());
8602  assert(m_pos <= m_end);
8603  return addIndentAndSuffix(line().substr(m_pos, m_len));
8604  }
8605 
8606  auto operator ++() -> iterator& {
8607  m_pos += m_len;
8608  if (m_pos < line().size() && line()[m_pos] == '\n')
8609  m_pos += 1;
8610  else
8611  while (m_pos < line().size() && isWhitespace(line()[m_pos]))
8612  ++m_pos;
8613 
8614  if (m_pos == line().size()) {
8615  m_pos = 0;
8616  ++m_stringIndex;
8617  }
8618  if (m_stringIndex < m_column.m_strings.size())
8619  calcLength();
8620  return *this;
8621  }
8622  auto operator ++(int) -> iterator {
8623  iterator prev(*this);
8624  operator++();
8625  return prev;
8626  }
8627 
8628  auto operator ==(iterator const& other) const -> bool {
8629  return
8630  m_pos == other.m_pos &&
8631  m_stringIndex == other.m_stringIndex &&
8632  &m_column == &other.m_column;
8633  }
8634  auto operator !=(iterator const& other) const -> bool {
8635  return !operator==(other);
8636  }
8637  };
8638  using const_iterator = iterator;
8639 
8640  explicit Column(std::string const& text) { m_strings.push_back(text); }
8641 
8642  auto width(size_t newWidth) -> Column& {
8643  assert(newWidth > 0);
8644  m_width = newWidth;
8645  return *this;
8646  }
8647  auto indent(size_t newIndent) -> Column& {
8648  m_indent = newIndent;
8649  return *this;
8650  }
8651  auto initialIndent(size_t newIndent) -> Column& {
8652  m_initialIndent = newIndent;
8653  return *this;
8654  }
8655 
8656  auto width() const -> size_t { return m_width; }
8657  auto begin() const -> iterator { return iterator(*this); }
8658  auto end() const -> iterator { return { *this, m_strings.size() }; }
8659 
8660  inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
8661  bool first = true;
8662  for (auto line : col) {
8663  if (first)
8664  first = false;
8665  else
8666  os << "\n";
8667  os << line;
8668  }
8669  return os;
8670  }
8671 
8672  auto operator + (Column const& other)->Columns;
8673 
8674  auto toString() const -> std::string {
8675  std::ostringstream oss;
8676  oss << *this;
8677  return oss.str();
8678  }
8679 };
8680 
8681 class Spacer : public Column {
8682 
8683 public:
8684  explicit Spacer(size_t spaceWidth) : Column("") {
8685  width(spaceWidth);
8686  }
8687 };
8688 
8689 class Columns {
8690  std::vector<Column> m_columns;
8691 
8692 public:
8693 
8694  class iterator {
8695  friend Columns;
8696  struct EndTag {};
8697 
8698  std::vector<Column> const& m_columns;
8699  std::vector<Column::iterator> m_iterators;
8700  size_t m_activeIterators;
8701 
8702  iterator(Columns const& columns, EndTag)
8703  : m_columns(columns.m_columns),
8704  m_activeIterators(0) {
8705  m_iterators.reserve(m_columns.size());
8706 
8707  for (auto const& col : m_columns)
8708  m_iterators.push_back(col.end());
8709  }
8710 
8711  public:
8712  using difference_type = std::ptrdiff_t;
8713  using value_type = std::string;
8714  using pointer = value_type * ;
8715  using reference = value_type & ;
8716  using iterator_category = std::forward_iterator_tag;
8717 
8718  explicit iterator(Columns const& columns)
8719  : m_columns(columns.m_columns),
8720  m_activeIterators(m_columns.size()) {
8721  m_iterators.reserve(m_columns.size());
8722 
8723  for (auto const& col : m_columns)
8724  m_iterators.push_back(col.begin());
8725  }
8726 
8727  auto operator ==(iterator const& other) const -> bool {
8728  return m_iterators == other.m_iterators;
8729  }
8730  auto operator !=(iterator const& other) const -> bool {
8731  return m_iterators != other.m_iterators;
8732  }
8733  auto operator *() const -> std::string {
8734  std::string row, padding;
8735 
8736  for (size_t i = 0; i < m_columns.size(); ++i) {
8737  auto width = m_columns[i].width();
8738  if (m_iterators[i] != m_columns[i].end()) {
8739  std::string col = *m_iterators[i];
8740  row += padding + col;
8741  if (col.size() < width)
8742  padding = std::string(width - col.size(), ' ');
8743  else
8744  padding = "";
8745  } else {
8746  padding += std::string(width, ' ');
8747  }
8748  }
8749  return row;
8750  }
8751  auto operator ++() -> iterator& {
8752  for (size_t i = 0; i < m_columns.size(); ++i) {
8753  if (m_iterators[i] != m_columns[i].end())
8754  ++m_iterators[i];
8755  }
8756  return *this;
8757  }
8758  auto operator ++(int) -> iterator {
8759  iterator prev(*this);
8760  operator++();
8761  return prev;
8762  }
8763  };
8764  using const_iterator = iterator;
8765 
8766  auto begin() const -> iterator { return iterator(*this); }
8767  auto end() const -> iterator { return { *this, iterator::EndTag() }; }
8768 
8769  auto operator += (Column const& col) -> Columns& {
8770  m_columns.push_back(col);
8771  return *this;
8772  }
8773  auto operator + (Column const& col) -> Columns {
8774  Columns combined = *this;
8775  combined += col;
8776  return combined;
8777  }
8778 
8779  inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
8780 
8781  bool first = true;
8782  for (auto line : cols) {
8783  if (first)
8784  first = false;
8785  else
8786  os << "\n";
8787  os << line;
8788  }
8789  return os;
8790  }
8791 
8792  auto toString() const -> std::string {
8793  std::ostringstream oss;
8794  oss << *this;
8795  return oss.str();
8796  }
8797 };
8798 
8799 inline auto Column::operator + (Column const& other) -> Columns {
8800  Columns cols;
8801  cols += *this;
8802  cols += other;
8803  return cols;
8804 }
8805 }
8806 
8807 }
8808 }
8809 
8810 // ----------- end of #include from clara_textflow.hpp -----------
8811 // ........... back in clara.hpp
8812 
8813 #include <cctype>
8814 #include <string>
8815 #include <memory>
8816 #include <set>
8817 #include <algorithm>
8818 
8819 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
8820 #define CATCH_PLATFORM_WINDOWS
8821 #endif
8822 
8823 namespace Catch { namespace clara {
8824 namespace detail {
8825 
8826  // Traits for extracting arg and return type of lambdas (for single argument lambdas)
8827  template<typename L>
8828  struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
8829 
8830  template<typename ClassT, typename ReturnT, typename... Args>
8831  struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
8832  static const bool isValid = false;
8833  };
8834 
8835  template<typename ClassT, typename ReturnT, typename ArgT>
8836  struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
8837  static const bool isValid = true;
8838  using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
8839  using ReturnType = ReturnT;
8840  };
8841 
8842  class TokenStream;
8843 
8844  // Transport for raw args (copied from main args, or supplied via init list for testing)
8845  class Args {
8846  friend TokenStream;
8847  std::string m_exeName;
8848  std::vector<std::string> m_args;
8849 
8850  public:
8851  Args( int argc, char const* const* argv )
8852  : m_exeName(argv[0]),
8853  m_args(argv + 1, argv + argc) {}
8854 
8855  Args( std::initializer_list<std::string> args )
8856  : m_exeName( *args.begin() ),
8857  m_args( args.begin()+1, args.end() )
8858  {}
8859 
8860  auto exeName() const -> std::string {
8861  return m_exeName;
8862  }
8863  };
8864 
8865  // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
8866  // may encode an option + its argument if the : or = form is used
8867  enum class TokenType {
8868  Option, Argument
8869  };
8870  struct Token {
8871  TokenType type;
8872  std::string token;
8873  };
8874 
8875  inline auto isOptPrefix( char c ) -> bool {
8876  return c == '-'
8877 #ifdef CATCH_PLATFORM_WINDOWS
8878  || c == '/'
8879 #endif
8880  ;
8881  }
8882 
8883  // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
8884  class TokenStream {
8885  using Iterator = std::vector<std::string>::const_iterator;
8886  Iterator it;
8887  Iterator itEnd;
8888  std::vector<Token> m_tokenBuffer;
8889 
8890  void loadBuffer() {
8891  m_tokenBuffer.resize( 0 );
8892 
8893  // Skip any empty strings
8894  while( it != itEnd && it->empty() )
8895  ++it;
8896 
8897  if( it != itEnd ) {
8898  auto const &next = *it;
8899  if( isOptPrefix( next[0] ) ) {
8900  auto delimiterPos = next.find_first_of( " :=" );
8901  if( delimiterPos != std::string::npos ) {
8902  m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
8903  m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
8904  } else {
8905  if( next[1] != '-' && next.size() > 2 ) {
8906  std::string opt = "- ";
8907  for( size_t i = 1; i < next.size(); ++i ) {
8908  opt[1] = next[i];
8909  m_tokenBuffer.push_back( { TokenType::Option, opt } );
8910  }
8911  } else {
8912  m_tokenBuffer.push_back( { TokenType::Option, next } );
8913  }
8914  }
8915  } else {
8916  m_tokenBuffer.push_back( { TokenType::Argument, next } );
8917  }
8918  }
8919  }
8920 
8921  public:
8922  explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
8923 
8924  TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
8925  loadBuffer();
8926  }
8927 
8928  explicit operator bool() const {
8929  return !m_tokenBuffer.empty() || it != itEnd;
8930  }
8931 
8932  auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
8933 
8934  auto operator*() const -> Token {
8935  assert( !m_tokenBuffer.empty() );
8936  return m_tokenBuffer.front();
8937  }
8938 
8939  auto operator->() const -> Token const * {
8940  assert( !m_tokenBuffer.empty() );
8941  return &m_tokenBuffer.front();
8942  }
8943 
8944  auto operator++() -> TokenStream & {
8945  if( m_tokenBuffer.size() >= 2 ) {
8946  m_tokenBuffer.erase( m_tokenBuffer.begin() );
8947  } else {
8948  if( it != itEnd )
8949  ++it;
8950  loadBuffer();
8951  }
8952  return *this;
8953  }
8954  };
8955 
8956  class ResultBase {
8957  public:
8958  enum Type {
8959  Ok, LogicError, RuntimeError
8960  };
8961 
8962  protected:
8963  ResultBase( Type type ) : m_type( type ) {}
8964  virtual ~ResultBase() = default;
8965 
8966  virtual void enforceOk() const = 0;
8967 
8968  Type m_type;
8969  };
8970 
8971  template<typename T>
8972  class ResultValueBase : public ResultBase {
8973  public:
8974  auto value() const -> T const & {
8975  enforceOk();
8976  return m_value;
8977  }
8978 
8979  protected:
8980  ResultValueBase( Type type ) : ResultBase( type ) {}
8981 
8982  ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
8983  if( m_type == ResultBase::Ok )
8984  new( &m_value ) T( other.m_value );
8985  }
8986 
8987  ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
8988  new( &m_value ) T( value );
8989  }
8990 
8991  auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
8992  if( m_type == ResultBase::Ok )
8993  m_value.~T();
8994  ResultBase::operator=(other);
8995  if( m_type == ResultBase::Ok )
8996  new( &m_value ) T( other.m_value );
8997  return *this;
8998  }
8999 
9000  ~ResultValueBase() override {
9001  if( m_type == Ok )
9002  m_value.~T();
9003  }
9004 
9005  union {
9006  T m_value;
9007  };
9008  };
9009 
9010  template<>
9011  class ResultValueBase<void> : public ResultBase {
9012  protected:
9013  using ResultBase::ResultBase;
9014  };
9015 
9016  template<typename T = void>
9017  class BasicResult : public ResultValueBase<T> {
9018  public:
9019  template<typename U>
9020  explicit BasicResult( BasicResult<U> const &other )
9021  : ResultValueBase<T>( other.type() ),
9022  m_errorMessage( other.errorMessage() )
9023  {
9024  assert( type() != ResultBase::Ok );
9025  }
9026 
9027  template<typename U>
9028  static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
9029  static auto ok() -> BasicResult { return { ResultBase::Ok }; }
9030  static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
9031  static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
9032 
9033  explicit operator bool() const { return m_type == ResultBase::Ok; }
9034  auto type() const -> ResultBase::Type { return m_type; }
9035  auto errorMessage() const -> std::string { return m_errorMessage; }
9036 
9037  protected:
9038  void enforceOk() const override {
9039 
9040  // Errors shouldn't reach this point, but if they do
9041  // the actual error message will be in m_errorMessage
9042  assert( m_type != ResultBase::LogicError );
9043  assert( m_type != ResultBase::RuntimeError );
9044  if( m_type != ResultBase::Ok )
9045  std::abort();
9046  }
9047 
9048  std::string m_errorMessage; // Only populated if resultType is an error
9049 
9050  BasicResult( ResultBase::Type type, std::string const &message )
9051  : ResultValueBase<T>(type),
9052  m_errorMessage(message)
9053  {
9054  assert( m_type != ResultBase::Ok );
9055  }
9056 
9058  using ResultBase::m_type;
9059  };
9060 
9061  enum class ParseResultType {
9062  Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
9063  };
9064 
9065  class ParseState {
9066  public:
9067 
9068  ParseState( ParseResultType type, TokenStream const &remainingTokens )
9069  : m_type(type),
9070  m_remainingTokens( remainingTokens )
9071  {}
9072 
9073  auto type() const -> ParseResultType { return m_type; }
9074  auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
9075 
9076  private:
9077  ParseResultType m_type;
9078  TokenStream m_remainingTokens;
9079  };
9080 
9081  using Result = BasicResult<void>;
9084 
9085  struct HelpColumns {
9086  std::string left;
9087  std::string right;
9088  };
9089 
9090  template<typename T>
9091  inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
9092  std::stringstream ss;
9093  ss << source;
9094  ss >> target;
9095  if( ss.fail() )
9096  return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
9097  else
9098  return ParserResult::ok( ParseResultType::Matched );
9099  }
9100  inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
9101  target = source;
9102  return ParserResult::ok( ParseResultType::Matched );
9103  }
9104  inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
9105  std::string srcLC = source;
9106  std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
9107  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
9108  target = true;
9109  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
9110  target = false;
9111  else
9112  return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
9113  return ParserResult::ok( ParseResultType::Matched );
9114  }
9115 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
9116  template<typename T>
9117  inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
9118  T temp;
9119  auto result = convertInto( source, temp );
9120  if( result )
9121  target = std::move(temp);
9122  return result;
9123  }
9124 #endif // CLARA_CONFIG_OPTIONAL_TYPE
9125 
9126  struct NonCopyable {
9127  NonCopyable() = default;
9128  NonCopyable( NonCopyable const & ) = delete;
9129  NonCopyable( NonCopyable && ) = delete;
9130  NonCopyable &operator=( NonCopyable const & ) = delete;
9131  NonCopyable &operator=( NonCopyable && ) = delete;
9132  };
9133 
9135  virtual ~BoundRef() = default;
9136  virtual auto isContainer() const -> bool { return false; }
9137  virtual auto isFlag() const -> bool { return false; }
9138  };
9140  virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
9141  };
9143  virtual auto setFlag( bool flag ) -> ParserResult = 0;
9144  virtual auto isFlag() const -> bool { return true; }
9145  };
9146 
9147  template<typename T>
9149  T &m_ref;
9150 
9151  explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
9152 
9153  auto setValue( std::string const &arg ) -> ParserResult override {
9154  return convertInto( arg, m_ref );
9155  }
9156  };
9157 
9158  template<typename T>
9159  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
9160  std::vector<T> &m_ref;
9161 
9162  explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
9163 
9164  auto isContainer() const -> bool override { return true; }
9165 
9166  auto setValue( std::string const &arg ) -> ParserResult override {
9167  T temp;
9168  auto result = convertInto( arg, temp );
9169  if( result )
9170  m_ref.push_back( temp );
9171  return result;
9172  }
9173  };
9174 
9176  bool &m_ref;
9177 
9178  explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
9179 
9180  auto setFlag( bool flag ) -> ParserResult override {
9181  m_ref = flag;
9182  return ParserResult::ok( ParseResultType::Matched );
9183  }
9184  };
9185 
9186  template<typename ReturnType>
9187  struct LambdaInvoker {
9188  static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
9189 
9190  template<typename L, typename ArgType>
9191  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9192  return lambda( arg );
9193  }
9194  };
9195 
9196  template<>
9197  struct LambdaInvoker<void> {
9198  template<typename L, typename ArgType>
9199  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
9200  lambda( arg );
9201  return ParserResult::ok( ParseResultType::Matched );
9202  }
9203  };
9204 
9205  template<typename ArgType, typename L>
9206  inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
9207  ArgType temp{};
9208  auto result = convertInto( arg, temp );
9209  return !result
9210  ? result
9211  : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
9212  }
9213 
9214  template<typename L>
9216  L m_lambda;
9217 
9218  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9219  explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
9220 
9221  auto setValue( std::string const &arg ) -> ParserResult override {
9222  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
9223  }
9224  };
9225 
9226  template<typename L>
9228  L m_lambda;
9229 
9230  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
9231  static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
9232 
9233  explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
9234 
9235  auto setFlag( bool flag ) -> ParserResult override {
9236  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
9237  }
9238  };
9239 
9240  enum class Optionality { Optional, Required };
9241 
9242  struct Parser;
9243 
9244  class ParserBase {
9245  public:
9246  virtual ~ParserBase() = default;
9247  virtual auto validate() const -> Result { return Result::ok(); }
9248  virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
9249  virtual auto cardinality() const -> size_t { return 1; }
9250 
9251  auto parse( Args const &args ) const -> InternalParseResult {
9252  return parse( args.exeName(), TokenStream( args ) );
9253  }
9254  };
9255 
9256  template<typename DerivedT>
9258  public:
9259  template<typename T>
9260  auto operator|( T const &other ) const -> Parser;
9261 
9262  template<typename T>
9263  auto operator+( T const &other ) const -> Parser;
9264  };
9265 
9266  // Common code and state for Args and Opts
9267  template<typename DerivedT>
9268  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
9269  protected:
9270  Optionality m_optionality = Optionality::Optional;
9271  std::shared_ptr<BoundRef> m_ref;
9272  std::string m_hint;
9273  std::string m_description;
9274 
9275  explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
9276 
9277  public:
9278  template<typename T>
9279  ParserRefImpl( T &ref, std::string const &hint )
9280  : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
9281  m_hint( hint )
9282  {}
9283 
9284  template<typename LambdaT>
9285  ParserRefImpl( LambdaT const &ref, std::string const &hint )
9286  : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
9287  m_hint(hint)
9288  {}
9289 
9290  auto operator()( std::string const &description ) -> DerivedT & {
9291  m_description = description;
9292  return static_cast<DerivedT &>( *this );
9293  }
9294 
9295  auto optional() -> DerivedT & {
9296  m_optionality = Optionality::Optional;
9297  return static_cast<DerivedT &>( *this );
9298  };
9299 
9300  auto required() -> DerivedT & {
9301  m_optionality = Optionality::Required;
9302  return static_cast<DerivedT &>( *this );
9303  };
9304 
9305  auto isOptional() const -> bool {
9306  return m_optionality == Optionality::Optional;
9307  }
9308 
9309  auto cardinality() const -> size_t override {
9310  if( m_ref->isContainer() )
9311  return 0;
9312  else
9313  return 1;
9314  }
9315 
9316  auto hint() const -> std::string { return m_hint; }
9317  };
9318 
9319  class ExeName : public ComposableParserImpl<ExeName> {
9320  std::shared_ptr<std::string> m_name;
9321  std::shared_ptr<BoundValueRefBase> m_ref;
9322 
9323  template<typename LambdaT>
9324  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
9325  return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
9326  }
9327 
9328  public:
9329  ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
9330 
9331  explicit ExeName( std::string &ref ) : ExeName() {
9332  m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
9333  }
9334 
9335  template<typename LambdaT>
9336  explicit ExeName( LambdaT const& lambda ) : ExeName() {
9337  m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
9338  }
9339 
9340  // The exe name is not parsed out of the normal tokens, but is handled specially
9341  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9342  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9343  }
9344 
9345  auto name() const -> std::string { return *m_name; }
9346  auto set( std::string const& newName ) -> ParserResult {
9347 
9348  auto lastSlash = newName.find_last_of( "\\/" );
9349  auto filename = ( lastSlash == std::string::npos )
9350  ? newName
9351  : newName.substr( lastSlash+1 );
9352 
9353  *m_name = filename;
9354  if( m_ref )
9355  return m_ref->setValue( filename );
9356  else
9357  return ParserResult::ok( ParseResultType::Matched );
9358  }
9359  };
9360 
9361  class Arg : public ParserRefImpl<Arg> {
9362  public:
9363  using ParserRefImpl::ParserRefImpl;
9364 
9365  auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
9366  auto validationResult = validate();
9367  if( !validationResult )
9368  return InternalParseResult( validationResult );
9369 
9370  auto remainingTokens = tokens;
9371  auto const &token = *remainingTokens;
9372  if( token.type != TokenType::Argument )
9373  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9374 
9375  assert( !m_ref->isFlag() );
9376  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9377 
9378  auto result = valueRef->setValue( remainingTokens->token );
9379  if( !result )
9380  return InternalParseResult( result );
9381  else
9382  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9383  }
9384  };
9385 
9386  inline auto normaliseOpt( std::string const &optName ) -> std::string {
9387 #ifdef CATCH_PLATFORM_WINDOWS
9388  if( optName[0] == '/' )
9389  return "-" + optName.substr( 1 );
9390  else
9391 #endif
9392  return optName;
9393  }
9394 
9395  class Opt : public ParserRefImpl<Opt> {
9396  protected:
9397  std::vector<std::string> m_optNames;
9398 
9399  public:
9400  template<typename LambdaT>
9401  explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
9402 
9403  explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
9404 
9405  template<typename LambdaT>
9406  Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9407 
9408  template<typename T>
9409  Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
9410 
9411  auto operator[]( std::string const &optName ) -> Opt & {
9412  m_optNames.push_back( optName );
9413  return *this;
9414  }
9415 
9416  auto getHelpColumns() const -> std::vector<HelpColumns> {
9417  std::ostringstream oss;
9418  bool first = true;
9419  for( auto const &opt : m_optNames ) {
9420  if (first)
9421  first = false;
9422  else
9423  oss << ", ";
9424  oss << opt;
9425  }
9426  if( !m_hint.empty() )
9427  oss << " <" << m_hint << ">";
9428  return { { oss.str(), m_description } };
9429  }
9430 
9431  auto isMatch( std::string const &optToken ) const -> bool {
9432  auto normalisedToken = normaliseOpt( optToken );
9433  for( auto const &name : m_optNames ) {
9434  if( normaliseOpt( name ) == normalisedToken )
9435  return true;
9436  }
9437  return false;
9438  }
9439 
9440  using ParserBase::parse;
9441 
9442  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
9443  auto validationResult = validate();
9444  if( !validationResult )
9445  return InternalParseResult( validationResult );
9446 
9447  auto remainingTokens = tokens;
9448  if( remainingTokens && remainingTokens->type == TokenType::Option ) {
9449  auto const &token = *remainingTokens;
9450  if( isMatch(token.token ) ) {
9451  if( m_ref->isFlag() ) {
9452  auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
9453  auto result = flagRef->setFlag( true );
9454  if( !result )
9455  return InternalParseResult( result );
9456  if( result.value() == ParseResultType::ShortCircuitAll )
9457  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9458  } else {
9459  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
9460  ++remainingTokens;
9461  if( !remainingTokens )
9462  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9463  auto const &argToken = *remainingTokens;
9464  if( argToken.type != TokenType::Argument )
9465  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
9466  auto result = valueRef->setValue( argToken.token );
9467  if( !result )
9468  return InternalParseResult( result );
9469  if( result.value() == ParseResultType::ShortCircuitAll )
9470  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
9471  }
9472  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
9473  }
9474  }
9475  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
9476  }
9477 
9478  auto validate() const -> Result override {
9479  if( m_optNames.empty() )
9480  return Result::logicError( "No options supplied to Opt" );
9481  for( auto const &name : m_optNames ) {
9482  if( name.empty() )
9483  return Result::logicError( "Option name cannot be empty" );
9484 #ifdef CATCH_PLATFORM_WINDOWS
9485  if( name[0] != '-' && name[0] != '/' )
9486  return Result::logicError( "Option name must begin with '-' or '/'" );
9487 #else
9488  if( name[0] != '-' )
9489  return Result::logicError( "Option name must begin with '-'" );
9490 #endif
9491  }
9492  return ParserRefImpl::validate();
9493  }
9494  };
9495 
9496  struct Help : Opt {
9497  Help( bool &showHelpFlag )
9498  : Opt([&]( bool flag ) {
9499  showHelpFlag = flag;
9500  return ParserResult::ok( ParseResultType::ShortCircuitAll );
9501  })
9502  {
9503  static_cast<Opt &>( *this )
9504  ("display usage information")
9505  ["-?"]["-h"]["--help"]
9506  .optional();
9507  }
9508  };
9509 
9510  struct Parser : ParserBase {
9511 
9512  mutable ExeName m_exeName;
9513  std::vector<Opt> m_options;
9514  std::vector<Arg> m_args;
9515 
9516  auto operator|=( ExeName const &exeName ) -> Parser & {
9517  m_exeName = exeName;
9518  return *this;
9519  }
9520 
9521  auto operator|=( Arg const &arg ) -> Parser & {
9522  m_args.push_back(arg);
9523  return *this;
9524  }
9525 
9526  auto operator|=( Opt const &opt ) -> Parser & {
9527  m_options.push_back(opt);
9528  return *this;
9529  }
9530 
9531  auto operator|=( Parser const &other ) -> Parser & {
9532  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
9533  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
9534  return *this;
9535  }
9536 
9537  template<typename T>
9538  auto operator|( T const &other ) const -> Parser {
9539  return Parser( *this ) |= other;
9540  }
9541 
9542  // Forward deprecated interface with '+' instead of '|'
9543  template<typename T>
9544  auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
9545  template<typename T>
9546  auto operator+( T const &other ) const -> Parser { return operator|( other ); }
9547 
9548  auto getHelpColumns() const -> std::vector<HelpColumns> {
9549  std::vector<HelpColumns> cols;
9550  for (auto const &o : m_options) {
9551  auto childCols = o.getHelpColumns();
9552  cols.insert( cols.end(), childCols.begin(), childCols.end() );
9553  }
9554  return cols;
9555  }
9556 
9557  void writeToStream( std::ostream &os ) const {
9558  if (!m_exeName.name().empty()) {
9559  os << "usage:\n" << " " << m_exeName.name() << " ";
9560  bool required = true, first = true;
9561  for( auto const &arg : m_args ) {
9562  if (first)
9563  first = false;
9564  else
9565  os << " ";
9566  if( arg.isOptional() && required ) {
9567  os << "[";
9568  required = false;
9569  }
9570  os << "<" << arg.hint() << ">";
9571  if( arg.cardinality() == 0 )
9572  os << " ... ";
9573  }
9574  if( !required )
9575  os << "]";
9576  if( !m_options.empty() )
9577  os << " options";
9578  os << "\n\nwhere options are:" << std::endl;
9579  }
9580 
9581  auto rows = getHelpColumns();
9582  size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
9583  size_t optWidth = 0;
9584  for( auto const &cols : rows )
9585  optWidth = (std::max)(optWidth, cols.left.size() + 2);
9586 
9587  optWidth = (std::min)(optWidth, consoleWidth/2);
9588 
9589  for( auto const &cols : rows ) {
9590  auto row =
9591  TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
9592  TextFlow::Spacer(4) +
9593  TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
9594  os << row << std::endl;
9595  }
9596  }
9597 
9598  friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
9599  parser.writeToStream( os );
9600  return os;
9601  }
9602 
9603  auto validate() const -> Result override {
9604  for( auto const &opt : m_options ) {
9605  auto result = opt.validate();
9606  if( !result )
9607  return result;
9608  }
9609  for( auto const &arg : m_args ) {
9610  auto result = arg.validate();
9611  if( !result )
9612  return result;
9613  }
9614  return Result::ok();
9615  }
9616 
9617  using ParserBase::parse;
9618 
9619  auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
9620 
9621  struct ParserInfo {
9622  ParserBase const* parser = nullptr;
9623  size_t count = 0;
9624  };
9625  const size_t totalParsers = m_options.size() + m_args.size();
9626  assert( totalParsers < 512 );
9627  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
9628  ParserInfo parseInfos[512];
9629 
9630  {
9631  size_t i = 0;
9632  for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
9633  for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
9634  }
9635 
9636  m_exeName.set( exeName );
9637 
9638  auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
9639  while( result.value().remainingTokens() ) {
9640  bool tokenParsed = false;
9641 
9642  for( size_t i = 0; i < totalParsers; ++i ) {
9643  auto& parseInfo = parseInfos[i];
9644  if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
9645  result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
9646  if (!result)
9647  return result;
9648  if (result.value().type() != ParseResultType::NoMatch) {
9649  tokenParsed = true;
9650  ++parseInfo.count;
9651  break;
9652  }
9653  }
9654  }
9655 
9656  if( result.value().type() == ParseResultType::ShortCircuitAll )
9657  return result;
9658  if( !tokenParsed )
9659  return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
9660  }
9661  // !TBD Check missing required options
9662  return result;
9663  }
9664  };
9665 
9666  template<typename DerivedT>
9667  template<typename T>
9668  auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
9669  return Parser() | static_cast<DerivedT const &>( *this ) | other;
9670  }
9671 } // namespace detail
9672 
9673 // A Combined parser
9674 using detail::Parser;
9675 
9676 // A parser for options
9677 using detail::Opt;
9678 
9679 // A parser for arguments
9680 using detail::Arg;
9681 
9682 // Wrapper for argc, argv from main()
9683 using detail::Args;
9684 
9685 // Specifies the name of the executable
9686 using detail::ExeName;
9687 
9688 // Convenience wrapper for option parser that specifies the help option
9689 using detail::Help;
9690 
9691 // enum of result types from a parse
9692 using detail::ParseResultType;
9693 
9694 // Result type for parser operation
9695 using detail::ParserResult;
9696 
9697 }} // namespace Catch::clara
9698 
9699 // end clara.hpp
9700 #ifdef __clang__
9701 #pragma clang diagnostic pop
9702 #endif
9703 
9704 // Restore Clara's value for console width, if present
9705 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9706 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9707 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9708 #endif
9709 
9710 // end catch_clara.h
9711 namespace Catch {
9712 
9713  clara::Parser makeCommandLineParser( ConfigData& config );
9714 
9715 } // end namespace Catch
9716 
9717 // end catch_commandline.h
9718 #include <fstream>
9719 #include <ctime>
9720 
9721 namespace Catch {
9722 
9723  clara::Parser makeCommandLineParser( ConfigData& config ) {
9724 
9725  using namespace clara;
9726 
9727  auto const setWarning = [&]( std::string const& warning ) {
9728  auto warningSet = [&]() {
9729  if( warning == "NoAssertions" )
9730  return WarnAbout::NoAssertions;
9731 
9732  if ( warning == "NoTests" )
9733  return WarnAbout::NoTests;
9734 
9735  return WarnAbout::Nothing;
9736  }();
9737 
9738  if (warningSet == WarnAbout::Nothing)
9739  return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
9740  config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
9741  return ParserResult::ok( ParseResultType::Matched );
9742  };
9743  auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
9744  std::ifstream f( filename.c_str() );
9745  if( !f.is_open() )
9746  return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
9747 
9748  std::string line;
9749  while( std::getline( f, line ) ) {
9750  line = trim(line);
9751  if( !line.empty() && !startsWith( line, '#' ) ) {
9752  if( !startsWith( line, '"' ) )
9753  line = '"' + line + '"';
9754  config.testsOrTags.push_back( line );
9755  config.testsOrTags.emplace_back( "," );
9756  }
9757  }
9758  //Remove comma in the end
9759  if(!config.testsOrTags.empty())
9760  config.testsOrTags.erase( config.testsOrTags.end()-1 );
9761 
9762  return ParserResult::ok( ParseResultType::Matched );
9763  };
9764  auto const setTestOrder = [&]( std::string const& order ) {
9765  if( startsWith( "declared", order ) )
9766  config.runOrder = RunTests::InDeclarationOrder;
9767  else if( startsWith( "lexical", order ) )
9768  config.runOrder = RunTests::InLexicographicalOrder;
9769  else if( startsWith( "random", order ) )
9770  config.runOrder = RunTests::InRandomOrder;
9771  else
9772  return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
9773  return ParserResult::ok( ParseResultType::Matched );
9774  };
9775  auto const setRngSeed = [&]( std::string const& seed ) {
9776  if( seed != "time" )
9777  return clara::detail::convertInto( seed, config.rngSeed );
9778  config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
9779  return ParserResult::ok( ParseResultType::Matched );
9780  };
9781  auto const setColourUsage = [&]( std::string const& useColour ) {
9782  auto mode = toLower( useColour );
9783 
9784  if( mode == "yes" )
9785  config.useColour = UseColour::Yes;
9786  else if( mode == "no" )
9787  config.useColour = UseColour::No;
9788  else if( mode == "auto" )
9789  config.useColour = UseColour::Auto;
9790  else
9791  return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
9792  return ParserResult::ok( ParseResultType::Matched );
9793  };
9794  auto const setWaitForKeypress = [&]( std::string const& keypress ) {
9795  auto keypressLc = toLower( keypress );
9796  if (keypressLc == "never")
9797  config.waitForKeypress = WaitForKeypress::Never;
9798  else if( keypressLc == "start" )
9799  config.waitForKeypress = WaitForKeypress::BeforeStart;
9800  else if( keypressLc == "exit" )
9801  config.waitForKeypress = WaitForKeypress::BeforeExit;
9802  else if( keypressLc == "both" )
9803  config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
9804  else
9805  return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
9806  return ParserResult::ok( ParseResultType::Matched );
9807  };
9808  auto const setVerbosity = [&]( std::string const& verbosity ) {
9809  auto lcVerbosity = toLower( verbosity );
9810  if( lcVerbosity == "quiet" )
9811  config.verbosity = Verbosity::Quiet;
9812  else if( lcVerbosity == "normal" )
9813  config.verbosity = Verbosity::Normal;
9814  else if( lcVerbosity == "high" )
9815  config.verbosity = Verbosity::High;
9816  else
9817  return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
9818  return ParserResult::ok( ParseResultType::Matched );
9819  };
9820  auto const setReporter = [&]( std::string const& reporter ) {
9821  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
9822 
9823  auto lcReporter = toLower( reporter );
9824  auto result = factories.find( lcReporter );
9825 
9826  if( factories.end() != result )
9827  config.reporterName = lcReporter;
9828  else
9829  return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
9830  return ParserResult::ok( ParseResultType::Matched );
9831  };
9832 
9833  auto cli
9834  = ExeName( config.processName )
9835  | Help( config.showHelp )
9836  | Opt( config.listTests )
9837  ["-l"]["--list-tests"]
9838  ( "list all/matching test cases" )
9839  | Opt( config.listTags )
9840  ["-t"]["--list-tags"]
9841  ( "list all/matching tags" )
9842  | Opt( config.showSuccessfulTests )
9843  ["-s"]["--success"]
9844  ( "include successful tests in output" )
9845  | Opt( config.shouldDebugBreak )
9846  ["-b"]["--break"]
9847  ( "break into debugger on failure" )
9848  | Opt( config.noThrow )
9849  ["-e"]["--nothrow"]
9850  ( "skip exception tests" )
9851  | Opt( config.showInvisibles )
9852  ["-i"]["--invisibles"]
9853  ( "show invisibles (tabs, newlines)" )
9854  | Opt( config.outputFilename, "filename" )
9855  ["-o"]["--out"]
9856  ( "output filename" )
9857  | Opt( setReporter, "name" )
9858  ["-r"]["--reporter"]
9859  ( "reporter to use (defaults to console)" )
9860  | Opt( config.name, "name" )
9861  ["-n"]["--name"]
9862  ( "suite name" )
9863  | Opt( [&]( bool ){ config.abortAfter = 1; } )
9864  ["-a"]["--abort"]
9865  ( "abort at first failure" )
9866  | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
9867  ["-x"]["--abortx"]
9868  ( "abort after x failures" )
9869  | Opt( setWarning, "warning name" )
9870  ["-w"]["--warn"]
9871  ( "enable warnings" )
9872  | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
9873  ["-d"]["--durations"]
9874  ( "show test durations" )
9875  | Opt( config.minDuration, "seconds" )
9876  ["-D"]["--min-duration"]
9877  ( "show test durations for tests taking at least the given number of seconds" )
9878  | Opt( loadTestNamesFromFile, "filename" )
9879  ["-f"]["--input-file"]
9880  ( "load test names to run from a file" )
9881  | Opt( config.filenamesAsTags )
9882  ["-#"]["--filenames-as-tags"]
9883  ( "adds a tag for the filename" )
9884  | Opt( config.sectionsToRun, "section name" )
9885  ["-c"]["--section"]
9886  ( "specify section to run" )
9887  | Opt( setVerbosity, "quiet|normal|high" )
9888  ["-v"]["--verbosity"]
9889  ( "set output verbosity" )
9890  | Opt( config.listTestNamesOnly )
9891  ["--list-test-names-only"]
9892  ( "list all/matching test cases names only" )
9893  | Opt( config.listReporters )
9894  ["--list-reporters"]
9895  ( "list all reporters" )
9896  | Opt( setTestOrder, "decl|lex|rand" )
9897  ["--order"]
9898  ( "test case order (defaults to decl)" )
9899  | Opt( setRngSeed, "'time'|number" )
9900  ["--rng-seed"]
9901  ( "set a specific seed for random numbers" )
9902  | Opt( setColourUsage, "yes|no" )
9903  ["--use-colour"]
9904  ( "should output be colourised" )
9905  | Opt( config.libIdentify )
9906  ["--libidentify"]
9907  ( "report name and version according to libidentify standard" )
9908  | Opt( setWaitForKeypress, "never|start|exit|both" )
9909  ["--wait-for-keypress"]
9910  ( "waits for a keypress before exiting" )
9911  | Opt( config.benchmarkSamples, "samples" )
9912  ["--benchmark-samples"]
9913  ( "number of samples to collect (default: 100)" )
9914  | Opt( config.benchmarkResamples, "resamples" )
9915  ["--benchmark-resamples"]
9916  ( "number of resamples for the bootstrap (default: 100000)" )
9917  | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
9918  ["--benchmark-confidence-interval"]
9919  ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
9920  | Opt( config.benchmarkNoAnalysis )
9921  ["--benchmark-no-analysis"]
9922  ( "perform only measurements; do not perform any analysis" )
9923  | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
9924  ["--benchmark-warmup-time"]
9925  ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
9926  | Arg( config.testsOrTags, "test name|pattern|tags" )
9927  ( "which test or tests to use" );
9928 
9929  return cli;
9930  }
9931 
9932 } // end namespace Catch
9933 // end catch_commandline.cpp
9934 // start catch_common.cpp
9935 
9936 #include <cstring>
9937 #include <ostream>
9938 
9939 namespace Catch {
9940 
9941  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
9942  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
9943  }
9944  bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
9945  // We can assume that the same file will usually have the same pointer.
9946  // Thus, if the pointers are the same, there is no point in calling the strcmp
9947  return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
9948  }
9949 
9950  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
9951 #ifndef __GNUG__
9952  os << info.file << '(' << info.line << ')';
9953 #else
9954  os << info.file << ':' << info.line;
9955 #endif
9956  return os;
9957  }
9958 
9959  std::string StreamEndStop::operator+() const {
9960  return std::string();
9961  }
9962 
9963  NonCopyable::NonCopyable() = default;
9964  NonCopyable::~NonCopyable() = default;
9965 
9966 }
9967 // end catch_common.cpp
9968 // start catch_config.cpp
9969 
9970 namespace Catch {
9971 
9972  Config::Config( ConfigData const& data )
9973  : m_data( data ),
9974  m_stream( openStream() )
9975  {
9976  // We need to trim filter specs to avoid trouble with superfluous
9977  // whitespace (esp. important for bdd macros, as those are manually
9978  // aligned with whitespace).
9979 
9980  for (auto& elem : m_data.testsOrTags) {
9981  elem = trim(elem);
9982  }
9983  for (auto& elem : m_data.sectionsToRun) {
9984  elem = trim(elem);
9985  }
9986 
9987  TestSpecParser parser(ITagAliasRegistry::get());
9988  if (!m_data.testsOrTags.empty()) {
9989  m_hasTestFilters = true;
9990  for (auto const& testOrTags : m_data.testsOrTags) {
9991  parser.parse(testOrTags);
9992  }
9993  }
9994  m_testSpec = parser.testSpec();
9995  }
9996 
9997  std::string const& Config::getFilename() const {
9998  return m_data.outputFilename ;
9999  }
10000 
10001  bool Config::listTests() const { return m_data.listTests; }
10002  bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
10003  bool Config::listTags() const { return m_data.listTags; }
10004  bool Config::listReporters() const { return m_data.listReporters; }
10005 
10006  std::string Config::getProcessName() const { return m_data.processName; }
10007  std::string const& Config::getReporterName() const { return m_data.reporterName; }
10008 
10009  std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
10010  std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
10011 
10012  TestSpec const& Config::testSpec() const { return m_testSpec; }
10013  bool Config::hasTestFilters() const { return m_hasTestFilters; }
10014 
10015  bool Config::showHelp() const { return m_data.showHelp; }
10016 
10017  // IConfig interface
10018  bool Config::allowThrows() const { return !m_data.noThrow; }
10019  std::ostream& Config::stream() const { return m_stream->stream(); }
10020  std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
10021  bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
10022  bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
10023  bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
10024  ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
10025  double Config::minDuration() const { return m_data.minDuration; }
10026  RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
10027  unsigned int Config::rngSeed() const { return m_data.rngSeed; }
10028  UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
10029  bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
10030  int Config::abortAfter() const { return m_data.abortAfter; }
10031  bool Config::showInvisibles() const { return m_data.showInvisibles; }
10032  Verbosity Config::verbosity() const { return m_data.verbosity; }
10033 
10034  bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
10035  int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
10036  double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
10037  unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
10038  std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
10039 
10040  IStream const* Config::openStream() {
10041  return Catch::makeStream(m_data.outputFilename);
10042  }
10043 
10044 } // end namespace Catch
10045 // end catch_config.cpp
10046 // start catch_console_colour.cpp
10047 
10048 #if defined(__clang__)
10049 # pragma clang diagnostic push
10050 # pragma clang diagnostic ignored "-Wexit-time-destructors"
10051 #endif
10052 
10053 // start catch_errno_guard.h
10054 
10055 namespace Catch {
10056 
10057  class ErrnoGuard {
10058  public:
10059  ErrnoGuard();
10060  ~ErrnoGuard();
10061  private:
10062  int m_oldErrno;
10063  };
10064 
10065 }
10066 
10067 // end catch_errno_guard.h
10068 #include <sstream>
10069 
10070 namespace Catch {
10071  namespace {
10072 
10073  struct IColourImpl {
10074  virtual ~IColourImpl() = default;
10075  virtual void use( Colour::Code _colourCode ) = 0;
10076  };
10077 
10079  void use( Colour::Code ) override {}
10080 
10081  static IColourImpl* instance() {
10082  static NoColourImpl s_instance;
10083  return &s_instance;
10084  }
10085  };
10086 
10087  } // anon namespace
10088 } // namespace Catch
10089 
10090 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
10091 # ifdef CATCH_PLATFORM_WINDOWS
10092 # define CATCH_CONFIG_COLOUR_WINDOWS
10093 # else
10094 # define CATCH_CONFIG_COLOUR_ANSI
10095 # endif
10096 #endif
10097 
10098 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
10099 
10100 namespace Catch {
10101 namespace {
10102 
10103  class Win32ColourImpl : public IColourImpl {
10104  public:
10105  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
10106  {
10107  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
10108  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
10109  originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
10110  originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
10111  }
10112 
10113  void use( Colour::Code _colourCode ) override {
10114  switch( _colourCode ) {
10115  case Colour::None: return setTextAttribute( originalForegroundAttributes );
10116  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10117  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
10118  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
10119  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
10120  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
10121  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
10122  case Colour::Grey: return setTextAttribute( 0 );
10123 
10124  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
10125  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
10126  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
10127  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
10128  case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
10129 
10130  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10131 
10132  default:
10133  CATCH_ERROR( "Unknown colour requested" );
10134  }
10135  }
10136 
10137  private:
10138  void setTextAttribute( WORD _textAttribute ) {
10139  SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
10140  }
10141  HANDLE stdoutHandle;
10142  WORD originalForegroundAttributes;
10143  WORD originalBackgroundAttributes;
10144  };
10145 
10146  IColourImpl* platformColourInstance() {
10147  static Win32ColourImpl s_instance;
10148 
10149  IConfigPtr config = getCurrentContext().getConfig();
10150  UseColour::YesOrNo colourMode = config
10151  ? config->useColour()
10152  : UseColour::Auto;
10153  if( colourMode == UseColour::Auto )
10154  colourMode = UseColour::Yes;
10155  return colourMode == UseColour::Yes
10156  ? &s_instance
10157  : NoColourImpl::instance();
10158  }
10159 
10160 } // end anon namespace
10161 } // end namespace Catch
10162 
10163 #elif defined( CATCH_CONFIG_COLOUR_ANSI )
10164 
10165 #include <unistd.h>
10166 
10167 namespace Catch {
10168 namespace {
10169 
10170  // use POSIX/ ANSI console terminal codes
10171  // Thanks to Adam Strzelecki for original contribution
10172  // (http://github.com/nanoant)
10173  // https://github.com/philsquared/Catch/pull/131
10174  class PosixColourImpl : public IColourImpl {
10175  public:
10176  void use( Colour::Code _colourCode ) override {
10177  switch( _colourCode ) {
10178  case Colour::None:
10179  case Colour::White: return setColour( "[0m" );
10180  case Colour::Red: return setColour( "[0;31m" );
10181  case Colour::Green: return setColour( "[0;32m" );
10182  case Colour::Blue: return setColour( "[0;34m" );
10183  case Colour::Cyan: return setColour( "[0;36m" );
10184  case Colour::Yellow: return setColour( "[0;33m" );
10185  case Colour::Grey: return setColour( "[1;30m" );
10186 
10187  case Colour::LightGrey: return setColour( "[0;37m" );
10188  case Colour::BrightRed: return setColour( "[1;31m" );
10189  case Colour::BrightGreen: return setColour( "[1;32m" );
10190  case Colour::BrightWhite: return setColour( "[1;37m" );
10191  case Colour::BrightYellow: return setColour( "[1;33m" );
10192 
10193  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
10194  default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
10195  }
10196  }
10197  static IColourImpl* instance() {
10198  static PosixColourImpl s_instance;
10199  return &s_instance;
10200  }
10201 
10202  private:
10203  void setColour( const char* _escapeCode ) {
10204  getCurrentContext().getConfig()->stream()
10205  << '\033' << _escapeCode;
10206  }
10207  };
10208 
10209  bool useColourOnPlatform() {
10210  return
10211 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10212  !isDebuggerActive() &&
10213 #endif
10214 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
10215  isatty(STDOUT_FILENO)
10216 #else
10217  false
10218 #endif
10219  ;
10220  }
10221  IColourImpl* platformColourInstance() {
10222  ErrnoGuard guard;
10223  IConfigPtr config = getCurrentContext().getConfig();
10224  UseColour::YesOrNo colourMode = config
10225  ? config->useColour()
10226  : UseColour::Auto;
10227  if( colourMode == UseColour::Auto )
10228  colourMode = useColourOnPlatform()
10229  ? UseColour::Yes
10230  : UseColour::No;
10231  return colourMode == UseColour::Yes
10232  ? PosixColourImpl::instance()
10233  : NoColourImpl::instance();
10234  }
10235 
10236 } // end anon namespace
10237 } // end namespace Catch
10238 
10239 #else // not Windows or ANSI ///////////////////////////////////////////////
10240 
10241 namespace Catch {
10242 
10243  static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
10244 
10245 } // end namespace Catch
10246 
10247 #endif // Windows/ ANSI/ None
10248 
10249 namespace Catch {
10250 
10251  Colour::Colour( Code _colourCode ) { use( _colourCode ); }
10252  Colour::Colour( Colour&& other ) noexcept {
10253  m_moved = other.m_moved;
10254  other.m_moved = true;
10255  }
10256  Colour& Colour::operator=( Colour&& other ) noexcept {
10257  m_moved = other.m_moved;
10258  other.m_moved = true;
10259  return *this;
10260  }
10261 
10262  Colour::~Colour(){ if( !m_moved ) use( None ); }
10263 
10264  void Colour::use( Code _colourCode ) {
10265  static IColourImpl* impl = platformColourInstance();
10266  // Strictly speaking, this cannot possibly happen.
10267  // However, under some conditions it does happen (see #1626),
10268  // and this change is small enough that we can let practicality
10269  // triumph over purity in this case.
10270  if (impl != nullptr) {
10271  impl->use( _colourCode );
10272  }
10273  }
10274 
10275  std::ostream& operator << ( std::ostream& os, Colour const& ) {
10276  return os;
10277  }
10278 
10279 } // end namespace Catch
10280 
10281 #if defined(__clang__)
10282 # pragma clang diagnostic pop
10283 #endif
10284 
10285 // end catch_console_colour.cpp
10286 // start catch_context.cpp
10287 
10288 namespace Catch {
10289 
10291 
10292  public: // IContext
10293  IResultCapture* getResultCapture() override {
10294  return m_resultCapture;
10295  }
10296  IRunner* getRunner() override {
10297  return m_runner;
10298  }
10299 
10300  IConfigPtr const& getConfig() const override {
10301  return m_config;
10302  }
10303 
10304  ~Context() override;
10305 
10306  public: // IMutableContext
10307  void setResultCapture( IResultCapture* resultCapture ) override {
10308  m_resultCapture = resultCapture;
10309  }
10310  void setRunner( IRunner* runner ) override {
10311  m_runner = runner;
10312  }
10313  void setConfig( IConfigPtr const& config ) override {
10314  m_config = config;
10315  }
10316 
10317  friend IMutableContext& getCurrentMutableContext();
10318 
10319  private:
10320  IConfigPtr m_config;
10321  IRunner* m_runner = nullptr;
10322  IResultCapture* m_resultCapture = nullptr;
10323  };
10324 
10325  IMutableContext *IMutableContext::currentContext = nullptr;
10326 
10327  void IMutableContext::createContext()
10328  {
10329  currentContext = new Context();
10330  }
10331 
10332  void cleanUpContext() {
10333  delete IMutableContext::currentContext;
10334  IMutableContext::currentContext = nullptr;
10335  }
10336  IContext::~IContext() = default;
10337  IMutableContext::~IMutableContext() = default;
10338  Context::~Context() = default;
10339 
10340  SimplePcg32& rng() {
10341  static SimplePcg32 s_rng;
10342  return s_rng;
10343  }
10344 
10345 }
10346 // end catch_context.cpp
10347 // start catch_debug_console.cpp
10348 
10349 // start catch_debug_console.h
10350 
10351 #include <string>
10352 
10353 namespace Catch {
10354  void writeToDebugConsole( std::string const& text );
10355 }
10356 
10357 // end catch_debug_console.h
10358 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
10359 #include <android/log.h>
10360 
10361  namespace Catch {
10362  void writeToDebugConsole( std::string const& text ) {
10363  __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
10364  }
10365  }
10366 
10367 #elif defined(CATCH_PLATFORM_WINDOWS)
10368 
10369  namespace Catch {
10370  void writeToDebugConsole( std::string const& text ) {
10371  ::OutputDebugStringA( text.c_str() );
10372  }
10373  }
10374 
10375 #else
10376 
10377  namespace Catch {
10378  void writeToDebugConsole( std::string const& text ) {
10379  // !TBD: Need a version for Mac/ XCode and other IDEs
10380  Catch::cout() << text;
10381  }
10382  }
10383 
10384 #endif // Platform
10385 // end catch_debug_console.cpp
10386 // start catch_debugger.cpp
10387 
10388 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10389 
10390 # include <cassert>
10391 # include <sys/types.h>
10392 # include <unistd.h>
10393 # include <cstddef>
10394 # include <ostream>
10395 
10396 #ifdef __apple_build_version__
10397  // These headers will only compile with AppleClang (XCode)
10398  // For other compilers (Clang, GCC, ... ) we need to exclude them
10399 # include <sys/sysctl.h>
10400 #endif
10401 
10402  namespace Catch {
10403  #ifdef __apple_build_version__
10404  // The following function is taken directly from the following technical note:
10405  // https://developer.apple.com/library/archive/qa/qa1361/_index.html
10406 
10407  // Returns true if the current process is being debugged (either
10408  // running under the debugger or has a debugger attached post facto).
10409  bool isDebuggerActive(){
10410  int mib[4];
10411  struct kinfo_proc info;
10412  std::size_t size;
10413 
10414  // Initialize the flags so that, if sysctl fails for some bizarre
10415  // reason, we get a predictable result.
10416 
10417  info.kp_proc.p_flag = 0;
10418 
10419  // Initialize mib, which tells sysctl the info we want, in this case
10420  // we're looking for information about a specific process ID.
10421 
10422  mib[0] = CTL_KERN;
10423  mib[1] = KERN_PROC;
10424  mib[2] = KERN_PROC_PID;
10425  mib[3] = getpid();
10426 
10427  // Call sysctl.
10428 
10429  size = sizeof(info);
10430  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
10431  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
10432  return false;
10433  }
10434 
10435  // We're being debugged if the P_TRACED flag is set.
10436 
10437  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
10438  }
10439  #else
10440  bool isDebuggerActive() {
10441  // We need to find another way to determine this for non-appleclang compilers on macOS
10442  return false;
10443  }
10444  #endif
10445  } // namespace Catch
10446 
10447 #elif defined(CATCH_PLATFORM_LINUX)
10448  #include <fstream>
10449  #include <string>
10450 
10451  namespace Catch{
10452  // The standard POSIX way of detecting a debugger is to attempt to
10453  // ptrace() the process, but this needs to be done from a child and not
10454  // this process itself to still allow attaching to this process later
10455  // if wanted, so is rather heavy. Under Linux we have the PID of the
10456  // "debugger" (which doesn't need to be gdb, of course, it could also
10457  // be strace, for example) in /proc/$PID/status, so just get it from
10458  // there instead.
10459  bool isDebuggerActive(){
10460  // Libstdc++ has a bug, where std::ifstream sets errno to 0
10461  // This way our users can properly assert over errno values
10462  ErrnoGuard guard;
10463  std::ifstream in("/proc/self/status");
10464  for( std::string line; std::getline(in, line); ) {
10465  static const int PREFIX_LEN = 11;
10466  if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
10467  // We're traced if the PID is not 0 and no other PID starts
10468  // with 0 digit, so it's enough to check for just a single
10469  // character.
10470  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
10471  }
10472  }
10473 
10474  return false;
10475  }
10476  } // namespace Catch
10477 #elif defined(_MSC_VER)
10478  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10479  namespace Catch {
10480  bool isDebuggerActive() {
10481  return IsDebuggerPresent() != 0;
10482  }
10483  }
10484 #elif defined(__MINGW32__)
10485  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10486  namespace Catch {
10487  bool isDebuggerActive() {
10488  return IsDebuggerPresent() != 0;
10489  }
10490  }
10491 #else
10492  namespace Catch {
10493  bool isDebuggerActive() { return false; }
10494  }
10495 #endif // Platform
10496 // end catch_debugger.cpp
10497 // start catch_decomposer.cpp
10498 
10499 namespace Catch {
10500 
10501  ITransientExpression::~ITransientExpression() = default;
10502 
10503  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
10504  if( lhs.size() + rhs.size() < 40 &&
10505  lhs.find('\n') == std::string::npos &&
10506  rhs.find('\n') == std::string::npos )
10507  os << lhs << " " << op << " " << rhs;
10508  else
10509  os << lhs << "\n" << op << "\n" << rhs;
10510  }
10511 }
10512 // end catch_decomposer.cpp
10513 // start catch_enforce.cpp
10514 
10515 #include <stdexcept>
10516 
10517 namespace Catch {
10518 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
10519  [[noreturn]]
10520  void throw_exception(std::exception const& e) {
10521  Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
10522  << "The message was: " << e.what() << '\n';
10523  std::terminate();
10524  }
10525 #endif
10526 
10527  [[noreturn]]
10528  void throw_logic_error(std::string const& msg) {
10529  throw_exception(std::logic_error(msg));
10530  }
10531 
10532  [[noreturn]]
10533  void throw_domain_error(std::string const& msg) {
10534  throw_exception(std::domain_error(msg));
10535  }
10536 
10537  [[noreturn]]
10538  void throw_runtime_error(std::string const& msg) {
10539  throw_exception(std::runtime_error(msg));
10540  }
10541 
10542 } // namespace Catch;
10543 // end catch_enforce.cpp
10544 // start catch_enum_values_registry.cpp
10545 // start catch_enum_values_registry.h
10546 
10547 #include <vector>
10548 #include <memory>
10549 
10550 namespace Catch {
10551 
10552  namespace Detail {
10553 
10554  std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
10555 
10557 
10558  std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
10559 
10560  EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
10561  };
10562 
10563  std::vector<StringRef> parseEnums( StringRef enums );
10564 
10565  } // Detail
10566 
10567 } // Catch
10568 
10569 // end catch_enum_values_registry.h
10570 
10571 #include <map>
10572 #include <cassert>
10573 
10574 namespace Catch {
10575 
10576  IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
10577 
10578  namespace Detail {
10579 
10580  namespace {
10581  // Extracts the actual name part of an enum instance
10582  // In other words, it returns the Blue part of Bikeshed::Colour::Blue
10583  StringRef extractInstanceName(StringRef enumInstance) {
10584  // Find last occurence of ":"
10585  size_t name_start = enumInstance.size();
10586  while (name_start > 0 && enumInstance[name_start - 1] != ':') {
10587  --name_start;
10588  }
10589  return enumInstance.substr(name_start, enumInstance.size() - name_start);
10590  }
10591  }
10592 
10593  std::vector<StringRef> parseEnums( StringRef enums ) {
10594  auto enumValues = splitStringRef( enums, ',' );
10595  std::vector<StringRef> parsed;
10596  parsed.reserve( enumValues.size() );
10597  for( auto const& enumValue : enumValues ) {
10598  parsed.push_back(trim(extractInstanceName(enumValue)));
10599  }
10600  return parsed;
10601  }
10602 
10603  EnumInfo::~EnumInfo() {}
10604 
10605  StringRef EnumInfo::lookup( int value ) const {
10606  for( auto const& valueToName : m_values ) {
10607  if( valueToName.first == value )
10608  return valueToName.second;
10609  }
10610  return "{** unexpected enum value **}"_sr;
10611  }
10612 
10613  std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10614  std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
10615  enumInfo->m_name = enumName;
10616  enumInfo->m_values.reserve( values.size() );
10617 
10618  const auto valueNames = Catch::Detail::parseEnums( allValueNames );
10619  assert( valueNames.size() == values.size() );
10620  std::size_t i = 0;
10621  for( auto value : values )
10622  enumInfo->m_values.emplace_back(value, valueNames[i++]);
10623 
10624  return enumInfo;
10625  }
10626 
10627  EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
10628  m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
10629  return *m_enumInfos.back();
10630  }
10631 
10632  } // Detail
10633 } // Catch
10634 
10635 // end catch_enum_values_registry.cpp
10636 // start catch_errno_guard.cpp
10637 
10638 #include <cerrno>
10639 
10640 namespace Catch {
10641  ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
10642  ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
10643 }
10644 // end catch_errno_guard.cpp
10645 // start catch_exception_translator_registry.cpp
10646 
10647 // start catch_exception_translator_registry.h
10648 
10649 #include <vector>
10650 #include <string>
10651 #include <memory>
10652 
10653 namespace Catch {
10654 
10656  public:
10658  virtual void registerTranslator( const IExceptionTranslator* translator );
10659  std::string translateActiveException() const override;
10660  std::string tryTranslators() const;
10661 
10662  private:
10663  std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
10664  };
10665 }
10666 
10667 // end catch_exception_translator_registry.h
10668 #ifdef __OBJC__
10669 #import "Foundation/Foundation.h"
10670 #endif
10671 
10672 namespace Catch {
10673 
10674  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
10675  }
10676 
10677  void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
10678  m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
10679  }
10680 
10681 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10682  std::string ExceptionTranslatorRegistry::translateActiveException() const {
10683  try {
10684 #ifdef __OBJC__
10685  // In Objective-C try objective-c exceptions first
10686  @try {
10687  return tryTranslators();
10688  }
10689  @catch (NSException *exception) {
10690  return Catch::Detail::stringify( [exception description] );
10691  }
10692 #else
10693  // Compiling a mixed mode project with MSVC means that CLR
10694  // exceptions will be caught in (...) as well. However, these
10695  // do not fill-in std::current_exception and thus lead to crash
10696  // when attempting rethrow.
10697  // /EHa switch also causes structured exceptions to be caught
10698  // here, but they fill-in current_exception properly, so
10699  // at worst the output should be a little weird, instead of
10700  // causing a crash.
10701  if (std::current_exception() == nullptr) {
10702  return "Non C++ exception. Possibly a CLR exception.";
10703  }
10704  return tryTranslators();
10705 #endif
10706  }
10707  catch( TestFailureException& ) {
10708  std::rethrow_exception(std::current_exception());
10709  }
10710  catch( std::exception& ex ) {
10711  return ex.what();
10712  }
10713  catch( std::string& msg ) {
10714  return msg;
10715  }
10716  catch( const char* msg ) {
10717  return msg;
10718  }
10719  catch(...) {
10720  return "Unknown exception";
10721  }
10722  }
10723 
10724  std::string ExceptionTranslatorRegistry::tryTranslators() const {
10725  if (m_translators.empty()) {
10726  std::rethrow_exception(std::current_exception());
10727  } else {
10728  return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
10729  }
10730  }
10731 
10732 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
10733  std::string ExceptionTranslatorRegistry::translateActiveException() const {
10734  CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10735  }
10736 
10737  std::string ExceptionTranslatorRegistry::tryTranslators() const {
10738  CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
10739  }
10740 #endif
10741 
10742 }
10743 // end catch_exception_translator_registry.cpp
10744 // start catch_fatal_condition.cpp
10745 
10746 #if defined(__GNUC__)
10747 # pragma GCC diagnostic push
10748 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
10749 #endif
10750 
10751 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
10752 
10753 namespace {
10754  // Report the error condition
10755  void reportFatal( char const * const message ) {
10756  Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
10757  }
10758 }
10759 
10760 #endif // signals/SEH handling
10761 
10762 #if defined( CATCH_CONFIG_WINDOWS_SEH )
10763 
10764 namespace Catch {
10765  struct SignalDefs { DWORD id; const char* name; };
10766 
10767  // There is no 1-1 mapping between signals and windows exceptions.
10768  // Windows can easily distinguish between SO and SigSegV,
10769  // but SigInt, SigTerm, etc are handled differently.
10770  static SignalDefs signalDefs[] = {
10771  { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
10772  { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
10773  { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
10774  { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
10775  };
10776 
10777  LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
10778  for (auto const& def : signalDefs) {
10779  if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
10780  reportFatal(def.name);
10781  }
10782  }
10783  // If its not an exception we care about, pass it along.
10784  // This stops us from eating debugger breaks etc.
10785  return EXCEPTION_CONTINUE_SEARCH;
10786  }
10787 
10788  FatalConditionHandler::FatalConditionHandler() {
10789  isSet = true;
10790  // 32k seems enough for Catch to handle stack overflow,
10791  // but the value was found experimentally, so there is no strong guarantee
10792  guaranteeSize = 32 * 1024;
10793  exceptionHandlerHandle = nullptr;
10794  // Register as first handler in current chain
10795  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
10796  // Pass in guarantee size to be filled
10797  SetThreadStackGuarantee(&guaranteeSize);
10798  }
10799 
10800  void FatalConditionHandler::reset() {
10801  if (isSet) {
10802  RemoveVectoredExceptionHandler(exceptionHandlerHandle);
10803  SetThreadStackGuarantee(&guaranteeSize);
10804  exceptionHandlerHandle = nullptr;
10805  isSet = false;
10806  }
10807  }
10808 
10809  FatalConditionHandler::~FatalConditionHandler() {
10810  reset();
10811  }
10812 
10813 bool FatalConditionHandler::isSet = false;
10814 ULONG FatalConditionHandler::guaranteeSize = 0;
10815 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
10816 
10817 } // namespace Catch
10818 
10819 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
10820 
10821 namespace Catch {
10822 
10823  struct SignalDefs {
10824  int id;
10825  const char* name;
10826  };
10827 
10828  // 32kb for the alternate stack seems to be sufficient. However, this value
10829  // is experimentally determined, so that's not guaranteed.
10830  static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
10831 
10832  static SignalDefs signalDefs[] = {
10833  { SIGINT, "SIGINT - Terminal interrupt signal" },
10834  { SIGILL, "SIGILL - Illegal instruction signal" },
10835  { SIGFPE, "SIGFPE - Floating point error signal" },
10836  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
10837  { SIGTERM, "SIGTERM - Termination request signal" },
10838  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
10839  };
10840 
10841  void FatalConditionHandler::handleSignal( int sig ) {
10842  char const * name = "<unknown signal>";
10843  for (auto const& def : signalDefs) {
10844  if (sig == def.id) {
10845  name = def.name;
10846  break;
10847  }
10848  }
10849  reset();
10850  reportFatal(name);
10851  raise( sig );
10852  }
10853 
10854  FatalConditionHandler::FatalConditionHandler() {
10855  isSet = true;
10856  stack_t sigStack;
10857  sigStack.ss_sp = altStackMem;
10858  sigStack.ss_size = sigStackSize;
10859  sigStack.ss_flags = 0;
10860  sigaltstack(&sigStack, &oldSigStack);
10861  struct sigaction sa = { };
10862 
10863  sa.sa_handler = handleSignal;
10864  sa.sa_flags = SA_ONSTACK;
10865  for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
10866  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
10867  }
10868  }
10869 
10870  FatalConditionHandler::~FatalConditionHandler() {
10871  reset();
10872  }
10873 
10874  void FatalConditionHandler::reset() {
10875  if( isSet ) {
10876  // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
10877  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
10878  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
10879  }
10880  // Return the old stack
10881  sigaltstack(&oldSigStack, nullptr);
10882  isSet = false;
10883  }
10884  }
10885 
10886  bool FatalConditionHandler::isSet = false;
10887  struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
10888  stack_t FatalConditionHandler::oldSigStack = {};
10889  char FatalConditionHandler::altStackMem[sigStackSize] = {};
10890 
10891 } // namespace Catch
10892 
10893 #else
10894 
10895 namespace Catch {
10896  void FatalConditionHandler::reset() {}
10897 }
10898 
10899 #endif // signals/SEH handling
10900 
10901 #if defined(__GNUC__)
10902 # pragma GCC diagnostic pop
10903 #endif
10904 // end catch_fatal_condition.cpp
10905 // start catch_generators.cpp
10906 
10907 #include <limits>
10908 #include <set>
10909 
10910 namespace Catch {
10911 
10912 IGeneratorTracker::~IGeneratorTracker() {}
10913 
10914 const char* GeneratorException::what() const noexcept {
10915  return m_msg;
10916 }
10917 
10918 namespace Generators {
10919 
10920  GeneratorUntypedBase::~GeneratorUntypedBase() {}
10921 
10922  auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
10923  return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
10924  }
10925 
10926 } // namespace Generators
10927 } // namespace Catch
10928 // end catch_generators.cpp
10929 // start catch_interfaces_capture.cpp
10930 
10931 namespace Catch {
10932  IResultCapture::~IResultCapture() = default;
10933 }
10934 // end catch_interfaces_capture.cpp
10935 // start catch_interfaces_config.cpp
10936 
10937 namespace Catch {
10938  IConfig::~IConfig() = default;
10939 }
10940 // end catch_interfaces_config.cpp
10941 // start catch_interfaces_exception.cpp
10942 
10943 namespace Catch {
10944  IExceptionTranslator::~IExceptionTranslator() = default;
10945  IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
10946 }
10947 // end catch_interfaces_exception.cpp
10948 // start catch_interfaces_registry_hub.cpp
10949 
10950 namespace Catch {
10951  IRegistryHub::~IRegistryHub() = default;
10952  IMutableRegistryHub::~IMutableRegistryHub() = default;
10953 }
10954 // end catch_interfaces_registry_hub.cpp
10955 // start catch_interfaces_reporter.cpp
10956 
10957 // start catch_reporter_listening.h
10958 
10959 namespace Catch {
10960 
10962  using Reporters = std::vector<IStreamingReporterPtr>;
10963  Reporters m_listeners;
10964  IStreamingReporterPtr m_reporter = nullptr;
10965  ReporterPreferences m_preferences;
10966 
10967  public:
10969 
10970  void addListener( IStreamingReporterPtr&& listener );
10971  void addReporter( IStreamingReporterPtr&& reporter );
10972 
10973  public: // IStreamingReporter
10974 
10975  ReporterPreferences getPreferences() const override;
10976 
10977  void noMatchingTestCases( std::string const& spec ) override;
10978 
10979  void reportInvalidArguments(std::string const&arg) override;
10980 
10981  static std::set<Verbosity> getSupportedVerbosities();
10982 
10983 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
10984  void benchmarkPreparing(std::string const& name) override;
10985  void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
10986  void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
10987  void benchmarkFailed(std::string const&) override;
10988 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
10989 
10990  void testRunStarting( TestRunInfo const& testRunInfo ) override;
10991  void testGroupStarting( GroupInfo const& groupInfo ) override;
10992  void testCaseStarting( TestCaseInfo const& testInfo ) override;
10993  void sectionStarting( SectionInfo const& sectionInfo ) override;
10994  void assertionStarting( AssertionInfo const& assertionInfo ) override;
10995 
10996  // The return value indicates if the messages buffer should be cleared:
10997  bool assertionEnded( AssertionStats const& assertionStats ) override;
10998  void sectionEnded( SectionStats const& sectionStats ) override;
10999  void testCaseEnded( TestCaseStats const& testCaseStats ) override;
11000  void testGroupEnded( TestGroupStats const& testGroupStats ) override;
11001  void testRunEnded( TestRunStats const& testRunStats ) override;
11002 
11003  void skipTest( TestCaseInfo const& testInfo ) override;
11004  bool isMulti() const override;
11005 
11006  };
11007 
11008 } // end namespace Catch
11009 
11010 // end catch_reporter_listening.h
11011 namespace Catch {
11012 
11013  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
11014  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
11015 
11016  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
11017  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
11018 
11019  std::ostream& ReporterConfig::stream() const { return *m_stream; }
11020  IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
11021 
11022  TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
11023 
11024  GroupInfo::GroupInfo( std::string const& _name,
11025  std::size_t _groupIndex,
11026  std::size_t _groupsCount )
11027  : name( _name ),
11028  groupIndex( _groupIndex ),
11029  groupsCounts( _groupsCount )
11030  {}
11031 
11032  AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
11033  std::vector<MessageInfo> const& _infoMessages,
11034  Totals const& _totals )
11035  : assertionResult( _assertionResult ),
11036  infoMessages( _infoMessages ),
11037  totals( _totals )
11038  {
11039  assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
11040 
11041  if( assertionResult.hasMessage() ) {
11042  // Copy message into messages list.
11043  // !TBD This should have been done earlier, somewhere
11044  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
11045  builder << assertionResult.getMessage();
11046  builder.m_info.message = builder.m_stream.str();
11047 
11048  infoMessages.push_back( builder.m_info );
11049  }
11050  }
11051 
11052  AssertionStats::~AssertionStats() = default;
11053 
11054  SectionStats::SectionStats( SectionInfo const& _sectionInfo,
11055  Counts const& _assertions,
11056  double _durationInSeconds,
11057  bool _missingAssertions )
11058  : sectionInfo( _sectionInfo ),
11059  assertions( _assertions ),
11060  durationInSeconds( _durationInSeconds ),
11061  missingAssertions( _missingAssertions )
11062  {}
11063 
11064  SectionStats::~SectionStats() = default;
11065 
11066  TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
11067  Totals const& _totals,
11068  std::string const& _stdOut,
11069  std::string const& _stdErr,
11070  bool _aborting )
11071  : testInfo( _testInfo ),
11072  totals( _totals ),
11073  stdOut( _stdOut ),
11074  stdErr( _stdErr ),
11075  aborting( _aborting )
11076  {}
11077 
11078  TestCaseStats::~TestCaseStats() = default;
11079 
11080  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
11081  Totals const& _totals,
11082  bool _aborting )
11083  : groupInfo( _groupInfo ),
11084  totals( _totals ),
11085  aborting( _aborting )
11086  {}
11087 
11088  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
11089  : groupInfo( _groupInfo ),
11090  aborting( false )
11091  {}
11092 
11093  TestGroupStats::~TestGroupStats() = default;
11094 
11095  TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
11096  Totals const& _totals,
11097  bool _aborting )
11098  : runInfo( _runInfo ),
11099  totals( _totals ),
11100  aborting( _aborting )
11101  {}
11102 
11103  TestRunStats::~TestRunStats() = default;
11104 
11105  void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
11106  bool IStreamingReporter::isMulti() const { return false; }
11107 
11108  IReporterFactory::~IReporterFactory() = default;
11109  IReporterRegistry::~IReporterRegistry() = default;
11110 
11111 } // end namespace Catch
11112 // end catch_interfaces_reporter.cpp
11113 // start catch_interfaces_runner.cpp
11114 
11115 namespace Catch {
11116  IRunner::~IRunner() = default;
11117 }
11118 // end catch_interfaces_runner.cpp
11119 // start catch_interfaces_testcase.cpp
11120 
11121 namespace Catch {
11122  ITestInvoker::~ITestInvoker() = default;
11123  ITestCaseRegistry::~ITestCaseRegistry() = default;
11124 }
11125 // end catch_interfaces_testcase.cpp
11126 // start catch_leak_detector.cpp
11127 
11128 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
11129 #include <crtdbg.h>
11130 
11131 namespace Catch {
11132 
11133  LeakDetector::LeakDetector() {
11134  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
11135  flag |= _CRTDBG_LEAK_CHECK_DF;
11136  flag |= _CRTDBG_ALLOC_MEM_DF;
11137  _CrtSetDbgFlag(flag);
11138  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
11139  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
11140  // Change this to leaking allocation's number to break there
11141  _CrtSetBreakAlloc(-1);
11142  }
11143 }
11144 
11145 #else
11146 
11147  Catch::LeakDetector::LeakDetector() {}
11148 
11149 #endif
11150 
11151 Catch::LeakDetector::~LeakDetector() {
11152  Catch::cleanUp();
11153 }
11154 // end catch_leak_detector.cpp
11155 // start catch_list.cpp
11156 
11157 // start catch_list.h
11158 
11159 #include <set>
11160 
11161 namespace Catch {
11162 
11163  std::size_t listTests( Config const& config );
11164 
11165  std::size_t listTestsNamesOnly( Config const& config );
11166 
11167  struct TagInfo {
11168  void add( std::string const& spelling );
11169  std::string all() const;
11170 
11171  std::set<std::string> spellings;
11172  std::size_t count = 0;
11173  };
11174 
11175  std::size_t listTags( Config const& config );
11176 
11177  std::size_t listReporters();
11178 
11179  Option<std::size_t> list( std::shared_ptr<Config> const& config );
11180 
11181 } // end namespace Catch
11182 
11183 // end catch_list.h
11184 // start catch_text.h
11185 
11186 namespace Catch {
11187  using namespace clara::TextFlow;
11188 }
11189 
11190 // end catch_text.h
11191 #include <limits>
11192 #include <algorithm>
11193 #include <iomanip>
11194 
11195 namespace Catch {
11196 
11197  std::size_t listTests( Config const& config ) {
11198  TestSpec const& testSpec = config.testSpec();
11199  if( config.hasTestFilters() )
11200  Catch::cout() << "Matching test cases:\n";
11201  else {
11202  Catch::cout() << "All available test cases:\n";
11203  }
11204 
11205  auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11206  for( auto const& testCaseInfo : matchedTestCases ) {
11207  Colour::Code colour = testCaseInfo.isHidden()
11208  ? Colour::SecondaryText
11209  : Colour::None;
11210  Colour colourGuard( colour );
11211 
11212  Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
11213  if( config.verbosity() >= Verbosity::High ) {
11214  Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
11215  std::string description = testCaseInfo.description;
11216  if( description.empty() )
11217  description = "(NO DESCRIPTION)";
11218  Catch::cout() << Column( description ).indent(4) << std::endl;
11219  }
11220  if( !testCaseInfo.tags.empty() )
11221  Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
11222  }
11223 
11224  if( !config.hasTestFilters() )
11225  Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
11226  else
11227  Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
11228  return matchedTestCases.size();
11229  }
11230 
11231  std::size_t listTestsNamesOnly( Config const& config ) {
11232  TestSpec const& testSpec = config.testSpec();
11233  std::size_t matchedTests = 0;
11234  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11235  for( auto const& testCaseInfo : matchedTestCases ) {
11236  matchedTests++;
11237  if( startsWith( testCaseInfo.name, '#' ) )
11238  Catch::cout() << '"' << testCaseInfo.name << '"';
11239  else
11240  Catch::cout() << testCaseInfo.name;
11241  if ( config.verbosity() >= Verbosity::High )
11242  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
11243  Catch::cout() << std::endl;
11244  }
11245  return matchedTests;
11246  }
11247 
11248  void TagInfo::add( std::string const& spelling ) {
11249  ++count;
11250  spellings.insert( spelling );
11251  }
11252 
11253  std::string TagInfo::all() const {
11254  size_t size = 0;
11255  for (auto const& spelling : spellings) {
11256  // Add 2 for the brackes
11257  size += spelling.size() + 2;
11258  }
11259 
11260  std::string out; out.reserve(size);
11261  for (auto const& spelling : spellings) {
11262  out += '[';
11263  out += spelling;
11264  out += ']';
11265  }
11266  return out;
11267  }
11268 
11269  std::size_t listTags( Config const& config ) {
11270  TestSpec const& testSpec = config.testSpec();
11271  if( config.hasTestFilters() )
11272  Catch::cout() << "Tags for matching test cases:\n";
11273  else {
11274  Catch::cout() << "All available tags:\n";
11275  }
11276 
11277  std::map<std::string, TagInfo> tagCounts;
11278 
11279  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
11280  for( auto const& testCase : matchedTestCases ) {
11281  for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
11282  std::string lcaseTagName = toLower( tagName );
11283  auto countIt = tagCounts.find( lcaseTagName );
11284  if( countIt == tagCounts.end() )
11285  countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
11286  countIt->second.add( tagName );
11287  }
11288  }
11289 
11290  for( auto const& tagCount : tagCounts ) {
11291  ReusableStringStream rss;
11292  rss << " " << std::setw(2) << tagCount.second.count << " ";
11293  auto str = rss.str();
11294  auto wrapper = Column( tagCount.second.all() )
11295  .initialIndent( 0 )
11296  .indent( str.size() )
11297  .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
11298  Catch::cout() << str << wrapper << '\n';
11299  }
11300  Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
11301  return tagCounts.size();
11302  }
11303 
11304  std::size_t listReporters() {
11305  Catch::cout() << "Available reporters:\n";
11306  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
11307  std::size_t maxNameLen = 0;
11308  for( auto const& factoryKvp : factories )
11309  maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
11310 
11311  for( auto const& factoryKvp : factories ) {
11312  Catch::cout()
11313  << Column( factoryKvp.first + ":" )
11314  .indent(2)
11315  .width( 5+maxNameLen )
11316  + Column( factoryKvp.second->getDescription() )
11317  .initialIndent(0)
11318  .indent(2)
11319  .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
11320  << "\n";
11321  }
11322  Catch::cout() << std::endl;
11323  return factories.size();
11324  }
11325 
11326  Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
11327  Option<std::size_t> listedCount;
11328  getCurrentMutableContext().setConfig( config );
11329  if( config->listTests() )
11330  listedCount = listedCount.valueOr(0) + listTests( *config );
11331  if( config->listTestNamesOnly() )
11332  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
11333  if( config->listTags() )
11334  listedCount = listedCount.valueOr(0) + listTags( *config );
11335  if( config->listReporters() )
11336  listedCount = listedCount.valueOr(0) + listReporters();
11337  return listedCount;
11338  }
11339 
11340 } // end namespace Catch
11341 // end catch_list.cpp
11342 // start catch_matchers.cpp
11343 
11344 namespace Catch {
11345 namespace Matchers {
11346  namespace Impl {
11347 
11348  std::string MatcherUntypedBase::toString() const {
11349  if( m_cachedToString.empty() )
11350  m_cachedToString = describe();
11351  return m_cachedToString;
11352  }
11353 
11354  MatcherUntypedBase::~MatcherUntypedBase() = default;
11355 
11356  } // namespace Impl
11357 } // namespace Matchers
11358 
11359 using namespace Matchers;
11360 using Matchers::Impl::MatcherBase;
11361 
11362 } // namespace Catch
11363 // end catch_matchers.cpp
11364 // start catch_matchers_exception.cpp
11365 
11366 namespace Catch {
11367 namespace Matchers {
11368 namespace Exception {
11369 
11370 bool ExceptionMessageMatcher::match(std::exception const& ex) const {
11371  return ex.what() == m_message;
11372 }
11373 
11374 std::string ExceptionMessageMatcher::describe() const {
11375  return "exception message matches \"" + m_message + "\"";
11376 }
11377 
11378 }
11379 Exception::ExceptionMessageMatcher Message(std::string const& message) {
11380  return Exception::ExceptionMessageMatcher(message);
11381 }
11382 
11383 // namespace Exception
11384 } // namespace Matchers
11385 } // namespace Catch
11386 // end catch_matchers_exception.cpp
11387 // start catch_matchers_floating.cpp
11388 
11389 // start catch_polyfills.hpp
11390 
11391 namespace Catch {
11392  bool isnan(float f);
11393  bool isnan(double d);
11394 }
11395 
11396 // end catch_polyfills.hpp
11397 // start catch_to_string.hpp
11398 
11399 #include <string>
11400 
11401 namespace Catch {
11402  template <typename T>
11403  std::string to_string(T const& t) {
11404 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11405  return std::to_string(t);
11406 #else
11407  ReusableStringStream rss;
11408  rss << t;
11409  return rss.str();
11410 #endif
11411  }
11412 } // end namespace Catch
11413 
11414 // end catch_to_string.hpp
11415 #include <algorithm>
11416 #include <cmath>
11417 #include <cstdlib>
11418 #include <cstdint>
11419 #include <cstring>
11420 #include <sstream>
11421 #include <type_traits>
11422 #include <iomanip>
11423 #include <limits>
11424 
11425 namespace Catch {
11426 namespace {
11427 
11428  int32_t convert(float f) {
11429  static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
11430  int32_t i;
11431  std::memcpy(&i, &f, sizeof(f));
11432  return i;
11433  }
11434 
11435  int64_t convert(double d) {
11436  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
11437  int64_t i;
11438  std::memcpy(&i, &d, sizeof(d));
11439  return i;
11440  }
11441 
11442  template <typename FP>
11443  bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
11444  // Comparison with NaN should always be false.
11445  // This way we can rule it out before getting into the ugly details
11446  if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
11447  return false;
11448  }
11449 
11450  auto lc = convert(lhs);
11451  auto rc = convert(rhs);
11452 
11453  if ((lc < 0) != (rc < 0)) {
11454  // Potentially we can have +0 and -0
11455  return lhs == rhs;
11456  }
11457 
11458  auto ulpDiff = std::abs(lc - rc);
11459  return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
11460  }
11461 
11462 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11463 
11464  float nextafter(float x, float y) {
11465  return ::nextafterf(x, y);
11466  }
11467 
11468  double nextafter(double x, double y) {
11469  return ::nextafter(x, y);
11470  }
11471 
11472 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
11473 
11474 template <typename FP>
11475 FP step(FP start, FP direction, uint64_t steps) {
11476  for (uint64_t i = 0; i < steps; ++i) {
11477 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11478  start = Catch::nextafter(start, direction);
11479 #else
11480  start = std::nextafter(start, direction);
11481 #endif
11482  }
11483  return start;
11484 }
11485 
11486 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11487 // But without the subtraction to allow for INFINITY in comparison
11488 bool marginComparison(double lhs, double rhs, double margin) {
11489  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
11490 }
11491 
11492 template <typename FloatingPoint>
11493 void write(std::ostream& out, FloatingPoint num) {
11494  out << std::scientific
11495  << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
11496  << num;
11497 }
11498 
11499 } // end anonymous namespace
11500 
11501 namespace Matchers {
11502 namespace Floating {
11503 
11504  enum class FloatingPointKind : uint8_t {
11505  Float,
11506  Double
11507  };
11508 
11509  WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
11510  :m_target{ target }, m_margin{ margin } {
11511  CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
11512  << " Margin has to be non-negative.");
11513  }
11514 
11515  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11516  // But without the subtraction to allow for INFINITY in comparison
11517  bool WithinAbsMatcher::match(double const& matchee) const {
11518  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
11519  }
11520 
11521  std::string WithinAbsMatcher::describe() const {
11522  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
11523  }
11524 
11525  WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
11526  :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
11527  CATCH_ENFORCE(m_type == FloatingPointKind::Double
11528  || m_ulps < (std::numeric_limits<uint32_t>::max)(),
11529  "Provided ULP is impossibly large for a float comparison.");
11530  }
11531 
11532 #if defined(__clang__)
11533 #pragma clang diagnostic push
11534 // Clang <3.5 reports on the default branch in the switch below
11535 #pragma clang diagnostic ignored "-Wunreachable-code"
11536 #endif
11537 
11538  bool WithinUlpsMatcher::match(double const& matchee) const {
11539  switch (m_type) {
11540  case FloatingPointKind::Float:
11541  return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
11542  case FloatingPointKind::Double:
11543  return almostEqualUlps<double>(matchee, m_target, m_ulps);
11544  default:
11545  CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
11546  }
11547  }
11548 
11549 #if defined(__clang__)
11550 #pragma clang diagnostic pop
11551 #endif
11552 
11553  std::string WithinUlpsMatcher::describe() const {
11554  std::stringstream ret;
11555 
11556  ret << "is within " << m_ulps << " ULPs of ";
11557 
11558  if (m_type == FloatingPointKind::Float) {
11559  write(ret, static_cast<float>(m_target));
11560  ret << 'f';
11561  } else {
11562  write(ret, m_target);
11563  }
11564 
11565  ret << " ([";
11566  if (m_type == FloatingPointKind::Double) {
11567  write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
11568  ret << ", ";
11569  write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
11570  } else {
11571  // We have to cast INFINITY to float because of MinGW, see #1782
11572  write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
11573  ret << ", ";
11574  write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
11575  }
11576  ret << "])";
11577 
11578  return ret.str();
11579  }
11580 
11581  WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
11582  m_target(target),
11583  m_epsilon(epsilon){
11584  CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense.");
11585  CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
11586  }
11587 
11588  bool WithinRelMatcher::match(double const& matchee) const {
11589  const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
11590  return marginComparison(matchee, m_target,
11591  std::isinf(relMargin)? 0 : relMargin);
11592  }
11593 
11594  std::string WithinRelMatcher::describe() const {
11595  Catch::ReusableStringStream sstr;
11596  sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
11597  return sstr.str();
11598  }
11599 
11600 }// namespace Floating
11601 
11602 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
11603  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
11604 }
11605 
11606 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
11607  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
11608 }
11609 
11610 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
11611  return Floating::WithinAbsMatcher(target, margin);
11612 }
11613 
11614 Floating::WithinRelMatcher WithinRel(double target, double eps) {
11615  return Floating::WithinRelMatcher(target, eps);
11616 }
11617 
11618 Floating::WithinRelMatcher WithinRel(double target) {
11619  return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
11620 }
11621 
11622 Floating::WithinRelMatcher WithinRel(float target, float eps) {
11623  return Floating::WithinRelMatcher(target, eps);
11624 }
11625 
11626 Floating::WithinRelMatcher WithinRel(float target) {
11627  return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
11628 }
11629 
11630 } // namespace Matchers
11631 } // namespace Catch
11632 
11633 // end catch_matchers_floating.cpp
11634 // start catch_matchers_generic.cpp
11635 
11636 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
11637  if (desc.empty()) {
11638  return "matches undescribed predicate";
11639  } else {
11640  return "matches predicate: \"" + desc + '"';
11641  }
11642 }
11643 // end catch_matchers_generic.cpp
11644 // start catch_matchers_string.cpp
11645 
11646 #include <regex>
11647 
11648 namespace Catch {
11649 namespace Matchers {
11650 
11651  namespace StdString {
11652 
11653  CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
11654  : m_caseSensitivity( caseSensitivity ),
11655  m_str( adjustString( str ) )
11656  {}
11657  std::string CasedString::adjustString( std::string const& str ) const {
11658  return m_caseSensitivity == CaseSensitive::No
11659  ? toLower( str )
11660  : str;
11661  }
11662  std::string CasedString::caseSensitivitySuffix() const {
11663  return m_caseSensitivity == CaseSensitive::No
11664  ? " (case insensitive)"
11665  : std::string();
11666  }
11667 
11668  StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
11669  : m_comparator( comparator ),
11670  m_operation( operation ) {
11671  }
11672 
11673  std::string StringMatcherBase::describe() const {
11674  std::string description;
11675  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
11676  m_comparator.caseSensitivitySuffix().size());
11677  description += m_operation;
11678  description += ": \"";
11679  description += m_comparator.m_str;
11680  description += "\"";
11681  description += m_comparator.caseSensitivitySuffix();
11682  return description;
11683  }
11684 
11685  EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
11686 
11687  bool EqualsMatcher::match( std::string const& source ) const {
11688  return m_comparator.adjustString( source ) == m_comparator.m_str;
11689  }
11690 
11691  ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
11692 
11693  bool ContainsMatcher::match( std::string const& source ) const {
11694  return contains( m_comparator.adjustString( source ), m_comparator.m_str );
11695  }
11696 
11697  StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
11698 
11699  bool StartsWithMatcher::match( std::string const& source ) const {
11700  return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11701  }
11702 
11703  EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
11704 
11705  bool EndsWithMatcher::match( std::string const& source ) const {
11706  return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
11707  }
11708 
11709  RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
11710 
11711  bool RegexMatcher::match(std::string const& matchee) const {
11712  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
11713  if (m_caseSensitivity == CaseSensitive::Choice::No) {
11714  flags |= std::regex::icase;
11715  }
11716  auto reg = std::regex(m_regex, flags);
11717  return std::regex_match(matchee, reg);
11718  }
11719 
11720  std::string RegexMatcher::describe() const {
11721  return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
11722  }
11723 
11724  } // namespace StdString
11725 
11726  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11727  return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
11728  }
11729  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11730  return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
11731  }
11732  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11733  return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11734  }
11735  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
11736  return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
11737  }
11738 
11739  StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
11740  return StdString::RegexMatcher(regex, caseSensitivity);
11741  }
11742 
11743 } // namespace Matchers
11744 } // namespace Catch
11745 // end catch_matchers_string.cpp
11746 // start catch_message.cpp
11747 
11748 // start catch_uncaught_exceptions.h
11749 
11750 namespace Catch {
11751  bool uncaught_exceptions();
11752 } // end namespace Catch
11753 
11754 // end catch_uncaught_exceptions.h
11755 #include <cassert>
11756 #include <stack>
11757 
11758 namespace Catch {
11759 
11760  MessageInfo::MessageInfo( StringRef const& _macroName,
11761  SourceLineInfo const& _lineInfo,
11762  ResultWas::OfType _type )
11763  : macroName( _macroName ),
11764  lineInfo( _lineInfo ),
11765  type( _type ),
11766  sequence( ++globalCount )
11767  {}
11768 
11769  bool MessageInfo::operator==( MessageInfo const& other ) const {
11770  return sequence == other.sequence;
11771  }
11772 
11773  bool MessageInfo::operator<( MessageInfo const& other ) const {
11774  return sequence < other.sequence;
11775  }
11776 
11777  // This may need protecting if threading support is added
11778  unsigned int MessageInfo::globalCount = 0;
11779 
11781 
11782  Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
11783  SourceLineInfo const& lineInfo,
11784  ResultWas::OfType type )
11785  :m_info(macroName, lineInfo, type) {}
11786 
11788 
11789  ScopedMessage::ScopedMessage( MessageBuilder const& builder )
11790  : m_info( builder.m_info ), m_moved()
11791  {
11792  m_info.message = builder.m_stream.str();
11793  getResultCapture().pushScopedMessage( m_info );
11794  }
11795 
11796  ScopedMessage::ScopedMessage( ScopedMessage&& old )
11797  : m_info( old.m_info ), m_moved()
11798  {
11799  old.m_moved = true;
11800  }
11801 
11802  ScopedMessage::~ScopedMessage() {
11803  if ( !uncaught_exceptions() && !m_moved ){
11804  getResultCapture().popScopedMessage(m_info);
11805  }
11806  }
11807 
11808  Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
11809  auto trimmed = [&] (size_t start, size_t end) {
11810  while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
11811  ++start;
11812  }
11813  while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
11814  --end;
11815  }
11816  return names.substr(start, end - start + 1);
11817  };
11818  auto skipq = [&] (size_t start, char quote) {
11819  for (auto i = start + 1; i < names.size() ; ++i) {
11820  if (names[i] == quote)
11821  return i;
11822  if (names[i] == '\\')
11823  ++i;
11824  }
11825  CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
11826  };
11827 
11828  size_t start = 0;
11829  std::stack<char> openings;
11830  for (size_t pos = 0; pos < names.size(); ++pos) {
11831  char c = names[pos];
11832  switch (c) {
11833  case '[':
11834  case '{':
11835  case '(':
11836  // It is basically impossible to disambiguate between
11837  // comparison and start of template args in this context
11838 // case '<':
11839  openings.push(c);
11840  break;
11841  case ']':
11842  case '}':
11843  case ')':
11844 // case '>':
11845  openings.pop();
11846  break;
11847  case '"':
11848  case '\'':
11849  pos = skipq(pos, c);
11850  break;
11851  case ',':
11852  if (start != pos && openings.empty()) {
11853  m_messages.emplace_back(macroName, lineInfo, resultType);
11854  m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
11855  m_messages.back().message += " := ";
11856  start = pos;
11857  }
11858  }
11859  }
11860  assert(openings.empty() && "Mismatched openings");
11861  m_messages.emplace_back(macroName, lineInfo, resultType);
11862  m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
11863  m_messages.back().message += " := ";
11864  }
11865  Capturer::~Capturer() {
11866  if ( !uncaught_exceptions() ){
11867  assert( m_captured == m_messages.size() );
11868  for( size_t i = 0; i < m_captured; ++i )
11869  m_resultCapture.popScopedMessage( m_messages[i] );
11870  }
11871  }
11872 
11873  void Capturer::captureValue( size_t index, std::string const& value ) {
11874  assert( index < m_messages.size() );
11875  m_messages[index].message += value;
11876  m_resultCapture.pushScopedMessage( m_messages[index] );
11877  m_captured++;
11878  }
11879 
11880 } // end namespace Catch
11881 // end catch_message.cpp
11882 // start catch_output_redirect.cpp
11883 
11884 // start catch_output_redirect.h
11885 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11886 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11887 
11888 #include <cstdio>
11889 #include <iosfwd>
11890 #include <string>
11891 
11892 namespace Catch {
11893 
11895  std::ostream& m_originalStream;
11896  std::ostream& m_redirectionStream;
11897  std::streambuf* m_prevBuf;
11898 
11899  public:
11900  RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
11901  ~RedirectedStream();
11902  };
11903 
11905  ReusableStringStream m_rss;
11906  RedirectedStream m_cout;
11907  public:
11908  RedirectedStdOut();
11909  auto str() const -> std::string;
11910  };
11911 
11912  // StdErr has two constituent streams in C++, std::cerr and std::clog
11913  // This means that we need to redirect 2 streams into 1 to keep proper
11914  // order of writes
11916  ReusableStringStream m_rss;
11917  RedirectedStream m_cerr;
11918  RedirectedStream m_clog;
11919  public:
11920  RedirectedStdErr();
11921  auto str() const -> std::string;
11922  };
11923 
11925  public:
11926  RedirectedStreams(RedirectedStreams const&) = delete;
11927  RedirectedStreams& operator=(RedirectedStreams const&) = delete;
11929  RedirectedStreams& operator=(RedirectedStreams&&) = delete;
11930 
11931  RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
11932  ~RedirectedStreams();
11933  private:
11934  std::string& m_redirectedCout;
11935  std::string& m_redirectedCerr;
11936  RedirectedStdOut m_redirectedStdOut;
11937  RedirectedStdErr m_redirectedStdErr;
11938  };
11939 
11940 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11941 
11942  // Windows's implementation of std::tmpfile is terrible (it tries
11943  // to create a file inside system folder, thus requiring elevated
11944  // privileges for the binary), so we have to use tmpnam(_s) and
11945  // create the file ourselves there.
11946  class TempFile {
11947  public:
11948  TempFile(TempFile const&) = delete;
11949  TempFile& operator=(TempFile const&) = delete;
11950  TempFile(TempFile&&) = delete;
11951  TempFile& operator=(TempFile&&) = delete;
11952 
11953  TempFile();
11954  ~TempFile();
11955 
11956  std::FILE* getFile();
11957  std::string getContents();
11958 
11959  private:
11960  std::FILE* m_file = nullptr;
11961  #if defined(_MSC_VER)
11962  char m_buffer[L_tmpnam] = { 0 };
11963  #endif
11964  };
11965 
11967  public:
11968  OutputRedirect(OutputRedirect const&) = delete;
11969  OutputRedirect& operator=(OutputRedirect const&) = delete;
11970  OutputRedirect(OutputRedirect&&) = delete;
11971  OutputRedirect& operator=(OutputRedirect&&) = delete;
11972 
11973  OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
11974  ~OutputRedirect();
11975 
11976  private:
11977  int m_originalStdout = -1;
11978  int m_originalStderr = -1;
11979  TempFile m_stdoutFile;
11980  TempFile m_stderrFile;
11981  std::string& m_stdoutDest;
11982  std::string& m_stderrDest;
11983  };
11984 
11985 #endif
11986 
11987 } // end namespace Catch
11988 
11989 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
11990 // end catch_output_redirect.h
11991 #include <cstdio>
11992 #include <cstring>
11993 #include <fstream>
11994 #include <sstream>
11995 #include <stdexcept>
11996 
11997 #if defined(CATCH_CONFIG_NEW_CAPTURE)
11998  #if defined(_MSC_VER)
11999  #include <io.h> //_dup and _dup2
12000  #define dup _dup
12001  #define dup2 _dup2
12002  #define fileno _fileno
12003  #else
12004  #include <unistd.h> // dup and dup2
12005  #endif
12006 #endif
12007 
12008 namespace Catch {
12009 
12010  RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
12011  : m_originalStream( originalStream ),
12012  m_redirectionStream( redirectionStream ),
12013  m_prevBuf( m_originalStream.rdbuf() )
12014  {
12015  m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
12016  }
12017 
12018  RedirectedStream::~RedirectedStream() {
12019  m_originalStream.rdbuf( m_prevBuf );
12020  }
12021 
12022  RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
12023  auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
12024 
12025  RedirectedStdErr::RedirectedStdErr()
12026  : m_cerr( Catch::cerr(), m_rss.get() ),
12027  m_clog( Catch::clog(), m_rss.get() )
12028  {}
12029  auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
12030 
12031  RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
12032  : m_redirectedCout(redirectedCout),
12033  m_redirectedCerr(redirectedCerr)
12034  {}
12035 
12036  RedirectedStreams::~RedirectedStreams() {
12037  m_redirectedCout += m_redirectedStdOut.str();
12038  m_redirectedCerr += m_redirectedStdErr.str();
12039  }
12040 
12041 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12042 
12043 #if defined(_MSC_VER)
12044  TempFile::TempFile() {
12045  if (tmpnam_s(m_buffer)) {
12046  CATCH_RUNTIME_ERROR("Could not get a temp filename");
12047  }
12048  if (fopen_s(&m_file, m_buffer, "w")) {
12049  char buffer[100];
12050  if (strerror_s(buffer, errno)) {
12051  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
12052  }
12053  CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
12054  }
12055  }
12056 #else
12057  TempFile::TempFile() {
12058  m_file = std::tmpfile();
12059  if (!m_file) {
12060  CATCH_RUNTIME_ERROR("Could not create a temp file.");
12061  }
12062  }
12063 
12064 #endif
12065 
12066  TempFile::~TempFile() {
12067  // TBD: What to do about errors here?
12068  std::fclose(m_file);
12069  // We manually create the file on Windows only, on Linux
12070  // it will be autodeleted
12071 #if defined(_MSC_VER)
12072  std::remove(m_buffer);
12073 #endif
12074  }
12075 
12076  FILE* TempFile::getFile() {
12077  return m_file;
12078  }
12079 
12080  std::string TempFile::getContents() {
12081  std::stringstream sstr;
12082  char buffer[100] = {};
12083  std::rewind(m_file);
12084  while (std::fgets(buffer, sizeof(buffer), m_file)) {
12085  sstr << buffer;
12086  }
12087  return sstr.str();
12088  }
12089 
12090  OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
12091  m_originalStdout(dup(1)),
12092  m_originalStderr(dup(2)),
12093  m_stdoutDest(stdout_dest),
12094  m_stderrDest(stderr_dest) {
12095  dup2(fileno(m_stdoutFile.getFile()), 1);
12096  dup2(fileno(m_stderrFile.getFile()), 2);
12097  }
12098 
12099  OutputRedirect::~OutputRedirect() {
12100  Catch::cout() << std::flush;
12101  fflush(stdout);
12102  // Since we support overriding these streams, we flush cerr
12103  // even though std::cerr is unbuffered
12104  Catch::cerr() << std::flush;
12105  Catch::clog() << std::flush;
12106  fflush(stderr);
12107 
12108  dup2(m_originalStdout, 1);
12109  dup2(m_originalStderr, 2);
12110 
12111  m_stdoutDest += m_stdoutFile.getContents();
12112  m_stderrDest += m_stderrFile.getContents();
12113  }
12114 
12115 #endif // CATCH_CONFIG_NEW_CAPTURE
12116 
12117 } // namespace Catch
12118 
12119 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12120  #if defined(_MSC_VER)
12121  #undef dup
12122  #undef dup2
12123  #undef fileno
12124  #endif
12125 #endif
12126 // end catch_output_redirect.cpp
12127 // start catch_polyfills.cpp
12128 
12129 #include <cmath>
12130 
12131 namespace Catch {
12132 
12133 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
12134  bool isnan(float f) {
12135  return std::isnan(f);
12136  }
12137  bool isnan(double d) {
12138  return std::isnan(d);
12139  }
12140 #else
12141  // For now we only use this for embarcadero
12142  bool isnan(float f) {
12143  return std::_isnan(f);
12144  }
12145  bool isnan(double d) {
12146  return std::_isnan(d);
12147  }
12148 #endif
12149 
12150 } // end namespace Catch
12151 // end catch_polyfills.cpp
12152 // start catch_random_number_generator.cpp
12153 
12154 namespace Catch {
12155 
12156 namespace {
12157 
12158 #if defined(_MSC_VER)
12159 #pragma warning(push)
12160 #pragma warning(disable:4146) // we negate uint32 during the rotate
12161 #endif
12162  // Safe rotr implementation thanks to John Regehr
12163  uint32_t rotate_right(uint32_t val, uint32_t count) {
12164  const uint32_t mask = 31;
12165  count &= mask;
12166  return (val >> count) | (val << (-count & mask));
12167  }
12168 
12169 #if defined(_MSC_VER)
12170 #pragma warning(pop)
12171 #endif
12172 
12173 }
12174 
12175  SimplePcg32::SimplePcg32(result_type seed_) {
12176  seed(seed_);
12177  }
12178 
12179  void SimplePcg32::seed(result_type seed_) {
12180  m_state = 0;
12181  (*this)();
12182  m_state += seed_;
12183  (*this)();
12184  }
12185 
12186  void SimplePcg32::discard(uint64_t skip) {
12187  // We could implement this to run in O(log n) steps, but this
12188  // should suffice for our use case.
12189  for (uint64_t s = 0; s < skip; ++s) {
12190  static_cast<void>((*this)());
12191  }
12192  }
12193 
12194  SimplePcg32::result_type SimplePcg32::operator()() {
12195  // prepare the output value
12196  const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
12197  const auto output = rotate_right(xorshifted, m_state >> 59u);
12198 
12199  // advance state
12200  m_state = m_state * 6364136223846793005ULL + s_inc;
12201 
12202  return output;
12203  }
12204 
12205  bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12206  return lhs.m_state == rhs.m_state;
12207  }
12208 
12209  bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
12210  return lhs.m_state != rhs.m_state;
12211  }
12212 }
12213 // end catch_random_number_generator.cpp
12214 // start catch_registry_hub.cpp
12215 
12216 // start catch_test_case_registry_impl.h
12217 
12218 #include <vector>
12219 #include <set>
12220 #include <algorithm>
12221 #include <ios>
12222 
12223 namespace Catch {
12224 
12225  class TestCase;
12226  struct IConfig;
12227 
12228  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
12229 
12230  bool isThrowSafe( TestCase const& testCase, IConfig const& config );
12231  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
12232 
12233  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
12234 
12235  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
12236  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
12237 
12239  public:
12240  virtual ~TestRegistry() = default;
12241 
12242  virtual void registerTest( TestCase const& testCase );
12243 
12244  std::vector<TestCase> const& getAllTests() const override;
12245  std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
12246 
12247  private:
12248  std::vector<TestCase> m_functions;
12249  mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
12250  mutable std::vector<TestCase> m_sortedFunctions;
12251  std::size_t m_unnamedCount = 0;
12252  std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
12253  };
12254 
12256 
12258  void(*m_testAsFunction)();
12259  public:
12260  TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
12261 
12262  void invoke() const override;
12263  };
12264 
12265  std::string extractClassName( StringRef const& classOrQualifiedMethodName );
12266 
12268 
12269 } // end namespace Catch
12270 
12271 // end catch_test_case_registry_impl.h
12272 // start catch_reporter_registry.h
12273 
12274 #include <map>
12275 
12276 namespace Catch {
12277 
12279 
12280  public:
12281 
12282  ~ReporterRegistry() override;
12283 
12284  IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
12285 
12286  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
12287  void registerListener( IReporterFactoryPtr const& factory );
12288 
12289  FactoryMap const& getFactories() const override;
12290  Listeners const& getListeners() const override;
12291 
12292  private:
12293  FactoryMap m_factories;
12294  Listeners m_listeners;
12295  };
12296 }
12297 
12298 // end catch_reporter_registry.h
12299 // start catch_tag_alias_registry.h
12300 
12301 // start catch_tag_alias.h
12302 
12303 #include <string>
12304 
12305 namespace Catch {
12306 
12307  struct TagAlias {
12308  TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
12309 
12310  std::string tag;
12311  SourceLineInfo lineInfo;
12312  };
12313 
12314 } // end namespace Catch
12315 
12316 // end catch_tag_alias.h
12317 #include <map>
12318 
12319 namespace Catch {
12320 
12322  public:
12323  ~TagAliasRegistry() override;
12324  TagAlias const* find( std::string const& alias ) const override;
12325  std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
12326  void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
12327 
12328  private:
12329  std::map<std::string, TagAlias> m_registry;
12330  };
12331 
12332 } // end namespace Catch
12333 
12334 // end catch_tag_alias_registry.h
12335 // start catch_startup_exception_registry.h
12336 
12337 #include <vector>
12338 #include <exception>
12339 
12340 namespace Catch {
12341 
12343 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12344  public:
12345  void add(std::exception_ptr const& exception) noexcept;
12346  std::vector<std::exception_ptr> const& getExceptions() const noexcept;
12347  private:
12348  std::vector<std::exception_ptr> m_exceptions;
12349 #endif
12350  };
12351 
12352 } // end namespace Catch
12353 
12354 // end catch_startup_exception_registry.h
12355 // start catch_singletons.hpp
12356 
12357 namespace Catch {
12358 
12359  struct ISingleton {
12360  virtual ~ISingleton();
12361  };
12362 
12363  void addSingleton( ISingleton* singleton );
12364  void cleanupSingletons();
12365 
12366  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
12367  class Singleton : SingletonImplT, public ISingleton {
12368 
12369  static auto getInternal() -> Singleton* {
12370  static Singleton* s_instance = nullptr;
12371  if( !s_instance ) {
12372  s_instance = new Singleton;
12373  addSingleton( s_instance );
12374  }
12375  return s_instance;
12376  }
12377 
12378  public:
12379  static auto get() -> InterfaceT const& {
12380  return *getInternal();
12381  }
12382  static auto getMutable() -> MutableInterfaceT& {
12383  return *getInternal();
12384  }
12385  };
12386 
12387 } // namespace Catch
12388 
12389 // end catch_singletons.hpp
12390 namespace Catch {
12391 
12392  namespace {
12393 
12395  private NonCopyable {
12396 
12397  public: // IRegistryHub
12398  RegistryHub() = default;
12399  IReporterRegistry const& getReporterRegistry() const override {
12400  return m_reporterRegistry;
12401  }
12402  ITestCaseRegistry const& getTestCaseRegistry() const override {
12403  return m_testCaseRegistry;
12404  }
12405  IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
12406  return m_exceptionTranslatorRegistry;
12407  }
12408  ITagAliasRegistry const& getTagAliasRegistry() const override {
12409  return m_tagAliasRegistry;
12410  }
12411  StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
12412  return m_exceptionRegistry;
12413  }
12414 
12415  public: // IMutableRegistryHub
12416  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
12417  m_reporterRegistry.registerReporter( name, factory );
12418  }
12419  void registerListener( IReporterFactoryPtr const& factory ) override {
12420  m_reporterRegistry.registerListener( factory );
12421  }
12422  void registerTest( TestCase const& testInfo ) override {
12423  m_testCaseRegistry.registerTest( testInfo );
12424  }
12425  void registerTranslator( const IExceptionTranslator* translator ) override {
12426  m_exceptionTranslatorRegistry.registerTranslator( translator );
12427  }
12428  void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
12429  m_tagAliasRegistry.add( alias, tag, lineInfo );
12430  }
12431  void registerStartupException() noexcept override {
12432 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12433  m_exceptionRegistry.add(std::current_exception());
12434 #else
12435  CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
12436 #endif
12437  }
12438  IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
12439  return m_enumValuesRegistry;
12440  }
12441 
12442  private:
12443  TestRegistry m_testCaseRegistry;
12444  ReporterRegistry m_reporterRegistry;
12445  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
12446  TagAliasRegistry m_tagAliasRegistry;
12447  StartupExceptionRegistry m_exceptionRegistry;
12448  Detail::EnumValuesRegistry m_enumValuesRegistry;
12449  };
12450  }
12451 
12453 
12454  IRegistryHub const& getRegistryHub() {
12455  return RegistryHubSingleton::get();
12456  }
12457  IMutableRegistryHub& getMutableRegistryHub() {
12458  return RegistryHubSingleton::getMutable();
12459  }
12460  void cleanUp() {
12461  cleanupSingletons();
12462  cleanUpContext();
12463  }
12464  std::string translateActiveException() {
12465  return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
12466  }
12467 
12468 } // end namespace Catch
12469 // end catch_registry_hub.cpp
12470 // start catch_reporter_registry.cpp
12471 
12472 namespace Catch {
12473 
12474  ReporterRegistry::~ReporterRegistry() = default;
12475 
12476  IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
12477  auto it = m_factories.find( name );
12478  if( it == m_factories.end() )
12479  return nullptr;
12480  return it->second->create( ReporterConfig( config ) );
12481  }
12482 
12483  void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
12484  m_factories.emplace(name, factory);
12485  }
12486  void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
12487  m_listeners.push_back( factory );
12488  }
12489 
12490  IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
12491  return m_factories;
12492  }
12493  IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
12494  return m_listeners;
12495  }
12496 
12497 }
12498 // end catch_reporter_registry.cpp
12499 // start catch_result_type.cpp
12500 
12501 namespace Catch {
12502 
12503  bool isOk( ResultWas::OfType resultType ) {
12504  return ( resultType & ResultWas::FailureBit ) == 0;
12505  }
12506  bool isJustInfo( int flags ) {
12507  return flags == ResultWas::Info;
12508  }
12509 
12510  ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
12511  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
12512  }
12513 
12514  bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
12515  bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
12516 
12517 } // end namespace Catch
12518 // end catch_result_type.cpp
12519 // start catch_run_context.cpp
12520 
12521 #include <cassert>
12522 #include <algorithm>
12523 #include <sstream>
12524 
12525 namespace Catch {
12526 
12527  namespace Generators {
12529  GeneratorBasePtr m_generator;
12530 
12531  GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
12532  : TrackerBase( nameAndLocation, ctx, parent )
12533  {}
12534  ~GeneratorTracker();
12535 
12536  static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
12537  std::shared_ptr<GeneratorTracker> tracker;
12538 
12539  ITracker& currentTracker = ctx.currentTracker();
12540  // Under specific circumstances, the generator we want
12541  // to acquire is also the current tracker. If this is
12542  // the case, we have to avoid looking through current
12543  // tracker's children, and instead return the current
12544  // tracker.
12545  // A case where this check is important is e.g.
12546  // for (int i = 0; i < 5; ++i) {
12547  // int n = GENERATE(1, 2);
12548  // }
12549  //
12550  // without it, the code above creates 5 nested generators.
12551  if (currentTracker.nameAndLocation() == nameAndLocation) {
12552  auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
12553  assert(thisTracker);
12554  assert(thisTracker->isGeneratorTracker());
12555  tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
12556  } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
12557  assert( childTracker );
12558  assert( childTracker->isGeneratorTracker() );
12559  tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
12560  } else {
12561  tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
12562  currentTracker.addChild( tracker );
12563  }
12564 
12565  if( !tracker->isComplete() ) {
12566  tracker->open();
12567  }
12568 
12569  return *tracker;
12570  }
12571 
12572  // TrackerBase interface
12573  bool isGeneratorTracker() const override { return true; }
12574  auto hasGenerator() const -> bool override {
12575  return !!m_generator;
12576  }
12577  void close() override {
12578  TrackerBase::close();
12579  // If a generator has a child (it is followed by a section)
12580  // and none of its children have started, then we must wait
12581  // until later to start consuming its values.
12582  // This catches cases where `GENERATE` is placed between two
12583  // `SECTION`s.
12584  // **The check for m_children.empty cannot be removed**.
12585  // doing so would break `GENERATE` _not_ followed by `SECTION`s.
12586  const bool should_wait_for_child =
12587  !m_children.empty() &&
12588  std::find_if( m_children.begin(),
12589  m_children.end(),
12590  []( TestCaseTracking::ITrackerPtr tracker ) {
12591  return tracker->hasStarted();
12592  } ) == m_children.end();
12593 
12594  // This check is a bit tricky, because m_generator->next()
12595  // has a side-effect, where it consumes generator's current
12596  // value, but we do not want to invoke the side-effect if
12597  // this generator is still waiting for any child to start.
12598  if ( should_wait_for_child ||
12599  ( m_runState == CompletedSuccessfully &&
12600  m_generator->next() ) ) {
12601  m_children.clear();
12602  m_runState = Executing;
12603  }
12604  }
12605 
12606  // IGeneratorTracker interface
12607  auto getGenerator() const -> GeneratorBasePtr const& override {
12608  return m_generator;
12609  }
12610  void setGenerator( GeneratorBasePtr&& generator ) override {
12611  m_generator = std::move( generator );
12612  }
12613  };
12614  GeneratorTracker::~GeneratorTracker() {}
12615  }
12616 
12617  RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
12618  : m_runInfo(_config->name()),
12619  m_context(getCurrentMutableContext()),
12620  m_config(_config),
12621  m_reporter(std::move(reporter)),
12622  m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
12623  m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
12624  {
12625  m_context.setRunner(this);
12626  m_context.setConfig(m_config);
12627  m_context.setResultCapture(this);
12628  m_reporter->testRunStarting(m_runInfo);
12629  }
12630 
12631  RunContext::~RunContext() {
12632  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
12633  }
12634 
12635  void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
12636  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
12637  }
12638 
12639  void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
12640  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
12641  }
12642 
12643  Totals RunContext::runTest(TestCase const& testCase) {
12644  Totals prevTotals = m_totals;
12645 
12646  std::string redirectedCout;
12647  std::string redirectedCerr;
12648 
12649  auto const& testInfo = testCase.getTestCaseInfo();
12650 
12651  m_reporter->testCaseStarting(testInfo);
12652 
12653  m_activeTestCase = &testCase;
12654 
12655  ITracker& rootTracker = m_trackerContext.startRun();
12656  assert(rootTracker.isSectionTracker());
12657  static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
12658  do {
12659  m_trackerContext.startCycle();
12660  m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
12661  runCurrentTest(redirectedCout, redirectedCerr);
12662  } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
12663 
12664  Totals deltaTotals = m_totals.delta(prevTotals);
12665  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
12666  deltaTotals.assertions.failed++;
12667  deltaTotals.testCases.passed--;
12668  deltaTotals.testCases.failed++;
12669  }
12670  m_totals.testCases += deltaTotals.testCases;
12671  m_reporter->testCaseEnded(TestCaseStats(testInfo,
12672  deltaTotals,
12673  redirectedCout,
12674  redirectedCerr,
12675  aborting()));
12676 
12677  m_activeTestCase = nullptr;
12678  m_testCaseTracker = nullptr;
12679 
12680  return deltaTotals;
12681  }
12682 
12683  IConfigPtr RunContext::config() const {
12684  return m_config;
12685  }
12686 
12687  IStreamingReporter& RunContext::reporter() const {
12688  return *m_reporter;
12689  }
12690 
12691  void RunContext::assertionEnded(AssertionResult const & result) {
12692  if (result.getResultType() == ResultWas::Ok) {
12693  m_totals.assertions.passed++;
12694  m_lastAssertionPassed = true;
12695  } else if (!result.isOk()) {
12696  m_lastAssertionPassed = false;
12697  if( m_activeTestCase->getTestCaseInfo().okToFail() )
12698  m_totals.assertions.failedButOk++;
12699  else
12700  m_totals.assertions.failed++;
12701  }
12702  else {
12703  m_lastAssertionPassed = true;
12704  }
12705 
12706  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
12707  // and should be let to clear themselves out.
12708  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
12709 
12710  if (result.getResultType() != ResultWas::Warning)
12711  m_messageScopes.clear();
12712 
12713  // Reset working state
12714  resetAssertionInfo();
12715  m_lastResult = result;
12716  }
12717  void RunContext::resetAssertionInfo() {
12718  m_lastAssertionInfo.macroName = StringRef();
12719  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
12720  }
12721 
12722  bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
12723  ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
12724  if (!sectionTracker.isOpen())
12725  return false;
12726  m_activeSections.push_back(&sectionTracker);
12727 
12728  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
12729 
12730  m_reporter->sectionStarting(sectionInfo);
12731 
12732  assertions = m_totals.assertions;
12733 
12734  return true;
12735  }
12736  auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
12737  using namespace Generators;
12738  GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
12739  TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
12740  m_lastAssertionInfo.lineInfo = lineInfo;
12741  return tracker;
12742  }
12743 
12744  bool RunContext::testForMissingAssertions(Counts& assertions) {
12745  if (assertions.total() != 0)
12746  return false;
12747  if (!m_config->warnAboutMissingAssertions())
12748  return false;
12749  if (m_trackerContext.currentTracker().hasChildren())
12750  return false;
12751  m_totals.assertions.failed++;
12752  assertions.failed++;
12753  return true;
12754  }
12755 
12756  void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
12757  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
12758  bool missingAssertions = testForMissingAssertions(assertions);
12759 
12760  if (!m_activeSections.empty()) {
12761  m_activeSections.back()->close();
12762  m_activeSections.pop_back();
12763  }
12764 
12765  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
12766  m_messages.clear();
12767  m_messageScopes.clear();
12768  }
12769 
12770  void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
12771  if (m_unfinishedSections.empty())
12772  m_activeSections.back()->fail();
12773  else
12774  m_activeSections.back()->close();
12775  m_activeSections.pop_back();
12776 
12777  m_unfinishedSections.push_back(endInfo);
12778  }
12779 
12780 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
12781  void RunContext::benchmarkPreparing(std::string const& name) {
12782  m_reporter->benchmarkPreparing(name);
12783  }
12784  void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
12785  m_reporter->benchmarkStarting( info );
12786  }
12787  void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
12788  m_reporter->benchmarkEnded( stats );
12789  }
12790  void RunContext::benchmarkFailed(std::string const & error) {
12791  m_reporter->benchmarkFailed(error);
12792  }
12793 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
12794 
12795  void RunContext::pushScopedMessage(MessageInfo const & message) {
12796  m_messages.push_back(message);
12797  }
12798 
12799  void RunContext::popScopedMessage(MessageInfo const & message) {
12800  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
12801  }
12802 
12803  void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
12804  m_messageScopes.emplace_back( builder );
12805  }
12806 
12807  std::string RunContext::getCurrentTestName() const {
12808  return m_activeTestCase
12809  ? m_activeTestCase->getTestCaseInfo().name
12810  : std::string();
12811  }
12812 
12813  const AssertionResult * RunContext::getLastResult() const {
12814  return &(*m_lastResult);
12815  }
12816 
12817  void RunContext::exceptionEarlyReported() {
12818  m_shouldReportUnexpected = false;
12819  }
12820 
12821  void RunContext::handleFatalErrorCondition( StringRef message ) {
12822  // First notify reporter that bad things happened
12823  m_reporter->fatalErrorEncountered(message);
12824 
12825  // Don't rebuild the result -- the stringification itself can cause more fatal errors
12826  // Instead, fake a result data.
12827  AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
12828  tempResult.message = static_cast<std::string>(message);
12829  AssertionResult result(m_lastAssertionInfo, tempResult);
12830 
12831  assertionEnded(result);
12832 
12833  handleUnfinishedSections();
12834 
12835  // Recreate section for test case (as we will lose the one that was in scope)
12836  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12837  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12838 
12839  Counts assertions;
12840  assertions.failed = 1;
12841  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
12842  m_reporter->sectionEnded(testCaseSectionStats);
12843 
12844  auto const& testInfo = m_activeTestCase->getTestCaseInfo();
12845 
12846  Totals deltaTotals;
12847  deltaTotals.testCases.failed = 1;
12848  deltaTotals.assertions.failed = 1;
12849  m_reporter->testCaseEnded(TestCaseStats(testInfo,
12850  deltaTotals,
12851  std::string(),
12852  std::string(),
12853  false));
12854  m_totals.testCases.failed++;
12855  testGroupEnded(std::string(), m_totals, 1, 1);
12856  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
12857  }
12858 
12859  bool RunContext::lastAssertionPassed() {
12860  return m_lastAssertionPassed;
12861  }
12862 
12863  void RunContext::assertionPassed() {
12864  m_lastAssertionPassed = true;
12865  ++m_totals.assertions.passed;
12866  resetAssertionInfo();
12867  m_messageScopes.clear();
12868  }
12869 
12870  bool RunContext::aborting() const {
12871  return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
12872  }
12873 
12874  void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
12875  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
12876  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
12877  m_reporter->sectionStarting(testCaseSection);
12878  Counts prevAssertions = m_totals.assertions;
12879  double duration = 0;
12880  m_shouldReportUnexpected = true;
12881  m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
12882 
12883  seedRng(*m_config);
12884 
12885  Timer timer;
12886  CATCH_TRY {
12887  if (m_reporter->getPreferences().shouldRedirectStdOut) {
12888 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
12889  RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
12890 
12891  timer.start();
12892  invokeActiveTestCase();
12893 #else
12894  OutputRedirect r(redirectedCout, redirectedCerr);
12895  timer.start();
12896  invokeActiveTestCase();
12897 #endif
12898  } else {
12899  timer.start();
12900  invokeActiveTestCase();
12901  }
12902  duration = timer.getElapsedSeconds();
12903  } CATCH_CATCH_ANON (TestFailureException&) {
12904  // This just means the test was aborted due to failure
12905  } CATCH_CATCH_ALL {
12906  // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
12907  // are reported without translation at the point of origin.
12908  if( m_shouldReportUnexpected ) {
12909  AssertionReaction dummyReaction;
12910  handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
12911  }
12912  }
12913  Counts assertions = m_totals.assertions - prevAssertions;
12914  bool missingAssertions = testForMissingAssertions(assertions);
12915 
12916  m_testCaseTracker->close();
12917  handleUnfinishedSections();
12918  m_messages.clear();
12919  m_messageScopes.clear();
12920 
12921  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
12922  m_reporter->sectionEnded(testCaseSectionStats);
12923  }
12924 
12925  void RunContext::invokeActiveTestCase() {
12926  FatalConditionHandler fatalConditionHandler; // Handle signals
12927  m_activeTestCase->invoke();
12928  fatalConditionHandler.reset();
12929  }
12930 
12931  void RunContext::handleUnfinishedSections() {
12932  // If sections ended prematurely due to an exception we stored their
12933  // infos here so we can tear them down outside the unwind process.
12934  for (auto it = m_unfinishedSections.rbegin(),
12935  itEnd = m_unfinishedSections.rend();
12936  it != itEnd;
12937  ++it)
12938  sectionEnded(*it);
12939  m_unfinishedSections.clear();
12940  }
12941 
12942  void RunContext::handleExpr(
12943  AssertionInfo const& info,
12944  ITransientExpression const& expr,
12945  AssertionReaction& reaction
12946  ) {
12947  m_reporter->assertionStarting( info );
12948 
12949  bool negated = isFalseTest( info.resultDisposition );
12950  bool result = expr.getResult() != negated;
12951 
12952  if( result ) {
12953  if (!m_includeSuccessfulResults) {
12954  assertionPassed();
12955  }
12956  else {
12957  reportExpr(info, ResultWas::Ok, &expr, negated);
12958  }
12959  }
12960  else {
12961  reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
12962  populateReaction( reaction );
12963  }
12964  }
12965  void RunContext::reportExpr(
12966  AssertionInfo const &info,
12967  ResultWas::OfType resultType,
12968  ITransientExpression const *expr,
12969  bool negated ) {
12970 
12971  m_lastAssertionInfo = info;
12972  AssertionResultData data( resultType, LazyExpression( negated ) );
12973 
12974  AssertionResult assertionResult{ info, data };
12975  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
12976 
12977  assertionEnded( assertionResult );
12978  }
12979 
12980  void RunContext::handleMessage(
12981  AssertionInfo const& info,
12982  ResultWas::OfType resultType,
12983  StringRef const& message,
12984  AssertionReaction& reaction
12985  ) {
12986  m_reporter->assertionStarting( info );
12987 
12988  m_lastAssertionInfo = info;
12989 
12990  AssertionResultData data( resultType, LazyExpression( false ) );
12991  data.message = static_cast<std::string>(message);
12992  AssertionResult assertionResult{ m_lastAssertionInfo, data };
12993  assertionEnded( assertionResult );
12994  if( !assertionResult.isOk() )
12995  populateReaction( reaction );
12996  }
12997  void RunContext::handleUnexpectedExceptionNotThrown(
12998  AssertionInfo const& info,
12999  AssertionReaction& reaction
13000  ) {
13001  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
13002  }
13003 
13004  void RunContext::handleUnexpectedInflightException(
13005  AssertionInfo const& info,
13006  std::string const& message,
13007  AssertionReaction& reaction
13008  ) {
13009  m_lastAssertionInfo = info;
13010 
13011  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
13012  data.message = message;
13013  AssertionResult assertionResult{ info, data };
13014  assertionEnded( assertionResult );
13015  populateReaction( reaction );
13016  }
13017 
13018  void RunContext::populateReaction( AssertionReaction& reaction ) {
13019  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
13020  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
13021  }
13022 
13023  void RunContext::handleIncomplete(
13024  AssertionInfo const& info
13025  ) {
13026  m_lastAssertionInfo = info;
13027 
13028  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
13029  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
13030  AssertionResult assertionResult{ info, data };
13031  assertionEnded( assertionResult );
13032  }
13033  void RunContext::handleNonExpr(
13034  AssertionInfo const &info,
13035  ResultWas::OfType resultType,
13036  AssertionReaction &reaction
13037  ) {
13038  m_lastAssertionInfo = info;
13039 
13040  AssertionResultData data( resultType, LazyExpression( false ) );
13041  AssertionResult assertionResult{ info, data };
13042  assertionEnded( assertionResult );
13043 
13044  if( !assertionResult.isOk() )
13045  populateReaction( reaction );
13046  }
13047 
13048  IResultCapture& getResultCapture() {
13049  if (auto* capture = getCurrentContext().getResultCapture())
13050  return *capture;
13051  else
13052  CATCH_INTERNAL_ERROR("No result capture instance");
13053  }
13054 
13055  void seedRng(IConfig const& config) {
13056  if (config.rngSeed() != 0) {
13057  std::srand(config.rngSeed());
13058  rng().seed(config.rngSeed());
13059  }
13060  }
13061 
13062  unsigned int rngSeed() {
13063  return getCurrentContext().getConfig()->rngSeed();
13064  }
13065 
13066 }
13067 // end catch_run_context.cpp
13068 // start catch_section.cpp
13069 
13070 namespace Catch {
13071 
13072  Section::Section( SectionInfo const& info )
13073  : m_info( info ),
13074  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
13075  {
13076  m_timer.start();
13077  }
13078 
13079  Section::~Section() {
13080  if( m_sectionIncluded ) {
13081  SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
13082  if( uncaught_exceptions() )
13083  getResultCapture().sectionEndedEarly( endInfo );
13084  else
13085  getResultCapture().sectionEnded( endInfo );
13086  }
13087  }
13088 
13089  // This indicates whether the section should be executed or not
13090  Section::operator bool() const {
13091  return m_sectionIncluded;
13092  }
13093 
13094 } // end namespace Catch
13095 // end catch_section.cpp
13096 // start catch_section_info.cpp
13097 
13098 namespace Catch {
13099 
13100  SectionInfo::SectionInfo
13101  ( SourceLineInfo const& _lineInfo,
13102  std::string const& _name )
13103  : name( _name ),
13104  lineInfo( _lineInfo )
13105  {}
13106 
13107 } // end namespace Catch
13108 // end catch_section_info.cpp
13109 // start catch_session.cpp
13110 
13111 // start catch_session.h
13112 
13113 #include <memory>
13114 
13115 namespace Catch {
13116 
13118  public:
13119 
13120  Session();
13121  ~Session() override;
13122 
13123  void showHelp() const;
13124  void libIdentify();
13125 
13126  int applyCommandLine( int argc, char const * const * argv );
13127  #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13128  int applyCommandLine( int argc, wchar_t const * const * argv );
13129  #endif
13130 
13131  void useConfigData( ConfigData const& configData );
13132 
13133  template<typename CharT>
13134  int run(int argc, CharT const * const argv[]) {
13135  if (m_startupExceptions)
13136  return 1;
13137  int returnCode = applyCommandLine(argc, argv);
13138  if (returnCode == 0)
13139  returnCode = run();
13140  return returnCode;
13141  }
13142 
13143  int run();
13144 
13145  clara::Parser const& cli() const;
13146  void cli( clara::Parser const& newParser );
13147  ConfigData& configData();
13148  Config& config();
13149  private:
13150  int runInternal();
13151 
13152  clara::Parser m_cli;
13153  ConfigData m_configData;
13154  std::shared_ptr<Config> m_config;
13155  bool m_startupExceptions = false;
13156  };
13157 
13158 } // end namespace Catch
13159 
13160 // end catch_session.h
13161 // start catch_version.h
13162 
13163 #include <iosfwd>
13164 
13165 namespace Catch {
13166 
13167  // Versioning information
13168  struct Version {
13169  Version( Version const& ) = delete;
13170  Version& operator=( Version const& ) = delete;
13171  Version( unsigned int _majorVersion,
13172  unsigned int _minorVersion,
13173  unsigned int _patchNumber,
13174  char const * const _branchName,
13175  unsigned int _buildNumber );
13176 
13177  unsigned int const majorVersion;
13178  unsigned int const minorVersion;
13179  unsigned int const patchNumber;
13180 
13181  // buildNumber is only used if branchName is not null
13182  char const * const branchName;
13183  unsigned int const buildNumber;
13184 
13185  friend std::ostream& operator << ( std::ostream& os, Version const& version );
13186  };
13187 
13188  Version const& libraryVersion();
13189 }
13190 
13191 // end catch_version.h
13192 #include <cstdlib>
13193 #include <iomanip>
13194 #include <set>
13195 #include <iterator>
13196 
13197 namespace Catch {
13198 
13199  namespace {
13200  const int MaxExitCode = 255;
13201 
13202  IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
13203  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
13204  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
13205 
13206  return reporter;
13207  }
13208 
13209  IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
13210  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
13211  return createReporter(config->getReporterName(), config);
13212  }
13213 
13214  // On older platforms, returning std::unique_ptr<ListeningReporter>
13215  // when the return type is std::unique_ptr<IStreamingReporter>
13216  // doesn't compile without a std::move call. However, this causes
13217  // a warning on newer platforms. Thus, we have to work around
13218  // it a bit and downcast the pointer manually.
13219  auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
13220  auto& multi = static_cast<ListeningReporter&>(*ret);
13221  auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
13222  for (auto const& listener : listeners) {
13223  multi.addListener(listener->create(Catch::ReporterConfig(config)));
13224  }
13225  multi.addReporter(createReporter(config->getReporterName(), config));
13226  return ret;
13227  }
13228 
13229  class TestGroup {
13230  public:
13231  explicit TestGroup(std::shared_ptr<Config> const& config)
13232  : m_config{config}
13233  , m_context{config, makeReporter(config)}
13234  {
13235  auto const& allTestCases = getAllTestCasesSorted(*m_config);
13236  m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
13237  auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13238 
13239  if (m_matches.empty() && invalidArgs.empty()) {
13240  for (auto const& test : allTestCases)
13241  if (!test.isHidden())
13242  m_tests.emplace(&test);
13243  } else {
13244  for (auto const& match : m_matches)
13245  m_tests.insert(match.tests.begin(), match.tests.end());
13246  }
13247  }
13248 
13249  Totals execute() {
13250  auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
13251  Totals totals;
13252  m_context.testGroupStarting(m_config->name(), 1, 1);
13253  for (auto const& testCase : m_tests) {
13254  if (!m_context.aborting())
13255  totals += m_context.runTest(*testCase);
13256  else
13257  m_context.reporter().skipTest(*testCase);
13258  }
13259 
13260  for (auto const& match : m_matches) {
13261  if (match.tests.empty()) {
13262  m_context.reporter().noMatchingTestCases(match.name);
13263  totals.error = -1;
13264  }
13265  }
13266 
13267  if (!invalidArgs.empty()) {
13268  for (auto const& invalidArg: invalidArgs)
13269  m_context.reporter().reportInvalidArguments(invalidArg);
13270  }
13271 
13272  m_context.testGroupEnded(m_config->name(), totals, 1, 1);
13273  return totals;
13274  }
13275 
13276  private:
13277  using Tests = std::set<TestCase const*>;
13278 
13279  std::shared_ptr<Config> m_config;
13280  RunContext m_context;
13281  Tests m_tests;
13282  TestSpec::Matches m_matches;
13283  };
13284 
13285  void applyFilenamesAsTags(Catch::IConfig const& config) {
13286  auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
13287  for (auto& testCase : tests) {
13288  auto tags = testCase.tags;
13289 
13290  std::string filename = testCase.lineInfo.file;
13291  auto lastSlash = filename.find_last_of("\\/");
13292  if (lastSlash != std::string::npos) {
13293  filename.erase(0, lastSlash);
13294  filename[0] = '#';
13295  }
13296 
13297  auto lastDot = filename.find_last_of('.');
13298  if (lastDot != std::string::npos) {
13299  filename.erase(lastDot);
13300  }
13301 
13302  tags.push_back(std::move(filename));
13303  setTags(testCase, tags);
13304  }
13305  }
13306 
13307  } // anon namespace
13308 
13309  Session::Session() {
13310  static bool alreadyInstantiated = false;
13311  if( alreadyInstantiated ) {
13312  CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
13313  CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
13314  }
13315 
13316  // There cannot be exceptions at startup in no-exception mode.
13317 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13318  const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
13319  if ( !exceptions.empty() ) {
13320  config();
13321  getCurrentMutableContext().setConfig(m_config);
13322 
13323  m_startupExceptions = true;
13324  Colour colourGuard( Colour::Red );
13325  Catch::cerr() << "Errors occurred during startup!" << '\n';
13326  // iterate over all exceptions and notify user
13327  for ( const auto& ex_ptr : exceptions ) {
13328  try {
13329  std::rethrow_exception(ex_ptr);
13330  } catch ( std::exception const& ex ) {
13331  Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
13332  }
13333  }
13334  }
13335 #endif
13336 
13337  alreadyInstantiated = true;
13338  m_cli = makeCommandLineParser( m_configData );
13339  }
13340  Session::~Session() {
13341  Catch::cleanUp();
13342  }
13343 
13344  void Session::showHelp() const {
13345  Catch::cout()
13346  << "\nCatch v" << libraryVersion() << "\n"
13347  << m_cli << std::endl
13348  << "For more detailed usage please see the project docs\n" << std::endl;
13349  }
13350  void Session::libIdentify() {
13351  Catch::cout()
13352  << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
13353  << std::left << std::setw(16) << "category: " << "testframework\n"
13354  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
13355  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
13356  }
13357 
13358  int Session::applyCommandLine( int argc, char const * const * argv ) {
13359  if( m_startupExceptions )
13360  return 1;
13361 
13362  auto result = m_cli.parse( clara::Args( argc, argv ) );
13363  if( !result ) {
13364  config();
13365  getCurrentMutableContext().setConfig(m_config);
13366  Catch::cerr()
13367  << Colour( Colour::Red )
13368  << "\nError(s) in input:\n"
13369  << Column( result.errorMessage() ).indent( 2 )
13370  << "\n\n";
13371  Catch::cerr() << "Run with -? for usage\n" << std::endl;
13372  return MaxExitCode;
13373  }
13374 
13375  if( m_configData.showHelp )
13376  showHelp();
13377  if( m_configData.libIdentify )
13378  libIdentify();
13379  m_config.reset();
13380  return 0;
13381  }
13382 
13383 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13384  int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
13385 
13386  char **utf8Argv = new char *[ argc ];
13387 
13388  for ( int i = 0; i < argc; ++i ) {
13389  int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
13390 
13391  utf8Argv[ i ] = new char[ bufSize ];
13392 
13393  WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
13394  }
13395 
13396  int returnCode = applyCommandLine( argc, utf8Argv );
13397 
13398  for ( int i = 0; i < argc; ++i )
13399  delete [] utf8Argv[ i ];
13400 
13401  delete [] utf8Argv;
13402 
13403  return returnCode;
13404  }
13405 #endif
13406 
13407  void Session::useConfigData( ConfigData const& configData ) {
13408  m_configData = configData;
13409  m_config.reset();
13410  }
13411 
13412  int Session::run() {
13413  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
13414  Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
13415  static_cast<void>(std::getchar());
13416  }
13417  int exitCode = runInternal();
13418  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
13419  Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
13420  static_cast<void>(std::getchar());
13421  }
13422  return exitCode;
13423  }
13424 
13425  clara::Parser const& Session::cli() const {
13426  return m_cli;
13427  }
13428  void Session::cli( clara::Parser const& newParser ) {
13429  m_cli = newParser;
13430  }
13431  ConfigData& Session::configData() {
13432  return m_configData;
13433  }
13434  Config& Session::config() {
13435  if( !m_config )
13436  m_config = std::make_shared<Config>( m_configData );
13437  return *m_config;
13438  }
13439 
13440  int Session::runInternal() {
13441  if( m_startupExceptions )
13442  return 1;
13443 
13444  if (m_configData.showHelp || m_configData.libIdentify) {
13445  return 0;
13446  }
13447 
13448  CATCH_TRY {
13449  config(); // Force config to be constructed
13450 
13451  seedRng( *m_config );
13452 
13453  if( m_configData.filenamesAsTags )
13454  applyFilenamesAsTags( *m_config );
13455 
13456  // Handle list request
13457  if( Option<std::size_t> listed = list( m_config ) )
13458  return static_cast<int>( *listed );
13459 
13460  TestGroup tests { m_config };
13461  auto const totals = tests.execute();
13462 
13463  if( m_config->warnAboutNoTests() && totals.error == -1 )
13464  return 2;
13465 
13466  // Note that on unices only the lower 8 bits are usually used, clamping
13467  // the return value to 255 prevents false negative when some multiple
13468  // of 256 tests has failed
13469  return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
13470  }
13471 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13472  catch( std::exception& ex ) {
13473  Catch::cerr() << ex.what() << std::endl;
13474  return MaxExitCode;
13475  }
13476 #endif
13477  }
13478 
13479 } // end namespace Catch
13480 // end catch_session.cpp
13481 // start catch_singletons.cpp
13482 
13483 #include <vector>
13484 
13485 namespace Catch {
13486 
13487  namespace {
13488  static auto getSingletons() -> std::vector<ISingleton*>*& {
13489  static std::vector<ISingleton*>* g_singletons = nullptr;
13490  if( !g_singletons )
13491  g_singletons = new std::vector<ISingleton*>();
13492  return g_singletons;
13493  }
13494  }
13495 
13496  ISingleton::~ISingleton() {}
13497 
13498  void addSingleton(ISingleton* singleton ) {
13499  getSingletons()->push_back( singleton );
13500  }
13501  void cleanupSingletons() {
13502  auto& singletons = getSingletons();
13503  for( auto singleton : *singletons )
13504  delete singleton;
13505  delete singletons;
13506  singletons = nullptr;
13507  }
13508 
13509 } // namespace Catch
13510 // end catch_singletons.cpp
13511 // start catch_startup_exception_registry.cpp
13512 
13513 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13514 namespace Catch {
13515 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
13516  CATCH_TRY {
13517  m_exceptions.push_back(exception);
13518  } CATCH_CATCH_ALL {
13519  // If we run out of memory during start-up there's really not a lot more we can do about it
13520  std::terminate();
13521  }
13522  }
13523 
13524  std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
13525  return m_exceptions;
13526  }
13527 
13528 } // end namespace Catch
13529 #endif
13530 // end catch_startup_exception_registry.cpp
13531 // start catch_stream.cpp
13532 
13533 #include <cstdio>
13534 #include <iostream>
13535 #include <fstream>
13536 #include <sstream>
13537 #include <vector>
13538 #include <memory>
13539 
13540 namespace Catch {
13541 
13542  Catch::IStream::~IStream() = default;
13543 
13544  namespace Detail { namespace {
13545  template<typename WriterF, std::size_t bufferSize=256>
13546  class StreamBufImpl : public std::streambuf {
13547  char data[bufferSize];
13548  WriterF m_writer;
13549 
13550  public:
13551  StreamBufImpl() {
13552  setp( data, data + sizeof(data) );
13553  }
13554 
13555  ~StreamBufImpl() noexcept {
13556  StreamBufImpl::sync();
13557  }
13558 
13559  private:
13560  int overflow( int c ) override {
13561  sync();
13562 
13563  if( c != EOF ) {
13564  if( pbase() == epptr() )
13565  m_writer( std::string( 1, static_cast<char>( c ) ) );
13566  else
13567  sputc( static_cast<char>( c ) );
13568  }
13569  return 0;
13570  }
13571 
13572  int sync() override {
13573  if( pbase() != pptr() ) {
13574  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
13575  setp( pbase(), epptr() );
13576  }
13577  return 0;
13578  }
13579  };
13580 
13582 
13584 
13585  void operator()( std::string const&str ) {
13586  writeToDebugConsole( str );
13587  }
13588  };
13589 
13591 
13592  class FileStream : public IStream {
13593  mutable std::ofstream m_ofs;
13594  public:
13595  FileStream( StringRef filename ) {
13596  m_ofs.open( filename.c_str() );
13597  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
13598  }
13599  ~FileStream() override = default;
13600  public: // IStream
13601  std::ostream& stream() const override {
13602  return m_ofs;
13603  }
13604  };
13605 
13607 
13608  class CoutStream : public IStream {
13609  mutable std::ostream m_os;
13610  public:
13611  // Store the streambuf from cout up-front because
13612  // cout may get redirected when running tests
13613  CoutStream() : m_os( Catch::cout().rdbuf() ) {}
13614  ~CoutStream() override = default;
13615 
13616  public: // IStream
13617  std::ostream& stream() const override { return m_os; }
13618  };
13619 
13621 
13622  class DebugOutStream : public IStream {
13623  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
13624  mutable std::ostream m_os;
13625  public:
13626  DebugOutStream()
13627  : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
13628  m_os( m_streamBuf.get() )
13629  {}
13630 
13631  ~DebugOutStream() override = default;
13632 
13633  public: // IStream
13634  std::ostream& stream() const override { return m_os; }
13635  };
13636 
13637  }} // namespace anon::detail
13638 
13640 
13641  auto makeStream( StringRef const &filename ) -> IStream const* {
13642  if( filename.empty() )
13643  return new Detail::CoutStream();
13644  else if( filename[0] == '%' ) {
13645  if( filename == "%debug" )
13646  return new Detail::DebugOutStream();
13647  else
13648  CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
13649  }
13650  else
13651  return new Detail::FileStream( filename );
13652  }
13653 
13654  // This class encapsulates the idea of a pool of ostringstreams that can be reused.
13655  struct StringStreams {
13656  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
13657  std::vector<std::size_t> m_unused;
13658  std::ostringstream m_referenceStream; // Used for copy state/ flags from
13659 
13660  auto add() -> std::size_t {
13661  if( m_unused.empty() ) {
13662  m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
13663  return m_streams.size()-1;
13664  }
13665  else {
13666  auto index = m_unused.back();
13667  m_unused.pop_back();
13668  return index;
13669  }
13670  }
13671 
13672  void release( std::size_t index ) {
13673  m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
13674  m_unused.push_back(index);
13675  }
13676  };
13677 
13678  ReusableStringStream::ReusableStringStream()
13679  : m_index( Singleton<StringStreams>::getMutable().add() ),
13680  m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
13681  {}
13682 
13683  ReusableStringStream::~ReusableStringStream() {
13684  static_cast<std::ostringstream*>( m_oss )->str("");
13685  m_oss->clear();
13686  Singleton<StringStreams>::getMutable().release( m_index );
13687  }
13688 
13689  auto ReusableStringStream::str() const -> std::string {
13690  return static_cast<std::ostringstream*>( m_oss )->str();
13691  }
13692 
13694 
13695 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
13696  std::ostream& cout() { return std::cout; }
13697  std::ostream& cerr() { return std::cerr; }
13698  std::ostream& clog() { return std::clog; }
13699 #endif
13700 }
13701 // end catch_stream.cpp
13702 // start catch_string_manip.cpp
13703 
13704 #include <algorithm>
13705 #include <ostream>
13706 #include <cstring>
13707 #include <cctype>
13708 #include <vector>
13709 
13710 namespace Catch {
13711 
13712  namespace {
13713  char toLowerCh(char c) {
13714  return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
13715  }
13716  }
13717 
13718  bool startsWith( std::string const& s, std::string const& prefix ) {
13719  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
13720  }
13721  bool startsWith( std::string const& s, char prefix ) {
13722  return !s.empty() && s[0] == prefix;
13723  }
13724  bool endsWith( std::string const& s, std::string const& suffix ) {
13725  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
13726  }
13727  bool endsWith( std::string const& s, char suffix ) {
13728  return !s.empty() && s[s.size()-1] == suffix;
13729  }
13730  bool contains( std::string const& s, std::string const& infix ) {
13731  return s.find( infix ) != std::string::npos;
13732  }
13733  void toLowerInPlace( std::string& s ) {
13734  std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
13735  }
13736  std::string toLower( std::string const& s ) {
13737  std::string lc = s;
13738  toLowerInPlace( lc );
13739  return lc;
13740  }
13741  std::string trim( std::string const& str ) {
13742  static char const* whitespaceChars = "\n\r\t ";
13743  std::string::size_type start = str.find_first_not_of( whitespaceChars );
13744  std::string::size_type end = str.find_last_not_of( whitespaceChars );
13745 
13746  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
13747  }
13748 
13749  StringRef trim(StringRef ref) {
13750  const auto is_ws = [](char c) {
13751  return c == ' ' || c == '\t' || c == '\n' || c == '\r';
13752  };
13753  size_t real_begin = 0;
13754  while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
13755  size_t real_end = ref.size();
13756  while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
13757 
13758  return ref.substr(real_begin, real_end - real_begin);
13759  }
13760 
13761  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
13762  bool replaced = false;
13763  std::size_t i = str.find( replaceThis );
13764  while( i != std::string::npos ) {
13765  replaced = true;
13766  str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
13767  if( i < str.size()-withThis.size() )
13768  i = str.find( replaceThis, i+withThis.size() );
13769  else
13770  i = std::string::npos;
13771  }
13772  return replaced;
13773  }
13774 
13775  std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
13776  std::vector<StringRef> subStrings;
13777  std::size_t start = 0;
13778  for(std::size_t pos = 0; pos < str.size(); ++pos ) {
13779  if( str[pos] == delimiter ) {
13780  if( pos - start > 1 )
13781  subStrings.push_back( str.substr( start, pos-start ) );
13782  start = pos+1;
13783  }
13784  }
13785  if( start < str.size() )
13786  subStrings.push_back( str.substr( start, str.size()-start ) );
13787  return subStrings;
13788  }
13789 
13790  pluralise::pluralise( std::size_t count, std::string const& label )
13791  : m_count( count ),
13792  m_label( label )
13793  {}
13794 
13795  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
13796  os << pluraliser.m_count << ' ' << pluraliser.m_label;
13797  if( pluraliser.m_count != 1 )
13798  os << 's';
13799  return os;
13800  }
13801 
13802 }
13803 // end catch_string_manip.cpp
13804 // start catch_stringref.cpp
13805 
13806 #include <algorithm>
13807 #include <ostream>
13808 #include <cstring>
13809 #include <cstdint>
13810 
13811 namespace Catch {
13812  StringRef::StringRef( char const* rawChars ) noexcept
13813  : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
13814  {}
13815 
13816  auto StringRef::c_str() const -> char const* {
13817  CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
13818  return m_start;
13819  }
13820  auto StringRef::data() const noexcept -> char const* {
13821  return m_start;
13822  }
13823 
13824  auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
13825  if (start < m_size) {
13826  return StringRef(m_start + start, (std::min)(m_size - start, size));
13827  } else {
13828  return StringRef();
13829  }
13830  }
13831  auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
13832  return m_size == other.m_size
13833  && (std::memcmp( m_start, other.m_start, m_size ) == 0);
13834  }
13835 
13836  auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
13837  return os.write(str.data(), str.size());
13838  }
13839 
13840  auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
13841  lhs.append(rhs.data(), rhs.size());
13842  return lhs;
13843  }
13844 
13845 } // namespace Catch
13846 // end catch_stringref.cpp
13847 // start catch_tag_alias.cpp
13848 
13849 namespace Catch {
13850  TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
13851 }
13852 // end catch_tag_alias.cpp
13853 // start catch_tag_alias_autoregistrar.cpp
13854 
13855 namespace Catch {
13856 
13857  RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
13858  CATCH_TRY {
13859  getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
13860  } CATCH_CATCH_ALL {
13861  // Do not throw when constructing global objects, instead register the exception to be processed later
13862  getMutableRegistryHub().registerStartupException();
13863  }
13864  }
13865 
13866 }
13867 // end catch_tag_alias_autoregistrar.cpp
13868 // start catch_tag_alias_registry.cpp
13869 
13870 #include <sstream>
13871 
13872 namespace Catch {
13873 
13874  TagAliasRegistry::~TagAliasRegistry() {}
13875 
13876  TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
13877  auto it = m_registry.find( alias );
13878  if( it != m_registry.end() )
13879  return &(it->second);
13880  else
13881  return nullptr;
13882  }
13883 
13884  std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
13885  std::string expandedTestSpec = unexpandedTestSpec;
13886  for( auto const& registryKvp : m_registry ) {
13887  std::size_t pos = expandedTestSpec.find( registryKvp.first );
13888  if( pos != std::string::npos ) {
13889  expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
13890  registryKvp.second.tag +
13891  expandedTestSpec.substr( pos + registryKvp.first.size() );
13892  }
13893  }
13894  return expandedTestSpec;
13895  }
13896 
13897  void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
13898  CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
13899  "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
13900 
13901  CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
13902  "error: tag alias, '" << alias << "' already registered.\n"
13903  << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
13904  << "\tRedefined at: " << lineInfo );
13905  }
13906 
13907  ITagAliasRegistry::~ITagAliasRegistry() {}
13908 
13909  ITagAliasRegistry const& ITagAliasRegistry::get() {
13910  return getRegistryHub().getTagAliasRegistry();
13911  }
13912 
13913 } // end namespace Catch
13914 // end catch_tag_alias_registry.cpp
13915 // start catch_test_case_info.cpp
13916 
13917 #include <cctype>
13918 #include <exception>
13919 #include <algorithm>
13920 #include <sstream>
13921 
13922 namespace Catch {
13923 
13924  namespace {
13925  TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
13926  if( startsWith( tag, '.' ) ||
13927  tag == "!hide" )
13928  return TestCaseInfo::IsHidden;
13929  else if( tag == "!throws" )
13930  return TestCaseInfo::Throws;
13931  else if( tag == "!shouldfail" )
13932  return TestCaseInfo::ShouldFail;
13933  else if( tag == "!mayfail" )
13934  return TestCaseInfo::MayFail;
13935  else if( tag == "!nonportable" )
13936  return TestCaseInfo::NonPortable;
13937  else if( tag == "!benchmark" )
13938  return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
13939  else
13940  return TestCaseInfo::None;
13941  }
13942  bool isReservedTag( std::string const& tag ) {
13943  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
13944  }
13945  void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
13946  CATCH_ENFORCE( !isReservedTag(tag),
13947  "Tag name: [" << tag << "] is not allowed.\n"
13948  << "Tag names starting with non alphanumeric characters are reserved\n"
13949  << _lineInfo );
13950  }
13951  }
13952 
13953  TestCase makeTestCase( ITestInvoker* _testCase,
13954  std::string const& _className,
13955  NameAndTags const& nameAndTags,
13956  SourceLineInfo const& _lineInfo )
13957  {
13958  bool isHidden = false;
13959 
13960  // Parse out tags
13961  std::vector<std::string> tags;
13962  std::string desc, tag;
13963  bool inTag = false;
13964  for (char c : nameAndTags.tags) {
13965  if( !inTag ) {
13966  if( c == '[' )
13967  inTag = true;
13968  else
13969  desc += c;
13970  }
13971  else {
13972  if( c == ']' ) {
13973  TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
13974  if( ( prop & TestCaseInfo::IsHidden ) != 0 )
13975  isHidden = true;
13976  else if( prop == TestCaseInfo::None )
13977  enforceNotReservedTag( tag, _lineInfo );
13978 
13979  // Merged hide tags like `[.approvals]` should be added as
13980  // `[.][approvals]`. The `[.]` is added at later point, so
13981  // we only strip the prefix
13982  if (startsWith(tag, '.') && tag.size() > 1) {
13983  tag.erase(0, 1);
13984  }
13985  tags.push_back( tag );
13986  tag.clear();
13987  inTag = false;
13988  }
13989  else
13990  tag += c;
13991  }
13992  }
13993  if( isHidden ) {
13994  // Add all "hidden" tags to make them behave identically
13995  tags.insert( tags.end(), { ".", "!hide" } );
13996  }
13997 
13998  TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
13999  return TestCase( _testCase, std::move(info) );
14000  }
14001 
14002  void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
14003  std::sort(begin(tags), end(tags));
14004  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
14005  testCaseInfo.lcaseTags.clear();
14006 
14007  for( auto const& tag : tags ) {
14008  std::string lcaseTag = toLower( tag );
14009  testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
14010  testCaseInfo.lcaseTags.push_back( lcaseTag );
14011  }
14012  testCaseInfo.tags = std::move(tags);
14013  }
14014 
14015  TestCaseInfo::TestCaseInfo( std::string const& _name,
14016  std::string const& _className,
14017  std::string const& _description,
14018  std::vector<std::string> const& _tags,
14019  SourceLineInfo const& _lineInfo )
14020  : name( _name ),
14021  className( _className ),
14022  description( _description ),
14023  lineInfo( _lineInfo ),
14024  properties( None )
14025  {
14026  setTags( *this, _tags );
14027  }
14028 
14029  bool TestCaseInfo::isHidden() const {
14030  return ( properties & IsHidden ) != 0;
14031  }
14032  bool TestCaseInfo::throws() const {
14033  return ( properties & Throws ) != 0;
14034  }
14035  bool TestCaseInfo::okToFail() const {
14036  return ( properties & (ShouldFail | MayFail ) ) != 0;
14037  }
14038  bool TestCaseInfo::expectedToFail() const {
14039  return ( properties & (ShouldFail ) ) != 0;
14040  }
14041 
14042  std::string TestCaseInfo::tagsAsString() const {
14043  std::string ret;
14044  // '[' and ']' per tag
14045  std::size_t full_size = 2 * tags.size();
14046  for (const auto& tag : tags) {
14047  full_size += tag.size();
14048  }
14049  ret.reserve(full_size);
14050  for (const auto& tag : tags) {
14051  ret.push_back('[');
14052  ret.append(tag);
14053  ret.push_back(']');
14054  }
14055 
14056  return ret;
14057  }
14058 
14059  TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
14060 
14061  TestCase TestCase::withName( std::string const& _newName ) const {
14062  TestCase other( *this );
14063  other.name = _newName;
14064  return other;
14065  }
14066 
14067  void TestCase::invoke() const {
14068  test->invoke();
14069  }
14070 
14071  bool TestCase::operator == ( TestCase const& other ) const {
14072  return test.get() == other.test.get() &&
14073  name == other.name &&
14074  className == other.className;
14075  }
14076 
14077  bool TestCase::operator < ( TestCase const& other ) const {
14078  return name < other.name;
14079  }
14080 
14081  TestCaseInfo const& TestCase::getTestCaseInfo() const
14082  {
14083  return *this;
14084  }
14085 
14086 } // end namespace Catch
14087 // end catch_test_case_info.cpp
14088 // start catch_test_case_registry_impl.cpp
14089 
14090 #include <algorithm>
14091 #include <sstream>
14092 
14093 namespace Catch {
14094 
14095  namespace {
14096  struct TestHasher {
14097  explicit TestHasher(Catch::SimplePcg32& rng) {
14098  basis = rng();
14099  basis <<= 32;
14100  basis |= rng();
14101  }
14102 
14103  uint64_t basis;
14104 
14105  uint64_t operator()(TestCase const& t) const {
14106  // Modified FNV-1a hash
14107  static constexpr uint64_t prime = 1099511628211;
14108  uint64_t hash = basis;
14109  for (const char c : t.name) {
14110  hash ^= c;
14111  hash *= prime;
14112  }
14113  return hash;
14114  }
14115  };
14116  } // end unnamed namespace
14117 
14118  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
14119  switch( config.runOrder() ) {
14120  case RunTests::InDeclarationOrder:
14121  // already in declaration order
14122  break;
14123 
14124  case RunTests::InLexicographicalOrder: {
14125  std::vector<TestCase> sorted = unsortedTestCases;
14126  std::sort( sorted.begin(), sorted.end() );
14127  return sorted;
14128  }
14129 
14130  case RunTests::InRandomOrder: {
14131  seedRng( config );
14132  TestHasher h( rng() );
14133 
14134  using hashedTest = std::pair<uint64_t, TestCase const*>;
14135  std::vector<hashedTest> indexed_tests;
14136  indexed_tests.reserve( unsortedTestCases.size() );
14137 
14138  for (auto const& testCase : unsortedTestCases) {
14139  indexed_tests.emplace_back(h(testCase), &testCase);
14140  }
14141 
14142  std::sort(indexed_tests.begin(), indexed_tests.end(),
14143  [](hashedTest const& lhs, hashedTest const& rhs) {
14144  if (lhs.first == rhs.first) {
14145  return lhs.second->name < rhs.second->name;
14146  }
14147  return lhs.first < rhs.first;
14148  });
14149 
14150  std::vector<TestCase> sorted;
14151  sorted.reserve( indexed_tests.size() );
14152 
14153  for (auto const& hashed : indexed_tests) {
14154  sorted.emplace_back(*hashed.second);
14155  }
14156 
14157  return sorted;
14158  }
14159  }
14160  return unsortedTestCases;
14161  }
14162 
14163  bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
14164  return !testCase.throws() || config.allowThrows();
14165  }
14166 
14167  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
14168  return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
14169  }
14170 
14171  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
14172  std::set<TestCase> seenFunctions;
14173  for( auto const& function : functions ) {
14174  auto prev = seenFunctions.insert( function );
14175  CATCH_ENFORCE( prev.second,
14176  "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
14177  << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
14178  << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
14179  }
14180  }
14181 
14182  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
14183  std::vector<TestCase> filtered;
14184  filtered.reserve( testCases.size() );
14185  for (auto const& testCase : testCases) {
14186  if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
14187  (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
14188  filtered.push_back(testCase);
14189  }
14190  }
14191  return filtered;
14192  }
14193  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
14194  return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
14195  }
14196 
14197  void TestRegistry::registerTest( TestCase const& testCase ) {
14198  std::string name = testCase.getTestCaseInfo().name;
14199  if( name.empty() ) {
14200  ReusableStringStream rss;
14201  rss << "Anonymous test case " << ++m_unnamedCount;
14202  return registerTest( testCase.withName( rss.str() ) );
14203  }
14204  m_functions.push_back( testCase );
14205  }
14206 
14207  std::vector<TestCase> const& TestRegistry::getAllTests() const {
14208  return m_functions;
14209  }
14210  std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
14211  if( m_sortedFunctions.empty() )
14212  enforceNoDuplicateTestCases( m_functions );
14213 
14214  if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
14215  m_sortedFunctions = sortTests( config, m_functions );
14216  m_currentSortOrder = config.runOrder();
14217  }
14218  return m_sortedFunctions;
14219  }
14220 
14222  TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
14223 
14224  void TestInvokerAsFunction::invoke() const {
14225  m_testAsFunction();
14226  }
14227 
14228  std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
14229  std::string className(classOrQualifiedMethodName);
14230  if( startsWith( className, '&' ) )
14231  {
14232  std::size_t lastColons = className.rfind( "::" );
14233  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
14234  if( penultimateColons == std::string::npos )
14235  penultimateColons = 1;
14236  className = className.substr( penultimateColons, lastColons-penultimateColons );
14237  }
14238  return className;
14239  }
14240 
14241 } // end namespace Catch
14242 // end catch_test_case_registry_impl.cpp
14243 // start catch_test_case_tracker.cpp
14244 
14245 #include <algorithm>
14246 #include <cassert>
14247 #include <stdexcept>
14248 #include <memory>
14249 #include <sstream>
14250 
14251 #if defined(__clang__)
14252 # pragma clang diagnostic push
14253 # pragma clang diagnostic ignored "-Wexit-time-destructors"
14254 #endif
14255 
14256 namespace Catch {
14257 namespace TestCaseTracking {
14258 
14259  NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
14260  : name( _name ),
14261  location( _location )
14262  {}
14263 
14264  ITracker::~ITracker() = default;
14265 
14266  ITracker& TrackerContext::startRun() {
14267  m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
14268  m_currentTracker = nullptr;
14269  m_runState = Executing;
14270  return *m_rootTracker;
14271  }
14272 
14273  void TrackerContext::endRun() {
14274  m_rootTracker.reset();
14275  m_currentTracker = nullptr;
14276  m_runState = NotStarted;
14277  }
14278 
14279  void TrackerContext::startCycle() {
14280  m_currentTracker = m_rootTracker.get();
14281  m_runState = Executing;
14282  }
14283  void TrackerContext::completeCycle() {
14284  m_runState = CompletedCycle;
14285  }
14286 
14287  bool TrackerContext::completedCycle() const {
14288  return m_runState == CompletedCycle;
14289  }
14290  ITracker& TrackerContext::currentTracker() {
14291  return *m_currentTracker;
14292  }
14293  void TrackerContext::setCurrentTracker( ITracker* tracker ) {
14294  m_currentTracker = tracker;
14295  }
14296 
14297  TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
14298  ITracker(nameAndLocation),
14299  m_ctx( ctx ),
14300  m_parent( parent )
14301  {}
14302 
14303  bool TrackerBase::isComplete() const {
14304  return m_runState == CompletedSuccessfully || m_runState == Failed;
14305  }
14306  bool TrackerBase::isSuccessfullyCompleted() const {
14307  return m_runState == CompletedSuccessfully;
14308  }
14309  bool TrackerBase::isOpen() const {
14310  return m_runState != NotStarted && !isComplete();
14311  }
14312  bool TrackerBase::hasChildren() const {
14313  return !m_children.empty();
14314  }
14315 
14316  void TrackerBase::addChild( ITrackerPtr const& child ) {
14317  m_children.push_back( child );
14318  }
14319 
14320  ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
14321  auto it = std::find_if( m_children.begin(), m_children.end(),
14322  [&nameAndLocation]( ITrackerPtr const& tracker ){
14323  return
14324  tracker->nameAndLocation().location == nameAndLocation.location &&
14325  tracker->nameAndLocation().name == nameAndLocation.name;
14326  } );
14327  return( it != m_children.end() )
14328  ? *it
14329  : nullptr;
14330  }
14331  ITracker& TrackerBase::parent() {
14332  assert( m_parent ); // Should always be non-null except for root
14333  return *m_parent;
14334  }
14335 
14336  void TrackerBase::openChild() {
14337  if( m_runState != ExecutingChildren ) {
14338  m_runState = ExecutingChildren;
14339  if( m_parent )
14340  m_parent->openChild();
14341  }
14342  }
14343 
14344  bool TrackerBase::isSectionTracker() const { return false; }
14345  bool TrackerBase::isGeneratorTracker() const { return false; }
14346 
14347  void TrackerBase::open() {
14348  m_runState = Executing;
14349  moveToThis();
14350  if( m_parent )
14351  m_parent->openChild();
14352  }
14353 
14354  void TrackerBase::close() {
14355 
14356  // Close any still open children (e.g. generators)
14357  while( &m_ctx.currentTracker() != this )
14358  m_ctx.currentTracker().close();
14359 
14360  switch( m_runState ) {
14361  case NeedsAnotherRun:
14362  break;
14363 
14364  case Executing:
14365  m_runState = CompletedSuccessfully;
14366  break;
14367  case ExecutingChildren:
14368  if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
14369  m_runState = CompletedSuccessfully;
14370  break;
14371 
14372  case NotStarted:
14373  case CompletedSuccessfully:
14374  case Failed:
14375  CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
14376 
14377  default:
14378  CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
14379  }
14380  moveToParent();
14381  m_ctx.completeCycle();
14382  }
14383  void TrackerBase::fail() {
14384  m_runState = Failed;
14385  if( m_parent )
14386  m_parent->markAsNeedingAnotherRun();
14387  moveToParent();
14388  m_ctx.completeCycle();
14389  }
14390  void TrackerBase::markAsNeedingAnotherRun() {
14391  m_runState = NeedsAnotherRun;
14392  }
14393 
14394  void TrackerBase::moveToParent() {
14395  assert( m_parent );
14396  m_ctx.setCurrentTracker( m_parent );
14397  }
14398  void TrackerBase::moveToThis() {
14399  m_ctx.setCurrentTracker( this );
14400  }
14401 
14402  SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
14403  : TrackerBase( nameAndLocation, ctx, parent ),
14404  m_trimmed_name(trim(nameAndLocation.name))
14405  {
14406  if( parent ) {
14407  while( !parent->isSectionTracker() )
14408  parent = &parent->parent();
14409 
14410  SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
14411  addNextFilters( parentSection.m_filters );
14412  }
14413  }
14414 
14415  bool SectionTracker::isComplete() const {
14416  bool complete = true;
14417 
14418  if (m_filters.empty()
14419  || m_filters[0] == ""
14420  || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
14421  complete = TrackerBase::isComplete();
14422  }
14423  return complete;
14424  }
14425 
14426  bool SectionTracker::isSectionTracker() const { return true; }
14427 
14428  SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
14429  std::shared_ptr<SectionTracker> section;
14430 
14431  ITracker& currentTracker = ctx.currentTracker();
14432  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
14433  assert( childTracker );
14434  assert( childTracker->isSectionTracker() );
14435  section = std::static_pointer_cast<SectionTracker>( childTracker );
14436  }
14437  else {
14438  section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
14439  currentTracker.addChild( section );
14440  }
14441  if( !ctx.completedCycle() )
14442  section->tryOpen();
14443  return *section;
14444  }
14445 
14446  void SectionTracker::tryOpen() {
14447  if( !isComplete() )
14448  open();
14449  }
14450 
14451  void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
14452  if( !filters.empty() ) {
14453  m_filters.reserve( m_filters.size() + filters.size() + 2 );
14454  m_filters.emplace_back(""); // Root - should never be consulted
14455  m_filters.emplace_back(""); // Test Case - not a section filter
14456  m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
14457  }
14458  }
14459  void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
14460  if( filters.size() > 1 )
14461  m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
14462  }
14463 
14464 } // namespace TestCaseTracking
14465 
14466 using TestCaseTracking::ITracker;
14467 using TestCaseTracking::TrackerContext;
14468 using TestCaseTracking::SectionTracker;
14469 
14470 } // namespace Catch
14471 
14472 #if defined(__clang__)
14473 # pragma clang diagnostic pop
14474 #endif
14475 // end catch_test_case_tracker.cpp
14476 // start catch_test_registry.cpp
14477 
14478 namespace Catch {
14479 
14480  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
14481  return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
14482  }
14483 
14484  NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
14485 
14486  AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
14487  CATCH_TRY {
14488  getMutableRegistryHub()
14489  .registerTest(
14490  makeTestCase(
14491  invoker,
14492  extractClassName( classOrMethod ),
14493  nameAndTags,
14494  lineInfo));
14495  } CATCH_CATCH_ALL {
14496  // Do not throw when constructing global objects, instead register the exception to be processed later
14497  getMutableRegistryHub().registerStartupException();
14498  }
14499  }
14500 
14501  AutoReg::~AutoReg() = default;
14502 }
14503 // end catch_test_registry.cpp
14504 // start catch_test_spec.cpp
14505 
14506 #include <algorithm>
14507 #include <string>
14508 #include <vector>
14509 #include <memory>
14510 
14511 namespace Catch {
14512 
14513  TestSpec::Pattern::Pattern( std::string const& name )
14514  : m_name( name )
14515  {}
14516 
14517  TestSpec::Pattern::~Pattern() = default;
14518 
14519  std::string const& TestSpec::Pattern::name() const {
14520  return m_name;
14521  }
14522 
14523  TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
14524  : Pattern( filterString )
14525  , m_wildcardPattern( toLower( name ), CaseSensitive::No )
14526  {}
14527 
14528  bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
14529  return m_wildcardPattern.matches( testCase.name );
14530  }
14531 
14532  TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
14533  : Pattern( filterString )
14534  , m_tag( toLower( tag ) )
14535  {}
14536 
14537  bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
14538  return std::find(begin(testCase.lcaseTags),
14539  end(testCase.lcaseTags),
14540  m_tag) != end(testCase.lcaseTags);
14541  }
14542 
14543  TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
14544  : Pattern( underlyingPattern->name() )
14545  , m_underlyingPattern( underlyingPattern )
14546  {}
14547 
14548  bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
14549  return !m_underlyingPattern->matches( testCase );
14550  }
14551 
14552  bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
14553  return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
14554  }
14555 
14556  std::string TestSpec::Filter::name() const {
14557  std::string name;
14558  for( auto const& p : m_patterns )
14559  name += p->name();
14560  return name;
14561  }
14562 
14563  bool TestSpec::hasFilters() const {
14564  return !m_filters.empty();
14565  }
14566 
14567  bool TestSpec::matches( TestCaseInfo const& testCase ) const {
14568  return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
14569  }
14570 
14571  TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
14572  {
14573  Matches matches( m_filters.size() );
14574  std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
14575  std::vector<TestCase const*> currentMatches;
14576  for( auto const& test : testCases )
14577  if( isThrowSafe( test, config ) && filter.matches( test ) )
14578  currentMatches.emplace_back( &test );
14579  return FilterMatch{ filter.name(), currentMatches };
14580  } );
14581  return matches;
14582  }
14583 
14584  const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
14585  return (m_invalidArgs);
14586  }
14587 
14588 }
14589 // end catch_test_spec.cpp
14590 // start catch_test_spec_parser.cpp
14591 
14592 namespace Catch {
14593 
14594  TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
14595 
14596  TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
14597  m_mode = None;
14598  m_exclusion = false;
14599  m_arg = m_tagAliases->expandAliases( arg );
14600  m_escapeChars.clear();
14601  m_substring.reserve(m_arg.size());
14602  m_patternName.reserve(m_arg.size());
14603  m_realPatternPos = 0;
14604 
14605  for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
14606  //if visitChar fails
14607  if( !visitChar( m_arg[m_pos] ) ){
14608  m_testSpec.m_invalidArgs.push_back(arg);
14609  break;
14610  }
14611  endMode();
14612  return *this;
14613  }
14614  TestSpec TestSpecParser::testSpec() {
14615  addFilter();
14616  return m_testSpec;
14617  }
14618  bool TestSpecParser::visitChar( char c ) {
14619  if( (m_mode != EscapedName) && (c == '\\') ) {
14620  escape();
14621  addCharToPattern(c);
14622  return true;
14623  }else if((m_mode != EscapedName) && (c == ',') ) {
14624  return separate();
14625  }
14626 
14627  switch( m_mode ) {
14628  case None:
14629  if( processNoneChar( c ) )
14630  return true;
14631  break;
14632  case Name:
14633  processNameChar( c );
14634  break;
14635  case EscapedName:
14636  endMode();
14637  addCharToPattern(c);
14638  return true;
14639  default:
14640  case Tag:
14641  case QuotedName:
14642  if( processOtherChar( c ) )
14643  return true;
14644  break;
14645  }
14646 
14647  m_substring += c;
14648  if( !isControlChar( c ) ) {
14649  m_patternName += c;
14650  m_realPatternPos++;
14651  }
14652  return true;
14653  }
14654  // Two of the processing methods return true to signal the caller to return
14655  // without adding the given character to the current pattern strings
14656  bool TestSpecParser::processNoneChar( char c ) {
14657  switch( c ) {
14658  case ' ':
14659  return true;
14660  case '~':
14661  m_exclusion = true;
14662  return false;
14663  case '[':
14664  startNewMode( Tag );
14665  return false;
14666  case '"':
14667  startNewMode( QuotedName );
14668  return false;
14669  default:
14670  startNewMode( Name );
14671  return false;
14672  }
14673  }
14674  void TestSpecParser::processNameChar( char c ) {
14675  if( c == '[' ) {
14676  if( m_substring == "exclude:" )
14677  m_exclusion = true;
14678  else
14679  endMode();
14680  startNewMode( Tag );
14681  }
14682  }
14683  bool TestSpecParser::processOtherChar( char c ) {
14684  if( !isControlChar( c ) )
14685  return false;
14686  m_substring += c;
14687  endMode();
14688  return true;
14689  }
14690  void TestSpecParser::startNewMode( Mode mode ) {
14691  m_mode = mode;
14692  }
14693  void TestSpecParser::endMode() {
14694  switch( m_mode ) {
14695  case Name:
14696  case QuotedName:
14697  return addNamePattern();
14698  case Tag:
14699  return addTagPattern();
14700  case EscapedName:
14701  revertBackToLastMode();
14702  return;
14703  case None:
14704  default:
14705  return startNewMode( None );
14706  }
14707  }
14708  void TestSpecParser::escape() {
14709  saveLastMode();
14710  m_mode = EscapedName;
14711  m_escapeChars.push_back(m_realPatternPos);
14712  }
14713  bool TestSpecParser::isControlChar( char c ) const {
14714  switch( m_mode ) {
14715  default:
14716  return false;
14717  case None:
14718  return c == '~';
14719  case Name:
14720  return c == '[';
14721  case EscapedName:
14722  return true;
14723  case QuotedName:
14724  return c == '"';
14725  case Tag:
14726  return c == '[' || c == ']';
14727  }
14728  }
14729 
14730  void TestSpecParser::addFilter() {
14731  if( !m_currentFilter.m_patterns.empty() ) {
14732  m_testSpec.m_filters.push_back( m_currentFilter );
14733  m_currentFilter = TestSpec::Filter();
14734  }
14735  }
14736 
14737  void TestSpecParser::saveLastMode() {
14738  lastMode = m_mode;
14739  }
14740 
14741  void TestSpecParser::revertBackToLastMode() {
14742  m_mode = lastMode;
14743  }
14744 
14745  bool TestSpecParser::separate() {
14746  if( (m_mode==QuotedName) || (m_mode==Tag) ){
14747  //invalid argument, signal failure to previous scope.
14748  m_mode = None;
14749  m_pos = m_arg.size();
14750  m_substring.clear();
14751  m_patternName.clear();
14752  m_realPatternPos = 0;
14753  return false;
14754  }
14755  endMode();
14756  addFilter();
14757  return true; //success
14758  }
14759 
14760  std::string TestSpecParser::preprocessPattern() {
14761  std::string token = m_patternName;
14762  for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
14763  token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
14764  m_escapeChars.clear();
14765  if (startsWith(token, "exclude:")) {
14766  m_exclusion = true;
14767  token = token.substr(8);
14768  }
14769 
14770  m_patternName.clear();
14771  m_realPatternPos = 0;
14772 
14773  return token;
14774  }
14775 
14776  void TestSpecParser::addNamePattern() {
14777  auto token = preprocessPattern();
14778 
14779  if (!token.empty()) {
14780  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
14781  if (m_exclusion)
14782  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14783  m_currentFilter.m_patterns.push_back(pattern);
14784  }
14785  m_substring.clear();
14786  m_exclusion = false;
14787  m_mode = None;
14788  }
14789 
14790  void TestSpecParser::addTagPattern() {
14791  auto token = preprocessPattern();
14792 
14793  if (!token.empty()) {
14794  // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
14795  // we have to create a separate hide tag and shorten the real one
14796  if (token.size() > 1 && token[0] == '.') {
14797  token.erase(token.begin());
14798  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
14799  if (m_exclusion) {
14800  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14801  }
14802  m_currentFilter.m_patterns.push_back(pattern);
14803  }
14804 
14805  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
14806 
14807  if (m_exclusion) {
14808  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
14809  }
14810  m_currentFilter.m_patterns.push_back(pattern);
14811  }
14812  m_substring.clear();
14813  m_exclusion = false;
14814  m_mode = None;
14815  }
14816 
14817  TestSpec parseTestSpec( std::string const& arg ) {
14818  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
14819  }
14820 
14821 } // namespace Catch
14822 // end catch_test_spec_parser.cpp
14823 // start catch_timer.cpp
14824 
14825 #include <chrono>
14826 
14827 static const uint64_t nanosecondsInSecond = 1000000000;
14828 
14829 namespace Catch {
14830 
14831  auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
14832  return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
14833  }
14834 
14835  namespace {
14836  auto estimateClockResolution() -> uint64_t {
14837  uint64_t sum = 0;
14838  static const uint64_t iterations = 1000000;
14839 
14840  auto startTime = getCurrentNanosecondsSinceEpoch();
14841 
14842  for( std::size_t i = 0; i < iterations; ++i ) {
14843 
14844  uint64_t ticks;
14845  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
14846  do {
14847  ticks = getCurrentNanosecondsSinceEpoch();
14848  } while( ticks == baseTicks );
14849 
14850  auto delta = ticks - baseTicks;
14851  sum += delta;
14852 
14853  // If we have been calibrating for over 3 seconds -- the clock
14854  // is terrible and we should move on.
14855  // TBD: How to signal that the measured resolution is probably wrong?
14856  if (ticks > startTime + 3 * nanosecondsInSecond) {
14857  return sum / ( i + 1u );
14858  }
14859  }
14860 
14861  // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
14862  // - and potentially do more iterations if there's a high variance.
14863  return sum/iterations;
14864  }
14865  }
14866  auto getEstimatedClockResolution() -> uint64_t {
14867  static auto s_resolution = estimateClockResolution();
14868  return s_resolution;
14869  }
14870 
14871  void Timer::start() {
14872  m_nanoseconds = getCurrentNanosecondsSinceEpoch();
14873  }
14874  auto Timer::getElapsedNanoseconds() const -> uint64_t {
14875  return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
14876  }
14877  auto Timer::getElapsedMicroseconds() const -> uint64_t {
14878  return getElapsedNanoseconds()/1000;
14879  }
14880  auto Timer::getElapsedMilliseconds() const -> unsigned int {
14881  return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
14882  }
14883  auto Timer::getElapsedSeconds() const -> double {
14884  return getElapsedMicroseconds()/1000000.0;
14885  }
14886 
14887 } // namespace Catch
14888 // end catch_timer.cpp
14889 // start catch_tostring.cpp
14890 
14891 #if defined(__clang__)
14892 # pragma clang diagnostic push
14893 # pragma clang diagnostic ignored "-Wexit-time-destructors"
14894 # pragma clang diagnostic ignored "-Wglobal-constructors"
14895 #endif
14896 
14897 // Enable specific decls locally
14898 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
14899 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
14900 #endif
14901 
14902 #include <cmath>
14903 #include <iomanip>
14904 
14905 namespace Catch {
14906 
14907 namespace Detail {
14908 
14909  const std::string unprintableString = "{?}";
14910 
14911  namespace {
14912  const int hexThreshold = 255;
14913 
14914  struct Endianness {
14915  enum Arch { Big, Little };
14916 
14917  static Arch which() {
14918  int one = 1;
14919  // If the lowest byte we read is non-zero, we can assume
14920  // that little endian format is used.
14921  auto value = *reinterpret_cast<char*>(&one);
14922  return value ? Little : Big;
14923  }
14924  };
14925  }
14926 
14927  std::string rawMemoryToString( const void *object, std::size_t size ) {
14928  // Reverse order for little endian architectures
14929  int i = 0, end = static_cast<int>( size ), inc = 1;
14930  if( Endianness::which() == Endianness::Little ) {
14931  i = end-1;
14932  end = inc = -1;
14933  }
14934 
14935  unsigned char const *bytes = static_cast<unsigned char const *>(object);
14937  rss << "0x" << std::setfill('0') << std::hex;
14938  for( ; i != end; i += inc )
14939  rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
14940  return rss.str();
14941  }
14942 }
14943 
14944 template<typename T>
14945 std::string fpToString( T value, int precision ) {
14946  if (Catch::isnan(value)) {
14947  return "nan";
14948  }
14949 
14950  ReusableStringStream rss;
14951  rss << std::setprecision( precision )
14952  << std::fixed
14953  << value;
14954  std::string d = rss.str();
14955  std::size_t i = d.find_last_not_of( '0' );
14956  if( i != std::string::npos && i != d.size()-1 ) {
14957  if( d[i] == '.' )
14958  i++;
14959  d = d.substr( 0, i+1 );
14960  }
14961  return d;
14962 }
14963 
14965 //
14966 // Out-of-line defs for full specialization of StringMaker
14967 //
14969 
14970 std::string StringMaker<std::string>::convert(const std::string& str) {
14971  if (!getCurrentContext().getConfig()->showInvisibles()) {
14972  return '"' + str + '"';
14973  }
14974 
14975  std::string s("\"");
14976  for (char c : str) {
14977  switch (c) {
14978  case '\n':
14979  s.append("\\n");
14980  break;
14981  case '\t':
14982  s.append("\\t");
14983  break;
14984  default:
14985  s.push_back(c);
14986  break;
14987  }
14988  }
14989  s.append("\"");
14990  return s;
14991 }
14992 
14993 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
14994 std::string StringMaker<std::string_view>::convert(std::string_view str) {
14995  return ::Catch::Detail::stringify(std::string{ str });
14996 }
14997 #endif
14998 
14999 std::string StringMaker<char const*>::convert(char const* str) {
15000  if (str) {
15001  return ::Catch::Detail::stringify(std::string{ str });
15002  } else {
15003  return{ "{null string}" };
15004  }
15005 }
15006 std::string StringMaker<char*>::convert(char* str) {
15007  if (str) {
15008  return ::Catch::Detail::stringify(std::string{ str });
15009  } else {
15010  return{ "{null string}" };
15011  }
15012 }
15013 
15014 #ifdef CATCH_CONFIG_WCHAR
15015 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
15016  std::string s;
15017  s.reserve(wstr.size());
15018  for (auto c : wstr) {
15019  s += (c <= 0xff) ? static_cast<char>(c) : '?';
15020  }
15021  return ::Catch::Detail::stringify(s);
15022 }
15023 
15024 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15025 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
15026  return StringMaker<std::wstring>::convert(std::wstring(str));
15027 }
15028 # endif
15029 
15030 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
15031  if (str) {
15032  return ::Catch::Detail::stringify(std::wstring{ str });
15033  } else {
15034  return{ "{null string}" };
15035  }
15036 }
15037 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
15038  if (str) {
15039  return ::Catch::Detail::stringify(std::wstring{ str });
15040  } else {
15041  return{ "{null string}" };
15042  }
15043 }
15044 #endif
15045 
15046 #if defined(CATCH_CONFIG_CPP17_BYTE)
15047 #include <cstddef>
15048 std::string StringMaker<std::byte>::convert(std::byte value) {
15049  return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
15050 }
15051 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
15052 
15053 std::string StringMaker<int>::convert(int value) {
15054  return ::Catch::Detail::stringify(static_cast<long long>(value));
15055 }
15056 std::string StringMaker<long>::convert(long value) {
15057  return ::Catch::Detail::stringify(static_cast<long long>(value));
15058 }
15059 std::string StringMaker<long long>::convert(long long value) {
15060  ReusableStringStream rss;
15061  rss << value;
15062  if (value > Detail::hexThreshold) {
15063  rss << " (0x" << std::hex << value << ')';
15064  }
15065  return rss.str();
15066 }
15067 
15068 std::string StringMaker<unsigned int>::convert(unsigned int value) {
15069  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15070 }
15071 std::string StringMaker<unsigned long>::convert(unsigned long value) {
15072  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15073 }
15074 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
15075  ReusableStringStream rss;
15076  rss << value;
15077  if (value > Detail::hexThreshold) {
15078  rss << " (0x" << std::hex << value << ')';
15079  }
15080  return rss.str();
15081 }
15082 
15083 std::string StringMaker<bool>::convert(bool b) {
15084  return b ? "true" : "false";
15085 }
15086 
15087 std::string StringMaker<signed char>::convert(signed char value) {
15088  if (value == '\r') {
15089  return "'\\r'";
15090  } else if (value == '\f') {
15091  return "'\\f'";
15092  } else if (value == '\n') {
15093  return "'\\n'";
15094  } else if (value == '\t') {
15095  return "'\\t'";
15096  } else if ('\0' <= value && value < ' ') {
15097  return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
15098  } else {
15099  char chstr[] = "' '";
15100  chstr[1] = value;
15101  return chstr;
15102  }
15103 }
15104 std::string StringMaker<char>::convert(char c) {
15105  return ::Catch::Detail::stringify(static_cast<signed char>(c));
15106 }
15107 std::string StringMaker<unsigned char>::convert(unsigned char c) {
15108  return ::Catch::Detail::stringify(static_cast<char>(c));
15109 }
15110 
15111 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
15112  return "nullptr";
15113 }
15114 
15115 int StringMaker<float>::precision = 5;
15116 
15117 std::string StringMaker<float>::convert(float value) {
15118  return fpToString(value, precision) + 'f';
15119 }
15120 
15121 int StringMaker<double>::precision = 10;
15122 
15123 std::string StringMaker<double>::convert(double value) {
15124  return fpToString(value, precision);
15125 }
15126 
15127 std::string ratio_string<std::atto>::symbol() { return "a"; }
15128 std::string ratio_string<std::femto>::symbol() { return "f"; }
15129 std::string ratio_string<std::pico>::symbol() { return "p"; }
15130 std::string ratio_string<std::nano>::symbol() { return "n"; }
15131 std::string ratio_string<std::micro>::symbol() { return "u"; }
15132 std::string ratio_string<std::milli>::symbol() { return "m"; }
15133 
15134 } // end namespace Catch
15135 
15136 #if defined(__clang__)
15137 # pragma clang diagnostic pop
15138 #endif
15139 
15140 // end catch_tostring.cpp
15141 // start catch_totals.cpp
15142 
15143 namespace Catch {
15144 
15145  Counts Counts::operator - ( Counts const& other ) const {
15146  Counts diff;
15147  diff.passed = passed - other.passed;
15148  diff.failed = failed - other.failed;
15149  diff.failedButOk = failedButOk - other.failedButOk;
15150  return diff;
15151  }
15152 
15153  Counts& Counts::operator += ( Counts const& other ) {
15154  passed += other.passed;
15155  failed += other.failed;
15156  failedButOk += other.failedButOk;
15157  return *this;
15158  }
15159 
15160  std::size_t Counts::total() const {
15161  return passed + failed + failedButOk;
15162  }
15163  bool Counts::allPassed() const {
15164  return failed == 0 && failedButOk == 0;
15165  }
15166  bool Counts::allOk() const {
15167  return failed == 0;
15168  }
15169 
15170  Totals Totals::operator - ( Totals const& other ) const {
15171  Totals diff;
15172  diff.assertions = assertions - other.assertions;
15173  diff.testCases = testCases - other.testCases;
15174  return diff;
15175  }
15176 
15177  Totals& Totals::operator += ( Totals const& other ) {
15178  assertions += other.assertions;
15179  testCases += other.testCases;
15180  return *this;
15181  }
15182 
15183  Totals Totals::delta( Totals const& prevTotals ) const {
15184  Totals diff = *this - prevTotals;
15185  if( diff.assertions.failed > 0 )
15186  ++diff.testCases.failed;
15187  else if( diff.assertions.failedButOk > 0 )
15188  ++diff.testCases.failedButOk;
15189  else
15190  ++diff.testCases.passed;
15191  return diff;
15192  }
15193 
15194 }
15195 // end catch_totals.cpp
15196 // start catch_uncaught_exceptions.cpp
15197 
15198 #include <exception>
15199 
15200 namespace Catch {
15201  bool uncaught_exceptions() {
15202 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
15203  return false;
15204 #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15205  return std::uncaught_exceptions() > 0;
15206 #else
15207  return std::uncaught_exception();
15208 #endif
15209  }
15210 } // end namespace Catch
15211 // end catch_uncaught_exceptions.cpp
15212 // start catch_version.cpp
15213 
15214 #include <ostream>
15215 
15216 namespace Catch {
15217 
15218  Version::Version
15219  ( unsigned int _majorVersion,
15220  unsigned int _minorVersion,
15221  unsigned int _patchNumber,
15222  char const * const _branchName,
15223  unsigned int _buildNumber )
15224  : majorVersion( _majorVersion ),
15225  minorVersion( _minorVersion ),
15226  patchNumber( _patchNumber ),
15227  branchName( _branchName ),
15228  buildNumber( _buildNumber )
15229  {}
15230 
15231  std::ostream& operator << ( std::ostream& os, Version const& version ) {
15232  os << version.majorVersion << '.'
15233  << version.minorVersion << '.'
15234  << version.patchNumber;
15235  // branchName is never null -> 0th char is \0 if it is empty
15236  if (version.branchName[0]) {
15237  os << '-' << version.branchName
15238  << '.' << version.buildNumber;
15239  }
15240  return os;
15241  }
15242 
15243  Version const& libraryVersion() {
15244  static Version version( 2, 13, 1, "", 0 );
15245  return version;
15246  }
15247 
15248 }
15249 // end catch_version.cpp
15250 // start catch_wildcard_pattern.cpp
15251 
15252 namespace Catch {
15253 
15254  WildcardPattern::WildcardPattern( std::string const& pattern,
15255  CaseSensitive::Choice caseSensitivity )
15256  : m_caseSensitivity( caseSensitivity ),
15257  m_pattern( normaliseString( pattern ) )
15258  {
15259  if( startsWith( m_pattern, '*' ) ) {
15260  m_pattern = m_pattern.substr( 1 );
15261  m_wildcard = WildcardAtStart;
15262  }
15263  if( endsWith( m_pattern, '*' ) ) {
15264  m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
15265  m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
15266  }
15267  }
15268 
15269  bool WildcardPattern::matches( std::string const& str ) const {
15270  switch( m_wildcard ) {
15271  case NoWildcard:
15272  return m_pattern == normaliseString( str );
15273  case WildcardAtStart:
15274  return endsWith( normaliseString( str ), m_pattern );
15275  case WildcardAtEnd:
15276  return startsWith( normaliseString( str ), m_pattern );
15277  case WildcardAtBothEnds:
15278  return contains( normaliseString( str ), m_pattern );
15279  default:
15280  CATCH_INTERNAL_ERROR( "Unknown enum" );
15281  }
15282  }
15283 
15284  std::string WildcardPattern::normaliseString( std::string const& str ) const {
15285  return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
15286  }
15287 }
15288 // end catch_wildcard_pattern.cpp
15289 // start catch_xmlwriter.cpp
15290 
15291 #include <iomanip>
15292 #include <type_traits>
15293 
15294 namespace Catch {
15295 
15296 namespace {
15297 
15298  size_t trailingBytes(unsigned char c) {
15299  if ((c & 0xE0) == 0xC0) {
15300  return 2;
15301  }
15302  if ((c & 0xF0) == 0xE0) {
15303  return 3;
15304  }
15305  if ((c & 0xF8) == 0xF0) {
15306  return 4;
15307  }
15308  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15309  }
15310 
15311  uint32_t headerValue(unsigned char c) {
15312  if ((c & 0xE0) == 0xC0) {
15313  return c & 0x1F;
15314  }
15315  if ((c & 0xF0) == 0xE0) {
15316  return c & 0x0F;
15317  }
15318  if ((c & 0xF8) == 0xF0) {
15319  return c & 0x07;
15320  }
15321  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15322  }
15323 
15324  void hexEscapeChar(std::ostream& os, unsigned char c) {
15325  std::ios_base::fmtflags f(os.flags());
15326  os << "\\x"
15327  << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
15328  << static_cast<int>(c);
15329  os.flags(f);
15330  }
15331 
15332  bool shouldNewline(XmlFormatting fmt) {
15333  return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
15334  }
15335 
15336  bool shouldIndent(XmlFormatting fmt) {
15337  return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
15338  }
15339 
15340 } // anonymous namespace
15341 
15342  XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
15343  return static_cast<XmlFormatting>(
15344  static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
15345  static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
15346  );
15347  }
15348 
15349  XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
15350  return static_cast<XmlFormatting>(
15351  static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
15352  static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
15353  );
15354  }
15355 
15356  XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
15357  : m_str( str ),
15358  m_forWhat( forWhat )
15359  {}
15360 
15361  void XmlEncode::encodeTo( std::ostream& os ) const {
15362  // Apostrophe escaping not necessary if we always use " to write attributes
15363  // (see: http://www.w3.org/TR/xml/#syntax)
15364 
15365  for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
15366  unsigned char c = m_str[idx];
15367  switch (c) {
15368  case '<': os << "&lt;"; break;
15369  case '&': os << "&amp;"; break;
15370 
15371  case '>':
15372  // See: http://www.w3.org/TR/xml/#syntax
15373  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
15374  os << "&gt;";
15375  else
15376  os << c;
15377  break;
15378 
15379  case '\"':
15380  if (m_forWhat == ForAttributes)
15381  os << "&quot;";
15382  else
15383  os << c;
15384  break;
15385 
15386  default:
15387  // Check for control characters and invalid utf-8
15388 
15389  // Escape control characters in standard ascii
15390  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
15391  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
15392  hexEscapeChar(os, c);
15393  break;
15394  }
15395 
15396  // Plain ASCII: Write it to stream
15397  if (c < 0x7F) {
15398  os << c;
15399  break;
15400  }
15401 
15402  // UTF-8 territory
15403  // Check if the encoding is valid and if it is not, hex escape bytes.
15404  // Important: We do not check the exact decoded values for validity, only the encoding format
15405  // First check that this bytes is a valid lead byte:
15406  // This means that it is not encoded as 1111 1XXX
15407  // Or as 10XX XXXX
15408  if (c < 0xC0 ||
15409  c >= 0xF8) {
15410  hexEscapeChar(os, c);
15411  break;
15412  }
15413 
15414  auto encBytes = trailingBytes(c);
15415  // Are there enough bytes left to avoid accessing out-of-bounds memory?
15416  if (idx + encBytes - 1 >= m_str.size()) {
15417  hexEscapeChar(os, c);
15418  break;
15419  }
15420  // The header is valid, check data
15421  // The next encBytes bytes must together be a valid utf-8
15422  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
15423  bool valid = true;
15424  uint32_t value = headerValue(c);
15425  for (std::size_t n = 1; n < encBytes; ++n) {
15426  unsigned char nc = m_str[idx + n];
15427  valid &= ((nc & 0xC0) == 0x80);
15428  value = (value << 6) | (nc & 0x3F);
15429  }
15430 
15431  if (
15432  // Wrong bit pattern of following bytes
15433  (!valid) ||
15434  // Overlong encodings
15435  (value < 0x80) ||
15436  (0x80 <= value && value < 0x800 && encBytes > 2) ||
15437  (0x800 < value && value < 0x10000 && encBytes > 3) ||
15438  // Encoded value out of range
15439  (value >= 0x110000)
15440  ) {
15441  hexEscapeChar(os, c);
15442  break;
15443  }
15444 
15445  // If we got here, this is in fact a valid(ish) utf-8 sequence
15446  for (std::size_t n = 0; n < encBytes; ++n) {
15447  os << m_str[idx + n];
15448  }
15449  idx += encBytes - 1;
15450  break;
15451  }
15452  }
15453  }
15454 
15455  std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
15456  xmlEncode.encodeTo( os );
15457  return os;
15458  }
15459 
15460  XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
15461  : m_writer( writer ),
15462  m_fmt(fmt)
15463  {}
15464 
15465  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
15466  : m_writer( other.m_writer ),
15467  m_fmt(other.m_fmt)
15468  {
15469  other.m_writer = nullptr;
15470  other.m_fmt = XmlFormatting::None;
15471  }
15472  XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
15473  if ( m_writer ) {
15474  m_writer->endElement();
15475  }
15476  m_writer = other.m_writer;
15477  other.m_writer = nullptr;
15478  m_fmt = other.m_fmt;
15479  other.m_fmt = XmlFormatting::None;
15480  return *this;
15481  }
15482 
15483  XmlWriter::ScopedElement::~ScopedElement() {
15484  if (m_writer) {
15485  m_writer->endElement(m_fmt);
15486  }
15487  }
15488 
15489  XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
15490  m_writer->writeText( text, fmt );
15491  return *this;
15492  }
15493 
15494  XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
15495  {
15496  writeDeclaration();
15497  }
15498 
15499  XmlWriter::~XmlWriter() {
15500  while (!m_tags.empty()) {
15501  endElement();
15502  }
15503  newlineIfNecessary();
15504  }
15505 
15506  XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
15507  ensureTagClosed();
15508  newlineIfNecessary();
15509  if (shouldIndent(fmt)) {
15510  m_os << m_indent;
15511  m_indent += " ";
15512  }
15513  m_os << '<' << name;
15514  m_tags.push_back( name );
15515  m_tagIsOpen = true;
15516  applyFormatting(fmt);
15517  return *this;
15518  }
15519 
15520  XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
15521  ScopedElement scoped( this, fmt );
15522  startElement( name, fmt );
15523  return scoped;
15524  }
15525 
15526  XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
15527  m_indent = m_indent.substr(0, m_indent.size() - 2);
15528 
15529  if( m_tagIsOpen ) {
15530  m_os << "/>";
15531  m_tagIsOpen = false;
15532  } else {
15533  newlineIfNecessary();
15534  if (shouldIndent(fmt)) {
15535  m_os << m_indent;
15536  }
15537  m_os << "</" << m_tags.back() << ">";
15538  }
15539  m_os << std::flush;
15540  applyFormatting(fmt);
15541  m_tags.pop_back();
15542  return *this;
15543  }
15544 
15545  XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
15546  if( !name.empty() && !attribute.empty() )
15547  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
15548  return *this;
15549  }
15550 
15551  XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
15552  m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
15553  return *this;
15554  }
15555 
15556  XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
15557  if( !text.empty() ){
15558  bool tagWasOpen = m_tagIsOpen;
15559  ensureTagClosed();
15560  if (tagWasOpen && shouldIndent(fmt)) {
15561  m_os << m_indent;
15562  }
15563  m_os << XmlEncode( text );
15564  applyFormatting(fmt);
15565  }
15566  return *this;
15567  }
15568 
15569  XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
15570  ensureTagClosed();
15571  if (shouldIndent(fmt)) {
15572  m_os << m_indent;
15573  }
15574  m_os << "<!--" << text << "-->";
15575  applyFormatting(fmt);
15576  return *this;
15577  }
15578 
15579  void XmlWriter::writeStylesheetRef( std::string const& url ) {
15580  m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
15581  }
15582 
15583  XmlWriter& XmlWriter::writeBlankLine() {
15584  ensureTagClosed();
15585  m_os << '\n';
15586  return *this;
15587  }
15588 
15589  void XmlWriter::ensureTagClosed() {
15590  if( m_tagIsOpen ) {
15591  m_os << '>' << std::flush;
15592  newlineIfNecessary();
15593  m_tagIsOpen = false;
15594  }
15595  }
15596 
15597  void XmlWriter::applyFormatting(XmlFormatting fmt) {
15598  m_needsNewline = shouldNewline(fmt);
15599  }
15600 
15601  void XmlWriter::writeDeclaration() {
15602  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
15603  }
15604 
15605  void XmlWriter::newlineIfNecessary() {
15606  if( m_needsNewline ) {
15607  m_os << std::endl;
15608  m_needsNewline = false;
15609  }
15610  }
15611 }
15612 // end catch_xmlwriter.cpp
15613 // start catch_reporter_bases.cpp
15614 
15615 #include <cstring>
15616 #include <cfloat>
15617 #include <cstdio>
15618 #include <cassert>
15619 #include <memory>
15620 
15621 namespace Catch {
15622  void prepareExpandedExpression(AssertionResult& result) {
15623  result.getExpandedExpression();
15624  }
15625 
15626  // Because formatting using c++ streams is stateful, drop down to C is required
15627  // Alternatively we could use stringstream, but its performance is... not good.
15628  std::string getFormattedDuration( double duration ) {
15629  // Max exponent + 1 is required to represent the whole part
15630  // + 1 for decimal point
15631  // + 3 for the 3 decimal places
15632  // + 1 for null terminator
15633  const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
15634  char buffer[maxDoubleSize];
15635 
15636  // Save previous errno, to prevent sprintf from overwriting it
15637  ErrnoGuard guard;
15638 #ifdef _MSC_VER
15639  sprintf_s(buffer, "%.3f", duration);
15640 #else
15641  std::sprintf(buffer, "%.3f", duration);
15642 #endif
15643  return std::string(buffer);
15644  }
15645 
15646  bool shouldShowDuration( IConfig const& config, double duration ) {
15647  if ( config.showDurations() == ShowDurations::Always ) {
15648  return true;
15649  }
15650  if ( config.showDurations() == ShowDurations::Never ) {
15651  return false;
15652  }
15653  const double min = config.minDuration();
15654  return min >= 0 && duration >= min;
15655  }
15656 
15657  std::string serializeFilters( std::vector<std::string> const& container ) {
15658  ReusableStringStream oss;
15659  bool first = true;
15660  for (auto&& filter : container)
15661  {
15662  if (!first)
15663  oss << ' ';
15664  else
15665  first = false;
15666 
15667  oss << filter;
15668  }
15669  return oss.str();
15670  }
15671 
15672  TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
15673  :StreamingReporterBase(_config) {}
15674 
15675  std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
15676  return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
15677  }
15678 
15679  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
15680 
15681  bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
15682  return false;
15683  }
15684 
15685 } // end namespace Catch
15686 // end catch_reporter_bases.cpp
15687 // start catch_reporter_compact.cpp
15688 
15689 namespace {
15690 
15691 #ifdef CATCH_PLATFORM_MAC
15692  const char* failedString() { return "FAILED"; }
15693  const char* passedString() { return "PASSED"; }
15694 #else
15695  const char* failedString() { return "failed"; }
15696  const char* passedString() { return "passed"; }
15697 #endif
15698 
15699  // Colour::LightGrey
15700  Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
15701 
15702  std::string bothOrAll( std::size_t count ) {
15703  return count == 1 ? std::string() :
15704  count == 2 ? "both " : "all " ;
15705  }
15706 
15707 } // anon namespace
15708 
15709 namespace Catch {
15710 namespace {
15711 // Colour, message variants:
15712 // - white: No tests ran.
15713 // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
15714 // - white: Passed [both/all] N test cases (no assertions).
15715 // - red: Failed N tests cases, failed M assertions.
15716 // - green: Passed [both/all] N tests cases with M assertions.
15717 void printTotals(std::ostream& out, const Totals& totals) {
15718  if (totals.testCases.total() == 0) {
15719  out << "No tests ran.";
15720  } else if (totals.testCases.failed == totals.testCases.total()) {
15721  Colour colour(Colour::ResultError);
15722  const std::string qualify_assertions_failed =
15723  totals.assertions.failed == totals.assertions.total() ?
15724  bothOrAll(totals.assertions.failed) : std::string();
15725  out <<
15726  "Failed " << bothOrAll(totals.testCases.failed)
15727  << pluralise(totals.testCases.failed, "test case") << ", "
15728  "failed " << qualify_assertions_failed <<
15729  pluralise(totals.assertions.failed, "assertion") << '.';
15730  } else if (totals.assertions.total() == 0) {
15731  out <<
15732  "Passed " << bothOrAll(totals.testCases.total())
15733  << pluralise(totals.testCases.total(), "test case")
15734  << " (no assertions).";
15735  } else if (totals.assertions.failed) {
15736  Colour colour(Colour::ResultError);
15737  out <<
15738  "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
15739  "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
15740  } else {
15741  Colour colour(Colour::ResultSuccess);
15742  out <<
15743  "Passed " << bothOrAll(totals.testCases.passed)
15744  << pluralise(totals.testCases.passed, "test case") <<
15745  " with " << pluralise(totals.assertions.passed, "assertion") << '.';
15746  }
15747 }
15748 
15749 // Implementation of CompactReporter formatting
15750 class AssertionPrinter {
15751 public:
15752  AssertionPrinter& operator= (AssertionPrinter const&) = delete;
15753  AssertionPrinter(AssertionPrinter const&) = delete;
15754  AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15755  : stream(_stream)
15756  , result(_stats.assertionResult)
15757  , messages(_stats.infoMessages)
15758  , itMessage(_stats.infoMessages.begin())
15759  , printInfoMessages(_printInfoMessages) {}
15760 
15761  void print() {
15762  printSourceInfo();
15763 
15764  itMessage = messages.begin();
15765 
15766  switch (result.getResultType()) {
15767  case ResultWas::Ok:
15768  printResultType(Colour::ResultSuccess, passedString());
15769  printOriginalExpression();
15770  printReconstructedExpression();
15771  if (!result.hasExpression())
15772  printRemainingMessages(Colour::None);
15773  else
15774  printRemainingMessages();
15775  break;
15776  case ResultWas::ExpressionFailed:
15777  if (result.isOk())
15778  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
15779  else
15780  printResultType(Colour::Error, failedString());
15781  printOriginalExpression();
15782  printReconstructedExpression();
15783  printRemainingMessages();
15784  break;
15785  case ResultWas::ThrewException:
15786  printResultType(Colour::Error, failedString());
15787  printIssue("unexpected exception with message:");
15788  printMessage();
15789  printExpressionWas();
15790  printRemainingMessages();
15791  break;
15792  case ResultWas::FatalErrorCondition:
15793  printResultType(Colour::Error, failedString());
15794  printIssue("fatal error condition with message:");
15795  printMessage();
15796  printExpressionWas();
15797  printRemainingMessages();
15798  break;
15799  case ResultWas::DidntThrowException:
15800  printResultType(Colour::Error, failedString());
15801  printIssue("expected exception, got none");
15802  printExpressionWas();
15803  printRemainingMessages();
15804  break;
15805  case ResultWas::Info:
15806  printResultType(Colour::None, "info");
15807  printMessage();
15808  printRemainingMessages();
15809  break;
15810  case ResultWas::Warning:
15811  printResultType(Colour::None, "warning");
15812  printMessage();
15813  printRemainingMessages();
15814  break;
15815  case ResultWas::ExplicitFailure:
15816  printResultType(Colour::Error, failedString());
15817  printIssue("explicitly");
15818  printRemainingMessages(Colour::None);
15819  break;
15820  // These cases are here to prevent compiler warnings
15821  case ResultWas::Unknown:
15822  case ResultWas::FailureBit:
15823  case ResultWas::Exception:
15824  printResultType(Colour::Error, "** internal error **");
15825  break;
15826  }
15827  }
15828 
15829 private:
15830  void printSourceInfo() const {
15831  Colour colourGuard(Colour::FileName);
15832  stream << result.getSourceInfo() << ':';
15833  }
15834 
15835  void printResultType(Colour::Code colour, std::string const& passOrFail) const {
15836  if (!passOrFail.empty()) {
15837  {
15838  Colour colourGuard(colour);
15839  stream << ' ' << passOrFail;
15840  }
15841  stream << ':';
15842  }
15843  }
15844 
15845  void printIssue(std::string const& issue) const {
15846  stream << ' ' << issue;
15847  }
15848 
15849  void printExpressionWas() {
15850  if (result.hasExpression()) {
15851  stream << ';';
15852  {
15853  Colour colour(dimColour());
15854  stream << " expression was:";
15855  }
15856  printOriginalExpression();
15857  }
15858  }
15859 
15860  void printOriginalExpression() const {
15861  if (result.hasExpression()) {
15862  stream << ' ' << result.getExpression();
15863  }
15864  }
15865 
15866  void printReconstructedExpression() const {
15867  if (result.hasExpandedExpression()) {
15868  {
15869  Colour colour(dimColour());
15870  stream << " for: ";
15871  }
15872  stream << result.getExpandedExpression();
15873  }
15874  }
15875 
15876  void printMessage() {
15877  if (itMessage != messages.end()) {
15878  stream << " '" << itMessage->message << '\'';
15879  ++itMessage;
15880  }
15881  }
15882 
15883  void printRemainingMessages(Colour::Code colour = dimColour()) {
15884  if (itMessage == messages.end())
15885  return;
15886 
15887  const auto itEnd = messages.cend();
15888  const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
15889 
15890  {
15891  Colour colourGuard(colour);
15892  stream << " with " << pluralise(N, "message") << ':';
15893  }
15894 
15895  while (itMessage != itEnd) {
15896  // If this assertion is a warning ignore any INFO messages
15897  if (printInfoMessages || itMessage->type != ResultWas::Info) {
15898  printMessage();
15899  if (itMessage != itEnd) {
15900  Colour colourGuard(dimColour());
15901  stream << " and";
15902  }
15903  continue;
15904  }
15905  ++itMessage;
15906  }
15907  }
15908 
15909 private:
15910  std::ostream& stream;
15911  AssertionResult const& result;
15912  std::vector<MessageInfo> messages;
15913  std::vector<MessageInfo>::const_iterator itMessage;
15914  bool printInfoMessages;
15915 };
15916 
15917 } // anon namespace
15918 
15919  std::string CompactReporter::getDescription() {
15920  return "Reports test results on a single line, suitable for IDEs";
15921  }
15922 
15923  void CompactReporter::noMatchingTestCases( std::string const& spec ) {
15924  stream << "No test cases matched '" << spec << '\'' << std::endl;
15925  }
15926 
15927  void CompactReporter::assertionStarting( AssertionInfo const& ) {}
15928 
15929  bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
15930  AssertionResult const& result = _assertionStats.assertionResult;
15931 
15932  bool printInfoMessages = true;
15933 
15934  // Drop out if result was successful and we're not printing those
15935  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
15936  if( result.getResultType() != ResultWas::Warning )
15937  return false;
15938  printInfoMessages = false;
15939  }
15940 
15941  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
15942  printer.print();
15943 
15944  stream << std::endl;
15945  return true;
15946  }
15947 
15948  void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
15949  double dur = _sectionStats.durationInSeconds;
15950  if ( shouldShowDuration( *m_config, dur ) ) {
15951  stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
15952  }
15953  }
15954 
15955  void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
15956  printTotals( stream, _testRunStats.totals );
15957  stream << '\n' << std::endl;
15958  StreamingReporterBase::testRunEnded( _testRunStats );
15959  }
15960 
15961  CompactReporter::~CompactReporter() {}
15962 
15963  CATCH_REGISTER_REPORTER( "compact", CompactReporter )
15964 
15965 } // end namespace Catch
15966 // end catch_reporter_compact.cpp
15967 // start catch_reporter_console.cpp
15968 
15969 #include <cfloat>
15970 #include <cstdio>
15971 
15972 #if defined(_MSC_VER)
15973 #pragma warning(push)
15974 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
15975  // Note that 4062 (not all labels are handled and default is missing) is enabled
15976 #endif
15977 
15978 #if defined(__clang__)
15979 # pragma clang diagnostic push
15980 // For simplicity, benchmarking-only helpers are always enabled
15981 # pragma clang diagnostic ignored "-Wunused-function"
15982 #endif
15983 
15984 namespace Catch {
15985 
15986 namespace {
15987 
15988 // Formatter impl for ConsoleReporter
15990 public:
15991  ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
15993  ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
15994  : stream(_stream),
15995  stats(_stats),
15996  result(_stats.assertionResult),
15997  colour(Colour::None),
15998  message(result.getMessage()),
15999  messages(_stats.infoMessages),
16000  printInfoMessages(_printInfoMessages) {
16001  switch (result.getResultType()) {
16002  case ResultWas::Ok:
16003  colour = Colour::Success;
16004  passOrFail = "PASSED";
16005  //if( result.hasMessage() )
16006  if (_stats.infoMessages.size() == 1)
16007  messageLabel = "with message";
16008  if (_stats.infoMessages.size() > 1)
16009  messageLabel = "with messages";
16010  break;
16011  case ResultWas::ExpressionFailed:
16012  if (result.isOk()) {
16013  colour = Colour::Success;
16014  passOrFail = "FAILED - but was ok";
16015  } else {
16016  colour = Colour::Error;
16017  passOrFail = "FAILED";
16018  }
16019  if (_stats.infoMessages.size() == 1)
16020  messageLabel = "with message";
16021  if (_stats.infoMessages.size() > 1)
16022  messageLabel = "with messages";
16023  break;
16024  case ResultWas::ThrewException:
16025  colour = Colour::Error;
16026  passOrFail = "FAILED";
16027  messageLabel = "due to unexpected exception with ";
16028  if (_stats.infoMessages.size() == 1)
16029  messageLabel += "message";
16030  if (_stats.infoMessages.size() > 1)
16031  messageLabel += "messages";
16032  break;
16033  case ResultWas::FatalErrorCondition:
16034  colour = Colour::Error;
16035  passOrFail = "FAILED";
16036  messageLabel = "due to a fatal error condition";
16037  break;
16038  case ResultWas::DidntThrowException:
16039  colour = Colour::Error;
16040  passOrFail = "FAILED";
16041  messageLabel = "because no exception was thrown where one was expected";
16042  break;
16043  case ResultWas::Info:
16044  messageLabel = "info";
16045  break;
16046  case ResultWas::Warning:
16047  messageLabel = "warning";
16048  break;
16049  case ResultWas::ExplicitFailure:
16050  passOrFail = "FAILED";
16051  colour = Colour::Error;
16052  if (_stats.infoMessages.size() == 1)
16053  messageLabel = "explicitly with message";
16054  if (_stats.infoMessages.size() > 1)
16055  messageLabel = "explicitly with messages";
16056  break;
16057  // These cases are here to prevent compiler warnings
16058  case ResultWas::Unknown:
16059  case ResultWas::FailureBit:
16060  case ResultWas::Exception:
16061  passOrFail = "** internal error **";
16062  colour = Colour::Error;
16063  break;
16064  }
16065  }
16066 
16067  void print() const {
16068  printSourceInfo();
16069  if (stats.totals.assertions.total() > 0) {
16070  printResultType();
16071  printOriginalExpression();
16072  printReconstructedExpression();
16073  } else {
16074  stream << '\n';
16075  }
16076  printMessage();
16077  }
16078 
16079 private:
16080  void printResultType() const {
16081  if (!passOrFail.empty()) {
16082  Colour colourGuard(colour);
16083  stream << passOrFail << ":\n";
16084  }
16085  }
16086  void printOriginalExpression() const {
16087  if (result.hasExpression()) {
16088  Colour colourGuard(Colour::OriginalExpression);
16089  stream << " ";
16090  stream << result.getExpressionInMacro();
16091  stream << '\n';
16092  }
16093  }
16094  void printReconstructedExpression() const {
16095  if (result.hasExpandedExpression()) {
16096  stream << "with expansion:\n";
16097  Colour colourGuard(Colour::ReconstructedExpression);
16098  stream << Column(result.getExpandedExpression()).indent(2) << '\n';
16099  }
16100  }
16101  void printMessage() const {
16102  if (!messageLabel.empty())
16103  stream << messageLabel << ':' << '\n';
16104  for (auto const& msg : messages) {
16105  // If this assertion is a warning ignore any INFO messages
16106  if (printInfoMessages || msg.type != ResultWas::Info)
16107  stream << Column(msg.message).indent(2) << '\n';
16108  }
16109  }
16110  void printSourceInfo() const {
16111  Colour colourGuard(Colour::FileName);
16112  stream << result.getSourceInfo() << ": ";
16113  }
16114 
16115  std::ostream& stream;
16116  AssertionStats const& stats;
16117  AssertionResult const& result;
16118  Colour::Code colour;
16119  std::string passOrFail;
16120  std::string messageLabel;
16121  std::string message;
16122  std::vector<MessageInfo> messages;
16123  bool printInfoMessages;
16124 };
16125 
16126 std::size_t makeRatio(std::size_t number, std::size_t total) {
16127  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
16128  return (ratio == 0 && number > 0) ? 1 : ratio;
16129 }
16130 
16131 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
16132  if (i > j && i > k)
16133  return i;
16134  else if (j > k)
16135  return j;
16136  else
16137  return k;
16138 }
16139 
16140 struct ColumnInfo {
16141  enum Justification { Left, Right };
16142  std::string name;
16143  int width;
16144  Justification justification;
16145 };
16146 struct ColumnBreak {};
16147 struct RowBreak {};
16148 
16149 class Duration {
16150  enum class Unit {
16151  Auto,
16152  Nanoseconds,
16153  Microseconds,
16154  Milliseconds,
16155  Seconds,
16156  Minutes
16157  };
16158  static const uint64_t s_nanosecondsInAMicrosecond = 1000;
16159  static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
16160  static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
16161  static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
16162 
16163  double m_inNanoseconds;
16164  Unit m_units;
16165 
16166 public:
16167  explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
16168  : m_inNanoseconds(inNanoseconds),
16169  m_units(units) {
16170  if (m_units == Unit::Auto) {
16171  if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
16172  m_units = Unit::Nanoseconds;
16173  else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
16174  m_units = Unit::Microseconds;
16175  else if (m_inNanoseconds < s_nanosecondsInASecond)
16176  m_units = Unit::Milliseconds;
16177  else if (m_inNanoseconds < s_nanosecondsInAMinute)
16178  m_units = Unit::Seconds;
16179  else
16180  m_units = Unit::Minutes;
16181  }
16182 
16183  }
16184 
16185  auto value() const -> double {
16186  switch (m_units) {
16187  case Unit::Microseconds:
16188  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
16189  case Unit::Milliseconds:
16190  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
16191  case Unit::Seconds:
16192  return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
16193  case Unit::Minutes:
16194  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
16195  default:
16196  return m_inNanoseconds;
16197  }
16198  }
16199  auto unitsAsString() const -> std::string {
16200  switch (m_units) {
16201  case Unit::Nanoseconds:
16202  return "ns";
16203  case Unit::Microseconds:
16204  return "us";
16205  case Unit::Milliseconds:
16206  return "ms";
16207  case Unit::Seconds:
16208  return "s";
16209  case Unit::Minutes:
16210  return "m";
16211  default:
16212  return "** internal error **";
16213  }
16214 
16215  }
16216  friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
16217  return os << duration.value() << ' ' << duration.unitsAsString();
16218  }
16219 };
16220 } // end anon namespace
16221 
16223  std::ostream& m_os;
16224  std::vector<ColumnInfo> m_columnInfos;
16225  std::ostringstream m_oss;
16226  int m_currentColumn = -1;
16227  bool m_isOpen = false;
16228 
16229 public:
16230  TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
16231  : m_os( os ),
16232  m_columnInfos( std::move( columnInfos ) ) {}
16233 
16234  auto columnInfos() const -> std::vector<ColumnInfo> const& {
16235  return m_columnInfos;
16236  }
16237 
16238  void open() {
16239  if (!m_isOpen) {
16240  m_isOpen = true;
16241  *this << RowBreak();
16242 
16243  Columns headerCols;
16244  Spacer spacer(2);
16245  for (auto const& info : m_columnInfos) {
16246  headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
16247  headerCols += spacer;
16248  }
16249  m_os << headerCols << '\n';
16250 
16251  m_os << Catch::getLineOfChars<'-'>() << '\n';
16252  }
16253  }
16254  void close() {
16255  if (m_isOpen) {
16256  *this << RowBreak();
16257  m_os << std::endl;
16258  m_isOpen = false;
16259  }
16260  }
16261 
16262  template<typename T>
16263  friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
16264  tp.m_oss << value;
16265  return tp;
16266  }
16267 
16268  friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
16269  auto colStr = tp.m_oss.str();
16270  const auto strSize = colStr.size();
16271  tp.m_oss.str("");
16272  tp.open();
16273  if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
16274  tp.m_currentColumn = -1;
16275  tp.m_os << '\n';
16276  }
16277  tp.m_currentColumn++;
16278 
16279  auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
16280  auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
16281  ? std::string(colInfo.width - (strSize + 1), ' ')
16282  : std::string();
16283  if (colInfo.justification == ColumnInfo::Left)
16284  tp.m_os << colStr << padding << ' ';
16285  else
16286  tp.m_os << padding << colStr << ' ';
16287  return tp;
16288  }
16289 
16290  friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
16291  if (tp.m_currentColumn > 0) {
16292  tp.m_os << '\n';
16293  tp.m_currentColumn = -1;
16294  }
16295  return tp;
16296  }
16297 };
16298 
16299 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
16300  : StreamingReporterBase(config),
16301  m_tablePrinter(new TablePrinter(config.stream(),
16302  [&config]() -> std::vector<ColumnInfo> {
16303  if (config.fullConfig()->benchmarkNoAnalysis())
16304  {
16305  return{
16306  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16307  { " samples", 14, ColumnInfo::Right },
16308  { " iterations", 14, ColumnInfo::Right },
16309  { " mean", 14, ColumnInfo::Right }
16310  };
16311  }
16312  else
16313  {
16314  return{
16315  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
16316  { "samples mean std dev", 14, ColumnInfo::Right },
16317  { "iterations low mean low std dev", 14, ColumnInfo::Right },
16318  { "estimated high mean high std dev", 14, ColumnInfo::Right }
16319  };
16320  }
16321  }())) {}
16322 ConsoleReporter::~ConsoleReporter() = default;
16323 
16324 std::string ConsoleReporter::getDescription() {
16325  return "Reports test results as plain lines of text";
16326 }
16327 
16328 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
16329  stream << "No test cases matched '" << spec << '\'' << std::endl;
16330 }
16331 
16332 void ConsoleReporter::reportInvalidArguments(std::string const&arg){
16333  stream << "Invalid Filter: " << arg << std::endl;
16334 }
16335 
16336 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
16337 
16338 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
16339  AssertionResult const& result = _assertionStats.assertionResult;
16340 
16341  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16342 
16343  // Drop out if result was successful but we're not printing them.
16344  if (!includeResults && result.getResultType() != ResultWas::Warning)
16345  return false;
16346 
16347  lazyPrint();
16348 
16349  ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
16350  printer.print();
16351  stream << std::endl;
16352  return true;
16353 }
16354 
16355 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
16356  m_tablePrinter->close();
16357  m_headerPrinted = false;
16358  StreamingReporterBase::sectionStarting(_sectionInfo);
16359 }
16360 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
16361  m_tablePrinter->close();
16362  if (_sectionStats.missingAssertions) {
16363  lazyPrint();
16364  Colour colour(Colour::ResultError);
16365  if (m_sectionStack.size() > 1)
16366  stream << "\nNo assertions in section";
16367  else
16368  stream << "\nNo assertions in test case";
16369  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
16370  }
16371  double dur = _sectionStats.durationInSeconds;
16372  if (shouldShowDuration(*m_config, dur)) {
16373  stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16374  }
16375  if (m_headerPrinted) {
16376  m_headerPrinted = false;
16377  }
16378  StreamingReporterBase::sectionEnded(_sectionStats);
16379 }
16380 
16381 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16382 void ConsoleReporter::benchmarkPreparing(std::string const& name) {
16383  lazyPrintWithoutClosingBenchmarkTable();
16384 
16385  auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
16386 
16387  bool firstLine = true;
16388  for (auto line : nameCol) {
16389  if (!firstLine)
16390  (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
16391  else
16392  firstLine = false;
16393 
16394  (*m_tablePrinter) << line << ColumnBreak();
16395  }
16396 }
16397 
16398 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
16399  (*m_tablePrinter) << info.samples << ColumnBreak()
16400  << info.iterations << ColumnBreak();
16401  if (!m_config->benchmarkNoAnalysis())
16402  (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
16403 }
16404 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
16405  if (m_config->benchmarkNoAnalysis())
16406  {
16407  (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
16408  }
16409  else
16410  {
16411  (*m_tablePrinter) << ColumnBreak()
16412  << Duration(stats.mean.point.count()) << ColumnBreak()
16413  << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
16414  << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
16415  << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
16416  << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
16417  << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
16418  }
16419 }
16420 
16421 void ConsoleReporter::benchmarkFailed(std::string const& error) {
16422  Colour colour(Colour::Red);
16423  (*m_tablePrinter)
16424  << "Benchmark failed (" << error << ')'
16425  << ColumnBreak() << RowBreak();
16426 }
16427 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16428 
16429 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
16430  m_tablePrinter->close();
16431  StreamingReporterBase::testCaseEnded(_testCaseStats);
16432  m_headerPrinted = false;
16433 }
16434 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
16435  if (currentGroupInfo.used) {
16436  printSummaryDivider();
16437  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
16438  printTotals(_testGroupStats.totals);
16439  stream << '\n' << std::endl;
16440  }
16441  StreamingReporterBase::testGroupEnded(_testGroupStats);
16442 }
16443 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
16444  printTotalsDivider(_testRunStats.totals);
16445  printTotals(_testRunStats.totals);
16446  stream << std::endl;
16447  StreamingReporterBase::testRunEnded(_testRunStats);
16448 }
16449 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
16450  StreamingReporterBase::testRunStarting(_testInfo);
16451  printTestFilters();
16452 }
16453 
16454 void ConsoleReporter::lazyPrint() {
16455 
16456  m_tablePrinter->close();
16457  lazyPrintWithoutClosingBenchmarkTable();
16458 }
16459 
16460 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
16461 
16462  if (!currentTestRunInfo.used)
16463  lazyPrintRunInfo();
16464  if (!currentGroupInfo.used)
16465  lazyPrintGroupInfo();
16466 
16467  if (!m_headerPrinted) {
16468  printTestCaseAndSectionHeader();
16469  m_headerPrinted = true;
16470  }
16471 }
16472 void ConsoleReporter::lazyPrintRunInfo() {
16473  stream << '\n' << getLineOfChars<'~'>() << '\n';
16474  Colour colour(Colour::SecondaryText);
16475  stream << currentTestRunInfo->name
16476  << " is a Catch v" << libraryVersion() << " host application.\n"
16477  << "Run with -? for options\n\n";
16478 
16479  if (m_config->rngSeed() != 0)
16480  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
16481 
16482  currentTestRunInfo.used = true;
16483 }
16484 void ConsoleReporter::lazyPrintGroupInfo() {
16485  if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
16486  printClosedHeader("Group: " + currentGroupInfo->name);
16487  currentGroupInfo.used = true;
16488  }
16489 }
16490 void ConsoleReporter::printTestCaseAndSectionHeader() {
16491  assert(!m_sectionStack.empty());
16492  printOpenHeader(currentTestCaseInfo->name);
16493 
16494  if (m_sectionStack.size() > 1) {
16495  Colour colourGuard(Colour::Headers);
16496 
16497  auto
16498  it = m_sectionStack.begin() + 1, // Skip first section (test case)
16499  itEnd = m_sectionStack.end();
16500  for (; it != itEnd; ++it)
16501  printHeaderString(it->name, 2);
16502  }
16503 
16504  SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
16505 
16506  stream << getLineOfChars<'-'>() << '\n';
16507  Colour colourGuard(Colour::FileName);
16508  stream << lineInfo << '\n';
16509  stream << getLineOfChars<'.'>() << '\n' << std::endl;
16510 }
16511 
16512 void ConsoleReporter::printClosedHeader(std::string const& _name) {
16513  printOpenHeader(_name);
16514  stream << getLineOfChars<'.'>() << '\n';
16515 }
16516 void ConsoleReporter::printOpenHeader(std::string const& _name) {
16517  stream << getLineOfChars<'-'>() << '\n';
16518  {
16519  Colour colourGuard(Colour::Headers);
16520  printHeaderString(_name);
16521  }
16522 }
16523 
16524 // if string has a : in first line will set indent to follow it on
16525 // subsequent lines
16526 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
16527  std::size_t i = _string.find(": ");
16528  if (i != std::string::npos)
16529  i += 2;
16530  else
16531  i = 0;
16532  stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
16533 }
16534 
16536 
16537  SummaryColumn( std::string _label, Colour::Code _colour )
16538  : label( std::move( _label ) ),
16539  colour( _colour ) {}
16540  SummaryColumn addRow( std::size_t count ) {
16542  rss << count;
16543  std::string row = rss.str();
16544  for (auto& oldRow : rows) {
16545  while (oldRow.size() < row.size())
16546  oldRow = ' ' + oldRow;
16547  while (oldRow.size() > row.size())
16548  row = ' ' + row;
16549  }
16550  rows.push_back(row);
16551  return *this;
16552  }
16553 
16554  std::string label;
16555  Colour::Code colour;
16556  std::vector<std::string> rows;
16557 
16558 };
16559 
16560 void ConsoleReporter::printTotals( Totals const& totals ) {
16561  if (totals.testCases.total() == 0) {
16562  stream << Colour(Colour::Warning) << "No tests ran\n";
16563  } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
16564  stream << Colour(Colour::ResultSuccess) << "All tests passed";
16565  stream << " ("
16566  << pluralise(totals.assertions.passed, "assertion") << " in "
16567  << pluralise(totals.testCases.passed, "test case") << ')'
16568  << '\n';
16569  } else {
16570 
16571  std::vector<SummaryColumn> columns;
16572  columns.push_back(SummaryColumn("", Colour::None)
16573  .addRow(totals.testCases.total())
16574  .addRow(totals.assertions.total()));
16575  columns.push_back(SummaryColumn("passed", Colour::Success)
16576  .addRow(totals.testCases.passed)
16577  .addRow(totals.assertions.passed));
16578  columns.push_back(SummaryColumn("failed", Colour::ResultError)
16579  .addRow(totals.testCases.failed)
16580  .addRow(totals.assertions.failed));
16581  columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
16582  .addRow(totals.testCases.failedButOk)
16583  .addRow(totals.assertions.failedButOk));
16584 
16585  printSummaryRow("test cases", columns, 0);
16586  printSummaryRow("assertions", columns, 1);
16587  }
16588 }
16589 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
16590  for (auto col : cols) {
16591  std::string value = col.rows[row];
16592  if (col.label.empty()) {
16593  stream << label << ": ";
16594  if (value != "0")
16595  stream << value;
16596  else
16597  stream << Colour(Colour::Warning) << "- none -";
16598  } else if (value != "0") {
16599  stream << Colour(Colour::LightGrey) << " | ";
16600  stream << Colour(col.colour)
16601  << value << ' ' << col.label;
16602  }
16603  }
16604  stream << '\n';
16605 }
16606 
16607 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
16608  if (totals.testCases.total() > 0) {
16609  std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
16610  std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
16611  std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
16612  while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
16613  findMax(failedRatio, failedButOkRatio, passedRatio)++;
16614  while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
16615  findMax(failedRatio, failedButOkRatio, passedRatio)--;
16616 
16617  stream << Colour(Colour::Error) << std::string(failedRatio, '=');
16618  stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
16619  if (totals.testCases.allPassed())
16620  stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
16621  else
16622  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
16623  } else {
16624  stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
16625  }
16626  stream << '\n';
16627 }
16628 void ConsoleReporter::printSummaryDivider() {
16629  stream << getLineOfChars<'-'>() << '\n';
16630 }
16631 
16632 void ConsoleReporter::printTestFilters() {
16633  if (m_config->testSpec().hasFilters()) {
16634  Colour guard(Colour::BrightYellow);
16635  stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
16636  }
16637 }
16638 
16639 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
16640 
16641 } // end namespace Catch
16642 
16643 #if defined(_MSC_VER)
16644 #pragma warning(pop)
16645 #endif
16646 
16647 #if defined(__clang__)
16648 # pragma clang diagnostic pop
16649 #endif
16650 // end catch_reporter_console.cpp
16651 // start catch_reporter_junit.cpp
16652 
16653 #include <cassert>
16654 #include <sstream>
16655 #include <ctime>
16656 #include <algorithm>
16657 
16658 namespace Catch {
16659 
16660  namespace {
16661  std::string getCurrentTimestamp() {
16662  // Beware, this is not reentrant because of backward compatibility issues
16663  // Also, UTC only, again because of backward compatibility (%z is C++11)
16664  time_t rawtime;
16665  std::time(&rawtime);
16666  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
16667 
16668 #ifdef _MSC_VER
16669  std::tm timeInfo = {};
16670  gmtime_s(&timeInfo, &rawtime);
16671 #else
16672  std::tm* timeInfo;
16673  timeInfo = std::gmtime(&rawtime);
16674 #endif
16675 
16676  char timeStamp[timeStampSize];
16677  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
16678 
16679 #ifdef _MSC_VER
16680  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
16681 #else
16682  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
16683 #endif
16684  return std::string(timeStamp);
16685  }
16686 
16687  std::string fileNameTag(const std::vector<std::string> &tags) {
16688  auto it = std::find_if(begin(tags),
16689  end(tags),
16690  [] (std::string const& tag) {return tag.front() == '#'; });
16691  if (it != tags.end())
16692  return it->substr(1);
16693  return std::string();
16694  }
16695  } // anonymous namespace
16696 
16697  JunitReporter::JunitReporter( ReporterConfig const& _config )
16698  : CumulativeReporterBase( _config ),
16699  xml( _config.stream() )
16700  {
16701  m_reporterPrefs.shouldRedirectStdOut = true;
16702  m_reporterPrefs.shouldReportAllAssertions = true;
16703  }
16704 
16705  JunitReporter::~JunitReporter() {}
16706 
16707  std::string JunitReporter::getDescription() {
16708  return "Reports test results in an XML format that looks like Ant's junitreport target";
16709  }
16710 
16711  void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
16712 
16713  void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
16714  CumulativeReporterBase::testRunStarting( runInfo );
16715  xml.startElement( "testsuites" );
16716  }
16717 
16718  void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16719  suiteTimer.start();
16720  stdOutForSuite.clear();
16721  stdErrForSuite.clear();
16722  unexpectedExceptions = 0;
16723  CumulativeReporterBase::testGroupStarting( groupInfo );
16724  }
16725 
16726  void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
16727  m_okToFail = testCaseInfo.okToFail();
16728  }
16729 
16730  bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
16731  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
16732  unexpectedExceptions++;
16733  return CumulativeReporterBase::assertionEnded( assertionStats );
16734  }
16735 
16736  void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
16737  stdOutForSuite += testCaseStats.stdOut;
16738  stdErrForSuite += testCaseStats.stdErr;
16739  CumulativeReporterBase::testCaseEnded( testCaseStats );
16740  }
16741 
16742  void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
16743  double suiteTime = suiteTimer.getElapsedSeconds();
16744  CumulativeReporterBase::testGroupEnded( testGroupStats );
16745  writeGroup( *m_testGroups.back(), suiteTime );
16746  }
16747 
16748  void JunitReporter::testRunEndedCumulative() {
16749  xml.endElement();
16750  }
16751 
16752  void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
16753  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
16754 
16755  TestGroupStats const& stats = groupNode.value;
16756  xml.writeAttribute( "name", stats.groupInfo.name );
16757  xml.writeAttribute( "errors", unexpectedExceptions );
16758  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
16759  xml.writeAttribute( "tests", stats.totals.assertions.total() );
16760  xml.writeAttribute( "hostname", "tbd" ); // !TBD
16761  if( m_config->showDurations() == ShowDurations::Never )
16762  xml.writeAttribute( "time", "" );
16763  else
16764  xml.writeAttribute( "time", suiteTime );
16765  xml.writeAttribute( "timestamp", getCurrentTimestamp() );
16766 
16767  // Write properties if there are any
16768  if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
16769  auto properties = xml.scopedElement("properties");
16770  if (m_config->hasTestFilters()) {
16771  xml.scopedElement("property")
16772  .writeAttribute("name", "filters")
16773  .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
16774  }
16775  if (m_config->rngSeed() != 0) {
16776  xml.scopedElement("property")
16777  .writeAttribute("name", "random-seed")
16778  .writeAttribute("value", m_config->rngSeed());
16779  }
16780  }
16781 
16782  // Write test cases
16783  for( auto const& child : groupNode.children )
16784  writeTestCase( *child );
16785 
16786  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
16787  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
16788  }
16789 
16790  void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
16791  TestCaseStats const& stats = testCaseNode.value;
16792 
16793  // All test cases have exactly one section - which represents the
16794  // test case itself. That section may have 0-n nested sections
16795  assert( testCaseNode.children.size() == 1 );
16796  SectionNode const& rootSection = *testCaseNode.children.front();
16797 
16798  std::string className = stats.testInfo.className;
16799 
16800  if( className.empty() ) {
16801  className = fileNameTag(stats.testInfo.tags);
16802  if ( className.empty() )
16803  className = "global";
16804  }
16805 
16806  if ( !m_config->name().empty() )
16807  className = m_config->name() + "." + className;
16808 
16809  writeSection( className, "", rootSection );
16810  }
16811 
16812  void JunitReporter::writeSection( std::string const& className,
16813  std::string const& rootName,
16814  SectionNode const& sectionNode ) {
16815  std::string name = trim( sectionNode.stats.sectionInfo.name );
16816  if( !rootName.empty() )
16817  name = rootName + '/' + name;
16818 
16819  if( !sectionNode.assertions.empty() ||
16820  !sectionNode.stdOut.empty() ||
16821  !sectionNode.stdErr.empty() ) {
16822  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
16823  if( className.empty() ) {
16824  xml.writeAttribute( "classname", name );
16825  xml.writeAttribute( "name", "root" );
16826  }
16827  else {
16828  xml.writeAttribute( "classname", className );
16829  xml.writeAttribute( "name", name );
16830  }
16831  xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
16832  // This is not ideal, but it should be enough to mimic gtest's
16833  // junit output.
16834  // Ideally the JUnit reporter would also handle `skipTest`
16835  // events and write those out appropriately.
16836  xml.writeAttribute( "status", "run" );
16837 
16838  writeAssertions( sectionNode );
16839 
16840  if( !sectionNode.stdOut.empty() )
16841  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
16842  if( !sectionNode.stdErr.empty() )
16843  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
16844  }
16845  for( auto const& childNode : sectionNode.childSections )
16846  if( className.empty() )
16847  writeSection( name, "", *childNode );
16848  else
16849  writeSection( className, name, *childNode );
16850  }
16851 
16852  void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
16853  for( auto const& assertion : sectionNode.assertions )
16854  writeAssertion( assertion );
16855  }
16856 
16857  void JunitReporter::writeAssertion( AssertionStats const& stats ) {
16858  AssertionResult const& result = stats.assertionResult;
16859  if( !result.isOk() ) {
16860  std::string elementName;
16861  switch( result.getResultType() ) {
16862  case ResultWas::ThrewException:
16863  case ResultWas::FatalErrorCondition:
16864  elementName = "error";
16865  break;
16866  case ResultWas::ExplicitFailure:
16867  case ResultWas::ExpressionFailed:
16868  case ResultWas::DidntThrowException:
16869  elementName = "failure";
16870  break;
16871 
16872  // We should never see these here:
16873  case ResultWas::Info:
16874  case ResultWas::Warning:
16875  case ResultWas::Ok:
16876  case ResultWas::Unknown:
16877  case ResultWas::FailureBit:
16878  case ResultWas::Exception:
16879  elementName = "internalError";
16880  break;
16881  }
16882 
16883  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
16884 
16885  xml.writeAttribute( "message", result.getExpression() );
16886  xml.writeAttribute( "type", result.getTestMacroName() );
16887 
16888  ReusableStringStream rss;
16889  if (stats.totals.assertions.total() > 0) {
16890  rss << "FAILED" << ":\n";
16891  if (result.hasExpression()) {
16892  rss << " ";
16893  rss << result.getExpressionInMacro();
16894  rss << '\n';
16895  }
16896  if (result.hasExpandedExpression()) {
16897  rss << "with expansion:\n";
16898  rss << Column(result.getExpandedExpression()).indent(2) << '\n';
16899  }
16900  } else {
16901  rss << '\n';
16902  }
16903 
16904  if( !result.getMessage().empty() )
16905  rss << result.getMessage() << '\n';
16906  for( auto const& msg : stats.infoMessages )
16907  if( msg.type == ResultWas::Info )
16908  rss << msg.message << '\n';
16909 
16910  rss << "at " << result.getSourceInfo();
16911  xml.writeText( rss.str(), XmlFormatting::Newline );
16912  }
16913  }
16914 
16915  CATCH_REGISTER_REPORTER( "junit", JunitReporter )
16916 
16917 } // end namespace Catch
16918 // end catch_reporter_junit.cpp
16919 // start catch_reporter_listening.cpp
16920 
16921 #include <cassert>
16922 
16923 namespace Catch {
16924 
16925  ListeningReporter::ListeningReporter() {
16926  // We will assume that listeners will always want all assertions
16927  m_preferences.shouldReportAllAssertions = true;
16928  }
16929 
16930  void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
16931  m_listeners.push_back( std::move( listener ) );
16932  }
16933 
16934  void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
16935  assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
16936  m_reporter = std::move( reporter );
16937  m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
16938  }
16939 
16940  ReporterPreferences ListeningReporter::getPreferences() const {
16941  return m_preferences;
16942  }
16943 
16944  std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
16945  return std::set<Verbosity>{ };
16946  }
16947 
16948  void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
16949  for ( auto const& listener : m_listeners ) {
16950  listener->noMatchingTestCases( spec );
16951  }
16952  m_reporter->noMatchingTestCases( spec );
16953  }
16954 
16955  void ListeningReporter::reportInvalidArguments(std::string const&arg){
16956  for ( auto const& listener : m_listeners ) {
16957  listener->reportInvalidArguments( arg );
16958  }
16959  m_reporter->reportInvalidArguments( arg );
16960  }
16961 
16962 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16963  void ListeningReporter::benchmarkPreparing( std::string const& name ) {
16964  for (auto const& listener : m_listeners) {
16965  listener->benchmarkPreparing(name);
16966  }
16967  m_reporter->benchmarkPreparing(name);
16968  }
16969  void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
16970  for ( auto const& listener : m_listeners ) {
16971  listener->benchmarkStarting( benchmarkInfo );
16972  }
16973  m_reporter->benchmarkStarting( benchmarkInfo );
16974  }
16975  void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
16976  for ( auto const& listener : m_listeners ) {
16977  listener->benchmarkEnded( benchmarkStats );
16978  }
16979  m_reporter->benchmarkEnded( benchmarkStats );
16980  }
16981 
16982  void ListeningReporter::benchmarkFailed( std::string const& error ) {
16983  for (auto const& listener : m_listeners) {
16984  listener->benchmarkFailed(error);
16985  }
16986  m_reporter->benchmarkFailed(error);
16987  }
16988 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16989 
16990  void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
16991  for ( auto const& listener : m_listeners ) {
16992  listener->testRunStarting( testRunInfo );
16993  }
16994  m_reporter->testRunStarting( testRunInfo );
16995  }
16996 
16997  void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
16998  for ( auto const& listener : m_listeners ) {
16999  listener->testGroupStarting( groupInfo );
17000  }
17001  m_reporter->testGroupStarting( groupInfo );
17002  }
17003 
17004  void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
17005  for ( auto const& listener : m_listeners ) {
17006  listener->testCaseStarting( testInfo );
17007  }
17008  m_reporter->testCaseStarting( testInfo );
17009  }
17010 
17011  void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
17012  for ( auto const& listener : m_listeners ) {
17013  listener->sectionStarting( sectionInfo );
17014  }
17015  m_reporter->sectionStarting( sectionInfo );
17016  }
17017 
17018  void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
17019  for ( auto const& listener : m_listeners ) {
17020  listener->assertionStarting( assertionInfo );
17021  }
17022  m_reporter->assertionStarting( assertionInfo );
17023  }
17024 
17025  // The return value indicates if the messages buffer should be cleared:
17026  bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
17027  for( auto const& listener : m_listeners ) {
17028  static_cast<void>( listener->assertionEnded( assertionStats ) );
17029  }
17030  return m_reporter->assertionEnded( assertionStats );
17031  }
17032 
17033  void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
17034  for ( auto const& listener : m_listeners ) {
17035  listener->sectionEnded( sectionStats );
17036  }
17037  m_reporter->sectionEnded( sectionStats );
17038  }
17039 
17040  void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
17041  for ( auto const& listener : m_listeners ) {
17042  listener->testCaseEnded( testCaseStats );
17043  }
17044  m_reporter->testCaseEnded( testCaseStats );
17045  }
17046 
17047  void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17048  for ( auto const& listener : m_listeners ) {
17049  listener->testGroupEnded( testGroupStats );
17050  }
17051  m_reporter->testGroupEnded( testGroupStats );
17052  }
17053 
17054  void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
17055  for ( auto const& listener : m_listeners ) {
17056  listener->testRunEnded( testRunStats );
17057  }
17058  m_reporter->testRunEnded( testRunStats );
17059  }
17060 
17061  void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
17062  for ( auto const& listener : m_listeners ) {
17063  listener->skipTest( testInfo );
17064  }
17065  m_reporter->skipTest( testInfo );
17066  }
17067 
17068  bool ListeningReporter::isMulti() const {
17069  return true;
17070  }
17071 
17072 } // end namespace Catch
17073 // end catch_reporter_listening.cpp
17074 // start catch_reporter_xml.cpp
17075 
17076 #if defined(_MSC_VER)
17077 #pragma warning(push)
17078 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
17079  // Note that 4062 (not all labels are handled
17080  // and default is missing) is enabled
17081 #endif
17082 
17083 namespace Catch {
17084  XmlReporter::XmlReporter( ReporterConfig const& _config )
17085  : StreamingReporterBase( _config ),
17086  m_xml(_config.stream())
17087  {
17088  m_reporterPrefs.shouldRedirectStdOut = true;
17089  m_reporterPrefs.shouldReportAllAssertions = true;
17090  }
17091 
17092  XmlReporter::~XmlReporter() = default;
17093 
17094  std::string XmlReporter::getDescription() {
17095  return "Reports test results as an XML document";
17096  }
17097 
17098  std::string XmlReporter::getStylesheetRef() const {
17099  return std::string();
17100  }
17101 
17102  void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
17103  m_xml
17104  .writeAttribute( "filename", sourceInfo.file )
17105  .writeAttribute( "line", sourceInfo.line );
17106  }
17107 
17108  void XmlReporter::noMatchingTestCases( std::string const& s ) {
17109  StreamingReporterBase::noMatchingTestCases( s );
17110  }
17111 
17112  void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
17113  StreamingReporterBase::testRunStarting( testInfo );
17114  std::string stylesheetRef = getStylesheetRef();
17115  if( !stylesheetRef.empty() )
17116  m_xml.writeStylesheetRef( stylesheetRef );
17117  m_xml.startElement( "Catch" );
17118  if( !m_config->name().empty() )
17119  m_xml.writeAttribute( "name", m_config->name() );
17120  if (m_config->testSpec().hasFilters())
17121  m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
17122  if( m_config->rngSeed() != 0 )
17123  m_xml.scopedElement( "Randomness" )
17124  .writeAttribute( "seed", m_config->rngSeed() );
17125  }
17126 
17127  void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
17128  StreamingReporterBase::testGroupStarting( groupInfo );
17129  m_xml.startElement( "Group" )
17130  .writeAttribute( "name", groupInfo.name );
17131  }
17132 
17133  void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
17134  StreamingReporterBase::testCaseStarting(testInfo);
17135  m_xml.startElement( "TestCase" )
17136  .writeAttribute( "name", trim( testInfo.name ) )
17137  .writeAttribute( "description", testInfo.description )
17138  .writeAttribute( "tags", testInfo.tagsAsString() );
17139 
17140  writeSourceInfo( testInfo.lineInfo );
17141 
17142  if ( m_config->showDurations() == ShowDurations::Always )
17143  m_testCaseTimer.start();
17144  m_xml.ensureTagClosed();
17145  }
17146 
17147  void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
17148  StreamingReporterBase::sectionStarting( sectionInfo );
17149  if( m_sectionDepth++ > 0 ) {
17150  m_xml.startElement( "Section" )
17151  .writeAttribute( "name", trim( sectionInfo.name ) );
17152  writeSourceInfo( sectionInfo.lineInfo );
17153  m_xml.ensureTagClosed();
17154  }
17155  }
17156 
17157  void XmlReporter::assertionStarting( AssertionInfo const& ) { }
17158 
17159  bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
17160 
17161  AssertionResult const& result = assertionStats.assertionResult;
17162 
17163  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
17164 
17165  if( includeResults || result.getResultType() == ResultWas::Warning ) {
17166  // Print any info messages in <Info> tags.
17167  for( auto const& msg : assertionStats.infoMessages ) {
17168  if( msg.type == ResultWas::Info && includeResults ) {
17169  m_xml.scopedElement( "Info" )
17170  .writeText( msg.message );
17171  } else if ( msg.type == ResultWas::Warning ) {
17172  m_xml.scopedElement( "Warning" )
17173  .writeText( msg.message );
17174  }
17175  }
17176  }
17177 
17178  // Drop out if result was successful but we're not printing them.
17179  if( !includeResults && result.getResultType() != ResultWas::Warning )
17180  return true;
17181 
17182  // Print the expression if there is one.
17183  if( result.hasExpression() ) {
17184  m_xml.startElement( "Expression" )
17185  .writeAttribute( "success", result.succeeded() )
17186  .writeAttribute( "type", result.getTestMacroName() );
17187 
17188  writeSourceInfo( result.getSourceInfo() );
17189 
17190  m_xml.scopedElement( "Original" )
17191  .writeText( result.getExpression() );
17192  m_xml.scopedElement( "Expanded" )
17193  .writeText( result.getExpandedExpression() );
17194  }
17195 
17196  // And... Print a result applicable to each result type.
17197  switch( result.getResultType() ) {
17198  case ResultWas::ThrewException:
17199  m_xml.startElement( "Exception" );
17200  writeSourceInfo( result.getSourceInfo() );
17201  m_xml.writeText( result.getMessage() );
17202  m_xml.endElement();
17203  break;
17204  case ResultWas::FatalErrorCondition:
17205  m_xml.startElement( "FatalErrorCondition" );
17206  writeSourceInfo( result.getSourceInfo() );
17207  m_xml.writeText( result.getMessage() );
17208  m_xml.endElement();
17209  break;
17210  case ResultWas::Info:
17211  m_xml.scopedElement( "Info" )
17212  .writeText( result.getMessage() );
17213  break;
17214  case ResultWas::Warning:
17215  // Warning will already have been written
17216  break;
17217  case ResultWas::ExplicitFailure:
17218  m_xml.startElement( "Failure" );
17219  writeSourceInfo( result.getSourceInfo() );
17220  m_xml.writeText( result.getMessage() );
17221  m_xml.endElement();
17222  break;
17223  default:
17224  break;
17225  }
17226 
17227  if( result.hasExpression() )
17228  m_xml.endElement();
17229 
17230  return true;
17231  }
17232 
17233  void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
17234  StreamingReporterBase::sectionEnded( sectionStats );
17235  if( --m_sectionDepth > 0 ) {
17236  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
17237  e.writeAttribute( "successes", sectionStats.assertions.passed );
17238  e.writeAttribute( "failures", sectionStats.assertions.failed );
17239  e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
17240 
17241  if ( m_config->showDurations() == ShowDurations::Always )
17242  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
17243 
17244  m_xml.endElement();
17245  }
17246  }
17247 
17248  void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
17249  StreamingReporterBase::testCaseEnded( testCaseStats );
17250  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
17251  e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
17252 
17253  if ( m_config->showDurations() == ShowDurations::Always )
17254  e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
17255 
17256  if( !testCaseStats.stdOut.empty() )
17257  m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
17258  if( !testCaseStats.stdErr.empty() )
17259  m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
17260 
17261  m_xml.endElement();
17262  }
17263 
17264  void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
17265  StreamingReporterBase::testGroupEnded( testGroupStats );
17266  // TODO: Check testGroupStats.aborting and act accordingly.
17267  m_xml.scopedElement( "OverallResults" )
17268  .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
17269  .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
17270  .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
17271  m_xml.scopedElement( "OverallResultsCases")
17272  .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
17273  .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
17274  .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
17275  m_xml.endElement();
17276  }
17277 
17278  void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
17279  StreamingReporterBase::testRunEnded( testRunStats );
17280  m_xml.scopedElement( "OverallResults" )
17281  .writeAttribute( "successes", testRunStats.totals.assertions.passed )
17282  .writeAttribute( "failures", testRunStats.totals.assertions.failed )
17283  .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
17284  m_xml.scopedElement( "OverallResultsCases")
17285  .writeAttribute( "successes", testRunStats.totals.testCases.passed )
17286  .writeAttribute( "failures", testRunStats.totals.testCases.failed )
17287  .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
17288  m_xml.endElement();
17289  }
17290 
17291 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17292  void XmlReporter::benchmarkPreparing(std::string const& name) {
17293  m_xml.startElement("BenchmarkResults")
17294  .writeAttribute("name", name);
17295  }
17296 
17297  void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
17298  m_xml.writeAttribute("samples", info.samples)
17299  .writeAttribute("resamples", info.resamples)
17300  .writeAttribute("iterations", info.iterations)
17301  .writeAttribute("clockResolution", info.clockResolution)
17302  .writeAttribute("estimatedDuration", info.estimatedDuration)
17303  .writeComment("All values in nano seconds");
17304  }
17305 
17306  void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
17307  m_xml.startElement("mean")
17308  .writeAttribute("value", benchmarkStats.mean.point.count())
17309  .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
17310  .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
17311  .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
17312  m_xml.endElement();
17313  m_xml.startElement("standardDeviation")
17314  .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
17315  .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
17316  .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
17317  .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
17318  m_xml.endElement();
17319  m_xml.startElement("outliers")
17320  .writeAttribute("variance", benchmarkStats.outlierVariance)
17321  .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
17322  .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
17323  .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
17324  .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
17325  m_xml.endElement();
17326  m_xml.endElement();
17327  }
17328 
17329  void XmlReporter::benchmarkFailed(std::string const &error) {
17330  m_xml.scopedElement("failed").
17331  writeAttribute("message", error);
17332  m_xml.endElement();
17333  }
17334 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17335 
17336  CATCH_REGISTER_REPORTER( "xml", XmlReporter )
17337 
17338 } // end namespace Catch
17339 
17340 #if defined(_MSC_VER)
17341 #pragma warning(pop)
17342 #endif
17343 // end catch_reporter_xml.cpp
17344 
17345 namespace Catch {
17346  LeakDetector leakDetector;
17347 }
17348 
17349 #ifdef __clang__
17350 #pragma clang diagnostic pop
17351 #endif
17352 
17353 // end catch_impl.hpp
17354 #endif
17355 
17356 #ifdef CATCH_CONFIG_MAIN
17357 // start catch_default_main.hpp
17358 
17359 #ifndef __OBJC__
17360 
17361 #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
17362 // Standard C/C++ Win32 Unicode wmain entry point
17363 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
17364 #else
17365 // Standard C/C++ main entry point
17366 int main (int argc, char * argv[]) {
17367 #endif
17368 
17369  return Catch::Session().run( argc, argv );
17370 }
17371 
17372 #else // __OBJC__
17373 
17374 // Objective-C entry point
17375 int main (int argc, char * const argv[]) {
17376 #if !CATCH_ARC_ENABLED
17377  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
17378 #endif
17379 
17380  Catch::registerTestMethods();
17381  int result = Catch::Session().run( argc, (char**)argv );
17382 
17383 #if !CATCH_ARC_ENABLED
17384  [pool drain];
17385 #endif
17386 
17387  return result;
17388 }
17389 
17390 #endif // __OBJC__
17391 
17392 // end catch_default_main.hpp
17393 #endif
17394 
17395 #if !defined(CATCH_CONFIG_IMPL_ONLY)
17396 
17397 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
17398 # undef CLARA_CONFIG_MAIN
17399 #endif
17400 
17401 #if !defined(CATCH_CONFIG_DISABLE)
17403 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17404 #ifdef CATCH_CONFIG_PREFIX_ALL
17405 
17406 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17407 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17408 
17409 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17410 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17411 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17412 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17413 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17414 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17415 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17416 
17417 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17418 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17419 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17420 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17421 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17422 
17423 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17424 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17425 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17426 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17427 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17428 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17429 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17430 
17431 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17432 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17433 
17434 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17435 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17436 
17437 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
17438 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
17439 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17440 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
17441 
17442 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17443 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17444 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17445 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17446 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17447 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17448 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17449 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17450 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17451 
17452 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17453 
17454 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17455 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17456 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17457 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17458 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17459 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17460 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17461 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17462 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17463 #else
17464 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17465 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17466 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17467 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17468 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17469 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17470 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17471 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17472 #endif
17473 
17474 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17475 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
17476 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
17477 #else
17478 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
17479 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
17480 #endif
17481 
17482 // "BDD-style" convenience wrappers
17483 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
17484 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17485 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
17486 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17487 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
17488 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17489 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
17490 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
17491 
17492 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17493 #define CATCH_BENCHMARK(...) \
17494  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__,,))
17495 #define CATCH_BENCHMARK_ADVANCED(name) \
17496  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17497 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17498 
17499 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17500 #else
17501 
17502 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17503 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17504 
17505 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17506 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
17507 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
17508 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17509 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
17510 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17511 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
17512 
17513 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17514 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
17515 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17516 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17517 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
17518 
17519 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17520 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
17521 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17522 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17523 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
17524 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17525 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17526 
17527 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17528 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
17529 
17530 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
17531 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17532 
17533 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
17534 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
17535 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
17536 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
17537 
17538 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
17539 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
17540 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
17541 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
17542 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
17543 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
17544 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
17545 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17546 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
17547 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17548 
17549 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17550 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17551 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
17552 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17553 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17554 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
17555 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
17556 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
17557 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
17558 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
17559 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
17560 #else
17561 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
17562 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
17563 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17564 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17565 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
17566 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
17567 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17568 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
17569 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
17570 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
17571 #endif
17572 
17573 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17574 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
17575 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
17576 #else
17577 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
17578 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
17579 #endif
17580 
17581 #endif
17582 
17583 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
17584 
17585 // "BDD-style" convenience wrappers
17586 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
17587 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
17588 
17589 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
17590 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
17591 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
17592 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
17593 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
17594 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
17595 
17596 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17597 #define BENCHMARK(...) \
17598  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__,,))
17599 #define BENCHMARK_ADVANCED(name) \
17600  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17601 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17602 
17603 using Catch::Detail::Approx;
17604 
17605 #else // CATCH_CONFIG_DISABLE
17606 
17608 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17609 #ifdef CATCH_CONFIG_PREFIX_ALL
17610 
17611 #define CATCH_REQUIRE( ... ) (void)(0)
17612 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
17613 
17614 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
17615 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17616 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
17617 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17618 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17619 #endif// CATCH_CONFIG_DISABLE_MATCHERS
17620 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
17621 
17622 #define CATCH_CHECK( ... ) (void)(0)
17623 #define CATCH_CHECK_FALSE( ... ) (void)(0)
17624 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
17625 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
17626 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
17627 
17628 #define CATCH_CHECK_THROWS( ... ) (void)(0)
17629 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17630 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
17631 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17632 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17633 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17634 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
17635 
17636 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17637 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
17638 
17639 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
17640 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17641 
17642 #define CATCH_INFO( msg ) (void)(0)
17643 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
17644 #define CATCH_WARN( msg ) (void)(0)
17645 #define CATCH_CAPTURE( msg ) (void)(0)
17646 
17647 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17648 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17649 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
17650 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
17651 #define CATCH_SECTION( ... )
17652 #define CATCH_DYNAMIC_SECTION( ... )
17653 #define CATCH_FAIL( ... ) (void)(0)
17654 #define CATCH_FAIL_CHECK( ... ) (void)(0)
17655 #define CATCH_SUCCEED( ... ) (void)(0)
17656 
17657 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17658 
17659 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17660 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17661 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17662 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17663 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17664 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17665 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17666 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17667 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17668 #else
17669 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17670 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17671 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17672 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17673 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17674 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
17675 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17676 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17677 #endif
17678 
17679 // "BDD-style" convenience wrappers
17680 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17681 #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 )
17682 #define CATCH_GIVEN( desc )
17683 #define CATCH_AND_GIVEN( desc )
17684 #define CATCH_WHEN( desc )
17685 #define CATCH_AND_WHEN( desc )
17686 #define CATCH_THEN( desc )
17687 #define CATCH_AND_THEN( desc )
17688 
17689 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
17690 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
17691 
17692 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17693 #else
17694 
17695 #define REQUIRE( ... ) (void)(0)
17696 #define REQUIRE_FALSE( ... ) (void)(0)
17697 
17698 #define REQUIRE_THROWS( ... ) (void)(0)
17699 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
17700 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
17701 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17702 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17703 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17704 #define REQUIRE_NOTHROW( ... ) (void)(0)
17705 
17706 #define CHECK( ... ) (void)(0)
17707 #define CHECK_FALSE( ... ) (void)(0)
17708 #define CHECKED_IF( ... ) if (__VA_ARGS__)
17709 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
17710 #define CHECK_NOFAIL( ... ) (void)(0)
17711 
17712 #define CHECK_THROWS( ... ) (void)(0)
17713 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
17714 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
17715 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17716 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
17717 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17718 #define CHECK_NOTHROW( ... ) (void)(0)
17719 
17720 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17721 #define CHECK_THAT( arg, matcher ) (void)(0)
17722 
17723 #define REQUIRE_THAT( arg, matcher ) (void)(0)
17724 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17725 
17726 #define INFO( msg ) (void)(0)
17727 #define UNSCOPED_INFO( msg ) (void)(0)
17728 #define WARN( msg ) (void)(0)
17729 #define CAPTURE( msg ) (void)(0)
17730 
17731 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17732 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17733 #define METHOD_AS_TEST_CASE( method, ... )
17734 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
17735 #define SECTION( ... )
17736 #define DYNAMIC_SECTION( ... )
17737 #define FAIL( ... ) (void)(0)
17738 #define FAIL_CHECK( ... ) (void)(0)
17739 #define SUCCEED( ... ) (void)(0)
17740 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
17741 
17742 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17743 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17744 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17745 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17746 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
17747 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17748 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17749 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17750 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17751 #else
17752 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
17753 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
17754 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
17755 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
17756 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17757 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
17758 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17759 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
17760 #endif
17761 
17762 #define STATIC_REQUIRE( ... ) (void)(0)
17763 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
17764 
17765 #endif
17766 
17767 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
17768 
17769 // "BDD-style" convenience wrappers
17770 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
17771 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
17772 
17773 #define GIVEN( desc )
17774 #define AND_GIVEN( desc )
17775 #define WHEN( desc )
17776 #define AND_WHEN( desc )
17777 #define THEN( desc )
17778 #define AND_THEN( desc )
17779 
17780 using Catch::Detail::Approx;
17781 
17782 #endif
17783 
17784 #endif // ! CATCH_CONFIG_IMPL_ONLY
17785 
17786 // start catch_reenable_warnings.h
17787 
17788 
17789 #ifdef __clang__
17790 # ifdef __ICC // icpc defines the __clang__ macro
17791 # pragma warning(pop)
17792 # else
17793 # pragma clang diagnostic pop
17794 # endif
17795 #elif defined __GNUC__
17796 # pragma GCC diagnostic pop
17797 #endif
17798 
17799 // end catch_reenable_warnings.h
17800 // end catch.hpp
17801 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
17802 
Definition: catch.hpp:2555
Definition: catch.hpp:5399
Definition: catch.hpp:2231
Definition: catch.hpp:2659
Definition: catch.hpp:5319
Definition: catch.hpp:10290
Definition: catch.hpp:3085
Definition: catch.hpp:10556
Definition: catch.hpp:1571
Definition: catch.hpp:10057
Definition: catch.hpp:3028
Definition: catch.hpp:10655
Definition: catch.hpp:2345
Definition: catch.hpp:3926
Definition: catch.hpp:4299
Definition: catch.hpp:4163
Definition: catch.hpp:3974
Definition: catch.hpp:3852
Definition: catch.hpp:3993
Definition: catch.hpp:4017
Definition: catch.hpp:4714
Definition: catch.hpp:4258
Definition: catch.hpp:4669
Definition: catch.hpp:4202
Definition: catch.hpp:3960
Definition: catch.hpp:4127
Definition: catch.hpp:6327
Definition: catch.hpp:2533
Definition: catch.hpp:6072
Definition: catch.hpp:10961
Definition: catch.hpp:3777
Definition: catch.hpp:498
Definition: catch.hpp:4875
Definition: catch.hpp:4411
Definition: catch.hpp:11966
Definition: catch.hpp:11915
Definition: catch.hpp:11904
Definition: catch.hpp:11894
Definition: catch.hpp:11924
Definition: catch.hpp:6051
Definition: catch.hpp:12278
Definition: catch.hpp:1447
Definition: catch.hpp:8081
Definition: catch.hpp:2648
Definition: catch.hpp:2918
Definition: catch.hpp:13117
Definition: catch.hpp:4560
Definition: catch.hpp:12367
Definition: catch.hpp:12342
Definition: catch.hpp:613
Definition: catch.hpp:16222
Definition: catch.hpp:12321
Definition: catch.hpp:11946
Definition: catch.hpp:4809
Definition: catch.hpp:7489
Definition: catch.hpp:7601
Definition: catch.hpp:7552
Definition: catch.hpp:7527
Definition: catch.hpp:12257
Definition: catch.hpp:969
Definition: catch.hpp:12238
Definition: catch.hpp:5113
Definition: catch.hpp:5203
Definition: catch.hpp:2901
Definition: catch.hpp:2307
Definition: catch.hpp:5082
Definition: catch.hpp:6234
Definition: catch.hpp:6375
Definition: catch.hpp:6252
Definition: catch.hpp:6249
Definition: catch.hpp:8512
Definition: catch.hpp:8689
Definition: catch.hpp:8681
Definition: catch.hpp:9361
Definition: catch.hpp:8845
Definition: catch.hpp:9017
Definition: catch.hpp:9319
Definition: catch.hpp:9395
Definition: catch.hpp:9065
Definition: catch.hpp:9244
Definition: catch.hpp:9268
Definition: catch.hpp:8956
Definition: catch.hpp:8972
Definition: catch.hpp:8884
Definition: catch.hpp:4864
Definition: catch.hpp:1404
Definition: catch.hpp:2550
Definition: catch.hpp:5386
Definition: catch.hpp:5527
Definition: catch.hpp:993
Definition: catch.hpp:7294
Definition: catch.hpp:6616
Definition: catch.hpp:6551
Definition: catch.hpp:7393
Definition: catch.hpp:6786
Definition: catch.hpp:6657
Definition: catch.hpp:6667
Definition: catch.hpp:5434
Definition: catch.hpp:6903
Definition: catch.hpp:5455
Definition: catch.hpp:7200
Definition: catch.hpp:6824
Definition: catch.hpp:6468
Definition: catch.hpp:5614
Definition: catch.hpp:5625
Definition: catch.hpp:493
Definition: catch.hpp:5990
Definition: catch.hpp:6118
Definition: catch.hpp:5275
Definition: catch.hpp:6155
Definition: catch.hpp:2836
Definition: catch.hpp:5810
Definition: catch.hpp:5808
Definition: catch.hpp:2421
Definition: catch.hpp:1473
Definition: catch.hpp:1934
Definition: catch.hpp:8025
Definition: catch.hpp:12528
Definition: catch.hpp:3948
Definition: catch.hpp:4067
Definition: catch.hpp:5517
Definition: catch.hpp:4514
Definition: catch.hpp:4361
Definition: catch.hpp:3017
Definition: catch.hpp:3022
Definition: catch.hpp:3866
Definition: catch.hpp:4370
Definition: catch.hpp:1483
Definition: catch.hpp:2983
Definition: catch.hpp:2972
Definition: catch.hpp:5696
Definition: catch.hpp:5703
Definition: catch.hpp:2465
Definition: catch.hpp:4842
Definition: catch.hpp:12359
Definition: catch.hpp:1440
Definition: catch.hpp:5651
Definition: catch.hpp:5189
Definition: catch.hpp:587
Definition: catch.hpp:579
Definition: catch.hpp:2209
Definition: catch.hpp:5500
Definition: catch.hpp:7633
Definition: catch.hpp:3295
Definition: catch.hpp:3328
Definition: catch.hpp:3363
Definition: catch.hpp:3287
Definition: catch.hpp:3269
Definition: catch.hpp:3546
Definition: catch.hpp:3688
Definition: catch.hpp:3665
Definition: catch.hpp:2634
Definition: catch.hpp:2606
Definition: catch.hpp:2623
Definition: catch.hpp:987
Definition: catch.hpp:556
Definition: catch.hpp:5481
Definition: catch.hpp:5494
Definition: catch.hpp:1384
Definition: catch.hpp:1360
Definition: catch.hpp:4495
Definition: catch.hpp:2883
Definition: catch.hpp:2867
Definition: catch.hpp:5543
Definition: catch.hpp:4490
Definition: catch.hpp:10765
Definition: catch.hpp:509
Definition: catch.hpp:541
Definition: catch.hpp:5736
Definition: catch.hpp:1622
Definition: catch.hpp:13655
Definition: catch.hpp:16535
Definition: catch.hpp:12307
Definition: catch.hpp:11167
Definition: catch.hpp:4774
Definition: catch.hpp:5560
Definition: catch.hpp:5974
Definition: catch.hpp:2528
Definition: catch.hpp:5580
Definition: catch.hpp:5513
Definition: catch.hpp:5597
Definition: catch.hpp:2849
Definition: catch.hpp:4500
Definition: catch.hpp:13168
Definition: catch.hpp:4505
Definition: catch.hpp:4484
Definition: catch.hpp:932
Definition: catch.hpp:9227
Definition: catch.hpp:9142
Definition: catch.hpp:9175
Definition: catch.hpp:9215
Definition: catch.hpp:9134
Definition: catch.hpp:9139
Definition: catch.hpp:9148
Definition: catch.hpp:9085
Definition: catch.hpp:9496
Definition: catch.hpp:9187
Definition: catch.hpp:9126
Definition: catch.hpp:9510
Definition: catch.hpp:8870
Definition: catch.hpp:8828
Definition: catch.hpp:2005
Definition: catch.hpp:2000
Definition: catch.hpp:935
Definition: catch.hpp:943
Definition: catch.hpp:2014
Definition: catch.hpp:3223
Definition: catch.hpp:2071
Definition: catch.hpp:934
Definition: catch.hpp:488