ChaiScript
catch.hpp
1 /*
2  * Catch v2.13.6
3  * Generated: 2021-04-16 18:23:38.044268
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved.
7  *
8  * Distributed under the Boost Software License, Version 1.0. (See accompanying
9  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 // start catch.hpp
14 
15 #define CATCH_VERSION_MAJOR 2
16 #define CATCH_VERSION_MINOR 13
17 #define CATCH_VERSION_PATCH 6
18 
19 #ifdef __clang__
20 #pragma clang system_header
21 #elif defined __GNUC__
22 #pragma GCC system_header
23 #endif
24 
25 // start catch_suppress_warnings.h
26 
27 #ifdef __clang__
28 #ifdef __ICC // icpc defines the __clang__ macro
29 #pragma warning(push)
30 #pragma warning(disable : 161 1682)
31 #else // __ICC
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wpadded"
34 #pragma clang diagnostic ignored "-Wswitch-enum"
35 #pragma clang diagnostic ignored "-Wcovered-switch-default"
36 #endif
37 #elif defined __GNUC__
38 // Because REQUIREs trigger GCC's -Wparentheses, and because still
39 // supported version of g++ have only buggy support for _Pragmas,
40 // Wparentheses have to be suppressed globally.
41 #pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
42 
43 #pragma GCC diagnostic push
44 #pragma GCC diagnostic ignored "-Wunused-variable"
45 #pragma GCC diagnostic ignored "-Wpadded"
46 #endif
47 // end catch_suppress_warnings.h
48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
49 #define CATCH_IMPL
50 #define CATCH_CONFIG_ALL_PARTS
51 #endif
52 
53 // In the impl file, we want to have access to all parts of the headers
54 // Can also be used to sanely support PCHs
55 #if defined(CATCH_CONFIG_ALL_PARTS)
56 #define CATCH_CONFIG_EXTERNAL_INTERFACES
57 #if defined(CATCH_CONFIG_DISABLE_MATCHERS)
58 #undef CATCH_CONFIG_DISABLE_MATCHERS
59 #endif
60 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
61 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
62 #endif
63 #endif
64 
65 #if !defined(CATCH_CONFIG_IMPL_ONLY)
66 // start catch_platform.h
67 
68 // See e.g.:
69 // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
70 #ifdef __APPLE__
71 #include <TargetConditionals.h>
72 #if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
73 #define CATCH_PLATFORM_MAC
74 #elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
75 #define CATCH_PLATFORM_IPHONE
76 #endif
77 
78 #elif defined(linux) || defined(__linux) || defined(__linux__)
79 #define CATCH_PLATFORM_LINUX
80 
81 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
82 #define CATCH_PLATFORM_WINDOWS
83 #endif
84 
85 // end catch_platform.h
86 
87 #ifdef CATCH_IMPL
88 #ifndef CLARA_CONFIG_MAIN
89 #define CLARA_CONFIG_MAIN_NOT_DEFINED
90 #define CLARA_CONFIG_MAIN
91 #endif
92 #endif
93 
94 // start catch_user_interfaces.h
95 
96 namespace Catch {
97  unsigned int rngSeed();
98 }
99 
100 // end catch_user_interfaces.h
101 // start catch_tag_alias_autoregistrar.h
102 
103 // start catch_common.h
104 
105 // start catch_compiler_capabilities.h
106 
107 // Detect a number of compiler features - by compiler
108 // The following features are defined:
109 //
110 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
111 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
112 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
113 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
114 // ****************
115 // Note to maintainers: if new toggles are added please document them
116 // in configuration.md, too
117 // ****************
118 
119 // In general each macro has a _NO_<feature name> form
120 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
121 // Many features, at point of detection, define an _INTERNAL_ macro, so they
122 // can be combined, en-mass, with the _NO_ forms later.
123 
124 #ifdef __cplusplus
125 
126 #if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
127 #define CATCH_CPP14_OR_GREATER
128 #endif
129 
130 #if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
131 #define CATCH_CPP17_OR_GREATER
132 #endif
133 
134 #endif
135 
136 // Only GCC compiler should be used in this block, so other compilers trying to
137 // mask themselves as GCC should be ignored.
138 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
139 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic push")
140 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic pop")
141 
142 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
143 
144 #endif
145 
146 #if defined(__clang__)
147 
148 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("clang diagnostic push")
149 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("clang diagnostic pop")
150 
151 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
152 // which results in calls to destructors being emitted for each temporary,
153 // without a matching initialization. In practice, this can result in something
154 // like `std::string::~string` being called on an uninitialized value.
155 //
156 // For example, this code will likely segfault under IBM XL:
157 // ```
158 // REQUIRE(std::string("12") + "34" == "1234")
159 // ```
160 //
161 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
162 #if !defined(__ibmxl__) && !defined(__CUDACC__)
163 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...) \
164  (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
165 #endif
166 
167 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
168  _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"")
169 
170 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma("clang diagnostic ignored \"-Wparentheses\"")
171 
172 #define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS _Pragma("clang diagnostic ignored \"-Wunused-variable\"")
173 
174 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"")
175 
176 #define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS _Pragma("clang diagnostic ignored \"-Wunused-template\"")
177 
178 #endif // __clang__
179 
181 // Assume that non-Windows platforms support posix signals by default
182 #if !defined(CATCH_PLATFORM_WINDOWS)
183 #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
184 #endif
185 
187 // We know some environments not to support full POSIX signals
188 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
189 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
190 #endif
191 
192 #ifdef __OS400__
193 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
194 #define CATCH_CONFIG_COLOUR_NONE
195 #endif
196 
198 // Android somehow still does not support std::to_string
199 #if defined(__ANDROID__)
200 #define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
201 #define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
202 #endif
203 
205 // Not all Windows environments support SEH properly
206 #if defined(__MINGW32__)
207 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
208 #endif
209 
211 // PS4
212 #if defined(__ORBIS__)
213 #define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
214 #endif
215 
217 // Cygwin
218 #ifdef __CYGWIN__
219 
220 // Required for some versions of Cygwin to declare gettimeofday
221 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
222 #define _BSD_SOURCE
223 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
224 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
225 #if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
226 
227 #define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
228 
229 #endif
230 #endif // __CYGWIN__
231 
233 // Visual C++
234 #if defined(_MSC_VER)
235 
236 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma(warning(push))
237 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma(warning(pop))
238 
239 // Universal Windows platform does not support SEH
240 // Or console colours (or console at all...)
241 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
242 #define CATCH_CONFIG_COLOUR_NONE
243 #else
244 #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
245 #endif
246 
247 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
248 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
249 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
250 #if !defined(__clang__) // Handle Clang masquerading for msvc
251 #if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
252 #define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
253 #endif // MSVC_TRADITIONAL
254 #endif // __clang__
255 
256 #endif // _MSC_VER
257 
258 #if defined(_REENTRANT) || defined(_MSC_VER)
259 // Enable async processing, as -pthread is specified or no additional linking is required
260 #define CATCH_INTERNAL_CONFIG_USE_ASYNC
261 #endif // _MSC_VER
262 
264 // Check if we are compiled with -fno-exceptions or equivalent
265 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
266 #define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
267 #endif
268 
270 // DJGPP
271 #ifdef __DJGPP__
272 #define CATCH_INTERNAL_CONFIG_NO_WCHAR
273 #endif // __DJGPP__
274 
276 // Embarcadero C++Build
277 #if defined(__BORLANDC__)
278 #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
279 #endif
280 
282 
283 // Use of __COUNTER__ is suppressed during code analysis in
284 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
285 // handled by it.
286 // Otherwise all supported compilers support COUNTER macro,
287 // but user still might want to turn it off
288 #if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L)
289 #define CATCH_INTERNAL_CONFIG_COUNTER
290 #endif
291 
293 
294 // RTX is a special version of Windows that is real time.
295 // This means that it is detected as Windows, but does not provide
296 // the same set of capabilities as real Windows does.
297 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
298 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
299 #define CATCH_INTERNAL_CONFIG_NO_ASYNC
300 #define CATCH_CONFIG_COLOUR_NONE
301 #endif
302 
303 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
304 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
305 #endif
306 
307 // Various stdlib support checks that require __has_include
308 #if defined(__has_include)
309 // Check if string_view is available and usable
310 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
311 #define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
312 #endif
313 
314 // Check if optional is available and usable
315 #if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
316 #define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
317 #endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
318 
319 // Check if byte is available and usable
320 #if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
321 #include <cstddef>
322 #if __cpp_lib_byte > 0
323 #define CATCH_INTERNAL_CONFIG_CPP17_BYTE
324 #endif
325 #endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
326 
327 // Check if variant is available and usable
328 #if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
329 #if defined(__clang__) && (__clang_major__ < 8)
330 // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
331 // fix should be in clang 8, workaround in libstdc++ 8.2
332 #include <ciso646>
333 #if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
334 #define CATCH_CONFIG_NO_CPP17_VARIANT
335 #else
336 #define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
337 #endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
338 #else
339 #define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
340 #endif // defined(__clang__) && (__clang_major__ < 8)
341 #endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
342 #endif // defined(__has_include)
343 
344 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
345 #define CATCH_CONFIG_COUNTER
346 #endif
347 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) \
348  && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
349 #define CATCH_CONFIG_WINDOWS_SEH
350 #endif
351 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
352 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) \
353  && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
354 #define CATCH_CONFIG_POSIX_SIGNALS
355 #endif
356 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
357 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
358 #define CATCH_CONFIG_WCHAR
359 #endif
360 
361 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) \
362  && !defined(CATCH_CONFIG_CPP11_TO_STRING)
363 #define CATCH_CONFIG_CPP11_TO_STRING
364 #endif
365 
366 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
367 #define CATCH_CONFIG_CPP17_OPTIONAL
368 #endif
369 
370 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) \
371  && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
372 #define CATCH_CONFIG_CPP17_STRING_VIEW
373 #endif
374 
375 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
376 #define CATCH_CONFIG_CPP17_VARIANT
377 #endif
378 
379 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
380 #define CATCH_CONFIG_CPP17_BYTE
381 #endif
382 
383 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
384 #define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
385 #endif
386 
387 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) \
388  && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
389 #define CATCH_CONFIG_NEW_CAPTURE
390 #endif
391 
392 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
393 #define CATCH_CONFIG_DISABLE_EXCEPTIONS
394 #endif
395 
396 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
397 #define CATCH_CONFIG_POLYFILL_ISNAN
398 #endif
399 
400 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) \
401  && !defined(CATCH_CONFIG_USE_ASYNC)
402 #define CATCH_CONFIG_USE_ASYNC
403 #endif
404 
405 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) \
406  && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
407 #define CATCH_CONFIG_ANDROID_LOGWRITE
408 #endif
409 
410 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) \
411  && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
412 #define CATCH_CONFIG_GLOBAL_NEXTAFTER
413 #endif
414 
415 // Even if we do not think the compiler has that warning, we still have
416 // to provide a macro that can be used by the code.
417 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
418 #define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
419 #endif
420 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
421 #define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
422 #endif
423 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
424 #define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
425 #endif
426 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
427 #define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
428 #endif
429 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
430 #define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
431 #endif
432 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
433 #define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
434 #endif
435 
436 // The goal of this macro is to avoid evaluation of the arguments, but
437 // still have the compiler warn on problems inside...
438 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
439 #define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
440 #endif
441 
442 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
443 #undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
444 #elif defined(__clang__) && (__clang_major__ < 5)
445 #undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
446 #endif
447 
448 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
449 #define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
450 #endif
451 
452 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
453 #define CATCH_TRY if ((true))
454 #define CATCH_CATCH_ALL if ((false))
455 #define CATCH_CATCH_ANON(type) if ((false))
456 #else
457 #define CATCH_TRY try
458 #define CATCH_CATCH_ALL catch (...)
459 #define CATCH_CATCH_ANON(type) catch (type)
460 #endif
461 
462 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) \
463  && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
464 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
465 #endif
466 
467 // end catch_compiler_capabilities.h
468 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line
469 #define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line)
470 #ifdef CATCH_CONFIG_COUNTER
471 #define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__)
472 #else
473 #define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__)
474 #endif
475 
476 #include <cstdint>
477 #include <iosfwd>
478 #include <string>
479 
480 // We need a dummy global operator<< so we can bring it into Catch namespace later
482 };
483 std::ostream &operator<<(std::ostream &, Catch_global_namespace_dummy);
484 
485 namespace Catch {
486  struct CaseSensitive {
487  enum Choice {
488  Yes,
489  No
490  };
491  };
492 
493  class NonCopyable {
494  NonCopyable(NonCopyable const &) = delete;
495  NonCopyable(NonCopyable &&) = delete;
496  NonCopyable &operator=(NonCopyable const &) = delete;
497  NonCopyable &operator=(NonCopyable &&) = delete;
498 
499  protected:
500  NonCopyable();
501  virtual ~NonCopyable();
502  };
503 
504  struct SourceLineInfo {
505  SourceLineInfo() = delete;
506  SourceLineInfo(char const *_file, std::size_t _line) noexcept
507  : file(_file)
508  , line(_line) {
509  }
510 
511  SourceLineInfo(SourceLineInfo const &other) = default;
512  SourceLineInfo &operator=(SourceLineInfo const &) = default;
513  SourceLineInfo(SourceLineInfo &&) noexcept = default;
514  SourceLineInfo &operator=(SourceLineInfo &&) noexcept = default;
515 
516  bool empty() const noexcept { return file[0] == '\0'; }
517  bool operator==(SourceLineInfo const &other) const noexcept;
518  bool operator<(SourceLineInfo const &other) const noexcept;
519 
520  char const *file;
521  std::size_t line;
522  };
523 
524  std::ostream &operator<<(std::ostream &os, SourceLineInfo const &info);
525 
526  // Bring in operator<< from global namespace into Catch namespace
527  // This is necessary because the overload of operator<< above makes
528  // lookup stop at namespace Catch
529  using ::operator<<;
530 
531  // Use this in variadic streaming macros to allow
532  // >> +StreamEndStop
533  // as well as
534  // >> stuff +StreamEndStop
535  struct StreamEndStop {
536  std::string operator+() const;
537  };
538  template<typename T>
539  T const &operator+(T const &value, StreamEndStop) {
540  return value;
541  }
542 } // namespace Catch
543 
544 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo(__FILE__, static_cast<std::size_t>(__LINE__))
545 
546 // end catch_common.h
547 namespace Catch {
549  RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo);
550  };
551 
552 } // end namespace Catch
553 
554 #define CATCH_REGISTER_TAG_ALIAS(alias, spec) \
555  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
556  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
557  namespace { \
558  Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME(AutoRegisterTagAlias)(alias, spec, CATCH_INTERNAL_LINEINFO); \
559  } \
560  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
561 
562 // end catch_tag_alias_autoregistrar.h
563 // start catch_test_registry.h
564 
565 // start catch_interfaces_testcase.h
566 
567 #include <vector>
568 
569 namespace Catch {
570  class TestSpec;
571 
572  struct ITestInvoker {
573  virtual void invoke() const = 0;
574  virtual ~ITestInvoker();
575  };
576 
577  class TestCase;
578  struct IConfig;
579 
581  virtual ~ITestCaseRegistry();
582  virtual std::vector<TestCase> const &getAllTests() const = 0;
583  virtual std::vector<TestCase> const &getAllTestsSorted(IConfig const &config) const = 0;
584  };
585 
586  bool isThrowSafe(TestCase const &testCase, IConfig const &config);
587  bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config);
588  std::vector<TestCase> filterTests(std::vector<TestCase> const &testCases, TestSpec const &testSpec, IConfig const &config);
589  std::vector<TestCase> const &getAllTestCasesSorted(IConfig const &config);
590 
591 } // namespace Catch
592 
593 // end catch_interfaces_testcase.h
594 // start catch_stringref.h
595 
596 #include <cassert>
597 #include <cstddef>
598 #include <iosfwd>
599 #include <string>
600 
601 namespace Catch {
605  class StringRef {
606  public:
607  using size_type = std::size_t;
608  using const_iterator = const char *;
609 
610  private:
611  static constexpr char const *const s_empty = "";
612 
613  char const *m_start = s_empty;
614  size_type m_size = 0;
615 
616  public: // construction
617  constexpr StringRef() noexcept = default;
618 
619  StringRef(char const *rawChars) noexcept;
620 
621  constexpr StringRef(char const *rawChars, size_type size) noexcept
622  : m_start(rawChars)
623  , m_size(size) {
624  }
625 
626  StringRef(std::string const &stdString) noexcept
627  : m_start(stdString.c_str())
628  , m_size(stdString.size()) {
629  }
630 
631  explicit operator std::string() const { return std::string(m_start, m_size); }
632 
633  public: // operators
634  auto operator==(StringRef const &other) const noexcept -> bool;
635  auto operator!=(StringRef const &other) const noexcept -> bool { return !(*this == other); }
636 
637  auto operator[](size_type index) const noexcept -> char {
638  assert(index < m_size);
639  return m_start[index];
640  }
641 
642  public: // named queries
643  constexpr auto empty() const noexcept -> bool { return m_size == 0; }
644  constexpr auto size() const noexcept -> size_type { return m_size; }
645 
646  // Returns the current start pointer. If the StringRef is not
647  // null-terminated, throws std::domain_exception
648  auto c_str() const -> char const *;
649 
650  public: // substrings and searches
651  // Returns a substring of [start, start + length).
652  // If start + length > size(), then the substring is [start, size()).
653  // If start > size(), then the substring is empty.
654  auto substr(size_type start, size_type length) const noexcept -> StringRef;
655 
656  // Returns the current start pointer. May not be null-terminated.
657  auto data() const noexcept -> char const *;
658 
659  constexpr auto isNullTerminated() const noexcept -> bool { return m_start[m_size] == '\0'; }
660 
661  public: // iterators
662  constexpr const_iterator begin() const { return m_start; }
663  constexpr const_iterator end() const { return m_start + m_size; }
664  };
665 
666  auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &;
667  auto operator<<(std::ostream &os, StringRef const &sr) -> std::ostream &;
668 
669  constexpr auto operator"" _sr(char const *rawChars, std::size_t size) noexcept -> StringRef {
670  return StringRef(rawChars, size);
671  }
672 } // namespace Catch
673 
674 constexpr auto operator"" _catch_sr(char const *rawChars, std::size_t size) noexcept -> Catch::StringRef {
675  return Catch::StringRef(rawChars, size);
676 }
677 
678 // end catch_stringref.h
679 // start catch_preprocessor.hpp
680 
681 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
682 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
683 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
684 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
685 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
686 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
687 
688 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
689 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
690 // MSVC needs more evaluations
691 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
692 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
693 #else
694 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
695 #endif
696 
697 #define CATCH_REC_END(...)
698 #define CATCH_REC_OUT
699 
700 #define CATCH_EMPTY()
701 #define CATCH_DEFER(id) id CATCH_EMPTY()
702 
703 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
704 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
705 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
706 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
707 #define CATCH_REC_NEXT1(test, next) \
708  CATCH_DEFER(CATCH_REC_NEXT0) \
709  (test, next, 0)
710 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
711 
712 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
713 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0))(f, peek, __VA_ARGS__)
714 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
715 
716 #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) \
717  , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__)
718 #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) \
719  , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD))(f, userdata, peek, __VA_ARGS__)
720 #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) \
721  f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__)
722 
723 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
724 // and passes userdata as the first parameter to each invocation,
725 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
726 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
727 
728 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
729 
730 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
731 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__
732 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
733 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
734 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
735 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
736 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
737 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
738 #else
739 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
740 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
741 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
742 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
743 #endif
744 
745 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
746 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
747 
748 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
749 
750 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
751 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
752 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
753 #else
754 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) \
755  INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
756 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) \
757  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
758 #endif
759 
760 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...) CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST, __VA_ARGS__)
761 
762 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
763 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
764 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
765 #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) \
766  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
767 #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) \
768  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
769 #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) \
770  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
771 #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) \
772  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
773 #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) \
774  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
775 #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) \
776  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
777 #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
778  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
779 #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
780  INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
781 
782 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
783 
784 #define INTERNAL_CATCH_TYPE_GEN \
785  template<typename...> \
786  struct TypeList { \
787  }; \
788  template<typename... Ts> \
789  constexpr auto get_wrapper() noexcept->TypeList<Ts...> { \
790  return {}; \
791  } \
792  template<template<typename...> class...> \
793  struct TemplateTypeList { \
794  }; \
795  template<template<typename...> class... Cs> \
796  constexpr auto get_wrapper() noexcept->TemplateTypeList<Cs...> { \
797  return {}; \
798  } \
799  template<typename...> \
800  struct append; \
801  template<typename...> \
802  struct rewrap; \
803  template<template<typename...> class, typename...> \
804  struct create; \
805  template<template<typename...> class, typename> \
806  struct convert; \
807  \
808  template<typename T> \
809  struct append<T> { \
810  using type = T; \
811  }; \
812  template<template<typename...> class L1, typename... E1, template<typename...> class L2, typename... E2, typename... Rest> \
813  struct append<L1<E1...>, L2<E2...>, Rest...> { \
814  using type = typename append<L1<E1..., E2...>, Rest...>::type; \
815  }; \
816  template<template<typename...> class L1, typename... E1, typename... Rest> \
817  struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { \
818  using type = L1<E1...>; \
819  }; \
820  \
821  template<template<typename...> class Container, template<typename...> class List, typename... elems> \
822  struct rewrap<TemplateTypeList<Container>, List<elems...>> { \
823  using type = TypeList<Container<elems...>>; \
824  }; \
825  template<template<typename...> class Container, template<typename...> class List, class... Elems, typename... Elements> \
826  struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { \
827  using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; \
828  }; \
829  \
830  template<template<typename...> class Final, template<typename...> class... Containers, typename... Types> \
831  struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { \
832  using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; \
833  }; \
834  template<template<typename...> class Final, template<typename...> class List, typename... Ts> \
835  struct convert<Final, List<Ts...>> { \
836  using type = typename append<Final<>, TypeList<Ts>...>::type; \
837  };
838 
839 #define INTERNAL_CATCH_NTTP_1(signature, ...) \
840  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
841  struct Nttp { \
842  }; \
843  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
844  constexpr auto get_wrapper() noexcept->Nttp<__VA_ARGS__> { \
845  return {}; \
846  } \
847  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> \
848  struct NttpTemplateTypeList { \
849  }; \
850  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Cs> \
851  constexpr auto get_wrapper() noexcept->NttpTemplateTypeList<Cs...> { \
852  return {}; \
853  } \
854  \
855  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, \
856  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
857  class List, \
858  INTERNAL_CATCH_REMOVE_PARENS(signature)> \
859  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { \
860  using type = TypeList<Container<__VA_ARGS__>>; \
861  }; \
862  template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, \
863  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
864  class List, \
865  INTERNAL_CATCH_REMOVE_PARENS(signature), \
866  typename... Elements> \
867  struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { \
868  using type = \
869  typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; \
870  }; \
871  template<template<typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Containers, typename... Types> \
872  struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { \
873  using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; \
874  };
875 
876 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
877 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature) \
878  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
879  static void TestName()
880 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...) \
881  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
882  static void TestName()
883 
884 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
885 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature) \
886  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
887  static void TestName()
888 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature, ...) \
889  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
890  static void TestName()
891 
892 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature) \
893  template<typename Type> \
894  void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags) { \
895  Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags); \
896  }
897 
898 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...) \
899  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
900  void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags) { \
901  Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags); \
902  }
903 
904 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...) \
905  template<typename Type> \
906  void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags) { \
907  Catch::AutoReg(Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags); \
908  }
909 
910 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...) \
911  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
912  void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags) { \
913  Catch::AutoReg(Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags); \
914  }
915 
916 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
917 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature) \
918  template<typename TestType> \
919  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
920  void test(); \
921  }
922 
923 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...) \
924  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
925  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
926  void test(); \
927  }
928 
929 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
930 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature) \
931  template<typename TestType> \
932  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
933 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...) \
934  template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
935  void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
936 
937 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
938 #define INTERNAL_CATCH_NTTP_0
939 #define INTERNAL_CATCH_NTTP_GEN(...) \
940  INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, \
941  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
942  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
943  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
944  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
945  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
946  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
947  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
948  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
949  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
950  INTERNAL_CATCH_NTTP_1(__VA_ARGS__), \
951  INTERNAL_CATCH_NTTP_0)
952 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) \
953  INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
954  __VA_ARGS__, \
955  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
956  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
957  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
958  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
959  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
960  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
961  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
962  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
963  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
964  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, \
965  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0) \
966  (TestName, __VA_ARGS__)
967 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) \
968  INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
969  __VA_ARGS__, \
970  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
971  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
972  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
973  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
974  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
975  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
976  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
977  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
978  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
979  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, \
980  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0) \
981  (TestName, ClassName, __VA_ARGS__)
982 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) \
983  INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
984  __VA_ARGS__, \
985  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
986  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
987  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
988  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
989  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
990  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
991  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
992  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
993  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
994  INTERNAL_CATCH_NTTP_REGISTER_METHOD0, \
995  INTERNAL_CATCH_NTTP_REGISTER_METHOD0) \
996  (TestName, __VA_ARGS__)
997 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) \
998  INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
999  __VA_ARGS__, \
1000  INTERNAL_CATCH_NTTP_REGISTER, \
1001  INTERNAL_CATCH_NTTP_REGISTER, \
1002  INTERNAL_CATCH_NTTP_REGISTER, \
1003  INTERNAL_CATCH_NTTP_REGISTER, \
1004  INTERNAL_CATCH_NTTP_REGISTER, \
1005  INTERNAL_CATCH_NTTP_REGISTER, \
1006  INTERNAL_CATCH_NTTP_REGISTER, \
1007  INTERNAL_CATCH_NTTP_REGISTER, \
1008  INTERNAL_CATCH_NTTP_REGISTER, \
1009  INTERNAL_CATCH_NTTP_REGISTER0, \
1010  INTERNAL_CATCH_NTTP_REGISTER0) \
1011  (TestFunc, __VA_ARGS__)
1012 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) \
1013  INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1014  __VA_ARGS__, \
1015  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1016  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1017  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1018  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1019  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1020  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1021  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1022  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1023  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1024  INTERNAL_CATCH_DEFINE_SIG_TEST1, \
1025  INTERNAL_CATCH_DEFINE_SIG_TEST0) \
1026  (TestName, __VA_ARGS__)
1027 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) \
1028  INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1029  __VA_ARGS__, \
1030  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1031  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1032  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1033  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1034  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1035  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1036  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1037  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1038  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1039  INTERNAL_CATCH_DECLARE_SIG_TEST1, \
1040  INTERNAL_CATCH_DECLARE_SIG_TEST0) \
1041  (TestName, __VA_ARGS__)
1042 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) \
1043  INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, \
1044  INTERNAL_CATCH_REMOVE_PARENS_11_ARG, \
1045  INTERNAL_CATCH_REMOVE_PARENS_10_ARG, \
1046  INTERNAL_CATCH_REMOVE_PARENS_9_ARG, \
1047  INTERNAL_CATCH_REMOVE_PARENS_8_ARG, \
1048  INTERNAL_CATCH_REMOVE_PARENS_7_ARG, \
1049  INTERNAL_CATCH_REMOVE_PARENS_6_ARG, \
1050  INTERNAL_CATCH_REMOVE_PARENS_5_ARG, \
1051  INTERNAL_CATCH_REMOVE_PARENS_4_ARG, \
1052  INTERNAL_CATCH_REMOVE_PARENS_3_ARG, \
1053  INTERNAL_CATCH_REMOVE_PARENS_2_ARG, \
1054  INTERNAL_CATCH_REMOVE_PARENS_1_ARG) \
1055  (__VA_ARGS__)
1056 #else
1057 #define INTERNAL_CATCH_NTTP_0(signature)
1058 #define INTERNAL_CATCH_NTTP_GEN(...) \
1059  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, \
1060  INTERNAL_CATCH_NTTP_1, \
1061  INTERNAL_CATCH_NTTP_1, \
1062  INTERNAL_CATCH_NTTP_1, \
1063  INTERNAL_CATCH_NTTP_1, \
1064  INTERNAL_CATCH_NTTP_1, \
1065  INTERNAL_CATCH_NTTP_1, \
1066  INTERNAL_CATCH_NTTP_1, \
1067  INTERNAL_CATCH_NTTP_1, \
1068  INTERNAL_CATCH_NTTP_1, \
1069  INTERNAL_CATCH_NTTP_1, \
1070  INTERNAL_CATCH_NTTP_0)(__VA_ARGS__))
1071 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) \
1072  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1073  __VA_ARGS__, \
1074  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1075  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1076  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1077  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1078  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1079  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1080  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1081  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1082  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, \
1083  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, \
1084  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
1085 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) \
1086  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1087  __VA_ARGS__, \
1088  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1089  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1090  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1091  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1092  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1093  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1094  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1095  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1096  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, \
1097  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, \
1098  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
1099 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) \
1100  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1101  __VA_ARGS__, \
1102  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1103  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1104  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1105  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1106  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1107  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1108  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1109  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1110  INTERNAL_CATCH_NTTP_REGISTER_METHOD, \
1111  INTERNAL_CATCH_NTTP_REGISTER_METHOD0, \
1112  INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
1113 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) \
1114  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1115  __VA_ARGS__, \
1116  INTERNAL_CATCH_NTTP_REGISTER, \
1117  INTERNAL_CATCH_NTTP_REGISTER, \
1118  INTERNAL_CATCH_NTTP_REGISTER, \
1119  INTERNAL_CATCH_NTTP_REGISTER, \
1120  INTERNAL_CATCH_NTTP_REGISTER, \
1121  INTERNAL_CATCH_NTTP_REGISTER, \
1122  INTERNAL_CATCH_NTTP_REGISTER, \
1123  INTERNAL_CATCH_NTTP_REGISTER, \
1124  INTERNAL_CATCH_NTTP_REGISTER, \
1125  INTERNAL_CATCH_NTTP_REGISTER0, \
1126  INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
1127 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) \
1128  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1129  __VA_ARGS__, \
1130  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1131  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1132  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1133  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1134  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1135  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1136  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1137  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1138  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1139  INTERNAL_CATCH_DEFINE_SIG_TEST1, \
1140  INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
1141 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) \
1142  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL("dummy", \
1143  __VA_ARGS__, \
1144  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1145  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1146  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1147  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1148  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1149  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1150  INTERNAL_CATCH_DEFINE_SIG_TEST_X, \
1151  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1152  INTERNAL_CATCH_DECLARE_SIG_TEST_X, \
1153  INTERNAL_CATCH_DECLARE_SIG_TEST1, \
1154  INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
1155 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) \
1156  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, \
1157  INTERNAL_CATCH_REMOVE_PARENS_11_ARG, \
1158  INTERNAL_CATCH_REMOVE_PARENS_10_ARG, \
1159  INTERNAL_CATCH_REMOVE_PARENS_9_ARG, \
1160  INTERNAL_CATCH_REMOVE_PARENS_8_ARG, \
1161  INTERNAL_CATCH_REMOVE_PARENS_7_ARG, \
1162  INTERNAL_CATCH_REMOVE_PARENS_6_ARG, \
1163  INTERNAL_CATCH_REMOVE_PARENS_5_ARG, \
1164  INTERNAL_CATCH_REMOVE_PARENS_4_ARG, \
1165  INTERNAL_CATCH_REMOVE_PARENS_3_ARG, \
1166  INTERNAL_CATCH_REMOVE_PARENS_2_ARG, \
1167  INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
1168 #endif
1169 
1170 // end catch_preprocessor.hpp
1171 // start catch_meta.hpp
1172 
1173 #include <type_traits>
1174 
1175 namespace Catch {
1176  template<typename T>
1177  struct always_false : std::false_type {
1178  };
1179 
1180  template<typename>
1181  struct true_given : std::true_type {
1182  };
1184  template<typename Fun, typename... Args>
1185  true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
1186  template<typename...>
1187  std::false_type static test(...);
1188  };
1189 
1190  template<typename T>
1191  struct is_callable;
1192 
1193  template<typename Fun, typename... Args>
1194  struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {
1195  };
1196 
1197 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
1198  // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
1199  // replaced with std::invoke_result here.
1200  template<typename Func, typename... U>
1201  using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
1202 #else
1203  // Keep ::type here because we still support C++11
1204  template<typename Func, typename... U>
1205  using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
1206 #endif
1207 
1208 } // namespace Catch
1209 
1210 namespace mpl_ {
1211  struct na;
1212 }
1213 
1214 // end catch_meta.hpp
1215 namespace Catch {
1216  template<typename C>
1218  void (C::*m_testAsMethod)();
1219 
1220  public:
1221  TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept
1222  : m_testAsMethod(testAsMethod) {
1223  }
1224 
1225  void invoke() const override {
1226  C obj;
1227  (obj.*m_testAsMethod)();
1228  }
1229  };
1230 
1231  auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker *;
1232 
1233  template<typename C>
1234  auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker * {
1235  return new (std::nothrow) TestInvokerAsMethod<C>(testAsMethod);
1236  }
1237 
1238  struct NameAndTags {
1239  NameAndTags(StringRef const &name_ = StringRef(), StringRef const &tags_ = StringRef()) noexcept;
1240  StringRef name;
1241  StringRef tags;
1242  };
1243 
1245  AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags) noexcept;
1246  ~AutoReg();
1247  };
1248 
1249 } // end namespace Catch
1250 
1251 #if defined(CATCH_CONFIG_DISABLE)
1252 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(TestName, ...) static void TestName()
1253 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(TestName, ClassName, ...) \
1254  namespace { \
1255  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1256  void test(); \
1257  }; \
1258  } \
1259  void TestName::test()
1260 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2(TestName, TestFunc, Name, Tags, Signature, ...) \
1261  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1262 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, ...) \
1263  namespace { \
1264  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1265  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
1266  } \
1267  } \
1268  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1269 
1270 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1271 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1272  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____), \
1273  INTERNAL_CATCH_UNIQUE_NAME( \
1274  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), \
1275  Name, \
1276  Tags, \
1277  typename TestType, \
1278  __VA_ARGS__)
1279 #else
1280 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
1281  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( \
1282  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1283  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____), \
1284  Name, \
1285  Tags, \
1286  typename TestType, \
1287  __VA_ARGS__))
1288 #endif
1289 
1290 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1291 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1292  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____), \
1293  INTERNAL_CATCH_UNIQUE_NAME( \
1294  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), \
1295  Name, \
1296  Tags, \
1297  Signature, \
1298  __VA_ARGS__)
1299 #else
1300 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1301  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( \
1302  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1303  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____), \
1304  Name, \
1305  Tags, \
1306  Signature, \
1307  __VA_ARGS__))
1308 #endif
1309 
1310 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1311 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...) \
1312  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME( \
1313  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____), \
1314  INTERNAL_CATCH_UNIQUE_NAME( \
1315  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1316  ClassName, \
1317  Name, \
1318  Tags, \
1319  typename T, \
1320  __VA_ARGS__)
1321 #else
1322 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...) \
1323  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( \
1324  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____), \
1325  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1326  ClassName, \
1327  Name, \
1328  Tags, \
1329  typename T, \
1330  __VA_ARGS__))
1331 #endif
1332 
1333 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1334 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(ClassName, Name, Tags, Signature, ...) \
1335  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2(INTERNAL_CATCH_UNIQUE_NAME( \
1336  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____), \
1337  INTERNAL_CATCH_UNIQUE_NAME( \
1338  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1339  ClassName, \
1340  Name, \
1341  Tags, \
1342  Signature, \
1343  __VA_ARGS__)
1344 #else
1345 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(ClassName, Name, Tags, Signature, ...) \
1346  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( \
1347  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____), \
1348  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1349  ClassName, \
1350  Name, \
1351  Tags, \
1352  Signature, \
1353  __VA_ARGS__))
1354 #endif
1355 #endif
1356 
1358 #define INTERNAL_CATCH_TESTCASE2(TestName, ...) \
1359  static void TestName(); \
1360  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1361  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1362  namespace { \
1363  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName), \
1364  CATCH_INTERNAL_LINEINFO, \
1365  Catch::StringRef(), \
1366  Catch::NameAndTags{__VA_ARGS__}); \
1367  } /* NOLINT */ \
1368  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1369  static void TestName()
1370 #define INTERNAL_CATCH_TESTCASE(...) INTERNAL_CATCH_TESTCASE2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), __VA_ARGS__)
1371 
1373 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE(QualifiedMethod, ...) \
1374  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1375  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1376  namespace { \
1377  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&QualifiedMethod), \
1378  CATCH_INTERNAL_LINEINFO, \
1379  "&" #QualifiedMethod, \
1380  Catch::NameAndTags{__VA_ARGS__}); \
1381  } /* NOLINT */ \
1382  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1383 
1385 #define INTERNAL_CATCH_TEST_CASE_METHOD2(TestName, ClassName, ...) \
1386  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1387  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1388  namespace { \
1389  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1390  void test(); \
1391  }; \
1392  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName::test), \
1393  CATCH_INTERNAL_LINEINFO, \
1394  #ClassName, \
1395  Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \
1396  } \
1397  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1398  void TestName::test()
1399 #define INTERNAL_CATCH_TEST_CASE_METHOD(ClassName, ...) \
1400  INTERNAL_CATCH_TEST_CASE_METHOD2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), ClassName, __VA_ARGS__)
1401 
1403 #define INTERNAL_CATCH_REGISTER_TESTCASE(Function, ...) \
1404  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1405  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1406  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( \
1407  autoRegistrar)(Catch::makeTestInvoker(Function), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{__VA_ARGS__}); /* NOLINT \
1408  */ \
1409  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1410 
1412 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ...) \
1413  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1414  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1415  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1416  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1417  INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
1418  namespace { \
1419  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1420  INTERNAL_CATCH_TYPE_GEN \
1421  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1422  INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1423  template<typename... Types> \
1424  struct TestName { \
1425  TestName() { \
1426  int index = 0; \
1427  constexpr char const *tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; \
1428  using expander = int[]; \
1429  (void)expander{(reg_test(Types{}, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), Tags}), index++)...}; /* NOLINT \
1430  */ \
1431  } \
1432  }; \
1433  static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
1434  TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>(); \
1435  return 0; \
1436  }(); \
1437  } \
1438  } \
1439  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1440  INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1441 
1442 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1443 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1444  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____), \
1445  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____), \
1446  Name, \
1447  Tags, \
1448  typename TestType, \
1449  __VA_ARGS__)
1450 #else
1451 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1452  INTERNAL_CATCH_EXPAND_VARGS( \
1453  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____), \
1454  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____), \
1455  Name, \
1456  Tags, \
1457  typename TestType, \
1458  __VA_ARGS__))
1459 #endif
1460 
1461 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1462 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1463  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____), \
1464  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____), \
1465  Name, \
1466  Tags, \
1467  Signature, \
1468  __VA_ARGS__)
1469 #else
1470 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1471  INTERNAL_CATCH_EXPAND_VARGS( \
1472  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____), \
1473  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____), \
1474  Name, \
1475  Tags, \
1476  Signature, \
1477  __VA_ARGS__))
1478 #endif
1479 
1480 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
1481  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1482  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1483  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1484  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1485  template<typename TestType> \
1486  static void TestFuncName(); \
1487  namespace { \
1488  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1489  INTERNAL_CATCH_TYPE_GEN \
1490  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1491  template<typename... Types> \
1492  struct TestName { \
1493  void reg_tests() { \
1494  int index = 0; \
1495  using expander = int[]; \
1496  constexpr char const *tmpl_types[] \
1497  = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))}; \
1498  constexpr char const *types_list[] \
1499  = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))}; \
1500  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]); \
1501  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestFuncName<Types>), \
1502  CATCH_INTERNAL_LINEINFO, \
1503  Catch::StringRef(), \
1504  Catch::NameAndTags{Name " - " + std::string(tmpl_types[index / num_types]) + "<" \
1505  + std::string(types_list[index % num_types]) + ">", \
1506  Tags}), \
1507  index++)...}; /* NOLINT */ \
1508  } \
1509  }; \
1510  static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
1511  using TestInit = \
1512  typename create<TestName, \
1513  decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), \
1514  TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
1515  TestInit t; \
1516  t.reg_tests(); \
1517  return 0; \
1518  }(); \
1519  } \
1520  } \
1521  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1522  template<typename TestType> \
1523  static void TestFuncName()
1524 
1525 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1526 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...) \
1527  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____), \
1528  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____), \
1529  Name, \
1530  Tags, \
1531  typename T, \
1532  __VA_ARGS__)
1533 #else
1534 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...) \
1535  INTERNAL_CATCH_EXPAND_VARGS( \
1536  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____), \
1537  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____), \
1538  Name, \
1539  Tags, \
1540  typename T, \
1541  __VA_ARGS__))
1542 #endif
1543 
1544 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1545 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1546  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____), \
1547  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____), \
1548  Name, \
1549  Tags, \
1550  Signature, \
1551  __VA_ARGS__)
1552 #else
1553 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1554  INTERNAL_CATCH_EXPAND_VARGS( \
1555  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____), \
1556  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____), \
1557  Name, \
1558  Tags, \
1559  Signature, \
1560  __VA_ARGS__))
1561 #endif
1562 
1563 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList) \
1564  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1565  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1566  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1567  template<typename TestType> \
1568  static void TestFunc(); \
1569  namespace { \
1570  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1571  INTERNAL_CATCH_TYPE_GEN \
1572  template<typename... Types> \
1573  struct TestName { \
1574  void reg_tests() { \
1575  int index = 0; \
1576  using expander = int[]; \
1577  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Types>), \
1578  CATCH_INTERNAL_LINEINFO, \
1579  Catch::StringRef(), \
1580  Catch::NameAndTags{Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " \
1581  + std::to_string(index), \
1582  Tags}), \
1583  index++)...}; /* NOLINT */ \
1584  } \
1585  }; \
1586  static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
1587  using TestInit = typename convert<TestName, TmplList>::type; \
1588  TestInit t; \
1589  t.reg_tests(); \
1590  return 0; \
1591  }(); \
1592  } \
1593  } \
1594  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1595  template<typename TestType> \
1596  static void TestFunc()
1597 
1598 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
1599  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____), \
1600  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____), \
1601  Name, \
1602  Tags, \
1603  TmplList)
1604 
1605 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, ...) \
1606  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1607  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1608  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1609  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1610  namespace { \
1611  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1612  INTERNAL_CATCH_TYPE_GEN \
1613  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1614  INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
1615  INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1616  template<typename... Types> \
1617  struct TestNameClass { \
1618  TestNameClass() { \
1619  int index = 0; \
1620  constexpr char const *tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; \
1621  using expander = int[]; \
1622  (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), Tags}), \
1623  index++)...}; /* NOLINT */ \
1624  } \
1625  }; \
1626  static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
1627  TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>(); \
1628  return 0; \
1629  }(); \
1630  } \
1631  } \
1632  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1633  INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1634 
1635 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1636 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
1637  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____), \
1638  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1639  ClassName, \
1640  Name, \
1641  Tags, \
1642  typename T, \
1643  __VA_ARGS__)
1644 #else
1645 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
1646  INTERNAL_CATCH_EXPAND_VARGS( \
1647  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____), \
1648  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1649  ClassName, \
1650  Name, \
1651  Tags, \
1652  typename T, \
1653  __VA_ARGS__))
1654 #endif
1655 
1656 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1657 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
1658  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____), \
1659  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1660  ClassName, \
1661  Name, \
1662  Tags, \
1663  Signature, \
1664  __VA_ARGS__)
1665 #else
1666 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
1667  INTERNAL_CATCH_EXPAND_VARGS( \
1668  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____), \
1669  INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____), \
1670  ClassName, \
1671  Name, \
1672  Tags, \
1673  Signature, \
1674  __VA_ARGS__))
1675 #endif
1676 
1677 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList) \
1678  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1679  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1680  CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1681  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1682  template<typename TestType> \
1683  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) { \
1684  void test(); \
1685  }; \
1686  namespace { \
1687  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) { \
1688  INTERNAL_CATCH_TYPE_GEN \
1689  INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
1690  template<typename... Types> \
1691  struct TestNameClass { \
1692  void reg_tests() { \
1693  int index = 0; \
1694  using expander = int[]; \
1695  constexpr char const *tmpl_types[] \
1696  = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))}; \
1697  constexpr char const *types_list[] \
1698  = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))}; \
1699  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]); \
1700  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), \
1701  CATCH_INTERNAL_LINEINFO, \
1702  #ClassName, \
1703  Catch::NameAndTags{Name " - " + std::string(tmpl_types[index / num_types]) + "<" \
1704  + std::string(types_list[index % num_types]) + ">", \
1705  Tags}), \
1706  index++)...}; /* NOLINT */ \
1707  } \
1708  }; \
1709  static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
1710  using TestInit = \
1711  typename create<TestNameClass, \
1712  decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), \
1713  TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
1714  TestInit t; \
1715  t.reg_tests(); \
1716  return 0; \
1717  }(); \
1718  } \
1719  } \
1720  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1721  template<typename TestType> \
1722  void TestName<TestType>::test()
1723 
1724 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1725 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
1726  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____), \
1727  INTERNAL_CATCH_UNIQUE_NAME( \
1728  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), \
1729  ClassName, \
1730  Name, \
1731  Tags, \
1732  typename T, \
1733  __VA_ARGS__)
1734 #else
1735 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
1736  INTERNAL_CATCH_EXPAND_VARGS( \
1737  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____), \
1738  INTERNAL_CATCH_UNIQUE_NAME( \
1739  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), \
1740  ClassName, \
1741  Name, \
1742  Tags, \
1743  typename T, \
1744  __VA_ARGS__))
1745 #endif
1746 
1747 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1748 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
1749  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____), \
1750  INTERNAL_CATCH_UNIQUE_NAME( \
1751  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), \
1752  ClassName, \
1753  Name, \
1754  Tags, \
1755  Signature, \
1756  __VA_ARGS__)
1757 #else
1758 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
1759  INTERNAL_CATCH_EXPAND_VARGS( \
1760  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____), \
1761  INTERNAL_CATCH_UNIQUE_NAME( \
1762  ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____), \
1763  ClassName, \
1764  Name, \
1765  Tags, \
1766  Signature, \
1767  __VA_ARGS__))
1768 #endif
1769 
1770 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
1771  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1772  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1773  CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1774  template<typename TestType> \
1775  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) { \
1776  void test(); \
1777  }; \
1778  namespace { \
1779  namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
1780  INTERNAL_CATCH_TYPE_GEN \
1781  template<typename... Types> \
1782  struct TestNameClass { \
1783  void reg_tests() { \
1784  int index = 0; \
1785  using expander = int[]; \
1786  (void)expander{(Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), \
1787  CATCH_INTERNAL_LINEINFO, \
1788  #ClassName, \
1789  Catch::NameAndTags{Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " \
1790  + std::to_string(index), \
1791  Tags}), \
1792  index++)...}; /* NOLINT */ \
1793  } \
1794  }; \
1795  static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
1796  using TestInit = typename convert<TestNameClass, TmplList>::type; \
1797  TestInit t; \
1798  t.reg_tests(); \
1799  return 0; \
1800  }(); \
1801  } \
1802  } \
1803  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1804  template<typename TestType> \
1805  void TestName<TestType>::test()
1806 
1807 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
1808  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____), \
1809  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____), \
1810  ClassName, \
1811  Name, \
1812  Tags, \
1813  TmplList)
1814 
1815 // end catch_test_registry.h
1816 // start catch_capture.hpp
1817 
1818 // start catch_assertionhandler.h
1819 
1820 // start catch_assertioninfo.h
1821 
1822 // start catch_result_type.h
1823 
1824 namespace Catch {
1825  // ResultWas::OfType enum
1826  struct ResultWas {
1827  enum OfType {
1828  Unknown = -1,
1829  Ok = 0,
1830  Info = 1,
1831  Warning = 2,
1832 
1833  FailureBit = 0x10,
1834 
1835  ExpressionFailed = FailureBit | 1,
1836  ExplicitFailure = FailureBit | 2,
1837 
1838  Exception = 0x100 | FailureBit,
1839 
1840  ThrewException = Exception | 1,
1841  DidntThrowException = Exception | 2,
1842 
1843  FatalErrorCondition = 0x200 | FailureBit
1844 
1845  };
1846  };
1847 
1848  bool isOk(ResultWas::OfType resultType);
1849  bool isJustInfo(int flags);
1850 
1851  // ResultDisposition::Flags enum
1853  enum Flags {
1854  Normal = 0x01,
1855 
1856  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
1857  FalseTest = 0x04, // Prefix expression with !
1858  SuppressFail = 0x08 // Failures are reported but do not fail the test
1859  };
1860  };
1861 
1862  ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs);
1863 
1864  bool shouldContinueOnFailure(int flags);
1865  inline bool isFalseTest(int flags) {
1866  return (flags & ResultDisposition::FalseTest) != 0;
1867  }
1868  bool shouldSuppressFailure(int flags);
1869 
1870 } // end namespace Catch
1871 
1872 // end catch_result_type.h
1873 namespace Catch {
1874  struct AssertionInfo {
1875  StringRef macroName;
1876  SourceLineInfo lineInfo;
1877  StringRef capturedExpression;
1878  ResultDisposition::Flags resultDisposition;
1879 
1880  // We want to delete this constructor but a compiler bug in 4.8 means
1881  // the struct is then treated as non-aggregate
1882  // AssertionInfo() = delete;
1883  };
1884 
1885 } // end namespace Catch
1886 
1887 // end catch_assertioninfo.h
1888 // start catch_decomposer.h
1889 
1890 // start catch_tostring.h
1891 
1892 #include <cstddef>
1893 #include <string>
1894 #include <type_traits>
1895 #include <vector>
1896 // start catch_stream.h
1897 
1898 #include <cstddef>
1899 #include <iosfwd>
1900 #include <ostream>
1901 
1902 namespace Catch {
1903  std::ostream &cout();
1904  std::ostream &cerr();
1905  std::ostream &clog();
1906 
1907  class StringRef;
1908 
1909  struct IStream {
1910  virtual ~IStream();
1911  virtual std::ostream &stream() const = 0;
1912  };
1913 
1914  auto makeStream(StringRef const &filename) -> IStream const *;
1915 
1917  std::size_t m_index;
1918  std::ostream *m_oss;
1919 
1920  public:
1923 
1924  auto str() const -> std::string;
1925 
1926  template<typename T>
1927  auto operator<<(T const &value) -> ReusableStringStream & {
1928  *m_oss << value;
1929  return *this;
1930  }
1931  auto get() -> std::ostream & { return *m_oss; }
1932  };
1933 } // namespace Catch
1934 
1935 // end catch_stream.h
1936 // start catch_interfaces_enum_values_registry.h
1937 
1938 #include <vector>
1939 
1940 namespace Catch {
1941  namespace Detail {
1942  struct EnumInfo {
1943  StringRef m_name;
1944  std::vector<std::pair<int, StringRef>> m_values;
1945 
1946  ~EnumInfo();
1947 
1948  StringRef lookup(int value) const;
1949  };
1950  } // namespace Detail
1951 
1953  virtual ~IMutableEnumValuesRegistry();
1954 
1955  virtual Detail::EnumInfo const &registerEnum(StringRef enumName, StringRef allEnums, std::vector<int> const &values) = 0;
1956 
1957  template<typename E>
1958  Detail::EnumInfo const &registerEnum(StringRef enumName, StringRef allEnums, std::initializer_list<E> values) {
1959  static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1960  std::vector<int> intValues;
1961  intValues.reserve(values.size());
1962  for (auto enumValue : values)
1963  intValues.push_back(static_cast<int>(enumValue));
1964  return registerEnum(enumName, allEnums, intValues);
1965  }
1966  };
1967 
1968 } // namespace Catch
1969 
1970 // end catch_interfaces_enum_values_registry.h
1971 
1972 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1973 #include <string_view>
1974 #endif
1975 
1976 #ifdef __OBJC__
1977 // start catch_objc_arc.hpp
1978 
1979 #import <Foundation/Foundation.h>
1980 
1981 #ifdef __has_feature
1982 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1983 #else
1984 #define CATCH_ARC_ENABLED 0
1985 #endif
1986 
1987 void arcSafeRelease(NSObject *obj);
1988 id performOptionalSelector(id obj, SEL sel);
1989 
1990 #if !CATCH_ARC_ENABLED
1991 inline void arcSafeRelease(NSObject *obj) {
1992  [obj release];
1993 }
1994 inline id performOptionalSelector(id obj, SEL sel) {
1995  if ([obj respondsToSelector:sel])
1996  return [obj performSelector:sel];
1997  return nil;
1998 }
1999 #define CATCH_UNSAFE_UNRETAINED
2000 #define CATCH_ARC_STRONG
2001 #else
2002 inline void arcSafeRelease(NSObject *) {
2003 }
2004 inline id performOptionalSelector(id obj, SEL sel) {
2005 #ifdef __clang__
2006 #pragma clang diagnostic push
2007 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
2008 #endif
2009  if ([obj respondsToSelector:sel])
2010  return [obj performSelector:sel];
2011 #ifdef __clang__
2012 #pragma clang diagnostic pop
2013 #endif
2014  return nil;
2015 }
2016 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
2017 #define CATCH_ARC_STRONG __strong
2018 #endif
2019 
2020 // end catch_objc_arc.hpp
2021 #endif
2022 
2023 #ifdef _MSC_VER
2024 #pragma warning(push)
2025 #pragma warning(disable : 4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
2026 #endif
2027 
2028 namespace Catch {
2029  namespace Detail {
2030  extern const std::string unprintableString;
2031 
2032  std::string rawMemoryToString(const void *object, std::size_t size);
2033 
2034  template<typename T>
2035  std::string rawMemoryToString(const T &object) {
2036  return rawMemoryToString(&object, sizeof(object));
2037  }
2038 
2039  template<typename T>
2041  template<typename Stream, typename U>
2042  static auto test(int) -> decltype(std::declval<Stream &>() << std::declval<U>(), std::true_type());
2043 
2044  template<typename, typename>
2045  static auto test(...) -> std::false_type;
2046 
2047  public:
2048  static const bool value = decltype(test<std::ostream, const T &>(0))::value;
2049  };
2050 
2051  template<typename E>
2052  std::string convertUnknownEnumToString(E e);
2053 
2054  template<typename T>
2055  typename std::enable_if<!std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value, std::string>::type convertUnstreamable(T const &) {
2056  return Detail::unprintableString;
2057  }
2058  template<typename T>
2059  typename std::enable_if<!std::is_enum<T>::value && std::is_base_of<std::exception, T>::value, std::string>::type convertUnstreamable(T const &ex) {
2060  return ex.what();
2061  }
2062 
2063  template<typename T>
2064  typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable(T const &value) {
2065  return convertUnknownEnumToString(value);
2066  }
2067 
2068 #if defined(_MANAGED)
2069  template<typename T>
2071  std::string clrReferenceToString(T ^ ref) {
2072  if (ref == nullptr)
2073  return std::string("null");
2074  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
2075  cli::pin_ptr<System::Byte> p = &bytes[0];
2076  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
2077  }
2078 #endif
2079 
2080  } // namespace Detail
2081 
2082  // If we decide for C++14, change these to enable_if_ts
2083  template<typename T, typename = void>
2084  struct StringMaker {
2085  template<typename Fake = T>
2086  static typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type convert(const Fake &value) {
2088  // NB: call using the function-like syntax to avoid ambiguity with
2089  // user-defined templated operator<< under clang.
2090  rss.operator<<(value);
2091  return rss.str();
2092  }
2093 
2094  template<typename Fake = T>
2095  static typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type convert(const Fake &value) {
2096 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
2097  return Detail::convertUnstreamable(value);
2098 #else
2099  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
2100 #endif
2101  }
2102  };
2103 
2104  namespace Detail {
2105  // This function dispatches all stringification requests inside of Catch.
2106  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
2107  template<typename T>
2108  std::string stringify(const T &e) {
2109  return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
2110  }
2111 
2112  template<typename E>
2113  std::string convertUnknownEnumToString(E e) {
2114  return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
2115  }
2116 
2117 #if defined(_MANAGED)
2118  template<typename T>
2119  std::string stringify(T ^ e) {
2120  return ::Catch::StringMaker<T ^>::convert(e);
2121  }
2122 #endif
2123 
2124  } // namespace Detail
2125 
2126  // Some predefined specializations
2127 
2128  template<>
2129  struct StringMaker<std::string> {
2130  static std::string convert(const std::string &str);
2131  };
2132 
2133 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2134  template<>
2135  struct StringMaker<std::string_view> {
2136  static std::string convert(std::string_view str);
2137  };
2138 #endif
2139 
2140  template<>
2141  struct StringMaker<char const *> {
2142  static std::string convert(char const *str);
2143  };
2144  template<>
2145  struct StringMaker<char *> {
2146  static std::string convert(char *str);
2147  };
2148 
2149 #ifdef CATCH_CONFIG_WCHAR
2150  template<>
2151  struct StringMaker<std::wstring> {
2152  static std::string convert(const std::wstring &wstr);
2153  };
2154 
2155 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2156  template<>
2157  struct StringMaker<std::wstring_view> {
2158  static std::string convert(std::wstring_view str);
2159  };
2160 #endif
2161 
2162  template<>
2163  struct StringMaker<wchar_t const *> {
2164  static std::string convert(wchar_t const *str);
2165  };
2166  template<>
2167  struct StringMaker<wchar_t *> {
2168  static std::string convert(wchar_t *str);
2169  };
2170 #endif
2171 
2172  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
2173  // while keeping string semantics?
2174  template<int SZ>
2175  struct StringMaker<char[SZ]> {
2176  static std::string convert(char const *str) { return ::Catch::Detail::stringify(std::string{str}); }
2177  };
2178  template<int SZ>
2179  struct StringMaker<signed char[SZ]> {
2180  static std::string convert(signed char const *str) {
2181  return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const *>(str)});
2182  }
2183  };
2184  template<int SZ>
2185  struct StringMaker<unsigned char[SZ]> {
2186  static std::string convert(unsigned char const *str) {
2187  return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const *>(str)});
2188  }
2189  };
2190 
2191 #if defined(CATCH_CONFIG_CPP17_BYTE)
2192  template<>
2193  struct StringMaker<std::byte> {
2194  static std::string convert(std::byte value);
2195  };
2196 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
2197  template<>
2198  struct StringMaker<int> {
2199  static std::string convert(int value);
2200  };
2201  template<>
2202  struct StringMaker<long> {
2203  static std::string convert(long value);
2204  };
2205  template<>
2206  struct StringMaker<long long> {
2207  static std::string convert(long long value);
2208  };
2209  template<>
2210  struct StringMaker<unsigned int> {
2211  static std::string convert(unsigned int value);
2212  };
2213  template<>
2214  struct StringMaker<unsigned long> {
2215  static std::string convert(unsigned long value);
2216  };
2217  template<>
2218  struct StringMaker<unsigned long long> {
2219  static std::string convert(unsigned long long value);
2220  };
2221 
2222  template<>
2223  struct StringMaker<bool> {
2224  static std::string convert(bool b);
2225  };
2226 
2227  template<>
2228  struct StringMaker<char> {
2229  static std::string convert(char c);
2230  };
2231  template<>
2232  struct StringMaker<signed char> {
2233  static std::string convert(signed char c);
2234  };
2235  template<>
2236  struct StringMaker<unsigned char> {
2237  static std::string convert(unsigned char c);
2238  };
2239 
2240  template<>
2241  struct StringMaker<std::nullptr_t> {
2242  static std::string convert(std::nullptr_t);
2243  };
2244 
2245  template<>
2246  struct StringMaker<float> {
2247  static std::string convert(float value);
2248  static int precision;
2249  };
2250 
2251  template<>
2252  struct StringMaker<double> {
2253  static std::string convert(double value);
2254  static int precision;
2255  };
2256 
2257  template<typename T>
2258  struct StringMaker<T *> {
2259  template<typename U>
2260  static std::string convert(U *p) {
2261  if (p) {
2262  return ::Catch::Detail::rawMemoryToString(p);
2263  } else {
2264  return "nullptr";
2265  }
2266  }
2267  };
2268 
2269  template<typename R, typename C>
2270  struct StringMaker<R C::*> {
2271  static std::string convert(R C::*p) {
2272  if (p) {
2273  return ::Catch::Detail::rawMemoryToString(p);
2274  } else {
2275  return "nullptr";
2276  }
2277  }
2278  };
2279 
2280 #if defined(_MANAGED)
2281  template<typename T>
2282  struct StringMaker<T ^> {
2283  static std::string convert(T ^ ref) { return ::Catch::Detail::clrReferenceToString(ref); }
2284  };
2285 #endif
2286 
2287  namespace Detail {
2288  template<typename InputIterator, typename Sentinel = InputIterator>
2289  std::string rangeToString(InputIterator first, Sentinel last) {
2291  rss << "{ ";
2292  if (first != last) {
2293  rss << ::Catch::Detail::stringify(*first);
2294  for (++first; first != last; ++first)
2295  rss << ", " << ::Catch::Detail::stringify(*first);
2296  }
2297  rss << " }";
2298  return rss.str();
2299  }
2300  } // namespace Detail
2301 
2302 #ifdef __OBJC__
2303  template<>
2304  struct StringMaker<NSString *> {
2305  static std::string convert(NSString *nsstring) {
2306  if (!nsstring)
2307  return "nil";
2308  return std::string("@") + [nsstring UTF8String];
2309  }
2310  };
2311  template<>
2312  struct StringMaker<NSObject *> {
2313  static std::string convert(NSObject *nsObject) { return ::Catch::Detail::stringify([nsObject description]); }
2314  };
2315  namespace Detail {
2316  inline std::string stringify(NSString *nsstring) {
2317  return StringMaker<NSString *>::convert(nsstring);
2318  }
2319 
2320  } // namespace Detail
2321 #endif // __OBJC__
2322 
2323 } // namespace Catch
2324 
2326 // Separate std-lib types stringification, so it can be selectively enabled
2327 // This means that we do not bring in
2328 
2329 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
2330 #define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2331 #define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2332 #define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2333 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2334 #define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2335 #endif
2336 
2337 // Separate std::pair specialization
2338 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
2339 #include <utility>
2340 namespace Catch {
2341  template<typename T1, typename T2>
2342  struct StringMaker<std::pair<T1, T2>> {
2343  static std::string convert(const std::pair<T1, T2> &pair) {
2345  rss << "{ " << ::Catch::Detail::stringify(pair.first) << ", " << ::Catch::Detail::stringify(pair.second) << " }";
2346  return rss.str();
2347  }
2348  };
2349 } // namespace Catch
2350 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2351 
2352 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
2353 #include <optional>
2354 namespace Catch {
2355  template<typename T>
2356  struct StringMaker<std::optional<T>> {
2357  static std::string convert(const std::optional<T> &optional) {
2359  if (optional.has_value()) {
2360  rss << ::Catch::Detail::stringify(*optional);
2361  } else {
2362  rss << "{ }";
2363  }
2364  return rss.str();
2365  }
2366  };
2367 } // namespace Catch
2368 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2369 
2370 // Separate std::tuple specialization
2371 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
2372 #include <tuple>
2373 namespace Catch {
2374  namespace Detail {
2375  template<typename Tuple, std::size_t N = 0, bool = (N < std::tuple_size<Tuple>::value)>
2376  struct TupleElementPrinter {
2377  static void print(const Tuple &tuple, std::ostream &os) {
2378  os << (N ? ", " : " ") << ::Catch::Detail::stringify(std::get<N>(tuple));
2379  TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
2380  }
2381  };
2382 
2383  template<typename Tuple, std::size_t N>
2384  struct TupleElementPrinter<Tuple, N, false> {
2385  static void print(const Tuple &, std::ostream &) {}
2386  };
2387 
2388  } // namespace Detail
2389 
2390  template<typename... Types>
2391  struct StringMaker<std::tuple<Types...>> {
2392  static std::string convert(const std::tuple<Types...> &tuple) {
2394  rss << '{';
2395  Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
2396  rss << " }";
2397  return rss.str();
2398  }
2399  };
2400 } // namespace Catch
2401 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2402 
2403 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
2404 #include <variant>
2405 namespace Catch {
2406  template<>
2407  struct StringMaker<std::monostate> {
2408  static std::string convert(const std::monostate &) { return "{ }"; }
2409  };
2410 
2411  template<typename... Elements>
2412  struct StringMaker<std::variant<Elements...>> {
2413  static std::string convert(const std::variant<Elements...> &variant) {
2414  if (variant.valueless_by_exception()) {
2415  return "{valueless variant}";
2416  } else {
2417  return std::visit([](const auto &value) { return ::Catch::Detail::stringify(value); }, variant);
2418  }
2419  }
2420  };
2421 } // namespace Catch
2422 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2423 
2424 namespace Catch {
2425  // Import begin/ end from std here
2426  using std::begin;
2427  using std::end;
2428 
2429  namespace detail {
2430  template<typename...>
2431  struct void_type {
2432  using type = void;
2433  };
2434 
2435  template<typename T, typename = void>
2436  struct is_range_impl : std::false_type {
2437  };
2438 
2439  template<typename T>
2441  };
2442  } // namespace detail
2443 
2444  template<typename T>
2446  };
2447 
2448 #if defined(_MANAGED) // Managed types are never ranges
2449  template<typename T>
2450  struct is_range<T ^> {
2451  static const bool value = false;
2452  };
2453 #endif
2454 
2455  template<typename Range>
2456  std::string rangeToString(Range const &range) {
2457  return ::Catch::Detail::rangeToString(begin(range), end(range));
2458  }
2459 
2460  // Handle vector<bool> specially
2461  template<typename Allocator>
2462  std::string rangeToString(std::vector<bool, Allocator> const &v) {
2464  rss << "{ ";
2465  bool first = true;
2466  for (bool b : v) {
2467  if (first)
2468  first = false;
2469  else
2470  rss << ", ";
2471  rss << ::Catch::Detail::stringify(b);
2472  }
2473  rss << " }";
2474  return rss.str();
2475  }
2476 
2477  template<typename R>
2479  static std::string convert(R const &range) { return rangeToString(range); }
2480  };
2481 
2482  template<typename T, int SZ>
2483  struct StringMaker<T[SZ]> {
2484  static std::string convert(T const (&arr)[SZ]) { return rangeToString(arr); }
2485  };
2486 
2487 } // namespace Catch
2488 
2489 // Separate std::chrono::duration specialization
2490 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2491 #include <chrono>
2492 #include <ctime>
2493 #include <ratio>
2494 
2495 namespace Catch {
2496  template<class Ratio>
2497  struct ratio_string {
2498  static std::string symbol();
2499  };
2500 
2501  template<class Ratio>
2502  std::string ratio_string<Ratio>::symbol() {
2504  rss << '[' << Ratio::num << '/' << Ratio::den << ']';
2505  return rss.str();
2506  }
2507  template<>
2508  struct ratio_string<std::atto> {
2509  static std::string symbol();
2510  };
2511  template<>
2512  struct ratio_string<std::femto> {
2513  static std::string symbol();
2514  };
2515  template<>
2516  struct ratio_string<std::pico> {
2517  static std::string symbol();
2518  };
2519  template<>
2520  struct ratio_string<std::nano> {
2521  static std::string symbol();
2522  };
2523  template<>
2524  struct ratio_string<std::micro> {
2525  static std::string symbol();
2526  };
2527  template<>
2528  struct ratio_string<std::milli> {
2529  static std::string symbol();
2530  };
2531 
2533  // std::chrono::duration specializations
2534  template<typename Value, typename Ratio>
2535  struct StringMaker<std::chrono::duration<Value, Ratio>> {
2536  static std::string convert(std::chrono::duration<Value, Ratio> const &duration) {
2538  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2539  return rss.str();
2540  }
2541  };
2542  template<typename Value>
2543  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
2544  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const &duration) {
2546  rss << duration.count() << " s";
2547  return rss.str();
2548  }
2549  };
2550  template<typename Value>
2551  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
2552  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const &duration) {
2554  rss << duration.count() << " m";
2555  return rss.str();
2556  }
2557  };
2558  template<typename Value>
2559  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
2560  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const &duration) {
2562  rss << duration.count() << " h";
2563  return rss.str();
2564  }
2565  };
2566 
2568  // std::chrono::time_point specialization
2569  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2570  template<typename Clock, typename Duration>
2571  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
2572  static std::string convert(std::chrono::time_point<Clock, Duration> const &time_point) {
2573  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2574  }
2575  };
2576  // std::chrono::time_point<system_clock> specialization
2577  template<typename Duration>
2578  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
2579  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const &time_point) {
2580  auto converted = std::chrono::system_clock::to_time_t(time_point);
2581 
2582 #ifdef _MSC_VER
2583  std::tm timeInfo = {};
2584  gmtime_s(&timeInfo, &converted);
2585 #else
2586  std::tm *timeInfo = std::gmtime(&converted);
2587 #endif
2588 
2589  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2590  char timeStamp[timeStampSize];
2591  const char *const fmt = "%Y-%m-%dT%H:%M:%SZ";
2592 
2593 #ifdef _MSC_VER
2594  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2595 #else
2596  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2597 #endif
2598  return std::string(timeStamp);
2599  }
2600  };
2601 } // namespace Catch
2602 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2603 
2604 #define INTERNAL_CATCH_REGISTER_ENUM(enumName, ...) \
2605  namespace Catch { \
2606  template<> \
2607  struct StringMaker<enumName> { \
2608  static std::string convert(enumName value) { \
2609  static const auto &enumInfo \
2610  = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum(#enumName, #__VA_ARGS__, {__VA_ARGS__}); \
2611  return static_cast<std::string>(enumInfo.lookup(static_cast<int>(value))); \
2612  } \
2613  }; \
2614  }
2615 
2616 #define CATCH_REGISTER_ENUM(enumName, ...) INTERNAL_CATCH_REGISTER_ENUM(enumName, __VA_ARGS__)
2617 
2618 #ifdef _MSC_VER
2619 #pragma warning(pop)
2620 #endif
2621 
2622 // end catch_tostring.h
2623 #include <iosfwd>
2624 
2625 #ifdef _MSC_VER
2626 #pragma warning(push)
2627 #pragma warning(disable : 4389) // '==' : signed/unsigned mismatch
2628 #pragma warning(disable : 4018) // more "signed/unsigned mismatch"
2629 #pragma warning(disable : 4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2630 #pragma warning(disable : 4180) // qualifier applied to function type has no meaning
2631 #pragma warning(disable : 4800) // Forcing result to true or false
2632 #endif
2633 
2634 namespace Catch {
2636  auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
2637  auto getResult() const -> bool { return m_result; }
2638  virtual void streamReconstructedExpression(std::ostream &os) const = 0;
2639 
2640  ITransientExpression(bool isBinaryExpression, bool result)
2641  : m_isBinaryExpression(isBinaryExpression)
2642  , m_result(result) {
2643  }
2644 
2645  // We don't actually need a virtual destructor, but many static analysers
2646  // complain if it's not here :-(
2647  virtual ~ITransientExpression();
2648 
2649  bool m_isBinaryExpression;
2650  bool m_result;
2651  };
2652 
2653  void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs);
2654 
2655  template<typename LhsT, typename RhsT>
2657  LhsT m_lhs;
2658  StringRef m_op;
2659  RhsT m_rhs;
2660 
2661  void streamReconstructedExpression(std::ostream &os) const override {
2662  formatReconstructedExpression(os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
2663  }
2664 
2665  public:
2666  BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
2667  : ITransientExpression{true, comparisonResult}
2668  , m_lhs(lhs)
2669  , m_op(op)
2670  , m_rhs(rhs) {
2671  }
2672 
2673  template<typename T>
2674  auto operator&&(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2675  static_assert(always_false<T>::value,
2676  "chained comparisons are not supported inside assertions, "
2677  "wrap the expression inside parentheses, or decompose it");
2678  }
2679 
2680  template<typename T>
2681  auto operator||(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2682  static_assert(always_false<T>::value,
2683  "chained comparisons are not supported inside assertions, "
2684  "wrap the expression inside parentheses, or decompose it");
2685  }
2686 
2687  template<typename T>
2688  auto operator==(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2689  static_assert(always_false<T>::value,
2690  "chained comparisons are not supported inside assertions, "
2691  "wrap the expression inside parentheses, or decompose it");
2692  }
2693 
2694  template<typename T>
2695  auto operator!=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2696  static_assert(always_false<T>::value,
2697  "chained comparisons are not supported inside assertions, "
2698  "wrap the expression inside parentheses, or decompose it");
2699  }
2700 
2701  template<typename T>
2702  auto operator>(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2703  static_assert(always_false<T>::value,
2704  "chained comparisons are not supported inside assertions, "
2705  "wrap the expression inside parentheses, or decompose it");
2706  }
2707 
2708  template<typename T>
2709  auto operator<(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2710  static_assert(always_false<T>::value,
2711  "chained comparisons are not supported inside assertions, "
2712  "wrap the expression inside parentheses, or decompose it");
2713  }
2714 
2715  template<typename T>
2716  auto operator>=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2717  static_assert(always_false<T>::value,
2718  "chained comparisons are not supported inside assertions, "
2719  "wrap the expression inside parentheses, or decompose it");
2720  }
2721 
2722  template<typename T>
2723  auto operator<=(T) const -> BinaryExpr<LhsT, RhsT const &> const {
2724  static_assert(always_false<T>::value,
2725  "chained comparisons are not supported inside assertions, "
2726  "wrap the expression inside parentheses, or decompose it");
2727  }
2728  };
2729 
2730  template<typename LhsT>
2732  LhsT m_lhs;
2733 
2734  void streamReconstructedExpression(std::ostream &os) const override { os << Catch::Detail::stringify(m_lhs); }
2735 
2736  public:
2737  explicit UnaryExpr(LhsT lhs)
2738  : ITransientExpression{false, static_cast<bool>(lhs)}
2739  , m_lhs(lhs) {
2740  }
2741  };
2742 
2743  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2744  template<typename LhsT, typename RhsT>
2745  auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool {
2746  return static_cast<bool>(lhs == rhs);
2747  }
2748  template<typename T>
2749  auto compareEqual(T *const &lhs, int rhs) -> bool {
2750  return lhs == reinterpret_cast<void const *>(rhs);
2751  }
2752  template<typename T>
2753  auto compareEqual(T *const &lhs, long rhs) -> bool {
2754  return lhs == reinterpret_cast<void const *>(rhs);
2755  }
2756  template<typename T>
2757  auto compareEqual(int lhs, T *const &rhs) -> bool {
2758  return reinterpret_cast<void const *>(lhs) == rhs;
2759  }
2760  template<typename T>
2761  auto compareEqual(long lhs, T *const &rhs) -> bool {
2762  return reinterpret_cast<void const *>(lhs) == rhs;
2763  }
2764 
2765  template<typename LhsT, typename RhsT>
2766  auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool {
2767  return static_cast<bool>(lhs != rhs);
2768  }
2769  template<typename T>
2770  auto compareNotEqual(T *const &lhs, int rhs) -> bool {
2771  return lhs != reinterpret_cast<void const *>(rhs);
2772  }
2773  template<typename T>
2774  auto compareNotEqual(T *const &lhs, long rhs) -> bool {
2775  return lhs != reinterpret_cast<void const *>(rhs);
2776  }
2777  template<typename T>
2778  auto compareNotEqual(int lhs, T *const &rhs) -> bool {
2779  return reinterpret_cast<void const *>(lhs) != rhs;
2780  }
2781  template<typename T>
2782  auto compareNotEqual(long lhs, T *const &rhs) -> bool {
2783  return reinterpret_cast<void const *>(lhs) != rhs;
2784  }
2785 
2786  template<typename LhsT>
2787  class ExprLhs {
2788  LhsT m_lhs;
2789 
2790  public:
2791  explicit ExprLhs(LhsT lhs)
2792  : m_lhs(lhs) {
2793  }
2794 
2795  template<typename RhsT>
2796  auto operator==(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2797  return {compareEqual(m_lhs, rhs), m_lhs, "==", rhs};
2798  }
2799  auto operator==(bool rhs) -> BinaryExpr<LhsT, bool> const { return {m_lhs == rhs, m_lhs, "==", rhs}; }
2800 
2801  template<typename RhsT>
2802  auto operator!=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2803  return {compareNotEqual(m_lhs, rhs), m_lhs, "!=", rhs};
2804  }
2805  auto operator!=(bool rhs) -> BinaryExpr<LhsT, bool> const { return {m_lhs != rhs, m_lhs, "!=", rhs}; }
2806 
2807  template<typename RhsT>
2808  auto operator>(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2809  return {static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs};
2810  }
2811  template<typename RhsT>
2812  auto operator<(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2813  return {static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs};
2814  }
2815  template<typename RhsT>
2816  auto operator>=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2817  return {static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs};
2818  }
2819  template<typename RhsT>
2820  auto operator<=(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2821  return {static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs};
2822  }
2823  template<typename RhsT>
2824  auto operator|(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2825  return {static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs};
2826  }
2827  template<typename RhsT>
2828  auto operator&(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2829  return {static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs};
2830  }
2831  template<typename RhsT>
2832  auto operator^(RhsT const &rhs) -> BinaryExpr<LhsT, RhsT const &> const {
2833  return {static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs};
2834  }
2835 
2836  template<typename RhsT>
2837  auto operator&&(RhsT const &) -> BinaryExpr<LhsT, RhsT const &> const {
2838  static_assert(always_false<RhsT>::value,
2839  "operator&& is not supported inside assertions, "
2840  "wrap the expression inside parentheses, or decompose it");
2841  }
2842 
2843  template<typename RhsT>
2844  auto operator||(RhsT const &) -> BinaryExpr<LhsT, RhsT const &> const {
2845  static_assert(always_false<RhsT>::value,
2846  "operator|| is not supported inside assertions, "
2847  "wrap the expression inside parentheses, or decompose it");
2848  }
2849 
2850  auto makeUnaryExpr() const -> UnaryExpr<LhsT> { return UnaryExpr<LhsT>{m_lhs}; }
2851  };
2852 
2853  void handleExpression(ITransientExpression const &expr);
2854 
2855  template<typename T>
2856  void handleExpression(ExprLhs<T> const &expr) {
2857  handleExpression(expr.makeUnaryExpr());
2858  }
2859 
2860  struct Decomposer {
2861  template<typename T>
2862  auto operator<=(T const &lhs) -> ExprLhs<T const &> {
2863  return ExprLhs<T const &>{lhs};
2864  }
2865 
2866  auto operator<=(bool value) -> ExprLhs<bool> { return ExprLhs<bool>{value}; }
2867  };
2868 
2869 } // end namespace Catch
2870 
2871 #ifdef _MSC_VER
2872 #pragma warning(pop)
2873 #endif
2874 
2875 // end catch_decomposer.h
2876 // start catch_interfaces_capture.h
2877 
2878 #include <chrono>
2879 #include <string>
2880 
2881 namespace Catch {
2882  class AssertionResult;
2883  struct AssertionInfo;
2884  struct SectionInfo;
2885  struct SectionEndInfo;
2886  struct MessageInfo;
2887  struct MessageBuilder;
2888  struct Counts;
2889  struct AssertionReaction;
2890  struct SourceLineInfo;
2891 
2892  struct ITransientExpression;
2893  struct IGeneratorTracker;
2894 
2895 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2896  struct BenchmarkInfo;
2897  template<typename Duration = std::chrono::duration<double, std::nano>>
2898  struct BenchmarkStats;
2899 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2900 
2902  virtual ~IResultCapture();
2903 
2904  virtual bool sectionStarted(SectionInfo const &sectionInfo, Counts &assertions) = 0;
2905  virtual void sectionEnded(SectionEndInfo const &endInfo) = 0;
2906  virtual void sectionEndedEarly(SectionEndInfo const &endInfo) = 0;
2907 
2908  virtual auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker & = 0;
2909 
2910 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
2911  virtual void benchmarkPreparing(std::string const &name) = 0;
2912  virtual void benchmarkStarting(BenchmarkInfo const &info) = 0;
2913  virtual void benchmarkEnded(BenchmarkStats<> const &stats) = 0;
2914  virtual void benchmarkFailed(std::string const &error) = 0;
2915 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
2916 
2917  virtual void pushScopedMessage(MessageInfo const &message) = 0;
2918  virtual void popScopedMessage(MessageInfo const &message) = 0;
2919 
2920  virtual void emplaceUnscopedMessage(MessageBuilder const &builder) = 0;
2921 
2922  virtual void handleFatalErrorCondition(StringRef message) = 0;
2923 
2924  virtual void handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction) = 0;
2925  virtual void handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, AssertionReaction &reaction)
2926  = 0;
2927  virtual void handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction) = 0;
2928  virtual void handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, AssertionReaction &reaction) = 0;
2929  virtual void handleIncomplete(AssertionInfo const &info) = 0;
2930  virtual void handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction) = 0;
2931 
2932  virtual bool lastAssertionPassed() = 0;
2933  virtual void assertionPassed() = 0;
2934 
2935  // Deprecated, do not use:
2936  virtual std::string getCurrentTestName() const = 0;
2937  virtual const AssertionResult *getLastResult() const = 0;
2938  virtual void exceptionEarlyReported() = 0;
2939  };
2940 
2941  IResultCapture &getResultCapture();
2942 } // namespace Catch
2943 
2944 // end catch_interfaces_capture.h
2945 namespace Catch {
2947  };
2948  struct AssertionResultData;
2949  struct IResultCapture;
2950  class RunContext;
2951 
2953  friend class AssertionHandler;
2954  friend struct AssertionStats;
2955  friend class RunContext;
2956 
2957  ITransientExpression const *m_transientExpression = nullptr;
2958  bool m_isNegated;
2959 
2960  public:
2961  LazyExpression(bool isNegated);
2962  LazyExpression(LazyExpression const &other);
2963  LazyExpression &operator=(LazyExpression const &) = delete;
2964 
2965  explicit operator bool() const;
2966 
2967  friend auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream &;
2968  };
2969 
2971  bool shouldDebugBreak = false;
2972  bool shouldThrow = false;
2973  };
2974 
2976  AssertionInfo m_assertionInfo;
2977  AssertionReaction m_reaction;
2978  bool m_completed = false;
2979  IResultCapture &m_resultCapture;
2980 
2981  public:
2982  AssertionHandler(StringRef const &macroName,
2983  SourceLineInfo const &lineInfo,
2984  StringRef capturedExpression,
2985  ResultDisposition::Flags resultDisposition);
2986  ~AssertionHandler() {
2987  if (!m_completed) {
2988  m_resultCapture.handleIncomplete(m_assertionInfo);
2989  }
2990  }
2991 
2992  template<typename T>
2993  void handleExpr(ExprLhs<T> const &expr) {
2994  handleExpr(expr.makeUnaryExpr());
2995  }
2996  void handleExpr(ITransientExpression const &expr);
2997 
2998  void handleMessage(ResultWas::OfType resultType, StringRef const &message);
2999 
3000  void handleExceptionThrownAsExpected();
3001  void handleUnexpectedExceptionNotThrown();
3002  void handleExceptionNotThrownAsExpected();
3003  void handleThrowingCallSkipped();
3004  void handleUnexpectedInflightException();
3005 
3006  void complete();
3007  void setCompleted();
3008 
3009  // query
3010  auto allowThrows() const -> bool;
3011  };
3012 
3013  void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef const &matcherString);
3014 
3015 } // namespace Catch
3016 
3017 // end catch_assertionhandler.h
3018 // start catch_message.h
3019 
3020 #include <string>
3021 #include <vector>
3022 
3023 namespace Catch {
3024  struct MessageInfo {
3025  MessageInfo(StringRef const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type);
3026 
3027  StringRef macroName;
3028  std::string message;
3029  SourceLineInfo lineInfo;
3030  ResultWas::OfType type;
3031  unsigned int sequence;
3032 
3033  bool operator==(MessageInfo const &other) const;
3034  bool operator<(MessageInfo const &other) const;
3035 
3036  private:
3037  static unsigned int globalCount;
3038  };
3039 
3040  struct MessageStream {
3041  template<typename T>
3042  MessageStream &operator<<(T const &value) {
3043  m_stream << value;
3044  return *this;
3045  }
3046 
3047  ReusableStringStream m_stream;
3048  };
3049 
3051  MessageBuilder(StringRef const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type);
3052 
3053  template<typename T>
3054  MessageBuilder &operator<<(T const &value) {
3055  m_stream << value;
3056  return *this;
3057  }
3058 
3059  MessageInfo m_info;
3060  };
3061 
3063  public:
3064  explicit ScopedMessage(MessageBuilder const &builder);
3065  ScopedMessage(ScopedMessage &duplicate) = delete;
3067  ~ScopedMessage();
3068 
3069  MessageInfo m_info;
3070  bool m_moved;
3071  };
3072 
3073  class Capturer {
3074  std::vector<MessageInfo> m_messages;
3075  IResultCapture &m_resultCapture = getResultCapture();
3076  size_t m_captured = 0;
3077 
3078  public:
3079  Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names);
3080  ~Capturer();
3081 
3082  void captureValue(size_t index, std::string const &value);
3083 
3084  template<typename T>
3085  void captureValues(size_t index, T const &value) {
3086  captureValue(index, Catch::Detail::stringify(value));
3087  }
3088 
3089  template<typename T, typename... Ts>
3090  void captureValues(size_t index, T const &value, Ts const &...values) {
3091  captureValue(index, Catch::Detail::stringify(value));
3092  captureValues(index + 1, values...);
3093  }
3094  };
3095 
3096 } // end namespace Catch
3097 
3098 // end catch_message.h
3099 #if !defined(CATCH_CONFIG_DISABLE)
3100 
3101 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
3102 #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
3103 #else
3104 #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
3105 #endif
3106 
3107 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3108 
3110 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
3111 // macros.
3112 #define INTERNAL_CATCH_TRY
3113 #define INTERNAL_CATCH_CATCH(capturer)
3114 
3115 #else // CATCH_CONFIG_FAST_COMPILE
3116 
3117 #define INTERNAL_CATCH_TRY try
3118 #define INTERNAL_CATCH_CATCH(handler) \
3119  catch (...) { \
3120  handler.handleUnexpectedInflightException(); \
3121  }
3122 
3123 #endif
3124 
3125 #define INTERNAL_CATCH_REACT(handler) handler.complete();
3126 
3128 #define INTERNAL_CATCH_TEST(macroName, resultDisposition, ...) \
3129  do { \
3130  CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
3131  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
3132  CATCH_INTERNAL_LINEINFO, \
3133  CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), \
3134  resultDisposition); \
3135  INTERNAL_CATCH_TRY { \
3136  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3137  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
3138  catchAssertionHandler.handleExpr(Catch::Decomposer() <= __VA_ARGS__); \
3139  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
3140  } \
3141  INTERNAL_CATCH_CATCH(catchAssertionHandler) \
3142  INTERNAL_CATCH_REACT(catchAssertionHandler) \
3143  } while ((void)0, (false) && static_cast<bool>(!!(__VA_ARGS__)))
3144 
3146 #define INTERNAL_CATCH_IF(macroName, resultDisposition, ...) \
3147  INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__); \
3148  if (Catch::getResultCapture().lastAssertionPassed())
3149 
3151 #define INTERNAL_CATCH_ELSE(macroName, resultDisposition, ...) \
3152  INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__); \
3153  if (!Catch::getResultCapture().lastAssertionPassed())
3154 
3156 #define INTERNAL_CATCH_NO_THROW(macroName, resultDisposition, ...) \
3157  do { \
3158  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
3159  CATCH_INTERNAL_LINEINFO, \
3160  CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), \
3161  resultDisposition); \
3162  try { \
3163  static_cast<void>(__VA_ARGS__); \
3164  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
3165  } catch (...) { \
3166  catchAssertionHandler.handleUnexpectedInflightException(); \
3167  } \
3168  INTERNAL_CATCH_REACT(catchAssertionHandler) \
3169  } while (false)
3170 
3172 #define INTERNAL_CATCH_THROWS(macroName, resultDisposition, ...) \
3173  do { \
3174  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
3175  CATCH_INTERNAL_LINEINFO, \
3176  CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), \
3177  resultDisposition); \
3178  if (catchAssertionHandler.allowThrows()) \
3179  try { \
3180  static_cast<void>(__VA_ARGS__); \
3181  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3182  } catch (...) { \
3183  catchAssertionHandler.handleExceptionThrownAsExpected(); \
3184  } \
3185  else \
3186  catchAssertionHandler.handleThrowingCallSkipped(); \
3187  INTERNAL_CATCH_REACT(catchAssertionHandler) \
3188  } while (false)
3189 
3191 #define INTERNAL_CATCH_THROWS_AS(macroName, exceptionType, resultDisposition, expr) \
3192  do { \
3193  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
3194  CATCH_INTERNAL_LINEINFO, \
3195  CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), \
3196  resultDisposition); \
3197  if (catchAssertionHandler.allowThrows()) \
3198  try { \
3199  static_cast<void>(expr); \
3200  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3201  } catch (exceptionType const &) { \
3202  catchAssertionHandler.handleExceptionThrownAsExpected(); \
3203  } catch (...) { \
3204  catchAssertionHandler.handleUnexpectedInflightException(); \
3205  } \
3206  else \
3207  catchAssertionHandler.handleThrowingCallSkipped(); \
3208  INTERNAL_CATCH_REACT(catchAssertionHandler) \
3209  } while (false)
3210 
3212 #define INTERNAL_CATCH_MSG(macroName, messageType, resultDisposition, ...) \
3213  do { \
3214  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition); \
3215  catchAssertionHandler.handleMessage(messageType, \
3216  (Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop()).m_stream.str()); \
3217  INTERNAL_CATCH_REACT(catchAssertionHandler) \
3218  } while (false)
3219 
3221 #define INTERNAL_CATCH_CAPTURE(varName, macroName, ...) \
3222  auto varName = Catch::Capturer(macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__); \
3223  varName.captureValues(0, __VA_ARGS__)
3224 
3226 #define INTERNAL_CATCH_INFO(macroName, log) \
3227  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME(scopedMessage)( \
3228  Catch::MessageBuilder(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log);
3229 
3231 #define INTERNAL_CATCH_UNSCOPED_INFO(macroName, log) \
3232  Catch::getResultCapture().emplaceUnscopedMessage( \
3233  Catch::MessageBuilder(macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log)
3234 
3236 // Although this is matcher-based, it can be used with just a string
3237 #define INTERNAL_CATCH_THROWS_STR_MATCHES(macroName, resultDisposition, matcher, ...) \
3238  do { \
3239  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
3240  CATCH_INTERNAL_LINEINFO, \
3241  CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), \
3242  resultDisposition); \
3243  if (catchAssertionHandler.allowThrows()) \
3244  try { \
3245  static_cast<void>(__VA_ARGS__); \
3246  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3247  } catch (...) { \
3248  Catch::handleExceptionMatchExpr(catchAssertionHandler, matcher, #matcher##_catch_sr); \
3249  } \
3250  else \
3251  catchAssertionHandler.handleThrowingCallSkipped(); \
3252  INTERNAL_CATCH_REACT(catchAssertionHandler) \
3253  } while (false)
3254 
3255 #endif // CATCH_CONFIG_DISABLE
3256 
3257 // end catch_capture.hpp
3258 // start catch_section.h
3259 
3260 // start catch_section_info.h
3261 
3262 // start catch_totals.h
3263 
3264 #include <cstddef>
3265 
3266 namespace Catch {
3267  struct Counts {
3268  Counts operator-(Counts const &other) const;
3269  Counts &operator+=(Counts const &other);
3270 
3271  std::size_t total() const;
3272  bool allPassed() const;
3273  bool allOk() const;
3274 
3275  std::size_t passed = 0;
3276  std::size_t failed = 0;
3277  std::size_t failedButOk = 0;
3278  };
3279 
3280  struct Totals {
3281  Totals operator-(Totals const &other) const;
3282  Totals &operator+=(Totals const &other);
3283 
3284  Totals delta(Totals const &prevTotals) const;
3285 
3286  int error = 0;
3287  Counts assertions;
3288  Counts testCases;
3289  };
3290 } // namespace Catch
3291 
3292 // end catch_totals.h
3293 #include <string>
3294 
3295 namespace Catch {
3296  struct SectionInfo {
3297  SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name);
3298 
3299  // Deprecated
3300  SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name, std::string const &)
3301  : SectionInfo(_lineInfo, _name) {
3302  }
3303 
3304  std::string name;
3305  std::string description; // !Deprecated: this will always be empty
3306  SourceLineInfo lineInfo;
3307  };
3308 
3310  SectionInfo sectionInfo;
3311  Counts prevAssertions;
3312  double durationInSeconds;
3313  };
3314 
3315 } // end namespace Catch
3316 
3317 // end catch_section_info.h
3318 // start catch_timer.h
3319 
3320 #include <cstdint>
3321 
3322 namespace Catch {
3323  auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
3324  auto getEstimatedClockResolution() -> uint64_t;
3325 
3326  class Timer {
3327  uint64_t m_nanoseconds = 0;
3328 
3329  public:
3330  void start();
3331  auto getElapsedNanoseconds() const -> uint64_t;
3332  auto getElapsedMicroseconds() const -> uint64_t;
3333  auto getElapsedMilliseconds() const -> unsigned int;
3334  auto getElapsedSeconds() const -> double;
3335  };
3336 
3337 } // namespace Catch
3338 
3339 // end catch_timer.h
3340 #include <string>
3341 
3342 namespace Catch {
3344  public:
3345  Section(SectionInfo const &info);
3346  ~Section();
3347 
3348  // This indicates whether the section should be executed or not
3349  explicit operator bool() const;
3350 
3351  private:
3352  SectionInfo m_info;
3353 
3354  std::string m_name;
3355  Counts m_assertions;
3356  bool m_sectionIncluded;
3357  Timer m_timer;
3358  };
3359 
3360 } // end namespace Catch
3361 
3362 #define INTERNAL_CATCH_SECTION(...) \
3363  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3364  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
3365  if (Catch::Section const &INTERNAL_CATCH_UNIQUE_NAME(catch_internal_Section) \
3366  = Catch::SectionInfo(CATCH_INTERNAL_LINEINFO, __VA_ARGS__)) \
3367  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
3368 
3369 #define INTERNAL_CATCH_DYNAMIC_SECTION(...) \
3370  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3371  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
3372  if (Catch::Section const &INTERNAL_CATCH_UNIQUE_NAME(catch_internal_Section) \
3373  = Catch::SectionInfo(CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str())) \
3374  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
3375 
3376 // end catch_section.h
3377 // start catch_interfaces_exception.h
3378 
3379 // start catch_interfaces_registry_hub.h
3380 
3381 #include <memory>
3382 #include <string>
3383 
3384 namespace Catch {
3385  class TestCase;
3386  struct ITestCaseRegistry;
3388  struct IExceptionTranslator;
3389  struct IReporterRegistry;
3390  struct IReporterFactory;
3391  struct ITagAliasRegistry;
3393 
3394  class StartupExceptionRegistry;
3395 
3396  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
3397 
3398  struct IRegistryHub {
3399  virtual ~IRegistryHub();
3400 
3401  virtual IReporterRegistry const &getReporterRegistry() const = 0;
3402  virtual ITestCaseRegistry const &getTestCaseRegistry() const = 0;
3403  virtual ITagAliasRegistry const &getTagAliasRegistry() const = 0;
3404  virtual IExceptionTranslatorRegistry const &getExceptionTranslatorRegistry() const = 0;
3405 
3406  virtual StartupExceptionRegistry const &getStartupExceptionRegistry() const = 0;
3407  };
3408 
3410  virtual ~IMutableRegistryHub();
3411  virtual void registerReporter(std::string const &name, IReporterFactoryPtr const &factory) = 0;
3412  virtual void registerListener(IReporterFactoryPtr const &factory) = 0;
3413  virtual void registerTest(TestCase const &testInfo) = 0;
3414  virtual void registerTranslator(const IExceptionTranslator *translator) = 0;
3415  virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) = 0;
3416  virtual void registerStartupException() noexcept = 0;
3417  virtual IMutableEnumValuesRegistry &getMutableEnumValuesRegistry() = 0;
3418  };
3419 
3420  IRegistryHub const &getRegistryHub();
3421  IMutableRegistryHub &getMutableRegistryHub();
3422  void cleanUp();
3423  std::string translateActiveException();
3424 
3425 } // namespace Catch
3426 
3427 // end catch_interfaces_registry_hub.h
3428 #if defined(CATCH_CONFIG_DISABLE)
3429 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(translatorName, signature) static std::string translatorName(signature)
3430 #endif
3431 
3432 #include <exception>
3433 #include <string>
3434 #include <vector>
3435 
3436 namespace Catch {
3437  using exceptionTranslateFunction = std::string (*)();
3438 
3439  struct IExceptionTranslator;
3440  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
3441 
3443  virtual ~IExceptionTranslator();
3444  virtual std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const = 0;
3445  };
3446 
3448  virtual ~IExceptionTranslatorRegistry();
3449 
3450  virtual std::string translateActiveException() const = 0;
3451  };
3452 
3454  template<typename T>
3455  class ExceptionTranslator : public IExceptionTranslator {
3456  public:
3457  ExceptionTranslator(std::string (*translateFunction)(T &))
3458  : m_translateFunction(translateFunction) {
3459  }
3460 
3461  std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override {
3462 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3463  return "";
3464 #else
3465  try {
3466  if (it == itEnd)
3467  std::rethrow_exception(std::current_exception());
3468  else
3469  return (*it)->translate(it + 1, itEnd);
3470  } catch (T &ex) {
3471  return m_translateFunction(ex);
3472  }
3473 #endif
3474  }
3475 
3476  protected:
3477  std::string (*m_translateFunction)(T &);
3478  };
3479 
3480  public:
3481  template<typename T>
3482  ExceptionTranslatorRegistrar(std::string (*translateFunction)(T &)) {
3483  getMutableRegistryHub().registerTranslator(new ExceptionTranslator<T>(translateFunction));
3484  }
3485  };
3486 } // namespace Catch
3487 
3489 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2(translatorName, signature) \
3490  static std::string translatorName(signature); \
3491  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
3492  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
3493  namespace { \
3494  Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionRegistrar)(&translatorName); \
3495  } \
3496  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
3497  static std::string translatorName(signature)
3498 
3499 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature) \
3500  INTERNAL_CATCH_TRANSLATE_EXCEPTION2(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature)
3501 
3502 // end catch_interfaces_exception.h
3503 // start catch_approx.h
3504 
3505 #include <type_traits>
3506 
3507 namespace Catch {
3508  namespace Detail {
3509  class Approx {
3510  private:
3511  bool equalityComparisonImpl(double other) const;
3512  // Validates the new margin (margin >= 0)
3513  // out-of-line to avoid including stdexcept in the header
3514  void setMargin(double margin);
3515  // Validates the new epsilon (0 < epsilon < 1)
3516  // out-of-line to avoid including stdexcept in the header
3517  void setEpsilon(double epsilon);
3518 
3519  public:
3520  explicit Approx(double value);
3521 
3522  static Approx custom();
3523 
3524  Approx operator-() const;
3525 
3526  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3527  Approx operator()(T const &value) {
3528  Approx approx(static_cast<double>(value));
3529  approx.m_epsilon = m_epsilon;
3530  approx.m_margin = m_margin;
3531  approx.m_scale = m_scale;
3532  return approx;
3533  }
3534 
3535  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3536  explicit Approx(T const &value)
3537  : Approx(static_cast<double>(value)) {
3538  }
3539 
3540  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3541  friend bool operator==(const T &lhs, Approx const &rhs) {
3542  auto lhs_v = static_cast<double>(lhs);
3543  return rhs.equalityComparisonImpl(lhs_v);
3544  }
3545 
3546  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3547  friend bool operator==(Approx const &lhs, const T &rhs) {
3548  return operator==(rhs, lhs);
3549  }
3550 
3551  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3552  friend bool operator!=(T const &lhs, Approx const &rhs) {
3553  return !operator==(lhs, rhs);
3554  }
3555 
3556  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3557  friend bool operator!=(Approx const &lhs, T const &rhs) {
3558  return !operator==(rhs, lhs);
3559  }
3560 
3561  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3562  friend bool operator<=(T const &lhs, Approx const &rhs) {
3563  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3564  }
3565 
3566  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3567  friend bool operator<=(Approx const &lhs, T const &rhs) {
3568  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3569  }
3570 
3571  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3572  friend bool operator>=(T const &lhs, Approx const &rhs) {
3573  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3574  }
3575 
3576  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3577  friend bool operator>=(Approx const &lhs, T const &rhs) {
3578  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3579  }
3580 
3581  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3582  Approx &epsilon(T const &newEpsilon) {
3583  double epsilonAsDouble = static_cast<double>(newEpsilon);
3584  setEpsilon(epsilonAsDouble);
3585  return *this;
3586  }
3587 
3588  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3589  Approx &margin(T const &newMargin) {
3590  double marginAsDouble = static_cast<double>(newMargin);
3591  setMargin(marginAsDouble);
3592  return *this;
3593  }
3594 
3595  template<typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
3596  Approx &scale(T const &newScale) {
3597  m_scale = static_cast<double>(newScale);
3598  return *this;
3599  }
3600 
3601  std::string toString() const;
3602 
3603  private:
3604  double m_epsilon;
3605  double m_margin;
3606  double m_scale;
3607  double m_value;
3608  };
3609  } // end namespace Detail
3610 
3611  namespace literals {
3612  Detail::Approx operator"" _a(long double val);
3613  Detail::Approx operator"" _a(unsigned long long val);
3614  } // end namespace literals
3615 
3616  template<>
3618  static std::string convert(Catch::Detail::Approx const &value);
3619  };
3620 
3621 } // end namespace Catch
3622 
3623 // end catch_approx.h
3624 // start catch_string_manip.h
3625 
3626 #include <iosfwd>
3627 #include <string>
3628 #include <vector>
3629 
3630 namespace Catch {
3631  bool startsWith(std::string const &s, std::string const &prefix);
3632  bool startsWith(std::string const &s, char prefix);
3633  bool endsWith(std::string const &s, std::string const &suffix);
3634  bool endsWith(std::string const &s, char suffix);
3635  bool contains(std::string const &s, std::string const &infix);
3636  void toLowerInPlace(std::string &s);
3637  std::string toLower(std::string const &s);
3639  std::string trim(std::string const &str);
3641  StringRef trim(StringRef ref);
3642 
3643  // !!! Be aware, returns refs into original string - make sure original string outlives them
3644  std::vector<StringRef> splitStringRef(StringRef str, char delimiter);
3645  bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis);
3646 
3647  struct pluralise {
3648  pluralise(std::size_t count, std::string const &label);
3649 
3650  friend std::ostream &operator<<(std::ostream &os, pluralise const &pluraliser);
3651 
3652  std::size_t m_count;
3653  std::string m_label;
3654  };
3655 } // namespace Catch
3656 
3657 // end catch_string_manip.h
3658 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
3659 // start catch_capture_matchers.h
3660 
3661 // start catch_matchers.h
3662 
3663 #include <string>
3664 #include <vector>
3665 
3666 namespace Catch {
3667  namespace Matchers {
3668  namespace Impl {
3669  template<typename ArgT>
3670  struct MatchAllOf;
3671  template<typename ArgT>
3672  struct MatchAnyOf;
3673  template<typename ArgT>
3674  struct MatchNotOf;
3675 
3677  public:
3678  MatcherUntypedBase() = default;
3679  MatcherUntypedBase(MatcherUntypedBase const &) = default;
3680  MatcherUntypedBase &operator=(MatcherUntypedBase const &) = delete;
3681  std::string toString() const;
3682 
3683  protected:
3684  virtual ~MatcherUntypedBase();
3685  virtual std::string describe() const = 0;
3686  mutable std::string m_cachedToString;
3687  };
3688 
3689 #ifdef __clang__
3690 #pragma clang diagnostic push
3691 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
3692 #endif
3693 
3694  template<typename ObjectT>
3695  struct MatcherMethod {
3696  virtual bool match(ObjectT const &arg) const = 0;
3697  };
3698 
3699 #if defined(__OBJC__)
3700  // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
3701  // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
3702  template<>
3703  struct MatcherMethod<NSString *> {
3704  virtual bool match(NSString *arg) const = 0;
3705  };
3706 #endif
3707 
3708 #ifdef __clang__
3709 #pragma clang diagnostic pop
3710 #endif
3711 
3712  template<typename T>
3714  MatchAllOf<T> operator&&(MatcherBase const &other) const;
3715  MatchAnyOf<T> operator||(MatcherBase const &other) const;
3716  MatchNotOf<T> operator!() const;
3717  };
3718 
3719  template<typename ArgT>
3720  struct MatchAllOf : MatcherBase<ArgT> {
3721  bool match(ArgT const &arg) const override {
3722  for (auto matcher : m_matchers) {
3723  if (!matcher->match(arg))
3724  return false;
3725  }
3726  return true;
3727  }
3728  std::string describe() const override {
3729  std::string description;
3730  description.reserve(4 + m_matchers.size() * 32);
3731  description += "( ";
3732  bool first = true;
3733  for (auto matcher : m_matchers) {
3734  if (first)
3735  first = false;
3736  else
3737  description += " and ";
3738  description += matcher->toString();
3739  }
3740  description += " )";
3741  return description;
3742  }
3743 
3744  MatchAllOf<ArgT> operator&&(MatcherBase<ArgT> const &other) {
3745  auto copy(*this);
3746  copy.m_matchers.push_back(&other);
3747  return copy;
3748  }
3749 
3750  std::vector<MatcherBase<ArgT> const *> m_matchers;
3751  };
3752  template<typename ArgT>
3753  struct MatchAnyOf : MatcherBase<ArgT> {
3754  bool match(ArgT const &arg) const override {
3755  for (auto matcher : m_matchers) {
3756  if (matcher->match(arg))
3757  return true;
3758  }
3759  return false;
3760  }
3761  std::string describe() const override {
3762  std::string description;
3763  description.reserve(4 + m_matchers.size() * 32);
3764  description += "( ";
3765  bool first = true;
3766  for (auto matcher : m_matchers) {
3767  if (first)
3768  first = false;
3769  else
3770  description += " or ";
3771  description += matcher->toString();
3772  }
3773  description += " )";
3774  return description;
3775  }
3776 
3777  MatchAnyOf<ArgT> operator||(MatcherBase<ArgT> const &other) {
3778  auto copy(*this);
3779  copy.m_matchers.push_back(&other);
3780  return copy;
3781  }
3782 
3783  std::vector<MatcherBase<ArgT> const *> m_matchers;
3784  };
3785 
3786  template<typename ArgT>
3787  struct MatchNotOf : MatcherBase<ArgT> {
3788  MatchNotOf(MatcherBase<ArgT> const &underlyingMatcher)
3789  : m_underlyingMatcher(underlyingMatcher) {
3790  }
3791 
3792  bool match(ArgT const &arg) const override { return !m_underlyingMatcher.match(arg); }
3793 
3794  std::string describe() const override { return "not " + m_underlyingMatcher.toString(); }
3795  MatcherBase<ArgT> const &m_underlyingMatcher;
3796  };
3797 
3798  template<typename T>
3800  return MatchAllOf<T>() && *this && other;
3801  }
3802  template<typename T>
3804  return MatchAnyOf<T>() || *this || other;
3805  }
3806  template<typename T>
3808  return MatchNotOf<T>(*this);
3809  }
3810 
3811  } // namespace Impl
3812  } // namespace Matchers
3813 
3814  using namespace Matchers;
3816 
3817 } // namespace Catch
3818 
3819 // end catch_matchers.h
3820 // start catch_matchers_exception.hpp
3821 
3822 namespace Catch {
3823  namespace Matchers {
3824  namespace Exception {
3825  class ExceptionMessageMatcher : public MatcherBase<std::exception> {
3826  std::string m_message;
3827 
3828  public:
3829  ExceptionMessageMatcher(std::string const &message)
3830  : m_message(message) {
3831  }
3832 
3833  bool match(std::exception const &ex) const override;
3834 
3835  std::string describe() const override;
3836  };
3837 
3838  } // namespace Exception
3839 
3840  Exception::ExceptionMessageMatcher Message(std::string const &message);
3841 
3842  } // namespace Matchers
3843 } // namespace Catch
3844 
3845 // end catch_matchers_exception.hpp
3846 // start catch_matchers_floating.h
3847 
3848 namespace Catch {
3849  namespace Matchers {
3850  namespace Floating {
3851  enum class FloatingPointKind : uint8_t;
3852 
3853  struct WithinAbsMatcher : MatcherBase<double> {
3854  WithinAbsMatcher(double target, double margin);
3855  bool match(double const &matchee) const override;
3856  std::string describe() const override;
3857 
3858  private:
3859  double m_target;
3860  double m_margin;
3861  };
3862 
3863  struct WithinUlpsMatcher : MatcherBase<double> {
3864  WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
3865  bool match(double const &matchee) const override;
3866  std::string describe() const override;
3867 
3868  private:
3869  double m_target;
3870  uint64_t m_ulps;
3871  FloatingPointKind m_type;
3872  };
3873 
3874  // Given IEEE-754 format for floats and doubles, we can assume
3875  // that float -> double promotion is lossless. Given this, we can
3876  // assume that if we do the standard relative comparison of
3877  // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
3878  // the same result if we do this for floats, as if we do this for
3879  // doubles that were promoted from floats.
3880  struct WithinRelMatcher : MatcherBase<double> {
3881  WithinRelMatcher(double target, double epsilon);
3882  bool match(double const &matchee) const override;
3883  std::string describe() const override;
3884 
3885  private:
3886  double m_target;
3887  double m_epsilon;
3888  };
3889 
3890  } // namespace Floating
3891 
3892  // The following functions create the actual matcher objects.
3893  // This allows the types to be inferred
3894  Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
3895  Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
3896  Floating::WithinAbsMatcher WithinAbs(double target, double margin);
3897  Floating::WithinRelMatcher WithinRel(double target, double eps);
3898  // defaults epsilon to 100*numeric_limits<double>::epsilon()
3899  Floating::WithinRelMatcher WithinRel(double target);
3900  Floating::WithinRelMatcher WithinRel(float target, float eps);
3901  // defaults epsilon to 100*numeric_limits<float>::epsilon()
3902  Floating::WithinRelMatcher WithinRel(float target);
3903 
3904  } // namespace Matchers
3905 } // namespace Catch
3906 
3907 // end catch_matchers_floating.h
3908 // start catch_matchers_generic.hpp
3909 
3910 #include <functional>
3911 #include <string>
3912 
3913 namespace Catch {
3914  namespace Matchers {
3915  namespace Generic {
3916  namespace Detail {
3917  std::string finalizeDescription(const std::string &desc);
3918  }
3919 
3920  template<typename T>
3921  class PredicateMatcher : public MatcherBase<T> {
3922  std::function<bool(T const &)> m_predicate;
3923  std::string m_description;
3924 
3925  public:
3926  PredicateMatcher(std::function<bool(T const &)> const &elem, std::string const &descr)
3927  : m_predicate(std::move(elem))
3928  , m_description(Detail::finalizeDescription(descr)) {
3929  }
3930 
3931  bool match(T const &item) const override { return m_predicate(item); }
3932 
3933  std::string describe() const override { return m_description; }
3934  };
3935 
3936  } // namespace Generic
3937 
3938  // The following functions create the actual matcher objects.
3939  // The user has to explicitly specify type to the function, because
3940  // inferring std::function<bool(T const&)> is hard (but possible) and
3941  // requires a lot of TMP.
3942  template<typename T>
3943  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const &)> const &predicate, std::string const &description = "") {
3944  return Generic::PredicateMatcher<T>(predicate, description);
3945  }
3946 
3947  } // namespace Matchers
3948 } // namespace Catch
3949 
3950 // end catch_matchers_generic.hpp
3951 // start catch_matchers_string.h
3952 
3953 #include <string>
3954 
3955 namespace Catch {
3956  namespace Matchers {
3957  namespace StdString {
3958  struct CasedString {
3959  CasedString(std::string const &str, CaseSensitive::Choice caseSensitivity);
3960  std::string adjustString(std::string const &str) const;
3961  std::string caseSensitivitySuffix() const;
3962 
3963  CaseSensitive::Choice m_caseSensitivity;
3964  std::string m_str;
3965  };
3966 
3967  struct StringMatcherBase : MatcherBase<std::string> {
3968  StringMatcherBase(std::string const &operation, CasedString const &comparator);
3969  std::string describe() const override;
3970 
3971  CasedString m_comparator;
3972  std::string m_operation;
3973  };
3974 
3976  EqualsMatcher(CasedString const &comparator);
3977  bool match(std::string const &source) const override;
3978  };
3980  ContainsMatcher(CasedString const &comparator);
3981  bool match(std::string const &source) const override;
3982  };
3984  StartsWithMatcher(CasedString const &comparator);
3985  bool match(std::string const &source) const override;
3986  };
3988  EndsWithMatcher(CasedString const &comparator);
3989  bool match(std::string const &source) const override;
3990  };
3991 
3992  struct RegexMatcher : MatcherBase<std::string> {
3993  RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity);
3994  bool match(std::string const &matchee) const override;
3995  std::string describe() const override;
3996 
3997  private:
3998  std::string m_regex;
3999  CaseSensitive::Choice m_caseSensitivity;
4000  };
4001 
4002  } // namespace StdString
4003 
4004  // The following functions create the actual matcher objects.
4005  // This allows the types to be inferred
4006 
4007  StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
4008  StdString::ContainsMatcher Contains(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
4009  StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
4010  StdString::StartsWithMatcher StartsWith(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
4011  StdString::RegexMatcher Matches(std::string const &regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
4012 
4013  } // namespace Matchers
4014 } // namespace Catch
4015 
4016 // end catch_matchers_string.h
4017 // start catch_matchers_vector.h
4018 
4019 #include <algorithm>
4020 
4021 namespace Catch {
4022  namespace Matchers {
4023  namespace Vector {
4024  template<typename T, typename Alloc>
4025  struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
4026  ContainsElementMatcher(T const &comparator)
4027  : m_comparator(comparator) {
4028  }
4029 
4030  bool match(std::vector<T, Alloc> const &v) const override {
4031  for (auto const &el : v) {
4032  if (el == m_comparator) {
4033  return true;
4034  }
4035  }
4036  return false;
4037  }
4038 
4039  std::string describe() const override { return "Contains: " + ::Catch::Detail::stringify(m_comparator); }
4040 
4041  T const &m_comparator;
4042  };
4043 
4044  template<typename T, typename AllocComp, typename AllocMatch>
4045  struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
4046  ContainsMatcher(std::vector<T, AllocComp> const &comparator)
4047  : m_comparator(comparator) {
4048  }
4049 
4050  bool match(std::vector<T, AllocMatch> const &v) const override {
4051  // !TBD: see note in EqualsMatcher
4052  if (m_comparator.size() > v.size())
4053  return false;
4054  for (auto const &comparator : m_comparator) {
4055  auto present = false;
4056  for (const auto &el : v) {
4057  if (el == comparator) {
4058  present = true;
4059  break;
4060  }
4061  }
4062  if (!present) {
4063  return false;
4064  }
4065  }
4066  return true;
4067  }
4068  std::string describe() const override { return "Contains: " + ::Catch::Detail::stringify(m_comparator); }
4069 
4070  std::vector<T, AllocComp> const &m_comparator;
4071  };
4072 
4073  template<typename T, typename AllocComp, typename AllocMatch>
4074  struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
4075  EqualsMatcher(std::vector<T, AllocComp> const &comparator)
4076  : m_comparator(comparator) {
4077  }
4078 
4079  bool match(std::vector<T, AllocMatch> const &v) const override {
4080  // !TBD: This currently works if all elements can be compared using !=
4081  // - a more general approach would be via a compare template that defaults
4082  // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
4083  // - then just call that directly
4084  if (m_comparator.size() != v.size())
4085  return false;
4086  for (std::size_t i = 0; i < v.size(); ++i)
4087  if (m_comparator[i] != v[i])
4088  return false;
4089  return true;
4090  }
4091  std::string describe() const override { return "Equals: " + ::Catch::Detail::stringify(m_comparator); }
4092  std::vector<T, AllocComp> const &m_comparator;
4093  };
4094 
4095  template<typename T, typename AllocComp, typename AllocMatch>
4096  struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
4097  ApproxMatcher(std::vector<T, AllocComp> const &comparator)
4098  : m_comparator(comparator) {
4099  }
4100 
4101  bool match(std::vector<T, AllocMatch> const &v) const override {
4102  if (m_comparator.size() != v.size())
4103  return false;
4104  for (std::size_t i = 0; i < v.size(); ++i)
4105  if (m_comparator[i] != approx(v[i]))
4106  return false;
4107  return true;
4108  }
4109  std::string describe() const override { return "is approx: " + ::Catch::Detail::stringify(m_comparator); }
4110  template<typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
4111  ApproxMatcher &epsilon(T const &newEpsilon) {
4112  approx.epsilon(newEpsilon);
4113  return *this;
4114  }
4115  template<typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
4116  ApproxMatcher &margin(T const &newMargin) {
4117  approx.margin(newMargin);
4118  return *this;
4119  }
4120  template<typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
4121  ApproxMatcher &scale(T const &newScale) {
4122  approx.scale(newScale);
4123  return *this;
4124  }
4125 
4126  std::vector<T, AllocComp> const &m_comparator;
4127  mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
4128  };
4129 
4130  template<typename T, typename AllocComp, typename AllocMatch>
4131  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
4132  UnorderedEqualsMatcher(std::vector<T, AllocComp> const &target)
4133  : m_target(target) {
4134  }
4135  bool match(std::vector<T, AllocMatch> const &vec) const override {
4136  if (m_target.size() != vec.size()) {
4137  return false;
4138  }
4139  return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
4140  }
4141 
4142  std::string describe() const override { return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); }
4143 
4144  private:
4145  std::vector<T, AllocComp> const &m_target;
4146  };
4147 
4148  } // namespace Vector
4149 
4150  // The following functions create the actual matcher objects.
4151  // This allows the types to be inferred
4152 
4153  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
4154  Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains(std::vector<T, AllocComp> const &comparator) {
4156  }
4157 
4158  template<typename T, typename Alloc = std::allocator<T>>
4159  Vector::ContainsElementMatcher<T, Alloc> VectorContains(T const &comparator) {
4160  return Vector::ContainsElementMatcher<T, Alloc>(comparator);
4161  }
4162 
4163  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
4164  Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals(std::vector<T, AllocComp> const &comparator) {
4166  }
4167 
4168  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
4169  Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx(std::vector<T, AllocComp> const &comparator) {
4171  }
4172 
4173  template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
4174  Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const &target) {
4176  }
4177 
4178  } // namespace Matchers
4179 } // namespace Catch
4180 
4181 // end catch_matchers_vector.h
4182 namespace Catch {
4183  template<typename ArgT, typename MatcherT>
4185  ArgT const &m_arg;
4186  MatcherT m_matcher;
4187  StringRef m_matcherString;
4188 
4189  public:
4190  MatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString)
4191  : ITransientExpression{true, matcher.match(arg)}
4192  , m_arg(arg)
4193  , m_matcher(matcher)
4194  , m_matcherString(matcherString) {
4195  }
4196 
4197  void streamReconstructedExpression(std::ostream &os) const override {
4198  auto matcherAsString = m_matcher.toString();
4199  os << Catch::Detail::stringify(m_arg) << ' ';
4200  if (matcherAsString == Detail::unprintableString)
4201  os << m_matcherString;
4202  else
4203  os << matcherAsString;
4204  }
4205  };
4206 
4208 
4209  void handleExceptionMatchExpr(AssertionHandler &handler, StringMatcher const &matcher, StringRef const &matcherString);
4210 
4211  template<typename ArgT, typename MatcherT>
4212  auto makeMatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString) -> MatchExpr<ArgT, MatcherT> {
4213  return MatchExpr<ArgT, MatcherT>(arg, matcher, matcherString);
4214  }
4215 
4216 } // namespace Catch
4217 
4219 #define INTERNAL_CHECK_THAT(macroName, matcher, resultDisposition, arg) \
4220  do { \
4221  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
4222  CATCH_INTERNAL_LINEINFO, \
4223  CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), \
4224  resultDisposition); \
4225  INTERNAL_CATCH_TRY { catchAssertionHandler.handleExpr(Catch::makeMatchExpr(arg, matcher, #matcher##_catch_sr)); } \
4226  INTERNAL_CATCH_CATCH(catchAssertionHandler) \
4227  INTERNAL_CATCH_REACT(catchAssertionHandler) \
4228  } while (false)
4229 
4231 #define INTERNAL_CATCH_THROWS_MATCHES(macroName, exceptionType, resultDisposition, matcher, ...) \
4232  do { \
4233  Catch::AssertionHandler catchAssertionHandler(macroName##_catch_sr, \
4234  CATCH_INTERNAL_LINEINFO, \
4235  CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY( \
4236  exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), \
4237  resultDisposition); \
4238  if (catchAssertionHandler.allowThrows()) \
4239  try { \
4240  static_cast<void>(__VA_ARGS__); \
4241  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
4242  } catch (exceptionType const &ex) { \
4243  catchAssertionHandler.handleExpr(Catch::makeMatchExpr(ex, matcher, #matcher##_catch_sr)); \
4244  } catch (...) { \
4245  catchAssertionHandler.handleUnexpectedInflightException(); \
4246  } \
4247  else \
4248  catchAssertionHandler.handleThrowingCallSkipped(); \
4249  INTERNAL_CATCH_REACT(catchAssertionHandler) \
4250  } while (false)
4251 
4252 // end catch_capture_matchers.h
4253 #endif
4254 // start catch_generators.hpp
4255 
4256 // start catch_interfaces_generatortracker.h
4257 
4258 #include <memory>
4259 
4260 namespace Catch {
4261  namespace Generators {
4263  public:
4264  GeneratorUntypedBase() = default;
4265  virtual ~GeneratorUntypedBase();
4266  // Attempts to move the generator to the next element
4267  //
4268  // Returns true iff the move succeeded (and a valid element
4269  // can be retrieved).
4270  virtual bool next() = 0;
4271  };
4272  using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
4273 
4274  } // namespace Generators
4275 
4277  virtual ~IGeneratorTracker();
4278  virtual auto hasGenerator() const -> bool = 0;
4279  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const & = 0;
4280  virtual void setGenerator(Generators::GeneratorBasePtr &&generator) = 0;
4281  };
4282 
4283 } // namespace Catch
4284 
4285 // end catch_interfaces_generatortracker.h
4286 // start catch_enforce.h
4287 
4288 #include <exception>
4289 
4290 namespace Catch {
4291 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
4292  template<typename Ex>
4293  [[noreturn]] void throw_exception(Ex const &e) {
4294  throw e;
4295  }
4296 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
4297  [[noreturn]] void throw_exception(std::exception const &e);
4298 #endif
4299 
4300  [[noreturn]] void throw_logic_error(std::string const &msg);
4301  [[noreturn]] void throw_domain_error(std::string const &msg);
4302  [[noreturn]] void throw_runtime_error(std::string const &msg);
4303 
4304 } // namespace Catch
4305 
4306 #define CATCH_MAKE_MSG(...) (Catch::ReusableStringStream() << __VA_ARGS__).str()
4307 
4308 #define CATCH_INTERNAL_ERROR(...) \
4309  Catch::throw_logic_error(CATCH_MAKE_MSG(CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
4310 
4311 #define CATCH_ERROR(...) Catch::throw_domain_error(CATCH_MAKE_MSG(__VA_ARGS__))
4312 
4313 #define CATCH_RUNTIME_ERROR(...) Catch::throw_runtime_error(CATCH_MAKE_MSG(__VA_ARGS__))
4314 
4315 #define CATCH_ENFORCE(condition, ...) \
4316  do { \
4317  if (!(condition)) \
4318  CATCH_ERROR(__VA_ARGS__); \
4319  } while (false)
4320 
4321 // end catch_enforce.h
4322 #include <cassert>
4323 #include <memory>
4324 #include <vector>
4325 
4326 #include <exception>
4327 #include <utility>
4328 
4329 namespace Catch {
4330  class GeneratorException : public std::exception {
4331  const char *const m_msg = "";
4332 
4333  public:
4334  GeneratorException(const char *msg)
4335  : m_msg(msg) {
4336  }
4337 
4338  const char *what() const noexcept override final;
4339  };
4340 
4341  namespace Generators {
4342  // !TBD move this into its own location?
4343  namespace pf {
4344  template<typename T, typename... Args>
4345  std::unique_ptr<T> make_unique(Args &&...args) {
4346  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
4347  }
4348  } // namespace pf
4349 
4350  template<typename T>
4352  virtual ~IGenerator() = default;
4353 
4354  // Returns the current element of the generator
4355  //
4356  // \Precondition The generator is either freshly constructed,
4357  // or the last call to `next()` returned true
4358  virtual T const &get() const = 0;
4359  using type = T;
4360  };
4361 
4362  template<typename T>
4363  class SingleValueGenerator final : public IGenerator<T> {
4364  T m_value;
4365 
4366  public:
4367  SingleValueGenerator(T &&value)
4368  : m_value(std::move(value)) {
4369  }
4370 
4371  T const &get() const override { return m_value; }
4372  bool next() override { return false; }
4373  };
4374 
4375  template<typename T>
4376  class FixedValuesGenerator final : public IGenerator<T> {
4377  static_assert(!std::is_same<T, bool>::value,
4378  "FixedValuesGenerator does not support bools because of std::vector<bool>"
4379  "specialization, use SingleValue Generator instead.");
4380  std::vector<T> m_values;
4381  size_t m_idx = 0;
4382 
4383  public:
4384  FixedValuesGenerator(std::initializer_list<T> values)
4385  : m_values(values) {
4386  }
4387 
4388  T const &get() const override { return m_values[m_idx]; }
4389  bool next() override {
4390  ++m_idx;
4391  return m_idx < m_values.size();
4392  }
4393  };
4394 
4395  template<typename T>
4396  class GeneratorWrapper final {
4397  std::unique_ptr<IGenerator<T>> m_generator;
4398 
4399  public:
4400  GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator)
4401  : m_generator(std::move(generator)) {
4402  }
4403  T const &get() const { return m_generator->get(); }
4404  bool next() { return m_generator->next(); }
4405  };
4406 
4407  template<typename T>
4408  GeneratorWrapper<T> value(T &&value) {
4409  return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
4410  }
4411  template<typename T>
4412  GeneratorWrapper<T> values(std::initializer_list<T> values) {
4413  return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
4414  }
4415 
4416  template<typename T>
4417  class Generators : public IGenerator<T> {
4418  std::vector<GeneratorWrapper<T>> m_generators;
4419  size_t m_current = 0;
4420 
4421  void populate(GeneratorWrapper<T> &&generator) { m_generators.emplace_back(std::move(generator)); }
4422  void populate(T &&val) { m_generators.emplace_back(value(std::forward<T>(val))); }
4423  template<typename U>
4424  void populate(U &&val) {
4425  populate(T(std::forward<U>(val)));
4426  }
4427  template<typename U, typename... Gs>
4428  void populate(U &&valueOrGenerator, Gs &&...moreGenerators) {
4429  populate(std::forward<U>(valueOrGenerator));
4430  populate(std::forward<Gs>(moreGenerators)...);
4431  }
4432 
4433  public:
4434  template<typename... Gs>
4435  Generators(Gs &&...moreGenerators) {
4436  m_generators.reserve(sizeof...(Gs));
4437  populate(std::forward<Gs>(moreGenerators)...);
4438  }
4439 
4440  T const &get() const override { return m_generators[m_current].get(); }
4441 
4442  bool next() override {
4443  if (m_current >= m_generators.size()) {
4444  return false;
4445  }
4446  const bool current_status = m_generators[m_current].next();
4447  if (!current_status) {
4448  ++m_current;
4449  }
4450  return m_current < m_generators.size();
4451  }
4452  };
4453 
4454  template<typename... Ts>
4455  GeneratorWrapper<std::tuple<Ts...>> table(std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples) {
4456  return values<std::tuple<Ts...>>(tuples);
4457  }
4458 
4459  // Tag type to signal that a generator sequence should convert arguments to a specific type
4460  template<typename T>
4461  struct as {
4462  };
4463 
4464  template<typename T, typename... Gs>
4465  auto makeGenerators(GeneratorWrapper<T> &&generator, Gs &&...moreGenerators) -> Generators<T> {
4466  return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
4467  }
4468  template<typename T>
4469  auto makeGenerators(GeneratorWrapper<T> &&generator) -> Generators<T> {
4470  return Generators<T>(std::move(generator));
4471  }
4472  template<typename T, typename... Gs>
4473  auto makeGenerators(T &&val, Gs &&...moreGenerators) -> Generators<T> {
4474  return makeGenerators(value(std::forward<T>(val)), std::forward<Gs>(moreGenerators)...);
4475  }
4476  template<typename T, typename U, typename... Gs>
4477  auto makeGenerators(as<T>, U &&val, Gs &&...moreGenerators) -> Generators<T> {
4478  return makeGenerators(value(T(std::forward<U>(val))), std::forward<Gs>(moreGenerators)...);
4479  }
4480 
4481  auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker &;
4482 
4483  template<typename L>
4484  // Note: The type after -> is weird, because VS2015 cannot parse
4485  // the expression used in the typedef inside, when it is in
4486  // return type. Yeah.
4487  auto generate(StringRef generatorName, SourceLineInfo const &lineInfo, L const &generatorExpression)
4488  -> decltype(std::declval<decltype(generatorExpression())>().get()) {
4489  using UnderlyingType = typename decltype(generatorExpression())::type;
4490 
4491  IGeneratorTracker &tracker = acquireGeneratorTracker(generatorName, lineInfo);
4492  if (!tracker.hasGenerator()) {
4493  tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
4494  }
4495 
4496  auto const &generator = static_cast<IGenerator<UnderlyingType> const &>(*tracker.getGenerator());
4497  return generator.get();
4498  }
4499 
4500  } // namespace Generators
4501 } // namespace Catch
4502 
4503 #define GENERATE(...) \
4504  Catch::Generators::generate(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), CATCH_INTERNAL_LINEINFO, [] { \
4505  using namespace Catch::Generators; \
4506  return makeGenerators(__VA_ARGS__); \
4507  }) // NOLINT(google-build-using-namespace)
4508 #define GENERATE_COPY(...) \
4509  Catch::Generators::generate(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), CATCH_INTERNAL_LINEINFO, [=] { \
4510  using namespace Catch::Generators; \
4511  return makeGenerators(__VA_ARGS__); \
4512  }) // NOLINT(google-build-using-namespace)
4513 #define GENERATE_REF(...) \
4514  Catch::Generators::generate(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), CATCH_INTERNAL_LINEINFO, [&] { \
4515  using namespace Catch::Generators; \
4516  return makeGenerators(__VA_ARGS__); \
4517  }) // NOLINT(google-build-using-namespace)
4518 
4519 // end catch_generators.hpp
4520 // start catch_generators_generic.hpp
4521 
4522 namespace Catch {
4523  namespace Generators {
4524  template<typename T>
4525  class TakeGenerator : public IGenerator<T> {
4526  GeneratorWrapper<T> m_generator;
4527  size_t m_returned = 0;
4528  size_t m_target;
4529 
4530  public:
4531  TakeGenerator(size_t target, GeneratorWrapper<T> &&generator)
4532  : m_generator(std::move(generator))
4533  , m_target(target) {
4534  assert(target != 0 && "Empty generators are not allowed");
4535  }
4536  T const &get() const override { return m_generator.get(); }
4537  bool next() override {
4538  ++m_returned;
4539  if (m_returned >= m_target) {
4540  return false;
4541  }
4542 
4543  const auto success = m_generator.next();
4544  // If the underlying generator does not contain enough values
4545  // then we cut short as well
4546  if (!success) {
4547  m_returned = m_target;
4548  }
4549  return success;
4550  }
4551  };
4552 
4553  template<typename T>
4554  GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T> &&generator) {
4555  return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
4556  }
4557 
4558  template<typename T, typename Predicate>
4559  class FilterGenerator : public IGenerator<T> {
4560  GeneratorWrapper<T> m_generator;
4561  Predicate m_predicate;
4562 
4563  public:
4564  template<typename P = Predicate>
4565  FilterGenerator(P &&pred, GeneratorWrapper<T> &&generator)
4566  : m_generator(std::move(generator))
4567  , m_predicate(std::forward<P>(pred)) {
4568  if (!m_predicate(m_generator.get())) {
4569  // It might happen that there are no values that pass the
4570  // filter. In that case we throw an exception.
4571  auto has_initial_value = next();
4572  if (!has_initial_value) {
4573  Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
4574  }
4575  }
4576  }
4577 
4578  T const &get() const override { return m_generator.get(); }
4579 
4580  bool next() override {
4581  bool success = m_generator.next();
4582  if (!success) {
4583  return false;
4584  }
4585  while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true)
4586  ;
4587  return success;
4588  }
4589  };
4590 
4591  template<typename T, typename Predicate>
4592  GeneratorWrapper<T> filter(Predicate &&pred, GeneratorWrapper<T> &&generator) {
4593  return GeneratorWrapper<T>(
4594  std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
4595  }
4596 
4597  template<typename T>
4598  class RepeatGenerator : public IGenerator<T> {
4599  static_assert(!std::is_same<T, bool>::value,
4600  "RepeatGenerator currently does not support bools"
4601  "because of std::vector<bool> specialization");
4602  GeneratorWrapper<T> m_generator;
4603  mutable std::vector<T> m_returned;
4604  size_t m_target_repeats;
4605  size_t m_current_repeat = 0;
4606  size_t m_repeat_index = 0;
4607 
4608  public:
4609  RepeatGenerator(size_t repeats, GeneratorWrapper<T> &&generator)
4610  : m_generator(std::move(generator))
4611  , m_target_repeats(repeats) {
4612  assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
4613  }
4614 
4615  T const &get() const override {
4616  if (m_current_repeat == 0) {
4617  m_returned.push_back(m_generator.get());
4618  return m_returned.back();
4619  }
4620  return m_returned[m_repeat_index];
4621  }
4622 
4623  bool next() override {
4624  // There are 2 basic cases:
4625  // 1) We are still reading the generator
4626  // 2) We are reading our own cache
4627 
4628  // In the first case, we need to poke the underlying generator.
4629  // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
4630  if (m_current_repeat == 0) {
4631  const auto success = m_generator.next();
4632  if (!success) {
4633  ++m_current_repeat;
4634  }
4635  return m_current_repeat < m_target_repeats;
4636  }
4637 
4638  // In the second case, we need to move indices forward and check that we haven't run up against the end
4639  ++m_repeat_index;
4640  if (m_repeat_index == m_returned.size()) {
4641  m_repeat_index = 0;
4642  ++m_current_repeat;
4643  }
4644  return m_current_repeat < m_target_repeats;
4645  }
4646  };
4647 
4648  template<typename T>
4649  GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T> &&generator) {
4650  return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
4651  }
4652 
4653  template<typename T, typename U, typename Func>
4654  class MapGenerator : public IGenerator<T> {
4655  // TBD: provide static assert for mapping function, for friendly error message
4656  GeneratorWrapper<U> m_generator;
4657  Func m_function;
4658  // To avoid returning dangling reference, we have to save the values
4659  T m_cache;
4660 
4661  public:
4662  template<typename F2 = Func>
4663  MapGenerator(F2 &&function, GeneratorWrapper<U> &&generator)
4664  : m_generator(std::move(generator))
4665  , m_function(std::forward<F2>(function))
4666  , m_cache(m_function(m_generator.get())) {
4667  }
4668 
4669  T const &get() const override { return m_cache; }
4670  bool next() override {
4671  const auto success = m_generator.next();
4672  if (success) {
4673  m_cache = m_function(m_generator.get());
4674  }
4675  return success;
4676  }
4677  };
4678 
4679  template<typename Func, typename U, typename T = FunctionReturnType<Func, U>>
4680  GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator) {
4681  return GeneratorWrapper<T>(pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)));
4682  }
4683 
4684  template<typename T, typename U, typename Func>
4685  GeneratorWrapper<T> map(Func &&function, GeneratorWrapper<U> &&generator) {
4686  return GeneratorWrapper<T>(pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)));
4687  }
4688 
4689  template<typename T>
4690  class ChunkGenerator final : public IGenerator<std::vector<T>> {
4691  std::vector<T> m_chunk;
4692  size_t m_chunk_size;
4693  GeneratorWrapper<T> m_generator;
4694  bool m_used_up = false;
4695 
4696  public:
4697  ChunkGenerator(size_t size, GeneratorWrapper<T> generator)
4698  : m_chunk_size(size)
4699  , m_generator(std::move(generator)) {
4700  m_chunk.reserve(m_chunk_size);
4701  if (m_chunk_size != 0) {
4702  m_chunk.push_back(m_generator.get());
4703  for (size_t i = 1; i < m_chunk_size; ++i) {
4704  if (!m_generator.next()) {
4705  Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
4706  }
4707  m_chunk.push_back(m_generator.get());
4708  }
4709  }
4710  }
4711  std::vector<T> const &get() const override { return m_chunk; }
4712  bool next() override {
4713  m_chunk.clear();
4714  for (size_t idx = 0; idx < m_chunk_size; ++idx) {
4715  if (!m_generator.next()) {
4716  return false;
4717  }
4718  m_chunk.push_back(m_generator.get());
4719  }
4720  return true;
4721  }
4722  };
4723 
4724  template<typename T>
4725  GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T> &&generator) {
4726  return GeneratorWrapper<std::vector<T>>(pf::make_unique<ChunkGenerator<T>>(size, std::move(generator)));
4727  }
4728 
4729  } // namespace Generators
4730 } // namespace Catch
4731 
4732 // end catch_generators_generic.hpp
4733 // start catch_generators_specific.hpp
4734 
4735 // start catch_context.h
4736 
4737 #include <memory>
4738 
4739 namespace Catch {
4740  struct IResultCapture;
4741  struct IRunner;
4742  struct IConfig;
4743  struct IMutableContext;
4744 
4745  using IConfigPtr = std::shared_ptr<IConfig const>;
4746 
4747  struct IContext {
4748  virtual ~IContext();
4749 
4750  virtual IResultCapture *getResultCapture() = 0;
4751  virtual IRunner *getRunner() = 0;
4752  virtual IConfigPtr const &getConfig() const = 0;
4753  };
4754 
4756  virtual ~IMutableContext();
4757  virtual void setResultCapture(IResultCapture *resultCapture) = 0;
4758  virtual void setRunner(IRunner *runner) = 0;
4759  virtual void setConfig(IConfigPtr const &config) = 0;
4760 
4761  private:
4762  static IMutableContext *currentContext;
4763  friend IMutableContext &getCurrentMutableContext();
4764  friend void cleanUpContext();
4765  static void createContext();
4766  };
4767 
4768  inline IMutableContext &getCurrentMutableContext() {
4769  if (!IMutableContext::currentContext)
4770  IMutableContext::createContext();
4771  // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
4772  return *IMutableContext::currentContext;
4773  }
4774 
4775  inline IContext &getCurrentContext() {
4776  return getCurrentMutableContext();
4777  }
4778 
4779  void cleanUpContext();
4780 
4781  class SimplePcg32;
4782  SimplePcg32 &rng();
4783 } // namespace Catch
4784 
4785 // end catch_context.h
4786 // start catch_interfaces_config.h
4787 
4788 // start catch_option.hpp
4789 
4790 namespace Catch {
4791  // An optional type
4792  template<typename T>
4793  class Option {
4794  public:
4795  Option()
4796  : nullableValue(nullptr) {
4797  }
4798  Option(T const &_value)
4799  : nullableValue(new (storage) T(_value)) {
4800  }
4801  Option(Option const &_other)
4802  : nullableValue(_other ? new (storage) T(*_other) : nullptr) {
4803  }
4804 
4805  ~Option() { reset(); }
4806 
4807  Option &operator=(Option const &_other) {
4808  if (&_other != this) {
4809  reset();
4810  if (_other)
4811  nullableValue = new (storage) T(*_other);
4812  }
4813  return *this;
4814  }
4815  Option &operator=(T const &_value) {
4816  reset();
4817  nullableValue = new (storage) T(_value);
4818  return *this;
4819  }
4820 
4821  void reset() {
4822  if (nullableValue)
4823  nullableValue->~T();
4824  nullableValue = nullptr;
4825  }
4826 
4827  T &operator*() { return *nullableValue; }
4828  T const &operator*() const { return *nullableValue; }
4829  T *operator->() { return nullableValue; }
4830  const T *operator->() const { return nullableValue; }
4831 
4832  T valueOr(T const &defaultValue) const { return nullableValue ? *nullableValue : defaultValue; }
4833 
4834  bool some() const { return nullableValue != nullptr; }
4835  bool none() const { return nullableValue == nullptr; }
4836 
4837  bool operator!() const { return nullableValue == nullptr; }
4838  explicit operator bool() const { return some(); }
4839 
4840  private:
4841  T *nullableValue;
4842  alignas(alignof(T)) char storage[sizeof(T)];
4843  };
4844 
4845 } // end namespace Catch
4846 
4847 // end catch_option.hpp
4848 #include <chrono>
4849 #include <iosfwd>
4850 #include <memory>
4851 #include <string>
4852 #include <vector>
4853 
4854 namespace Catch {
4855  enum class Verbosity {
4856  Quiet = 0,
4857  Normal,
4858  High
4859  };
4860 
4861  struct WarnAbout {
4862  enum What {
4863  Nothing = 0x00,
4864  NoAssertions = 0x01,
4865  NoTests = 0x02
4866  };
4867  };
4868 
4869  struct ShowDurations {
4870  enum OrNot {
4871  DefaultForReporter,
4872  Always,
4873  Never
4874  };
4875  };
4876  struct RunTests {
4877  enum InWhatOrder {
4878  InDeclarationOrder,
4879  InLexicographicalOrder,
4880  InRandomOrder
4881  };
4882  };
4883  struct UseColour {
4884  enum YesOrNo {
4885  Auto,
4886  Yes,
4887  No
4888  };
4889  };
4891  enum When {
4892  Never,
4893  BeforeStart = 1,
4894  BeforeExit = 2,
4895  BeforeStartAndExit = BeforeStart | BeforeExit
4896  };
4897  };
4898 
4899  class TestSpec;
4900 
4902  virtual ~IConfig();
4903 
4904  virtual bool allowThrows() const = 0;
4905  virtual std::ostream &stream() const = 0;
4906  virtual std::string name() const = 0;
4907  virtual bool includeSuccessfulResults() const = 0;
4908  virtual bool shouldDebugBreak() const = 0;
4909  virtual bool warnAboutMissingAssertions() const = 0;
4910  virtual bool warnAboutNoTests() const = 0;
4911  virtual int abortAfter() const = 0;
4912  virtual bool showInvisibles() const = 0;
4913  virtual ShowDurations::OrNot showDurations() const = 0;
4914  virtual double minDuration() const = 0;
4915  virtual TestSpec const &testSpec() const = 0;
4916  virtual bool hasTestFilters() const = 0;
4917  virtual std::vector<std::string> const &getTestsOrTags() const = 0;
4918  virtual RunTests::InWhatOrder runOrder() const = 0;
4919  virtual unsigned int rngSeed() const = 0;
4920  virtual UseColour::YesOrNo useColour() const = 0;
4921  virtual std::vector<std::string> const &getSectionsToRun() const = 0;
4922  virtual Verbosity verbosity() const = 0;
4923 
4924  virtual bool benchmarkNoAnalysis() const = 0;
4925  virtual int benchmarkSamples() const = 0;
4926  virtual double benchmarkConfidenceInterval() const = 0;
4927  virtual unsigned int benchmarkResamples() const = 0;
4928  virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
4929  };
4930 
4931  using IConfigPtr = std::shared_ptr<IConfig const>;
4932 } // namespace Catch
4933 
4934 // end catch_interfaces_config.h
4935 // start catch_random_number_generator.h
4936 
4937 #include <cstdint>
4938 
4939 namespace Catch {
4940  // This is a simple implementation of C++11 Uniform Random Number
4941  // Generator. It does not provide all operators, because Catch2
4942  // does not use it, but it should behave as expected inside stdlib's
4943  // distributions.
4944  // The implementation is based on the PCG family (http://pcg-random.org)
4945  class SimplePcg32 {
4946  using state_type = std::uint64_t;
4947 
4948  public:
4949  using result_type = std::uint32_t;
4950  static constexpr result_type(min)() { return 0; }
4951  static constexpr result_type(max)() { return static_cast<result_type>(-1); }
4952 
4953  // Provide some default initial state for the default constructor
4954  SimplePcg32()
4955  : SimplePcg32(0xed743cc4U) {
4956  }
4957 
4958  explicit SimplePcg32(result_type seed_);
4959 
4960  void seed(result_type seed_);
4961  void discard(uint64_t skip);
4962 
4963  result_type operator()();
4964 
4965  private:
4966  friend bool operator==(SimplePcg32 const &lhs, SimplePcg32 const &rhs);
4967  friend bool operator!=(SimplePcg32 const &lhs, SimplePcg32 const &rhs);
4968 
4969  // In theory we also need operator<< and operator>>
4970  // In practice we do not use them, so we will skip them for now
4971 
4972  std::uint64_t m_state;
4973  // This part of the state determines which "stream" of the numbers
4974  // is chosen -- we take it as a constant for Catch2, so we only
4975  // need to deal with seeding the main state.
4976  // Picked by reading 8 bytes from `/dev/random` :-)
4977  static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
4978  };
4979 
4980 } // end namespace Catch
4981 
4982 // end catch_random_number_generator.h
4983 #include <random>
4984 
4985 namespace Catch {
4986  namespace Generators {
4987  template<typename Float>
4988  class RandomFloatingGenerator final : public IGenerator<Float> {
4989  Catch::SimplePcg32 &m_rng;
4990  std::uniform_real_distribution<Float> m_dist;
4991  Float m_current_number;
4992 
4993  public:
4994  RandomFloatingGenerator(Float a, Float b)
4995  : m_rng(rng())
4996  , m_dist(a, b) {
4997  static_cast<void>(next());
4998  }
4999 
5000  Float const &get() const override { return m_current_number; }
5001  bool next() override {
5002  m_current_number = m_dist(m_rng);
5003  return true;
5004  }
5005  };
5006 
5007  template<typename Integer>
5008  class RandomIntegerGenerator final : public IGenerator<Integer> {
5009  Catch::SimplePcg32 &m_rng;
5010  std::uniform_int_distribution<Integer> m_dist;
5011  Integer m_current_number;
5012 
5013  public:
5014  RandomIntegerGenerator(Integer a, Integer b)
5015  : m_rng(rng())
5016  , m_dist(a, b) {
5017  static_cast<void>(next());
5018  }
5019 
5020  Integer const &get() const override { return m_current_number; }
5021  bool next() override {
5022  m_current_number = m_dist(m_rng);
5023  return true;
5024  }
5025  };
5026 
5027  // TODO: Ideally this would be also constrained against the various char types,
5028  // but I don't expect users to run into that in practice.
5029  template<typename T>
5030  typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, GeneratorWrapper<T>>::type random(T a, T b) {
5031  return GeneratorWrapper<T>(pf::make_unique<RandomIntegerGenerator<T>>(a, b));
5032  }
5033 
5034  template<typename T>
5035  typename std::enable_if<std::is_floating_point<T>::value, GeneratorWrapper<T>>::type random(T a, T b) {
5036  return GeneratorWrapper<T>(pf::make_unique<RandomFloatingGenerator<T>>(a, b));
5037  }
5038 
5039  template<typename T>
5040  class RangeGenerator final : public IGenerator<T> {
5041  T m_current;
5042  T m_end;
5043  T m_step;
5044  bool m_positive;
5045 
5046  public:
5047  RangeGenerator(T const &start, T const &end, T const &step)
5048  : m_current(start)
5049  , m_end(end)
5050  , m_step(step)
5051  , m_positive(m_step > T(0)) {
5052  assert(m_current != m_end && "Range start and end cannot be equal");
5053  assert(m_step != T(0) && "Step size cannot be zero");
5054  assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
5055  }
5056 
5057  RangeGenerator(T const &start, T const &end)
5058  : RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) {
5059  }
5060 
5061  T const &get() const override { return m_current; }
5062 
5063  bool next() override {
5064  m_current += m_step;
5065  return (m_positive) ? (m_current < m_end) : (m_current > m_end);
5066  }
5067  };
5068 
5069  template<typename T>
5070  GeneratorWrapper<T> range(T const &start, T const &end, T const &step) {
5071  static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
5072  return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
5073  }
5074 
5075  template<typename T>
5076  GeneratorWrapper<T> range(T const &start, T const &end) {
5077  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
5078  return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
5079  }
5080 
5081  template<typename T>
5082  class IteratorGenerator final : public IGenerator<T> {
5083  static_assert(!std::is_same<T, bool>::value,
5084  "IteratorGenerator currently does not support bools"
5085  "because of std::vector<bool> specialization");
5086 
5087  std::vector<T> m_elems;
5088  size_t m_current = 0;
5089 
5090  public:
5091  template<typename InputIterator, typename InputSentinel>
5092  IteratorGenerator(InputIterator first, InputSentinel last)
5093  : m_elems(first, last) {
5094  if (m_elems.empty()) {
5095  Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
5096  }
5097  }
5098 
5099  T const &get() const override { return m_elems[m_current]; }
5100 
5101  bool next() override {
5102  ++m_current;
5103  return m_current != m_elems.size();
5104  }
5105  };
5106 
5107  template<typename InputIterator, typename InputSentinel, typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
5108  GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
5109  return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
5110  }
5111 
5112  template<typename Container, typename ResultType = typename Container::value_type>
5113  GeneratorWrapper<ResultType> from_range(Container const &cnt) {
5114  return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
5115  }
5116 
5117  } // namespace Generators
5118 } // namespace Catch
5119 
5120 // end catch_generators_specific.hpp
5121 
5122 // These files are included here so the single_include script doesn't put them
5123 // in the conditionally compiled sections
5124 // start catch_test_case_info.h
5125 
5126 #include <memory>
5127 #include <string>
5128 #include <vector>
5129 
5130 #ifdef __clang__
5131 #pragma clang diagnostic push
5132 #pragma clang diagnostic ignored "-Wpadded"
5133 #endif
5134 
5135 namespace Catch {
5136  struct ITestInvoker;
5137 
5138  struct TestCaseInfo {
5139  enum SpecialProperties {
5140  None = 0,
5141  IsHidden = 1 << 1,
5142  ShouldFail = 1 << 2,
5143  MayFail = 1 << 3,
5144  Throws = 1 << 4,
5145  NonPortable = 1 << 5,
5146  Benchmark = 1 << 6
5147  };
5148 
5149  TestCaseInfo(std::string const &_name,
5150  std::string const &_className,
5151  std::string const &_description,
5152  std::vector<std::string> const &_tags,
5153  SourceLineInfo const &_lineInfo);
5154 
5155  friend void setTags(TestCaseInfo &testCaseInfo, std::vector<std::string> tags);
5156 
5157  bool isHidden() const;
5158  bool throws() const;
5159  bool okToFail() const;
5160  bool expectedToFail() const;
5161 
5162  std::string tagsAsString() const;
5163 
5164  std::string name;
5165  std::string className;
5166  std::string description;
5167  std::vector<std::string> tags;
5168  std::vector<std::string> lcaseTags;
5169  SourceLineInfo lineInfo;
5170  SpecialProperties properties;
5171  };
5172 
5173  class TestCase : public TestCaseInfo {
5174  public:
5175  TestCase(ITestInvoker *testCase, TestCaseInfo &&info);
5176 
5177  TestCase withName(std::string const &_newName) const;
5178 
5179  void invoke() const;
5180 
5181  TestCaseInfo const &getTestCaseInfo() const;
5182 
5183  bool operator==(TestCase const &other) const;
5184  bool operator<(TestCase const &other) const;
5185 
5186  private:
5187  std::shared_ptr<ITestInvoker> test;
5188  };
5189 
5190  TestCase makeTestCase(ITestInvoker *testCase, std::string const &className, NameAndTags const &nameAndTags, SourceLineInfo const &lineInfo);
5191 } // namespace Catch
5192 
5193 #ifdef __clang__
5194 #pragma clang diagnostic pop
5195 #endif
5196 
5197 // end catch_test_case_info.h
5198 // start catch_interfaces_runner.h
5199 
5200 namespace Catch {
5201  struct IRunner {
5202  virtual ~IRunner();
5203  virtual bool aborting() const = 0;
5204  };
5205 } // namespace Catch
5206 
5207 // end catch_interfaces_runner.h
5208 
5209 #ifdef __OBJC__
5210 // start catch_objc.hpp
5211 
5212 #import <objc/runtime.h>
5213 
5214 #include <string>
5215 
5216 // NB. Any general catch headers included here must be included
5217 // in catch.hpp first to make sure they are included by the single
5218 // header for non obj-usage
5219 
5221 // This protocol is really only here for (self) documenting purposes, since
5222 // all its methods are optional.
5223 @protocol OcFixture
5224 
5225 @optional
5226 
5227 - (void)setUp;
5228 - (void)tearDown;
5229 
5230 @end
5231 
5232 namespace Catch {
5233  class OcMethod : public ITestInvoker {
5234  public:
5235  OcMethod(Class cls, SEL sel)
5236  : m_cls(cls)
5237  , m_sel(sel) {
5238  }
5239 
5240  virtual void invoke() const {
5241  id obj = [[m_cls alloc] init];
5242 
5243  performOptionalSelector(obj, @selector(setUp));
5244  performOptionalSelector(obj, m_sel);
5245  performOptionalSelector(obj, @selector(tearDown));
5246 
5247  arcSafeRelease(obj);
5248  }
5249 
5250  private:
5251  virtual ~OcMethod() {}
5252 
5253  Class m_cls;
5254  SEL m_sel;
5255  };
5256 
5257  namespace Detail {
5258  inline std::string getAnnotation(Class cls, std::string const &annotationName, std::string const &testCaseName) {
5259  NSString *selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
5260  SEL sel = NSSelectorFromString(selStr);
5261  arcSafeRelease(selStr);
5262  id value = performOptionalSelector(cls, sel);
5263  if (value)
5264  return [(NSString *)value UTF8String];
5265  return "";
5266  }
5267  } // namespace Detail
5268 
5269  inline std::size_t registerTestMethods() {
5270  std::size_t noTestMethods = 0;
5271  int noClasses = objc_getClassList(nullptr, 0);
5272 
5273  Class *classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(sizeof(Class) * noClasses);
5274  objc_getClassList(classes, noClasses);
5275 
5276  for (int c = 0; c < noClasses; c++) {
5277  Class cls = classes[c];
5278  {
5279  u_int count;
5280  Method *methods = class_copyMethodList(cls, &count);
5281  for (u_int m = 0; m < count; m++) {
5282  SEL selector = method_getName(methods[m]);
5283  std::string methodName = sel_getName(selector);
5284  if (startsWith(methodName, "Catch_TestCase_")) {
5285  std::string testCaseName = methodName.substr(15);
5286  std::string name = Detail::getAnnotation(cls, "Name", testCaseName);
5287  std::string desc = Detail::getAnnotation(cls, "Description", testCaseName);
5288  const char *className = class_getName(cls);
5289 
5290  getMutableRegistryHub().registerTest(
5291  makeTestCase(new OcMethod(cls, selector), className, NameAndTags(name.c_str(), desc.c_str()), SourceLineInfo("", 0)));
5292  noTestMethods++;
5293  }
5294  }
5295  free(methods);
5296  }
5297  }
5298  return noTestMethods;
5299  }
5300 
5301 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
5302 
5303  namespace Matchers {
5304  namespace Impl {
5305  namespace NSStringMatchers {
5306  struct StringHolder : MatcherBase<NSString *> {
5307  StringHolder(NSString *substr)
5308  : m_substr([substr copy]) {
5309  }
5310  StringHolder(StringHolder const &other)
5311  : m_substr([other.m_substr copy]) {
5312  }
5313  StringHolder() { arcSafeRelease(m_substr); }
5314 
5315  bool match(NSString *str) const override { return false; }
5316 
5317  NSString *CATCH_ARC_STRONG m_substr;
5318  };
5319 
5320  struct Equals : StringHolder {
5321  Equals(NSString *substr)
5322  : StringHolder(substr) {
5323  }
5324 
5325  bool match(NSString *str) const override { return (str != nil || m_substr == nil) && [str isEqualToString:m_substr]; }
5326 
5327  std::string describe() const override { return "equals string: " + Catch::Detail::stringify(m_substr); }
5328  };
5329 
5330  struct Contains : StringHolder {
5331  Contains(NSString *substr)
5332  : StringHolder(substr) {
5333  }
5334 
5335  bool match(NSString *str) const override {
5336  return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location != NSNotFound;
5337  }
5338 
5339  std::string describe() const override { return "contains string: " + Catch::Detail::stringify(m_substr); }
5340  };
5341 
5342  struct StartsWith : StringHolder {
5343  StartsWith(NSString *substr)
5344  : StringHolder(substr) {
5345  }
5346 
5347  bool match(NSString *str) const override { return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location == 0; }
5348 
5349  std::string describe() const override { return "starts with: " + Catch::Detail::stringify(m_substr); }
5350  };
5351  struct EndsWith : StringHolder {
5352  EndsWith(NSString *substr)
5353  : StringHolder(substr) {
5354  }
5355 
5356  bool match(NSString *str) const override {
5357  return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location == [str length] - [m_substr length];
5358  }
5359 
5360  std::string describe() const override { return "ends with: " + Catch::Detail::stringify(m_substr); }
5361  };
5362 
5363  } // namespace NSStringMatchers
5364  } // namespace Impl
5365 
5366  inline Impl::NSStringMatchers::Equals Equals(NSString *substr) {
5367  return Impl::NSStringMatchers::Equals(substr);
5368  }
5369 
5370  inline Impl::NSStringMatchers::Contains Contains(NSString *substr) {
5371  return Impl::NSStringMatchers::Contains(substr);
5372  }
5373 
5374  inline Impl::NSStringMatchers::StartsWith StartsWith(NSString *substr) {
5375  return Impl::NSStringMatchers::StartsWith(substr);
5376  }
5377 
5378  inline Impl::NSStringMatchers::EndsWith EndsWith(NSString *substr) {
5379  return Impl::NSStringMatchers::EndsWith(substr);
5380  }
5381 
5382  } // namespace Matchers
5383 
5384  using namespace Matchers;
5385 
5386 #endif // CATCH_CONFIG_DISABLE_MATCHERS
5387 
5388 } // namespace Catch
5389 
5391 #define OC_MAKE_UNIQUE_NAME(root, uniqueSuffix) root##uniqueSuffix
5392 #define OC_TEST_CASE2(name, desc, uniqueSuffix) \
5393  +(NSString *)OC_MAKE_UNIQUE_NAME(Catch_Name_test_, uniqueSuffix) { \
5394  return @name; \
5395  } \
5396  +(NSString *)OC_MAKE_UNIQUE_NAME(Catch_Description_test_, uniqueSuffix) { \
5397  return @desc; \
5398  } \
5399  -(void)OC_MAKE_UNIQUE_NAME(Catch_TestCase_test_, uniqueSuffix)
5400 
5401 #define OC_TEST_CASE(name, desc) OC_TEST_CASE2(name, desc, __LINE__)
5402 
5403 // end catch_objc.hpp
5404 #endif
5405 
5406 // Benchmarking needs the externally-facing parts of reporters to work
5407 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5408 // start catch_external_interfaces.h
5409 
5410 // start catch_reporter_bases.hpp
5411 
5412 // start catch_interfaces_reporter.h
5413 
5414 // start catch_config.hpp
5415 
5416 // start catch_test_spec_parser.h
5417 
5418 #ifdef __clang__
5419 #pragma clang diagnostic push
5420 #pragma clang diagnostic ignored "-Wpadded"
5421 #endif
5422 
5423 // start catch_test_spec.h
5424 
5425 #ifdef __clang__
5426 #pragma clang diagnostic push
5427 #pragma clang diagnostic ignored "-Wpadded"
5428 #endif
5429 
5430 // start catch_wildcard_pattern.h
5431 
5432 namespace Catch {
5433  class WildcardPattern {
5434  enum WildcardPosition {
5435  NoWildcard = 0,
5436  WildcardAtStart = 1,
5437  WildcardAtEnd = 2,
5438  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
5439  };
5440 
5441  public:
5442  WildcardPattern(std::string const &pattern, CaseSensitive::Choice caseSensitivity);
5443  virtual ~WildcardPattern() = default;
5444  virtual bool matches(std::string const &str) const;
5445 
5446  private:
5447  std::string normaliseString(std::string const &str) const;
5448  CaseSensitive::Choice m_caseSensitivity;
5449  WildcardPosition m_wildcard = NoWildcard;
5450  std::string m_pattern;
5451  };
5452 } // namespace Catch
5453 
5454 // end catch_wildcard_pattern.h
5455 #include <memory>
5456 #include <string>
5457 #include <vector>
5458 
5459 namespace Catch {
5460  struct IConfig;
5461 
5462  class TestSpec {
5463  class Pattern {
5464  public:
5465  explicit Pattern(std::string const &name);
5466  virtual ~Pattern();
5467  virtual bool matches(TestCaseInfo const &testCase) const = 0;
5468  std::string const &name() const;
5469 
5470  private:
5471  std::string const m_name;
5472  };
5473  using PatternPtr = std::shared_ptr<Pattern>;
5474 
5475  class NamePattern : public Pattern {
5476  public:
5477  explicit NamePattern(std::string const &name, std::string const &filterString);
5478  bool matches(TestCaseInfo const &testCase) const override;
5479 
5480  private:
5481  WildcardPattern m_wildcardPattern;
5482  };
5483 
5484  class TagPattern : public Pattern {
5485  public:
5486  explicit TagPattern(std::string const &tag, std::string const &filterString);
5487  bool matches(TestCaseInfo const &testCase) const override;
5488 
5489  private:
5490  std::string m_tag;
5491  };
5492 
5493  class ExcludedPattern : public Pattern {
5494  public:
5495  explicit ExcludedPattern(PatternPtr const &underlyingPattern);
5496  bool matches(TestCaseInfo const &testCase) const override;
5497 
5498  private:
5499  PatternPtr m_underlyingPattern;
5500  };
5501 
5502  struct Filter {
5503  std::vector<PatternPtr> m_patterns;
5504 
5505  bool matches(TestCaseInfo const &testCase) const;
5506  std::string name() const;
5507  };
5508 
5509  public:
5510  struct FilterMatch {
5511  std::string name;
5512  std::vector<TestCase const *> tests;
5513  };
5514  using Matches = std::vector<FilterMatch>;
5515  using vectorStrings = std::vector<std::string>;
5516 
5517  bool hasFilters() const;
5518  bool matches(TestCaseInfo const &testCase) const;
5519  Matches matchesByFilter(std::vector<TestCase> const &testCases, IConfig const &config) const;
5520  const vectorStrings &getInvalidArgs() const;
5521 
5522  private:
5523  std::vector<Filter> m_filters;
5524  std::vector<std::string> m_invalidArgs;
5525  friend class TestSpecParser;
5526  };
5527 } // namespace Catch
5528 
5529 #ifdef __clang__
5530 #pragma clang diagnostic pop
5531 #endif
5532 
5533 // end catch_test_spec.h
5534 // start catch_interfaces_tag_alias_registry.h
5535 
5536 #include <string>
5537 
5538 namespace Catch {
5539  struct TagAlias;
5540 
5541  struct ITagAliasRegistry {
5542  virtual ~ITagAliasRegistry();
5543  // Nullptr if not present
5544  virtual TagAlias const *find(std::string const &alias) const = 0;
5545  virtual std::string expandAliases(std::string const &unexpandedTestSpec) const = 0;
5546 
5547  static ITagAliasRegistry const &get();
5548  };
5549 
5550 } // end namespace Catch
5551 
5552 // end catch_interfaces_tag_alias_registry.h
5553 namespace Catch {
5554  class TestSpecParser {
5555  enum Mode {
5556  None,
5557  Name,
5558  QuotedName,
5559  Tag,
5560  EscapedName
5561  };
5562  Mode m_mode = None;
5563  Mode lastMode = None;
5564  bool m_exclusion = false;
5565  std::size_t m_pos = 0;
5566  std::size_t m_realPatternPos = 0;
5567  std::string m_arg;
5568  std::string m_substring;
5569  std::string m_patternName;
5570  std::vector<std::size_t> m_escapeChars;
5571  TestSpec::Filter m_currentFilter;
5572  TestSpec m_testSpec;
5573  ITagAliasRegistry const *m_tagAliases = nullptr;
5574 
5575  public:
5576  TestSpecParser(ITagAliasRegistry const &tagAliases);
5577 
5578  TestSpecParser &parse(std::string const &arg);
5579  TestSpec testSpec();
5580 
5581  private:
5582  bool visitChar(char c);
5583  void startNewMode(Mode mode);
5584  bool processNoneChar(char c);
5585  void processNameChar(char c);
5586  bool processOtherChar(char c);
5587  void endMode();
5588  void escape();
5589  bool isControlChar(char c) const;
5590  void saveLastMode();
5591  void revertBackToLastMode();
5592  void addFilter();
5593  bool separate();
5594 
5595  // Handles common preprocessing of the pattern for name/tag patterns
5596  std::string preprocessPattern();
5597  // Adds the current pattern as a test name
5598  void addNamePattern();
5599  // Adds the current pattern as a tag
5600  void addTagPattern();
5601 
5602  inline void addCharToPattern(char c) {
5603  m_substring += c;
5604  m_patternName += c;
5605  m_realPatternPos++;
5606  }
5607  };
5608  TestSpec parseTestSpec(std::string const &arg);
5609 
5610 } // namespace Catch
5611 
5612 #ifdef __clang__
5613 #pragma clang diagnostic pop
5614 #endif
5615 
5616 // end catch_test_spec_parser.h
5617 // Libstdc++ doesn't like incomplete classes for unique_ptr
5618 
5619 #include <memory>
5620 #include <string>
5621 #include <vector>
5622 
5623 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
5624 #define CATCH_CONFIG_CONSOLE_WIDTH 80
5625 #endif
5626 
5627 namespace Catch {
5628  struct IStream;
5629 
5630  struct ConfigData {
5631  bool listTests = false;
5632  bool listTags = false;
5633  bool listReporters = false;
5634  bool listTestNamesOnly = false;
5635 
5636  bool showSuccessfulTests = false;
5637  bool shouldDebugBreak = false;
5638  bool noThrow = false;
5639  bool showHelp = false;
5640  bool showInvisibles = false;
5641  bool filenamesAsTags = false;
5642  bool libIdentify = false;
5643 
5644  int abortAfter = -1;
5645  unsigned int rngSeed = 0;
5646 
5647  bool benchmarkNoAnalysis = false;
5648  unsigned int benchmarkSamples = 100;
5649  double benchmarkConfidenceInterval = 0.95;
5650  unsigned int benchmarkResamples = 100000;
5651  std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
5652 
5653  Verbosity verbosity = Verbosity::Normal;
5654  WarnAbout::What warnings = WarnAbout::Nothing;
5655  ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
5656  double minDuration = -1;
5657  RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
5658  UseColour::YesOrNo useColour = UseColour::Auto;
5659  WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
5660 
5661  std::string outputFilename;
5662  std::string name;
5663  std::string processName;
5664 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
5665 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
5666 #endif
5667  std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
5668 #undef CATCH_CONFIG_DEFAULT_REPORTER
5669 
5670  std::vector<std::string> testsOrTags;
5671  std::vector<std::string> sectionsToRun;
5672  };
5673 
5674  class Config : public IConfig {
5675  public:
5676  Config() = default;
5677  Config(ConfigData const &data);
5678  virtual ~Config() = default;
5679 
5680  std::string const &getFilename() const;
5681 
5682  bool listTests() const;
5683  bool listTestNamesOnly() const;
5684  bool listTags() const;
5685  bool listReporters() const;
5686 
5687  std::string getProcessName() const;
5688  std::string const &getReporterName() const;
5689 
5690  std::vector<std::string> const &getTestsOrTags() const override;
5691  std::vector<std::string> const &getSectionsToRun() const override;
5692 
5693  TestSpec const &testSpec() const override;
5694  bool hasTestFilters() const override;
5695 
5696  bool showHelp() const;
5697 
5698  // IConfig interface
5699  bool allowThrows() const override;
5700  std::ostream &stream() const override;
5701  std::string name() const override;
5702  bool includeSuccessfulResults() const override;
5703  bool warnAboutMissingAssertions() const override;
5704  bool warnAboutNoTests() const override;
5705  ShowDurations::OrNot showDurations() const override;
5706  double minDuration() const override;
5707  RunTests::InWhatOrder runOrder() const override;
5708  unsigned int rngSeed() const override;
5709  UseColour::YesOrNo useColour() const override;
5710  bool shouldDebugBreak() const override;
5711  int abortAfter() const override;
5712  bool showInvisibles() const override;
5713  Verbosity verbosity() const override;
5714  bool benchmarkNoAnalysis() const override;
5715  int benchmarkSamples() const override;
5716  double benchmarkConfidenceInterval() const override;
5717  unsigned int benchmarkResamples() const override;
5718  std::chrono::milliseconds benchmarkWarmupTime() const override;
5719 
5720  private:
5721  IStream const *openStream();
5722  ConfigData m_data;
5723 
5724  std::unique_ptr<IStream const> m_stream;
5725  TestSpec m_testSpec;
5726  bool m_hasTestFilters = false;
5727  };
5728 
5729 } // end namespace Catch
5730 
5731 // end catch_config.hpp
5732 // start catch_assertionresult.h
5733 
5734 #include <string>
5735 
5736 namespace Catch {
5737  struct AssertionResultData {
5738  AssertionResultData() = delete;
5739 
5740  AssertionResultData(ResultWas::OfType _resultType, LazyExpression const &_lazyExpression);
5741 
5742  std::string message;
5743  mutable std::string reconstructedExpression;
5744  LazyExpression lazyExpression;
5745  ResultWas::OfType resultType;
5746 
5747  std::string reconstructExpression() const;
5748  };
5749 
5750  class AssertionResult {
5751  public:
5752  AssertionResult() = delete;
5753  AssertionResult(AssertionInfo const &info, AssertionResultData const &data);
5754 
5755  bool isOk() const;
5756  bool succeeded() const;
5757  ResultWas::OfType getResultType() const;
5758  bool hasExpression() const;
5759  bool hasMessage() const;
5760  std::string getExpression() const;
5761  std::string getExpressionInMacro() const;
5762  bool hasExpandedExpression() const;
5763  std::string getExpandedExpression() const;
5764  std::string getMessage() const;
5765  SourceLineInfo getSourceInfo() const;
5766  StringRef getTestMacroName() const;
5767 
5768  // protected:
5769  AssertionInfo m_info;
5770  AssertionResultData m_resultData;
5771  };
5772 
5773 } // end namespace Catch
5774 
5775 // end catch_assertionresult.h
5776 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5777 // start catch_estimate.hpp
5778 
5779 // Statistics estimates
5780 
5781 namespace Catch {
5782  namespace Benchmark {
5783  template<typename Duration>
5784  struct Estimate {
5785  Duration point;
5786  Duration lower_bound;
5787  Duration upper_bound;
5788  double confidence_interval;
5789 
5790  template<typename Duration2>
5791  operator Estimate<Duration2>() const {
5792  return {point, lower_bound, upper_bound, confidence_interval};
5793  }
5794  };
5795  } // namespace Benchmark
5796 } // namespace Catch
5797 
5798 // end catch_estimate.hpp
5799 // start catch_outlier_classification.hpp
5800 
5801 // Outlier information
5802 
5803 namespace Catch {
5804  namespace Benchmark {
5805  struct OutlierClassification {
5806  int samples_seen = 0;
5807  int low_severe = 0; // more than 3 times IQR below Q1
5808  int low_mild = 0; // 1.5 to 3 times IQR below Q1
5809  int high_mild = 0; // 1.5 to 3 times IQR above Q3
5810  int high_severe = 0; // more than 3 times IQR above Q3
5811 
5812  int total() const { return low_severe + low_mild + high_mild + high_severe; }
5813  };
5814  } // namespace Benchmark
5815 } // namespace Catch
5816 
5817 // end catch_outlier_classification.hpp
5818 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5819 
5820 #include <algorithm>
5821 #include <iosfwd>
5822 #include <map>
5823 #include <memory>
5824 #include <set>
5825 #include <string>
5826 
5827 namespace Catch {
5828  struct ReporterConfig {
5829  explicit ReporterConfig(IConfigPtr const &_fullConfig);
5830 
5831  ReporterConfig(IConfigPtr const &_fullConfig, std::ostream &_stream);
5832 
5833  std::ostream &stream() const;
5834  IConfigPtr fullConfig() const;
5835 
5836  private:
5837  std::ostream *m_stream;
5838  IConfigPtr m_fullConfig;
5839  };
5840 
5841  struct ReporterPreferences {
5842  bool shouldRedirectStdOut = false;
5843  bool shouldReportAllAssertions = false;
5844  };
5845 
5846  template<typename T>
5847  struct LazyStat : Option<T> {
5848  LazyStat &operator=(T const &_value) {
5849  Option<T>::operator=(_value);
5850  used = false;
5851  return *this;
5852  }
5853  void reset() {
5854  Option<T>::reset();
5855  used = false;
5856  }
5857  bool used = false;
5858  };
5859 
5860  struct TestRunInfo {
5861  TestRunInfo(std::string const &_name);
5862  std::string name;
5863  };
5864  struct GroupInfo {
5865  GroupInfo(std::string const &_name, std::size_t _groupIndex, std::size_t _groupsCount);
5866 
5867  std::string name;
5868  std::size_t groupIndex;
5869  std::size_t groupsCounts;
5870  };
5871 
5872  struct AssertionStats {
5873  AssertionStats(AssertionResult const &_assertionResult, std::vector<MessageInfo> const &_infoMessages, Totals const &_totals);
5874 
5875  AssertionStats(AssertionStats const &) = default;
5876  AssertionStats(AssertionStats &&) = default;
5877  AssertionStats &operator=(AssertionStats const &) = delete;
5878  AssertionStats &operator=(AssertionStats &&) = delete;
5879  virtual ~AssertionStats();
5880 
5881  AssertionResult assertionResult;
5882  std::vector<MessageInfo> infoMessages;
5883  Totals totals;
5884  };
5885 
5886  struct SectionStats {
5887  SectionStats(SectionInfo const &_sectionInfo, Counts const &_assertions, double _durationInSeconds, bool _missingAssertions);
5888  SectionStats(SectionStats const &) = default;
5889  SectionStats(SectionStats &&) = default;
5890  SectionStats &operator=(SectionStats const &) = default;
5891  SectionStats &operator=(SectionStats &&) = default;
5892  virtual ~SectionStats();
5893 
5894  SectionInfo sectionInfo;
5895  Counts assertions;
5896  double durationInSeconds;
5897  bool missingAssertions;
5898  };
5899 
5900  struct TestCaseStats {
5901  TestCaseStats(TestCaseInfo const &_testInfo, Totals const &_totals, std::string const &_stdOut, std::string const &_stdErr, bool _aborting);
5902 
5903  TestCaseStats(TestCaseStats const &) = default;
5904  TestCaseStats(TestCaseStats &&) = default;
5905  TestCaseStats &operator=(TestCaseStats const &) = default;
5906  TestCaseStats &operator=(TestCaseStats &&) = default;
5907  virtual ~TestCaseStats();
5908 
5909  TestCaseInfo testInfo;
5910  Totals totals;
5911  std::string stdOut;
5912  std::string stdErr;
5913  bool aborting;
5914  };
5915 
5916  struct TestGroupStats {
5917  TestGroupStats(GroupInfo const &_groupInfo, Totals const &_totals, bool _aborting);
5918  TestGroupStats(GroupInfo const &_groupInfo);
5919 
5920  TestGroupStats(TestGroupStats const &) = default;
5921  TestGroupStats(TestGroupStats &&) = default;
5922  TestGroupStats &operator=(TestGroupStats const &) = default;
5923  TestGroupStats &operator=(TestGroupStats &&) = default;
5924  virtual ~TestGroupStats();
5925 
5926  GroupInfo groupInfo;
5927  Totals totals;
5928  bool aborting;
5929  };
5930 
5931  struct TestRunStats {
5932  TestRunStats(TestRunInfo const &_runInfo, Totals const &_totals, bool _aborting);
5933 
5934  TestRunStats(TestRunStats const &) = default;
5935  TestRunStats(TestRunStats &&) = default;
5936  TestRunStats &operator=(TestRunStats const &) = default;
5937  TestRunStats &operator=(TestRunStats &&) = default;
5938  virtual ~TestRunStats();
5939 
5940  TestRunInfo runInfo;
5941  Totals totals;
5942  bool aborting;
5943  };
5944 
5945 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
5946  struct BenchmarkInfo {
5947  std::string name;
5948  double estimatedDuration;
5949  int iterations;
5950  int samples;
5951  unsigned int resamples;
5952  double clockResolution;
5953  double clockCost;
5954  };
5955 
5956  template<class Duration>
5957  struct BenchmarkStats {
5958  BenchmarkInfo info;
5959 
5960  std::vector<Duration> samples;
5961  Benchmark::Estimate<Duration> mean;
5962  Benchmark::Estimate<Duration> standardDeviation;
5963  Benchmark::OutlierClassification outliers;
5964  double outlierVariance;
5965 
5966  template<typename Duration2>
5967  operator BenchmarkStats<Duration2>() const {
5968  std::vector<Duration2> samples2;
5969  samples2.reserve(samples.size());
5970  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
5971  return {
5972  info,
5973  std::move(samples2),
5974  mean,
5975  standardDeviation,
5976  outliers,
5977  outlierVariance,
5978  };
5979  }
5980  };
5981 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
5982 
5983  struct IStreamingReporter {
5984  virtual ~IStreamingReporter() = default;
5985 
5986  // Implementing class must also provide the following static methods:
5987  // static std::string getDescription();
5988  // static std::set<Verbosity> getSupportedVerbosities()
5989 
5990  virtual ReporterPreferences getPreferences() const = 0;
5991 
5992  virtual void noMatchingTestCases(std::string const &spec) = 0;
5993 
5994  virtual void reportInvalidArguments(std::string const &) {}
5995 
5996  virtual void testRunStarting(TestRunInfo const &testRunInfo) = 0;
5997  virtual void testGroupStarting(GroupInfo const &groupInfo) = 0;
5998 
5999  virtual void testCaseStarting(TestCaseInfo const &testInfo) = 0;
6000  virtual void sectionStarting(SectionInfo const &sectionInfo) = 0;
6001 
6002 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6003  virtual void benchmarkPreparing(std::string const &) {
6004  }
6005  virtual void benchmarkStarting(BenchmarkInfo const &) {}
6006  virtual void benchmarkEnded(BenchmarkStats<> const &) {}
6007  virtual void benchmarkFailed(std::string const &) {}
6008 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6009 
6010  virtual void assertionStarting(AssertionInfo const &assertionInfo) = 0;
6011 
6012  // The return value indicates if the messages buffer should be cleared:
6013  virtual bool assertionEnded(AssertionStats const &assertionStats) = 0;
6014 
6015  virtual void sectionEnded(SectionStats const &sectionStats) = 0;
6016  virtual void testCaseEnded(TestCaseStats const &testCaseStats) = 0;
6017  virtual void testGroupEnded(TestGroupStats const &testGroupStats) = 0;
6018  virtual void testRunEnded(TestRunStats const &testRunStats) = 0;
6019 
6020  virtual void skipTest(TestCaseInfo const &testInfo) = 0;
6021 
6022  // Default empty implementation provided
6023  virtual void fatalErrorEncountered(StringRef name);
6024 
6025  virtual bool isMulti() const;
6026  };
6027  using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
6028 
6029  struct IReporterFactory {
6030  virtual ~IReporterFactory();
6031  virtual IStreamingReporterPtr create(ReporterConfig const &config) const = 0;
6032  virtual std::string getDescription() const = 0;
6033  };
6034  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
6035 
6036  struct IReporterRegistry {
6037  using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
6038  using Listeners = std::vector<IReporterFactoryPtr>;
6039 
6040  virtual ~IReporterRegistry();
6041  virtual IStreamingReporterPtr create(std::string const &name, IConfigPtr const &config) const = 0;
6042  virtual FactoryMap const &getFactories() const = 0;
6043  virtual Listeners const &getListeners() const = 0;
6044  };
6045 
6046 } // end namespace Catch
6047 
6048 // end catch_interfaces_reporter.h
6049 #include <algorithm>
6050 #include <cassert>
6051 #include <cfloat>
6052 #include <cstdio>
6053 #include <cstring>
6054 #include <memory>
6055 #include <ostream>
6056 
6057 namespace Catch {
6058  void prepareExpandedExpression(AssertionResult &result);
6059 
6060  // Returns double formatted as %.3f (format expected on output)
6061  std::string getFormattedDuration(double duration);
6062 
6064  bool shouldShowDuration(IConfig const &config, double duration);
6065 
6066  std::string serializeFilters(std::vector<std::string> const &container);
6067 
6068  template<typename DerivedT>
6069  struct StreamingReporterBase : IStreamingReporter {
6070  StreamingReporterBase(ReporterConfig const &_config)
6071  : m_config(_config.fullConfig())
6072  , stream(_config.stream()) {
6073  m_reporterPrefs.shouldRedirectStdOut = false;
6074  if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity()))
6075  CATCH_ERROR("Verbosity level not supported by this reporter");
6076  }
6077 
6078  ReporterPreferences getPreferences() const override { return m_reporterPrefs; }
6079 
6080  static std::set<Verbosity> getSupportedVerbosities() { return {Verbosity::Normal}; }
6081 
6082  ~StreamingReporterBase() override = default;
6083 
6084  void noMatchingTestCases(std::string const &) override {}
6085 
6086  void reportInvalidArguments(std::string const &) override {}
6087 
6088  void testRunStarting(TestRunInfo const &_testRunInfo) override { currentTestRunInfo = _testRunInfo; }
6089 
6090  void testGroupStarting(GroupInfo const &_groupInfo) override { currentGroupInfo = _groupInfo; }
6091 
6092  void testCaseStarting(TestCaseInfo const &_testInfo) override { currentTestCaseInfo = _testInfo; }
6093  void sectionStarting(SectionInfo const &_sectionInfo) override { m_sectionStack.push_back(_sectionInfo); }
6094 
6095  void sectionEnded(SectionStats const & /* _sectionStats */) override { m_sectionStack.pop_back(); }
6096  void testCaseEnded(TestCaseStats const & /* _testCaseStats */) override { currentTestCaseInfo.reset(); }
6097  void testGroupEnded(TestGroupStats const & /* _testGroupStats */) override { currentGroupInfo.reset(); }
6098  void testRunEnded(TestRunStats const & /* _testRunStats */) override {
6099  currentTestCaseInfo.reset();
6100  currentGroupInfo.reset();
6101  currentTestRunInfo.reset();
6102  }
6103 
6104  void skipTest(TestCaseInfo const &) override {
6105  // Don't do anything with this by default.
6106  // It can optionally be overridden in the derived class.
6107  }
6108 
6109  IConfigPtr m_config;
6110  std::ostream &stream;
6111 
6112  LazyStat<TestRunInfo> currentTestRunInfo;
6113  LazyStat<GroupInfo> currentGroupInfo;
6114  LazyStat<TestCaseInfo> currentTestCaseInfo;
6115 
6116  std::vector<SectionInfo> m_sectionStack;
6117  ReporterPreferences m_reporterPrefs;
6118  };
6119 
6120  template<typename DerivedT>
6121  struct CumulativeReporterBase : IStreamingReporter {
6122  template<typename T, typename ChildNodeT>
6123  struct Node {
6124  explicit Node(T const &_value)
6125  : value(_value) {
6126  }
6127  virtual ~Node() {}
6128 
6129  using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
6130  T value;
6131  ChildNodes children;
6132  };
6133  struct SectionNode {
6134  explicit SectionNode(SectionStats const &_stats)
6135  : stats(_stats) {
6136  }
6137  virtual ~SectionNode() = default;
6138 
6139  bool operator==(SectionNode const &other) const { return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; }
6140  bool operator==(std::shared_ptr<SectionNode> const &other) const { return operator==(*other); }
6141 
6142  SectionStats stats;
6143  using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
6144  using Assertions = std::vector<AssertionStats>;
6145  ChildSections childSections;
6146  Assertions assertions;
6147  std::string stdOut;
6148  std::string stdErr;
6149  };
6150 
6151  struct BySectionInfo {
6152  BySectionInfo(SectionInfo const &other)
6153  : m_other(other) {
6154  }
6155  BySectionInfo(BySectionInfo const &other)
6156  : m_other(other.m_other) {
6157  }
6158  bool operator()(std::shared_ptr<SectionNode> const &node) const {
6159  return ((node->stats.sectionInfo.name == m_other.name) && (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
6160  }
6161  void operator=(BySectionInfo const &) = delete;
6162 
6163  private:
6164  SectionInfo const &m_other;
6165  };
6166 
6167  using TestCaseNode = Node<TestCaseStats, SectionNode>;
6168  using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
6169  using TestRunNode = Node<TestRunStats, TestGroupNode>;
6170 
6171  CumulativeReporterBase(ReporterConfig const &_config)
6172  : m_config(_config.fullConfig())
6173  , stream(_config.stream()) {
6174  m_reporterPrefs.shouldRedirectStdOut = false;
6175  if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity()))
6176  CATCH_ERROR("Verbosity level not supported by this reporter");
6177  }
6178  ~CumulativeReporterBase() override = default;
6179 
6180  ReporterPreferences getPreferences() const override { return m_reporterPrefs; }
6181 
6182  static std::set<Verbosity> getSupportedVerbosities() { return {Verbosity::Normal}; }
6183 
6184  void testRunStarting(TestRunInfo const &) override {}
6185  void testGroupStarting(GroupInfo const &) override {}
6186 
6187  void testCaseStarting(TestCaseInfo const &) override {}
6188 
6189  void sectionStarting(SectionInfo const &sectionInfo) override {
6190  SectionStats incompleteStats(sectionInfo, Counts(), 0, false);
6191  std::shared_ptr<SectionNode> node;
6192  if (m_sectionStack.empty()) {
6193  if (!m_rootSection)
6194  m_rootSection = std::make_shared<SectionNode>(incompleteStats);
6195  node = m_rootSection;
6196  } else {
6197  SectionNode &parentNode = *m_sectionStack.back();
6198  auto it = std::find_if(parentNode.childSections.begin(), parentNode.childSections.end(), BySectionInfo(sectionInfo));
6199  if (it == parentNode.childSections.end()) {
6200  node = std::make_shared<SectionNode>(incompleteStats);
6201  parentNode.childSections.push_back(node);
6202  } else
6203  node = *it;
6204  }
6205  m_sectionStack.push_back(node);
6206  m_deepestSection = std::move(node);
6207  }
6208 
6209  void assertionStarting(AssertionInfo const &) override {}
6210 
6211  bool assertionEnded(AssertionStats const &assertionStats) override {
6212  assert(!m_sectionStack.empty());
6213  // AssertionResult holds a pointer to a temporary DecomposedExpression,
6214  // which getExpandedExpression() calls to build the expression string.
6215  // Our section stack copy of the assertionResult will likely outlive the
6216  // temporary, so it must be expanded or discarded now to avoid calling
6217  // a destroyed object later.
6218  prepareExpandedExpression(const_cast<AssertionResult &>(assertionStats.assertionResult));
6219  SectionNode &sectionNode = *m_sectionStack.back();
6220  sectionNode.assertions.push_back(assertionStats);
6221  return true;
6222  }
6223  void sectionEnded(SectionStats const &sectionStats) override {
6224  assert(!m_sectionStack.empty());
6225  SectionNode &node = *m_sectionStack.back();
6226  node.stats = sectionStats;
6227  m_sectionStack.pop_back();
6228  }
6229  void testCaseEnded(TestCaseStats const &testCaseStats) override {
6230  auto node = std::make_shared<TestCaseNode>(testCaseStats);
6231  assert(m_sectionStack.size() == 0);
6232  node->children.push_back(m_rootSection);
6233  m_testCases.push_back(node);
6234  m_rootSection.reset();
6235 
6236  assert(m_deepestSection);
6237  m_deepestSection->stdOut = testCaseStats.stdOut;
6238  m_deepestSection->stdErr = testCaseStats.stdErr;
6239  }
6240  void testGroupEnded(TestGroupStats const &testGroupStats) override {
6241  auto node = std::make_shared<TestGroupNode>(testGroupStats);
6242  node->children.swap(m_testCases);
6243  m_testGroups.push_back(node);
6244  }
6245  void testRunEnded(TestRunStats const &testRunStats) override {
6246  auto node = std::make_shared<TestRunNode>(testRunStats);
6247  node->children.swap(m_testGroups);
6248  m_testRuns.push_back(node);
6249  testRunEndedCumulative();
6250  }
6251  virtual void testRunEndedCumulative() = 0;
6252 
6253  void skipTest(TestCaseInfo const &) override {}
6254 
6255  IConfigPtr m_config;
6256  std::ostream &stream;
6257  std::vector<AssertionStats> m_assertions;
6258  std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
6259  std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
6260  std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
6261 
6262  std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
6263 
6264  std::shared_ptr<SectionNode> m_rootSection;
6265  std::shared_ptr<SectionNode> m_deepestSection;
6266  std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
6267  ReporterPreferences m_reporterPrefs;
6268  };
6269 
6270  template<char C>
6271  char const *getLineOfChars() {
6272  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
6273  if (!*line) {
6274  std::memset(line, C, CATCH_CONFIG_CONSOLE_WIDTH - 1);
6275  line[CATCH_CONFIG_CONSOLE_WIDTH - 1] = 0;
6276  }
6277  return line;
6278  }
6279 
6280  struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
6281  TestEventListenerBase(ReporterConfig const &_config);
6282 
6283  static std::set<Verbosity> getSupportedVerbosities();
6284 
6285  void assertionStarting(AssertionInfo const &) override;
6286  bool assertionEnded(AssertionStats const &) override;
6287  };
6288 
6289 } // end namespace Catch
6290 
6291 // end catch_reporter_bases.hpp
6292 // start catch_console_colour.h
6293 
6294 namespace Catch {
6295  struct Colour {
6296  enum Code {
6297  None = 0,
6298 
6299  White,
6300  Red,
6301  Green,
6302  Blue,
6303  Cyan,
6304  Yellow,
6305  Grey,
6306 
6307  Bright = 0x10,
6308 
6309  BrightRed = Bright | Red,
6310  BrightGreen = Bright | Green,
6311  LightGrey = Bright | Grey,
6312  BrightWhite = Bright | White,
6313  BrightYellow = Bright | Yellow,
6314 
6315  // By intention
6316  FileName = LightGrey,
6317  Warning = BrightYellow,
6318  ResultError = BrightRed,
6319  ResultSuccess = BrightGreen,
6320  ResultExpectedFailure = Warning,
6321 
6322  Error = BrightRed,
6323  Success = Green,
6324 
6325  OriginalExpression = Cyan,
6326  ReconstructedExpression = BrightYellow,
6327 
6328  SecondaryText = LightGrey,
6329  Headers = White
6330  };
6331 
6332  // Use constructed object for RAII guard
6333  Colour(Code _colourCode);
6334  Colour(Colour &&other) noexcept;
6335  Colour &operator=(Colour &&other) noexcept;
6336  ~Colour();
6337 
6338  // Use static method for one-shot changes
6339  static void use(Code _colourCode);
6340 
6341  private:
6342  bool m_moved = false;
6343  };
6344 
6345  std::ostream &operator<<(std::ostream &os, Colour const &);
6346 
6347 } // end namespace Catch
6348 
6349 // end catch_console_colour.h
6350 // start catch_reporter_registrars.hpp
6351 
6352 namespace Catch {
6353  template<typename T>
6354  class ReporterRegistrar {
6355  class ReporterFactory : public IReporterFactory {
6356  IStreamingReporterPtr create(ReporterConfig const &config) const override { return std::unique_ptr<T>(new T(config)); }
6357 
6358  std::string getDescription() const override { return T::getDescription(); }
6359  };
6360 
6361  public:
6362  explicit ReporterRegistrar(std::string const &name) {
6363  getMutableRegistryHub().registerReporter(name, std::make_shared<ReporterFactory>());
6364  }
6365  };
6366 
6367  template<typename T>
6368  class ListenerRegistrar {
6369  class ListenerFactory : public IReporterFactory {
6370  IStreamingReporterPtr create(ReporterConfig const &config) const override { return std::unique_ptr<T>(new T(config)); }
6371  std::string getDescription() const override { return std::string(); }
6372  };
6373 
6374  public:
6375  ListenerRegistrar() { getMutableRegistryHub().registerListener(std::make_shared<ListenerFactory>()); }
6376  };
6377 } // namespace Catch
6378 
6379 #if !defined(CATCH_CONFIG_DISABLE)
6380 
6381 #define CATCH_REGISTER_REPORTER(name, reporterType) \
6382  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6383  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6384  namespace { \
6385  Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType(name); \
6386  } \
6387  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6388 
6389 #define CATCH_REGISTER_LISTENER(listenerType) \
6390  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6391  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6392  namespace { \
6393  Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; \
6394  } \
6395  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6396 #else // CATCH_CONFIG_DISABLE
6397 
6398 #define CATCH_REGISTER_REPORTER(name, reporterType)
6399 #define CATCH_REGISTER_LISTENER(listenerType)
6400 
6401 #endif // CATCH_CONFIG_DISABLE
6402 
6403 // end catch_reporter_registrars.hpp
6404 // Allow users to base their work off existing reporters
6405 // start catch_reporter_compact.h
6406 
6407 namespace Catch {
6408  struct CompactReporter : StreamingReporterBase<CompactReporter> {
6409  using StreamingReporterBase::StreamingReporterBase;
6410 
6411  ~CompactReporter() override;
6412 
6413  static std::string getDescription();
6414 
6415  void noMatchingTestCases(std::string const &spec) override;
6416 
6417  void assertionStarting(AssertionInfo const &) override;
6418 
6419  bool assertionEnded(AssertionStats const &_assertionStats) override;
6420 
6421  void sectionEnded(SectionStats const &_sectionStats) override;
6422 
6423  void testRunEnded(TestRunStats const &_testRunStats) override;
6424  };
6425 
6426 } // end namespace Catch
6427 
6428 // end catch_reporter_compact.h
6429 // start catch_reporter_console.h
6430 
6431 #if defined(_MSC_VER)
6432 #pragma warning(push)
6433 #pragma warning(disable : 4061) // Not all labels are EXPLICITLY handled in switch \
6434  // Note that 4062 (not all labels are handled \
6435  // and default is missing) is enabled
6436 #endif
6437 
6438 namespace Catch {
6439  // Fwd decls
6440  struct SummaryColumn;
6441  class TablePrinter;
6442 
6443  struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
6444  std::unique_ptr<TablePrinter> m_tablePrinter;
6445 
6446  ConsoleReporter(ReporterConfig const &config);
6447  ~ConsoleReporter() override;
6448  static std::string getDescription();
6449 
6450  void noMatchingTestCases(std::string const &spec) override;
6451 
6452  void reportInvalidArguments(std::string const &arg) override;
6453 
6454  void assertionStarting(AssertionInfo const &) override;
6455 
6456  bool assertionEnded(AssertionStats const &_assertionStats) override;
6457 
6458  void sectionStarting(SectionInfo const &_sectionInfo) override;
6459  void sectionEnded(SectionStats const &_sectionStats) override;
6460 
6461 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6462  void benchmarkPreparing(std::string const &name) override;
6463  void benchmarkStarting(BenchmarkInfo const &info) override;
6464  void benchmarkEnded(BenchmarkStats<> const &stats) override;
6465  void benchmarkFailed(std::string const &error) override;
6466 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6467 
6468  void testCaseEnded(TestCaseStats const &_testCaseStats) override;
6469  void testGroupEnded(TestGroupStats const &_testGroupStats) override;
6470  void testRunEnded(TestRunStats const &_testRunStats) override;
6471  void testRunStarting(TestRunInfo const &_testRunInfo) override;
6472 
6473  private:
6474  void lazyPrint();
6475 
6476  void lazyPrintWithoutClosingBenchmarkTable();
6477  void lazyPrintRunInfo();
6478  void lazyPrintGroupInfo();
6479  void printTestCaseAndSectionHeader();
6480 
6481  void printClosedHeader(std::string const &_name);
6482  void printOpenHeader(std::string const &_name);
6483 
6484  // if string has a : in first line will set indent to follow it on
6485  // subsequent lines
6486  void printHeaderString(std::string const &_string, std::size_t indent = 0);
6487 
6488  void printTotals(Totals const &totals);
6489  void printSummaryRow(std::string const &label, std::vector<SummaryColumn> const &cols, std::size_t row);
6490 
6491  void printTotalsDivider(Totals const &totals);
6492  void printSummaryDivider();
6493  void printTestFilters();
6494 
6495  private:
6496  bool m_headerPrinted = false;
6497  };
6498 
6499 } // end namespace Catch
6500 
6501 #if defined(_MSC_VER)
6502 #pragma warning(pop)
6503 #endif
6504 
6505 // end catch_reporter_console.h
6506 // start catch_reporter_junit.h
6507 
6508 // start catch_xmlwriter.h
6509 
6510 #include <vector>
6511 
6512 namespace Catch {
6513  enum class XmlFormatting {
6514  None = 0x00,
6515  Indent = 0x01,
6516  Newline = 0x02,
6517  };
6518 
6519  XmlFormatting operator|(XmlFormatting lhs, XmlFormatting rhs);
6520  XmlFormatting operator&(XmlFormatting lhs, XmlFormatting rhs);
6521 
6522  class XmlEncode {
6523  public:
6524  enum ForWhat {
6525  ForTextNodes,
6526  ForAttributes
6527  };
6528 
6529  XmlEncode(std::string const &str, ForWhat forWhat = ForTextNodes);
6530 
6531  void encodeTo(std::ostream &os) const;
6532 
6533  friend std::ostream &operator<<(std::ostream &os, XmlEncode const &xmlEncode);
6534 
6535  private:
6536  std::string m_str;
6537  ForWhat m_forWhat;
6538  };
6539 
6540  class XmlWriter {
6541  public:
6542  class ScopedElement {
6543  public:
6544  ScopedElement(XmlWriter *writer, XmlFormatting fmt);
6545 
6546  ScopedElement(ScopedElement &&other) noexcept;
6547  ScopedElement &operator=(ScopedElement &&other) noexcept;
6548 
6549  ~ScopedElement();
6550 
6551  ScopedElement &writeText(std::string const &text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6552 
6553  template<typename T>
6554  ScopedElement &writeAttribute(std::string const &name, T const &attribute) {
6555  m_writer->writeAttribute(name, attribute);
6556  return *this;
6557  }
6558 
6559  private:
6560  mutable XmlWriter *m_writer = nullptr;
6561  XmlFormatting m_fmt;
6562  };
6563 
6564  XmlWriter(std::ostream &os = Catch::cout());
6565  ~XmlWriter();
6566 
6567  XmlWriter(XmlWriter const &) = delete;
6568  XmlWriter &operator=(XmlWriter const &) = delete;
6569 
6570  XmlWriter &startElement(std::string const &name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6571 
6572  ScopedElement scopedElement(std::string const &name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6573 
6574  XmlWriter &endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6575 
6576  XmlWriter &writeAttribute(std::string const &name, std::string const &attribute);
6577 
6578  XmlWriter &writeAttribute(std::string const &name, bool attribute);
6579 
6580  template<typename T>
6581  XmlWriter &writeAttribute(std::string const &name, T const &attribute) {
6583  rss << attribute;
6584  return writeAttribute(name, rss.str());
6585  }
6586 
6587  XmlWriter &writeText(std::string const &text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6588 
6589  XmlWriter &writeComment(std::string const &text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
6590 
6591  void writeStylesheetRef(std::string const &url);
6592 
6593  XmlWriter &writeBlankLine();
6594 
6595  void ensureTagClosed();
6596 
6597  private:
6598  void applyFormatting(XmlFormatting fmt);
6599 
6600  void writeDeclaration();
6601 
6602  void newlineIfNecessary();
6603 
6604  bool m_tagIsOpen = false;
6605  bool m_needsNewline = false;
6606  std::vector<std::string> m_tags;
6607  std::string m_indent;
6608  std::ostream &m_os;
6609  };
6610 
6611 } // namespace Catch
6612 
6613 // end catch_xmlwriter.h
6614 namespace Catch {
6615  class JunitReporter : public CumulativeReporterBase<JunitReporter> {
6616  public:
6617  JunitReporter(ReporterConfig const &_config);
6618 
6619  ~JunitReporter() override;
6620 
6621  static std::string getDescription();
6622 
6623  void noMatchingTestCases(std::string const & /*spec*/) override;
6624 
6625  void testRunStarting(TestRunInfo const &runInfo) override;
6626 
6627  void testGroupStarting(GroupInfo const &groupInfo) override;
6628 
6629  void testCaseStarting(TestCaseInfo const &testCaseInfo) override;
6630  bool assertionEnded(AssertionStats const &assertionStats) override;
6631 
6632  void testCaseEnded(TestCaseStats const &testCaseStats) override;
6633 
6634  void testGroupEnded(TestGroupStats const &testGroupStats) override;
6635 
6636  void testRunEndedCumulative() override;
6637 
6638  void writeGroup(TestGroupNode const &groupNode, double suiteTime);
6639 
6640  void writeTestCase(TestCaseNode const &testCaseNode);
6641 
6642  void writeSection(std::string const &className, std::string const &rootName, SectionNode const &sectionNode);
6643 
6644  void writeAssertions(SectionNode const &sectionNode);
6645  void writeAssertion(AssertionStats const &stats);
6646 
6647  XmlWriter xml;
6648  Timer suiteTimer;
6649  std::string stdOutForSuite;
6650  std::string stdErrForSuite;
6651  unsigned int unexpectedExceptions = 0;
6652  bool m_okToFail = false;
6653  };
6654 
6655 } // end namespace Catch
6656 
6657 // end catch_reporter_junit.h
6658 // start catch_reporter_xml.h
6659 
6660 namespace Catch {
6661  class XmlReporter : public StreamingReporterBase<XmlReporter> {
6662  public:
6663  XmlReporter(ReporterConfig const &_config);
6664 
6665  ~XmlReporter() override;
6666 
6667  static std::string getDescription();
6668 
6669  virtual std::string getStylesheetRef() const;
6670 
6671  void writeSourceInfo(SourceLineInfo const &sourceInfo);
6672 
6673  public: // StreamingReporterBase
6674  void noMatchingTestCases(std::string const &s) override;
6675 
6676  void testRunStarting(TestRunInfo const &testInfo) override;
6677 
6678  void testGroupStarting(GroupInfo const &groupInfo) override;
6679 
6680  void testCaseStarting(TestCaseInfo const &testInfo) override;
6681 
6682  void sectionStarting(SectionInfo const &sectionInfo) override;
6683 
6684  void assertionStarting(AssertionInfo const &) override;
6685 
6686  bool assertionEnded(AssertionStats const &assertionStats) override;
6687 
6688  void sectionEnded(SectionStats const &sectionStats) override;
6689 
6690  void testCaseEnded(TestCaseStats const &testCaseStats) override;
6691 
6692  void testGroupEnded(TestGroupStats const &testGroupStats) override;
6693 
6694  void testRunEnded(TestRunStats const &testRunStats) override;
6695 
6696 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6697  void benchmarkPreparing(std::string const &name) override;
6698  void benchmarkStarting(BenchmarkInfo const &) override;
6699  void benchmarkEnded(BenchmarkStats<> const &) override;
6700  void benchmarkFailed(std::string const &) override;
6701 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
6702 
6703  private:
6704  Timer m_testCaseTimer;
6705  XmlWriter m_xml;
6706  int m_sectionDepth = 0;
6707  };
6708 
6709 } // end namespace Catch
6710 
6711 // end catch_reporter_xml.h
6712 
6713 // end catch_external_interfaces.h
6714 #endif
6715 
6716 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
6717 // start catch_benchmarking_all.hpp
6718 
6719 // A proxy header that includes all of the benchmarking headers to allow
6720 // concise include of the benchmarking features. You should prefer the
6721 // individual includes in standard use.
6722 
6723 // start catch_benchmark.hpp
6724 
6725 // Benchmark
6726 
6727 // start catch_chronometer.hpp
6728 
6729 // User-facing chronometer
6730 
6731 // start catch_clock.hpp
6732 
6733 // Clocks
6734 
6735 #include <chrono>
6736 #include <ratio>
6737 
6738 namespace Catch {
6739  namespace Benchmark {
6740  template<typename Clock>
6741  using ClockDuration = typename Clock::duration;
6742  template<typename Clock>
6743  using FloatDuration = std::chrono::duration<double, typename Clock::period>;
6744 
6745  template<typename Clock>
6746  using TimePoint = typename Clock::time_point;
6747 
6748  using default_clock = std::chrono::steady_clock;
6749 
6750  template<typename Clock>
6751  struct now {
6752  TimePoint<Clock> operator()() const { return Clock::now(); }
6753  };
6754 
6755  using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
6756  } // namespace Benchmark
6757 } // namespace Catch
6758 
6759 // end catch_clock.hpp
6760 // start catch_optimizer.hpp
6761 
6762 // Hinting the optimizer
6763 
6764 #if defined(_MSC_VER)
6765 #include <atomic> // atomic_thread_fence
6766 #endif
6767 
6768 namespace Catch {
6769  namespace Benchmark {
6770 #if defined(__GNUC__) || defined(__clang__)
6771  template<typename T>
6772  inline void keep_memory(T *p) {
6773  asm volatile(""
6774  :
6775  : "g"(p)
6776  : "memory");
6777  }
6778  inline void keep_memory() {
6779  asm volatile(""
6780  :
6781  :
6782  : "memory");
6783  }
6784 
6785  namespace Detail {
6786  inline void optimizer_barrier() {
6787  keep_memory();
6788  }
6789  } // namespace Detail
6790 #elif defined(_MSC_VER)
6791 
6792 #pragma optimize("", off)
6793  template<typename T>
6794  inline void keep_memory(T *p) {
6795  // thanks @milleniumbug
6796  *reinterpret_cast<char volatile *>(p) = *reinterpret_cast<char const volatile *>(p);
6797  }
6798 // TODO equivalent keep_memory()
6799 #pragma optimize("", on)
6800 
6801  namespace Detail {
6802  inline void optimizer_barrier() {
6803  std::atomic_thread_fence(std::memory_order_seq_cst);
6804  }
6805  } // namespace Detail
6806 
6807 #endif
6808 
6809  template<typename T>
6810  inline void deoptimize_value(T &&x) {
6811  keep_memory(&x);
6812  }
6813 
6814  template<typename Fn, typename... Args>
6815  inline auto invoke_deoptimized(Fn &&fn, Args &&...args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
6816  deoptimize_value(std::forward<Fn>(fn)(std::forward<Args...>(args...)));
6817  }
6818 
6819  template<typename Fn, typename... Args>
6820  inline auto invoke_deoptimized(Fn &&fn, Args &&...args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
6821  std::forward<Fn>(fn)(std::forward<Args...>(args...));
6822  }
6823  } // namespace Benchmark
6824 } // namespace Catch
6825 
6826 // end catch_optimizer.hpp
6827 // start catch_complete_invoke.hpp
6828 
6829 // Invoke with a special case for void
6830 
6831 #include <type_traits>
6832 #include <utility>
6833 
6834 namespace Catch {
6835  namespace Benchmark {
6836  namespace Detail {
6837  template<typename T>
6838  struct CompleteType {
6839  using type = T;
6840  };
6841  template<>
6842  struct CompleteType<void> {
6843  struct type {
6844  };
6845  };
6846 
6847  template<typename T>
6848  using CompleteType_t = typename CompleteType<T>::type;
6849 
6850  template<typename Result>
6851  struct CompleteInvoker {
6852  template<typename Fun, typename... Args>
6853  static Result invoke(Fun &&fun, Args &&...args) {
6854  return std::forward<Fun>(fun)(std::forward<Args>(args)...);
6855  }
6856  };
6857  template<>
6858  struct CompleteInvoker<void> {
6859  template<typename Fun, typename... Args>
6860  static CompleteType_t<void> invoke(Fun &&fun, Args &&...args) {
6861  std::forward<Fun>(fun)(std::forward<Args>(args)...);
6862  return {};
6863  }
6864  };
6865 
6866  // invoke and not return void :(
6867  template<typename Fun, typename... Args>
6868  CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun &&fun, Args &&...args) {
6869  return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
6870  }
6871 
6872  const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
6873  } // namespace Detail
6874 
6875  template<typename Fun>
6876  Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun &&fun) {
6877  CATCH_TRY { return Detail::complete_invoke(std::forward<Fun>(fun)); }
6878  CATCH_CATCH_ALL {
6879  getResultCapture().benchmarkFailed(translateActiveException());
6880  CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
6881  }
6882  }
6883  } // namespace Benchmark
6884 } // namespace Catch
6885 
6886 // end catch_complete_invoke.hpp
6887 namespace Catch {
6888  namespace Benchmark {
6889  namespace Detail {
6890  struct ChronometerConcept {
6891  virtual void start() = 0;
6892  virtual void finish() = 0;
6893  virtual ~ChronometerConcept() = default;
6894  };
6895  template<typename Clock>
6896  struct ChronometerModel final : public ChronometerConcept {
6897  void start() override { started = Clock::now(); }
6898  void finish() override { finished = Clock::now(); }
6899 
6900  ClockDuration<Clock> elapsed() const { return finished - started; }
6901 
6902  TimePoint<Clock> started;
6903  TimePoint<Clock> finished;
6904  };
6905  } // namespace Detail
6906 
6907  struct Chronometer {
6908  public:
6909  template<typename Fun>
6910  void measure(Fun &&fun) {
6911  measure(std::forward<Fun>(fun), is_callable<Fun(int)>());
6912  }
6913 
6914  int runs() const { return k; }
6915 
6916  Chronometer(Detail::ChronometerConcept &meter, int k)
6917  : impl(&meter)
6918  , k(k) {
6919  }
6920 
6921  private:
6922  template<typename Fun>
6923  void measure(Fun &&fun, std::false_type) {
6924  measure([&fun](int) { return fun(); }, std::true_type());
6925  }
6926 
6927  template<typename Fun>
6928  void measure(Fun &&fun, std::true_type) {
6929  Detail::optimizer_barrier();
6930  impl->start();
6931  for (int i = 0; i < k; ++i)
6932  invoke_deoptimized(fun, i);
6933  impl->finish();
6934  Detail::optimizer_barrier();
6935  }
6936 
6937  Detail::ChronometerConcept *impl;
6938  int k;
6939  };
6940  } // namespace Benchmark
6941 } // namespace Catch
6942 
6943 // end catch_chronometer.hpp
6944 // start catch_environment.hpp
6945 
6946 // Environment information
6947 
6948 namespace Catch {
6949  namespace Benchmark {
6950  template<typename Duration>
6951  struct EnvironmentEstimate {
6952  Duration mean;
6953  OutlierClassification outliers;
6954 
6955  template<typename Duration2>
6956  operator EnvironmentEstimate<Duration2>() const {
6957  return {mean, outliers};
6958  }
6959  };
6960  template<typename Clock>
6961  struct Environment {
6962  using clock_type = Clock;
6963  EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
6964  EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
6965  };
6966  } // namespace Benchmark
6967 } // namespace Catch
6968 
6969 // end catch_environment.hpp
6970 // start catch_execution_plan.hpp
6971 
6972 // Execution plan
6973 
6974 // start catch_benchmark_function.hpp
6975 
6976 // Dumb std::function implementation for consistent call overhead
6977 
6978 #include <cassert>
6979 #include <memory>
6980 #include <type_traits>
6981 #include <utility>
6982 
6983 namespace Catch {
6984  namespace Benchmark {
6985  namespace Detail {
6986  template<typename T>
6987  using Decay = typename std::decay<T>::type;
6988  template<typename T, typename U>
6989  struct is_related : std::is_same<Decay<T>, Decay<U>> {
6990  };
6991 
6999  struct BenchmarkFunction {
7000  private:
7001  struct callable {
7002  virtual void call(Chronometer meter) const = 0;
7003  virtual callable *clone() const = 0;
7004  virtual ~callable() = default;
7005  };
7006  template<typename Fun>
7007  struct model : public callable {
7008  model(Fun &&fun)
7009  : fun(std::move(fun)) {
7010  }
7011  model(Fun const &fun)
7012  : fun(fun) {
7013  }
7014 
7015  model<Fun> *clone() const override { return new model<Fun>(*this); }
7016 
7017  void call(Chronometer meter) const override { call(meter, is_callable<Fun(Chronometer)>()); }
7018  void call(Chronometer meter, std::true_type) const { fun(meter); }
7019  void call(Chronometer meter, std::false_type) const { meter.measure(fun); }
7020 
7021  Fun fun;
7022  };
7023 
7024  struct do_nothing {
7025  void operator()() const {}
7026  };
7027 
7028  template<typename T>
7029  BenchmarkFunction(model<T> *c)
7030  : f(c) {
7031  }
7032 
7033  public:
7034  BenchmarkFunction()
7035  : f(new model<do_nothing>{{}}) {
7036  }
7037 
7038  template<typename Fun, typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
7039  BenchmarkFunction(Fun &&fun)
7040  : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {
7041  }
7042 
7043  BenchmarkFunction(BenchmarkFunction &&that)
7044  : f(std::move(that.f)) {
7045  }
7046 
7047  BenchmarkFunction(BenchmarkFunction const &that)
7048  : f(that.f->clone()) {
7049  }
7050 
7051  BenchmarkFunction &operator=(BenchmarkFunction &&that) {
7052  f = std::move(that.f);
7053  return *this;
7054  }
7055 
7056  BenchmarkFunction &operator=(BenchmarkFunction const &that) {
7057  f.reset(that.f->clone());
7058  return *this;
7059  }
7060 
7061  void operator()(Chronometer meter) const { f->call(meter); }
7062 
7063  private:
7064  std::unique_ptr<callable> f;
7065  };
7066  } // namespace Detail
7067  } // namespace Benchmark
7068 } // namespace Catch
7069 
7070 // end catch_benchmark_function.hpp
7071 // start catch_repeat.hpp
7072 
7073 // repeat algorithm
7074 
7075 #include <type_traits>
7076 #include <utility>
7077 
7078 namespace Catch {
7079  namespace Benchmark {
7080  namespace Detail {
7081  template<typename Fun>
7082  struct repeater {
7083  void operator()(int k) const {
7084  for (int i = 0; i < k; ++i) {
7085  fun();
7086  }
7087  }
7088  Fun fun;
7089  };
7090  template<typename Fun>
7091  repeater<typename std::decay<Fun>::type> repeat(Fun &&fun) {
7092  return {std::forward<Fun>(fun)};
7093  }
7094  } // namespace Detail
7095  } // namespace Benchmark
7096 } // namespace Catch
7097 
7098 // end catch_repeat.hpp
7099 // start catch_run_for_at_least.hpp
7100 
7101 // Run a function for a minimum amount of time
7102 
7103 // start catch_measure.hpp
7104 
7105 // Measure
7106 
7107 // start catch_timing.hpp
7108 
7109 // Timing
7110 
7111 #include <tuple>
7112 #include <type_traits>
7113 
7114 namespace Catch {
7115  namespace Benchmark {
7116  template<typename Duration, typename Result>
7117  struct Timing {
7118  Duration elapsed;
7119  Result result;
7120  int iterations;
7121  };
7122  template<typename Clock, typename Func, typename... Args>
7123  using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
7124  } // namespace Benchmark
7125 } // namespace Catch
7126 
7127 // end catch_timing.hpp
7128 #include <utility>
7129 
7130 namespace Catch {
7131  namespace Benchmark {
7132  namespace Detail {
7133  template<typename Clock, typename Fun, typename... Args>
7134  TimingOf<Clock, Fun, Args...> measure(Fun &&fun, Args &&...args) {
7135  auto start = Clock::now();
7136  auto &&r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
7137  auto end = Clock::now();
7138  auto delta = end - start;
7139  return {delta, std::forward<decltype(r)>(r), 1};
7140  }
7141  } // namespace Detail
7142  } // namespace Benchmark
7143 } // namespace Catch
7144 
7145 // end catch_measure.hpp
7146 #include <type_traits>
7147 #include <utility>
7148 
7149 namespace Catch {
7150  namespace Benchmark {
7151  namespace Detail {
7152  template<typename Clock, typename Fun>
7153  TimingOf<Clock, Fun, int> measure_one(Fun &&fun, int iters, std::false_type) {
7154  return Detail::measure<Clock>(fun, iters);
7155  }
7156  template<typename Clock, typename Fun>
7157  TimingOf<Clock, Fun, Chronometer> measure_one(Fun &&fun, int iters, std::true_type) {
7158  Detail::ChronometerModel<Clock> meter;
7159  auto &&result = Detail::complete_invoke(fun, Chronometer(meter, iters));
7160 
7161  return {meter.elapsed(), std::move(result), iters};
7162  }
7163 
7164  template<typename Clock, typename Fun>
7165  using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
7166 
7167  struct optimized_away_error : std::exception {
7168  const char *what() const noexcept override { return "could not measure benchmark, maybe it was optimized away"; }
7169  };
7170 
7171  template<typename Clock, typename Fun>
7172  TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun &&fun) {
7173  auto iters = seed;
7174  while (iters < (1 << 30)) {
7175  auto &&Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
7176 
7177  if (Timing.elapsed >= how_long) {
7178  return {Timing.elapsed, std::move(Timing.result), iters};
7179  }
7180  iters *= 2;
7181  }
7182  throw optimized_away_error{};
7183  }
7184  } // namespace Detail
7185  } // namespace Benchmark
7186 } // namespace Catch
7187 
7188 // end catch_run_for_at_least.hpp
7189 #include <algorithm>
7190 
7191 namespace Catch {
7192  namespace Benchmark {
7193  template<typename Duration>
7194  struct ExecutionPlan {
7195  int iterations_per_sample;
7196  Duration estimated_duration;
7197  Detail::BenchmarkFunction benchmark;
7198  Duration warmup_time;
7199  int warmup_iterations;
7200 
7201  template<typename Duration2>
7202  operator ExecutionPlan<Duration2>() const {
7203  return {iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations};
7204  }
7205 
7206  template<typename Clock>
7207  std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
7208  // warmup a bit
7209  Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time),
7210  warmup_iterations,
7211  Detail::repeat(now<Clock>{}));
7212 
7213  std::vector<FloatDuration<Clock>> times;
7214  times.reserve(cfg.benchmarkSamples());
7215  std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
7216  Detail::ChronometerModel<Clock> model;
7217  this->benchmark(Chronometer(model, iterations_per_sample));
7218  auto sample_time = model.elapsed() - env.clock_cost.mean;
7219  if (sample_time < FloatDuration<Clock>::zero())
7220  sample_time = FloatDuration<Clock>::zero();
7221  return sample_time / iterations_per_sample;
7222  });
7223  return times;
7224  }
7225  };
7226  } // namespace Benchmark
7227 } // namespace Catch
7228 
7229 // end catch_execution_plan.hpp
7230 // start catch_estimate_clock.hpp
7231 
7232 // Environment measurement
7233 
7234 // start catch_stats.hpp
7235 
7236 // Statistical analysis tools
7237 
7238 #include <algorithm>
7239 #include <cmath>
7240 #include <cstddef>
7241 #include <functional>
7242 #include <iterator>
7243 #include <numeric>
7244 #include <random>
7245 #include <tuple>
7246 #include <utility>
7247 #include <vector>
7248 
7249 namespace Catch {
7250  namespace Benchmark {
7251  namespace Detail {
7252  using sample = std::vector<double>;
7253 
7254  double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
7255 
7256  template<typename Iterator>
7257  OutlierClassification classify_outliers(Iterator first, Iterator last) {
7258  std::vector<double> copy(first, last);
7259 
7260  auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
7261  auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
7262  auto iqr = q3 - q1;
7263  auto los = q1 - (iqr * 3.);
7264  auto lom = q1 - (iqr * 1.5);
7265  auto him = q3 + (iqr * 1.5);
7266  auto his = q3 + (iqr * 3.);
7267 
7268  OutlierClassification o;
7269  for (; first != last; ++first) {
7270  auto &&t = *first;
7271  if (t < los)
7272  ++o.low_severe;
7273  else if (t < lom)
7274  ++o.low_mild;
7275  else if (t > his)
7276  ++o.high_severe;
7277  else if (t > him)
7278  ++o.high_mild;
7279  ++o.samples_seen;
7280  }
7281  return o;
7282  }
7283 
7284  template<typename Iterator>
7285  double mean(Iterator first, Iterator last) {
7286  auto count = last - first;
7287  double sum = std::accumulate(first, last, 0.);
7288  return sum / count;
7289  }
7290 
7291  template<typename URng, typename Iterator, typename Estimator>
7292  sample resample(URng &rng, int resamples, Iterator first, Iterator last, Estimator &estimator) {
7293  auto n = last - first;
7294  std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
7295 
7296  sample out;
7297  out.reserve(resamples);
7298  std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
7299  std::vector<double> resampled;
7300  resampled.reserve(n);
7301  std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
7302  return estimator(resampled.begin(), resampled.end());
7303  });
7304  std::sort(out.begin(), out.end());
7305  return out;
7306  }
7307 
7308  template<typename Estimator, typename Iterator>
7309  sample jackknife(Estimator &&estimator, Iterator first, Iterator last) {
7310  auto n = last - first;
7311  auto second = std::next(first);
7312  sample results;
7313  results.reserve(n);
7314 
7315  for (auto it = first; it != last; ++it) {
7316  std::iter_swap(it, first);
7317  results.push_back(estimator(second, last));
7318  }
7319 
7320  return results;
7321  }
7322 
7323  inline double normal_cdf(double x) {
7324  return std::erfc(-x / std::sqrt(2.0)) / 2.0;
7325  }
7326 
7327  double erfc_inv(double x);
7328 
7329  double normal_quantile(double p);
7330 
7331  template<typename Iterator, typename Estimator>
7332  Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const &resample, Estimator &&estimator) {
7333  auto n_samples = last - first;
7334 
7335  double point = estimator(first, last);
7336  // Degenerate case with a single sample
7337  if (n_samples == 1)
7338  return {point, point, point, confidence_level};
7339 
7340  sample jack = jackknife(estimator, first, last);
7341  double jack_mean = mean(jack.begin(), jack.end());
7342  double sum_squares, sum_cubes;
7343  std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(),
7344  jack.end(),
7345  std::make_pair(0., 0.),
7346  [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
7347  auto d = jack_mean - x;
7348  auto d2 = d * d;
7349  auto d3 = d2 * d;
7350  return {sqcb.first + d2, sqcb.second + d3};
7351  });
7352 
7353  double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
7354  int n = static_cast<int>(resample.size());
7355  double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
7356  // degenerate case with uniform samples
7357  if (prob_n == 0)
7358  return {point, point, point, confidence_level};
7359 
7360  double bias = normal_quantile(prob_n);
7361  double z1 = normal_quantile((1. - confidence_level) / 2.);
7362 
7363  auto cumn = [n](double x) -> int { return std::lround(normal_cdf(x) * n); };
7364  auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
7365  double b1 = bias + z1;
7366  double b2 = bias - z1;
7367  double a1 = a(b1);
7368  double a2 = a(b2);
7369  auto lo = (std::max)(cumn(a1), 0);
7370  auto hi = (std::min)(cumn(a2), n - 1);
7371 
7372  return {point, resample[lo], resample[hi], confidence_level};
7373  }
7374 
7375  double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
7376 
7377  struct bootstrap_analysis {
7378  Estimate<double> mean;
7379  Estimate<double> standard_deviation;
7380  double outlier_variance;
7381  };
7382 
7383  bootstrap_analysis
7384  analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
7385  } // namespace Detail
7386  } // namespace Benchmark
7387 } // namespace Catch
7388 
7389 // end catch_stats.hpp
7390 #include <algorithm>
7391 #include <cmath>
7392 #include <iterator>
7393 #include <tuple>
7394 #include <vector>
7395 
7396 namespace Catch {
7397  namespace Benchmark {
7398  namespace Detail {
7399  template<typename Clock>
7400  std::vector<double> resolution(int k) {
7401  std::vector<TimePoint<Clock>> times;
7402  times.reserve(k + 1);
7403  std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
7404 
7405  std::vector<double> deltas;
7406  deltas.reserve(k);
7407  std::transform(std::next(times.begin()), times.end(), times.begin(), std::back_inserter(deltas), [](TimePoint<Clock> a, TimePoint<Clock> b) {
7408  return static_cast<double>((a - b).count());
7409  });
7410 
7411  return deltas;
7412  }
7413 
7414  const auto warmup_iterations = 10000;
7415  const auto warmup_time = std::chrono::milliseconds(100);
7416  const auto minimum_ticks = 1000;
7417  const auto warmup_seed = 10000;
7418  const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
7419  const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
7420  const auto clock_cost_estimation_tick_limit = 100000;
7421  const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
7422  const auto clock_cost_estimation_iterations = 10000;
7423 
7424  template<typename Clock>
7425  int warmup() {
7426  return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>).iterations;
7427  }
7428  template<typename Clock>
7429  EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
7430  auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time),
7431  iterations,
7432  &resolution<Clock>)
7433  .result;
7434  return {
7435  FloatDuration<Clock>(mean(r.begin(), r.end())),
7436  classify_outliers(r.begin(), r.end()),
7437  };
7438  }
7439  template<typename Clock>
7440  EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
7441  auto time_limit = (std::min)(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
7442  auto time_clock = [](int k) {
7443  return Detail::measure<Clock>([k] {
7444  for (int i = 0; i < k; ++i) {
7445  volatile auto ignored = Clock::now();
7446  (void)ignored;
7447  }
7448  })
7449  .elapsed;
7450  };
7451  time_clock(1);
7452  int iters = clock_cost_estimation_iterations;
7453  auto &&r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
7454  std::vector<double> times;
7455  int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
7456  times.reserve(nsamples);
7457  std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
7458  return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
7459  });
7460  return {
7461  FloatDuration<Clock>(mean(times.begin(), times.end())),
7462  classify_outliers(times.begin(), times.end()),
7463  };
7464  }
7465 
7466  template<typename Clock>
7467  Environment<FloatDuration<Clock>> measure_environment() {
7468  static Environment<FloatDuration<Clock>> *env = nullptr;
7469  if (env) {
7470  return *env;
7471  }
7472 
7473  auto iters = Detail::warmup<Clock>();
7474  auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
7475  auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
7476 
7477  env = new Environment<FloatDuration<Clock>>{resolution, cost};
7478  return *env;
7479  }
7480  } // namespace Detail
7481  } // namespace Benchmark
7482 } // namespace Catch
7483 
7484 // end catch_estimate_clock.hpp
7485 // start catch_analyse.hpp
7486 
7487 // Run and analyse one benchmark
7488 
7489 // start catch_sample_analysis.hpp
7490 
7491 // Benchmark results
7492 
7493 #include <algorithm>
7494 #include <iterator>
7495 #include <string>
7496 #include <vector>
7497 
7498 namespace Catch {
7499  namespace Benchmark {
7500  template<typename Duration>
7501  struct SampleAnalysis {
7502  std::vector<Duration> samples;
7503  Estimate<Duration> mean;
7504  Estimate<Duration> standard_deviation;
7505  OutlierClassification outliers;
7506  double outlier_variance;
7507 
7508  template<typename Duration2>
7509  operator SampleAnalysis<Duration2>() const {
7510  std::vector<Duration2> samples2;
7511  samples2.reserve(samples.size());
7512  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
7513  return {
7514  std::move(samples2),
7515  mean,
7516  standard_deviation,
7517  outliers,
7518  outlier_variance,
7519  };
7520  }
7521  };
7522  } // namespace Benchmark
7523 } // namespace Catch
7524 
7525 // end catch_sample_analysis.hpp
7526 #include <algorithm>
7527 #include <iterator>
7528 #include <vector>
7529 
7530 namespace Catch {
7531  namespace Benchmark {
7532  namespace Detail {
7533  template<typename Duration, typename Iterator>
7534  SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
7535  if (!cfg.benchmarkNoAnalysis()) {
7536  std::vector<double> samples;
7537  samples.reserve(last - first);
7538  std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
7539 
7540  auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(),
7541  cfg.benchmarkResamples(),
7542  samples.begin(),
7543  samples.end());
7544  auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
7545 
7546  auto wrap_estimate = [](Estimate<double> e) {
7547  return Estimate<Duration>{
7548  Duration(e.point),
7549  Duration(e.lower_bound),
7550  Duration(e.upper_bound),
7551  e.confidence_interval,
7552  };
7553  };
7554  std::vector<Duration> samples2;
7555  samples2.reserve(samples.size());
7556  std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
7557  return {
7558  std::move(samples2),
7559  wrap_estimate(analysis.mean),
7560  wrap_estimate(analysis.standard_deviation),
7561  outliers,
7562  analysis.outlier_variance,
7563  };
7564  } else {
7565  std::vector<Duration> samples;
7566  samples.reserve(last - first);
7567 
7568  Duration mean = Duration(0);
7569  int i = 0;
7570  for (auto it = first; it < last; ++it, ++i) {
7571  samples.push_back(Duration(*it));
7572  mean += Duration(*it);
7573  }
7574  mean /= i;
7575 
7576  return {std::move(samples),
7577  Estimate<Duration>{mean, mean, mean, 0.0},
7578  Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
7579  OutlierClassification{},
7580  0.0};
7581  }
7582  }
7583  } // namespace Detail
7584  } // namespace Benchmark
7585 } // namespace Catch
7586 
7587 // end catch_analyse.hpp
7588 #include <algorithm>
7589 #include <cmath>
7590 #include <functional>
7591 #include <string>
7592 #include <vector>
7593 
7594 namespace Catch {
7595  namespace Benchmark {
7596  struct Benchmark {
7597  Benchmark(std::string &&name)
7598  : name(std::move(name)) {
7599  }
7600 
7601  template<class FUN>
7602  Benchmark(std::string &&name, FUN &&func)
7603  : fun(std::move(func))
7604  , name(std::move(name)) {
7605  }
7606 
7607  template<typename Clock>
7608  ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
7609  auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
7610  auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
7611  auto &&test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
7612  int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
7613  return {new_iters,
7614  test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(),
7615  fun,
7616  std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()),
7617  Detail::warmup_iterations};
7618  }
7619 
7620  template<typename Clock = default_clock>
7621  void run() {
7622  IConfigPtr cfg = getCurrentContext().getConfig();
7623 
7624  auto env = Detail::measure_environment<Clock>();
7625 
7626  getResultCapture().benchmarkPreparing(name);
7627  CATCH_TRY {
7628  auto plan = user_code([&] { return prepare<Clock>(*cfg, env); });
7629 
7630  BenchmarkInfo info{name,
7631  plan.estimated_duration.count(),
7632  plan.iterations_per_sample,
7633  cfg->benchmarkSamples(),
7634  cfg->benchmarkResamples(),
7635  env.clock_resolution.mean.count(),
7636  env.clock_cost.mean.count()};
7637 
7638  getResultCapture().benchmarkStarting(info);
7639 
7640  auto samples = user_code([&] { return plan.template run<Clock>(*cfg, env); });
7641 
7642  auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
7643  BenchmarkStats<FloatDuration<Clock>> stats{info,
7644  analysis.samples,
7645  analysis.mean,
7646  analysis.standard_deviation,
7647  analysis.outliers,
7648  analysis.outlier_variance};
7649  getResultCapture().benchmarkEnded(stats);
7650  }
7651  CATCH_CATCH_ALL {
7652  if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
7653  std::rethrow_exception(std::current_exception());
7654  }
7655  }
7656 
7657  // sets lambda to be used in fun *and* executes benchmark!
7658  template<typename Fun, typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
7659  Benchmark &operator=(Fun func) {
7660  fun = Detail::BenchmarkFunction(func);
7661  run();
7662  return *this;
7663  }
7664 
7665  explicit operator bool() { return true; }
7666 
7667  private:
7668  Detail::BenchmarkFunction fun;
7669  std::string name;
7670  };
7671  } // namespace Benchmark
7672 } // namespace Catch
7673 
7674 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
7675 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
7676 
7677 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex) \
7678  if (Catch::Benchmark::Benchmark BenchmarkName{name}) \
7679  BenchmarkName = [&](int benchmarkIndex)
7680 
7681 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name) \
7682  if (Catch::Benchmark::Benchmark BenchmarkName{name}) \
7683  BenchmarkName = [&]
7684 
7685 // end catch_benchmark.hpp
7686 // start catch_constructor.hpp
7687 
7688 // Constructor and destructor helpers
7689 
7690 #include <type_traits>
7691 
7692 namespace Catch {
7693  namespace Benchmark {
7694  namespace Detail {
7695  template<typename T, bool Destruct>
7696  struct ObjectStorage {
7697  using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
7698 
7699  ObjectStorage()
7700  : data() {
7701  }
7702 
7703  ObjectStorage(const ObjectStorage &other) { new (&data) T(other.stored_object()); }
7704 
7705  ObjectStorage(ObjectStorage &&other) { new (&data) T(std::move(other.stored_object())); }
7706 
7707  ~ObjectStorage() { destruct_on_exit<T>(); }
7708 
7709  template<typename... Args>
7710  void construct(Args &&...args) {
7711  new (&data) T(std::forward<Args>(args)...);
7712  }
7713 
7714  template<bool AllowManualDestruction = !Destruct>
7715  typename std::enable_if<AllowManualDestruction>::type destruct() {
7716  stored_object().~T();
7717  }
7718 
7719  private:
7720  // If this is a constructor benchmark, destruct the underlying object
7721  template<typename U>
7722  void destruct_on_exit(typename std::enable_if<Destruct, U>::type * = 0) {
7723  destruct<true>();
7724  }
7725  // Otherwise, don't
7726  template<typename U>
7727  void destruct_on_exit(typename std::enable_if<!Destruct, U>::type * = 0) {
7728  }
7729 
7730  T &stored_object() { return *static_cast<T *>(static_cast<void *>(&data)); }
7731 
7732  T const &stored_object() const { return *static_cast<T *>(static_cast<void *>(&data)); }
7733 
7734  TStorage data;
7735  };
7736  } // namespace Detail
7737 
7738  template<typename T>
7739  using storage_for = Detail::ObjectStorage<T, true>;
7740 
7741  template<typename T>
7742  using destructable_object = Detail::ObjectStorage<T, false>;
7743  } // namespace Benchmark
7744 } // namespace Catch
7745 
7746 // end catch_constructor.hpp
7747 // end catch_benchmarking_all.hpp
7748 #endif
7749 
7750 #endif // ! CATCH_CONFIG_IMPL_ONLY
7751 
7752 #ifdef CATCH_IMPL
7753 // start catch_impl.hpp
7754 
7755 #ifdef __clang__
7756 #pragma clang diagnostic push
7757 #pragma clang diagnostic ignored "-Wweak-vtables"
7758 #endif
7759 
7760 // Keep these here for external reporters
7761 // start catch_test_case_tracker.h
7762 
7763 #include <memory>
7764 #include <string>
7765 #include <vector>
7766 
7767 namespace Catch {
7768  namespace TestCaseTracking {
7769  struct NameAndLocation {
7770  std::string name;
7771  SourceLineInfo location;
7772 
7773  NameAndLocation(std::string const &_name, SourceLineInfo const &_location);
7774  friend bool operator==(NameAndLocation const &lhs, NameAndLocation const &rhs) {
7775  return lhs.name == rhs.name && lhs.location == rhs.location;
7776  }
7777  };
7778 
7779  class ITracker;
7780 
7781  using ITrackerPtr = std::shared_ptr<ITracker>;
7782 
7783  class ITracker {
7784  NameAndLocation m_nameAndLocation;
7785 
7786  public:
7787  ITracker(NameAndLocation const &nameAndLoc)
7788  : m_nameAndLocation(nameAndLoc) {
7789  }
7790 
7791  // static queries
7792  NameAndLocation const &nameAndLocation() const { return m_nameAndLocation; }
7793 
7794  virtual ~ITracker();
7795 
7796  // dynamic queries
7797  virtual bool isComplete() const = 0; // Successfully completed or failed
7798  virtual bool isSuccessfullyCompleted() const = 0;
7799  virtual bool isOpen() const = 0; // Started but not complete
7800  virtual bool hasChildren() const = 0;
7801  virtual bool hasStarted() const = 0;
7802 
7803  virtual ITracker &parent() = 0;
7804 
7805  // actions
7806  virtual void close() = 0; // Successfully complete
7807  virtual void fail() = 0;
7808  virtual void markAsNeedingAnotherRun() = 0;
7809 
7810  virtual void addChild(ITrackerPtr const &child) = 0;
7811  virtual ITrackerPtr findChild(NameAndLocation const &nameAndLocation) = 0;
7812  virtual void openChild() = 0;
7813 
7814  // Debug/ checking
7815  virtual bool isSectionTracker() const = 0;
7816  virtual bool isGeneratorTracker() const = 0;
7817  };
7818 
7819  class TrackerContext {
7820  enum RunState {
7821  NotStarted,
7822  Executing,
7823  CompletedCycle
7824  };
7825 
7826  ITrackerPtr m_rootTracker;
7827  ITracker *m_currentTracker = nullptr;
7828  RunState m_runState = NotStarted;
7829 
7830  public:
7831  ITracker &startRun();
7832  void endRun();
7833 
7834  void startCycle();
7835  void completeCycle();
7836 
7837  bool completedCycle() const;
7838  ITracker &currentTracker();
7839  void setCurrentTracker(ITracker *tracker);
7840  };
7841 
7842  class TrackerBase : public ITracker {
7843  protected:
7844  enum CycleState {
7845  NotStarted,
7846  Executing,
7847  ExecutingChildren,
7848  NeedsAnotherRun,
7849  CompletedSuccessfully,
7850  Failed
7851  };
7852 
7853  using Children = std::vector<ITrackerPtr>;
7854  TrackerContext &m_ctx;
7855  ITracker *m_parent;
7856  Children m_children;
7857  CycleState m_runState = NotStarted;
7858 
7859  public:
7860  TrackerBase(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent);
7861 
7862  bool isComplete() const override;
7863  bool isSuccessfullyCompleted() const override;
7864  bool isOpen() const override;
7865  bool hasChildren() const override;
7866  bool hasStarted() const override { return m_runState != NotStarted; }
7867 
7868  void addChild(ITrackerPtr const &child) override;
7869 
7870  ITrackerPtr findChild(NameAndLocation const &nameAndLocation) override;
7871  ITracker &parent() override;
7872 
7873  void openChild() override;
7874 
7875  bool isSectionTracker() const override;
7876  bool isGeneratorTracker() const override;
7877 
7878  void open();
7879 
7880  void close() override;
7881  void fail() override;
7882  void markAsNeedingAnotherRun() override;
7883 
7884  private:
7885  void moveToParent();
7886  void moveToThis();
7887  };
7888 
7889  class SectionTracker : public TrackerBase {
7890  std::vector<std::string> m_filters;
7891  std::string m_trimmed_name;
7892 
7893  public:
7894  SectionTracker(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent);
7895 
7896  bool isSectionTracker() const override;
7897 
7898  bool isComplete() const override;
7899 
7900  static SectionTracker &acquire(TrackerContext &ctx, NameAndLocation const &nameAndLocation);
7901 
7902  void tryOpen();
7903 
7904  void addInitialFilters(std::vector<std::string> const &filters);
7905  void addNextFilters(std::vector<std::string> const &filters);
7907  std::vector<std::string> const &getFilters() const;
7909  std::string const &trimmedName() const;
7910  };
7911 
7912  } // namespace TestCaseTracking
7913 
7914  using TestCaseTracking::ITracker;
7915  using TestCaseTracking::SectionTracker;
7916  using TestCaseTracking::TrackerContext;
7917 
7918 } // namespace Catch
7919 
7920 // end catch_test_case_tracker.h
7921 
7922 // start catch_leak_detector.h
7923 
7924 namespace Catch {
7925  struct LeakDetector {
7926  LeakDetector();
7927  ~LeakDetector();
7928  };
7929 
7930 } // namespace Catch
7931 // end catch_leak_detector.h
7932 // Cpp files will be included in the single-header file here
7933 // start catch_stats.cpp
7934 
7935 // Statistical analysis tools
7936 
7937 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
7938 
7939 #include <cassert>
7940 #include <random>
7941 
7942 #if defined(CATCH_CONFIG_USE_ASYNC)
7943 #include <future>
7944 #endif
7945 
7946 namespace {
7947  double erf_inv(double x) {
7948  // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
7949  double w, p;
7950 
7951  w = -log((1.0 - x) * (1.0 + x));
7952 
7953  if (w < 6.250000) {
7954  w = w - 3.125000;
7955  p = -3.6444120640178196996e-21;
7956  p = -1.685059138182016589e-19 + p * w;
7957  p = 1.2858480715256400167e-18 + p * w;
7958  p = 1.115787767802518096e-17 + p * w;
7959  p = -1.333171662854620906e-16 + p * w;
7960  p = 2.0972767875968561637e-17 + p * w;
7961  p = 6.6376381343583238325e-15 + p * w;
7962  p = -4.0545662729752068639e-14 + p * w;
7963  p = -8.1519341976054721522e-14 + p * w;
7964  p = 2.6335093153082322977e-12 + p * w;
7965  p = -1.2975133253453532498e-11 + p * w;
7966  p = -5.4154120542946279317e-11 + p * w;
7967  p = 1.051212273321532285e-09 + p * w;
7968  p = -4.1126339803469836976e-09 + p * w;
7969  p = -2.9070369957882005086e-08 + p * w;
7970  p = 4.2347877827932403518e-07 + p * w;
7971  p = -1.3654692000834678645e-06 + p * w;
7972  p = -1.3882523362786468719e-05 + p * w;
7973  p = 0.0001867342080340571352 + p * w;
7974  p = -0.00074070253416626697512 + p * w;
7975  p = -0.0060336708714301490533 + p * w;
7976  p = 0.24015818242558961693 + p * w;
7977  p = 1.6536545626831027356 + p * w;
7978  } else if (w < 16.000000) {
7979  w = sqrt(w) - 3.250000;
7980  p = 2.2137376921775787049e-09;
7981  p = 9.0756561938885390979e-08 + p * w;
7982  p = -2.7517406297064545428e-07 + p * w;
7983  p = 1.8239629214389227755e-08 + p * w;
7984  p = 1.5027403968909827627e-06 + p * w;
7985  p = -4.013867526981545969e-06 + p * w;
7986  p = 2.9234449089955446044e-06 + p * w;
7987  p = 1.2475304481671778723e-05 + p * w;
7988  p = -4.7318229009055733981e-05 + p * w;
7989  p = 6.8284851459573175448e-05 + p * w;
7990  p = 2.4031110387097893999e-05 + p * w;
7991  p = -0.0003550375203628474796 + p * w;
7992  p = 0.00095328937973738049703 + p * w;
7993  p = -0.0016882755560235047313 + p * w;
7994  p = 0.0024914420961078508066 + p * w;
7995  p = -0.0037512085075692412107 + p * w;
7996  p = 0.005370914553590063617 + p * w;
7997  p = 1.0052589676941592334 + p * w;
7998  p = 3.0838856104922207635 + p * w;
7999  } else {
8000  w = sqrt(w) - 5.000000;
8001  p = -2.7109920616438573243e-11;
8002  p = -2.5556418169965252055e-10 + p * w;
8003  p = 1.5076572693500548083e-09 + p * w;
8004  p = -3.7894654401267369937e-09 + p * w;
8005  p = 7.6157012080783393804e-09 + p * w;
8006  p = -1.4960026627149240478e-08 + p * w;
8007  p = 2.9147953450901080826e-08 + p * w;
8008  p = -6.7711997758452339498e-08 + p * w;
8009  p = 2.2900482228026654717e-07 + p * w;
8010  p = -9.9298272942317002539e-07 + p * w;
8011  p = 4.5260625972231537039e-06 + p * w;
8012  p = -1.9681778105531670567e-05 + p * w;
8013  p = 7.5995277030017761139e-05 + p * w;
8014  p = -0.00021503011930044477347 + p * w;
8015  p = -0.00013871931833623122026 + p * w;
8016  p = 1.0103004648645343977 + p * w;
8017  p = 4.8499064014085844221 + p * w;
8018  }
8019  return p * x;
8020  }
8021 
8022  double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
8023  auto m = Catch::Benchmark::Detail::mean(first, last);
8024  double variance = std::accumulate(first,
8025  last,
8026  0.,
8027  [m](double a, double b) {
8028  double diff = b - m;
8029  return a + diff * diff;
8030  })
8031  / (last - first);
8032  return std::sqrt(variance);
8033  }
8034 
8035 } // namespace
8036 
8037 namespace Catch {
8038  namespace Benchmark {
8039  namespace Detail {
8040  double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
8041  auto count = last - first;
8042  double idx = (count - 1) * k / static_cast<double>(q);
8043  int j = static_cast<int>(idx);
8044  double g = idx - j;
8045  std::nth_element(first, first + j, last);
8046  auto xj = first[j];
8047  if (g == 0)
8048  return xj;
8049 
8050  auto xj1 = *std::min_element(first + (j + 1), last);
8051  return xj + g * (xj1 - xj);
8052  }
8053 
8054  double erfc_inv(double x) {
8055  return erf_inv(1.0 - x);
8056  }
8057 
8058  double normal_quantile(double p) {
8059  static const double ROOT_TWO = std::sqrt(2.0);
8060 
8061  double result = 0.0;
8062  assert(p >= 0 && p <= 1);
8063  if (p < 0 || p > 1) {
8064  return result;
8065  }
8066 
8067  result = -erfc_inv(2.0 * p);
8068  // result *= normal distribution standard deviation (1.0) * sqrt(2)
8069  result *= /*sd * */ ROOT_TWO;
8070  // result += normal disttribution mean (0)
8071  return result;
8072  }
8073 
8074  double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
8075  double sb = stddev.point;
8076  double mn = mean.point / n;
8077  double mg_min = mn / 2.;
8078  double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
8079  double sg2 = sg * sg;
8080  double sb2 = sb * sb;
8081 
8082  auto c_max = [n, mn, sb2, sg2](double x) -> double {
8083  double k = mn - x;
8084  double d = k * k;
8085  double nd = n * d;
8086  double k0 = -n * nd;
8087  double k1 = sb2 - n * sg2 + nd;
8088  double det = k1 * k1 - 4 * sg2 * k0;
8089  return (int)(-2. * k0 / (k1 + std::sqrt(det)));
8090  };
8091 
8092  auto var_out = [n, sb2, sg2](double c) {
8093  double nc = n - c;
8094  return (nc / n) * (sb2 - nc * sg2);
8095  };
8096 
8097  return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
8098  }
8099 
8100  bootstrap_analysis
8101  analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
8102  CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
8103  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
8104  static std::random_device entropy;
8105  CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
8106 
8107  auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
8108 
8109  auto mean = &Detail::mean<std::vector<double>::iterator>;
8110  auto stddev = &standard_deviation;
8111 
8112 #if defined(CATCH_CONFIG_USE_ASYNC)
8113  auto Estimate = [=](double (*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
8114  auto seed = entropy();
8115  return std::async(std::launch::async, [=] {
8116  std::mt19937 rng(seed);
8117  auto resampled = resample(rng, n_resamples, first, last, f);
8118  return bootstrap(confidence_level, first, last, resampled, f);
8119  });
8120  };
8121 
8122  auto mean_future = Estimate(mean);
8123  auto stddev_future = Estimate(stddev);
8124 
8125  auto mean_estimate = mean_future.get();
8126  auto stddev_estimate = stddev_future.get();
8127 #else
8128  auto Estimate = [=](double (*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
8129  auto seed = entropy();
8130  std::mt19937 rng(seed);
8131  auto resampled = resample(rng, n_resamples, first, last, f);
8132  return bootstrap(confidence_level, first, last, resampled, f);
8133  };
8134 
8135  auto mean_estimate = Estimate(mean);
8136  auto stddev_estimate = Estimate(stddev);
8137 #endif // CATCH_USE_ASYNC
8138 
8139  double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
8140 
8141  return {mean_estimate, stddev_estimate, outlier_variance};
8142  }
8143  } // namespace Detail
8144  } // namespace Benchmark
8145 } // namespace Catch
8146 
8147 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING \
8148  // end catch_stats.cpp
8149 // start catch_approx.cpp
8150 
8151 #include <cmath>
8152 #include <limits>
8153 
8154 namespace {
8155  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
8156  // But without the subtraction to allow for INFINITY in comparison
8157  bool marginComparison(double lhs, double rhs, double margin) {
8158  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
8159  }
8160 
8161 } // namespace
8162 
8163 namespace Catch {
8164  namespace Detail {
8165  Approx::Approx(double value)
8166  : m_epsilon(std::numeric_limits<float>::epsilon() * 100)
8167  , m_margin(0.0)
8168  , m_scale(0.0)
8169  , m_value(value) {
8170  }
8171 
8172  Approx Approx::custom() {
8173  return Approx(0);
8174  }
8175 
8176  Approx Approx::operator-() const {
8177  auto temp(*this);
8178  temp.m_value = -temp.m_value;
8179  return temp;
8180  }
8181 
8182  std::string Approx::toString() const {
8184  rss << "Approx( " << ::Catch::Detail::stringify(m_value) << " )";
8185  return rss.str();
8186  }
8187 
8188  bool Approx::equalityComparisonImpl(const double other) const {
8189  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
8190  // Thanks to Richard Harris for his help refining the scaled margin value
8191  return marginComparison(m_value, other, m_margin)
8192  || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value) ? 0 : m_value)));
8193  }
8194 
8195  void Approx::setMargin(double newMargin) {
8196  CATCH_ENFORCE(newMargin >= 0, "Invalid Approx::margin: " << newMargin << '.' << " Approx::Margin has to be non-negative.");
8197  m_margin = newMargin;
8198  }
8199 
8200  void Approx::setEpsilon(double newEpsilon) {
8201  CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
8202  "Invalid Approx::epsilon: " << newEpsilon << '.' << " Approx::epsilon has to be in [0, 1]");
8203  m_epsilon = newEpsilon;
8204  }
8205 
8206  } // end namespace Detail
8207 
8208  namespace literals {
8209  Detail::Approx operator"" _a(long double val) {
8210  return Detail::Approx(val);
8211  }
8212  Detail::Approx operator"" _a(unsigned long long val) {
8213  return Detail::Approx(val);
8214  }
8215  } // end namespace literals
8216 
8218  return value.toString();
8219  }
8220 
8221 } // end namespace Catch
8222 // end catch_approx.cpp
8223 // start catch_assertionhandler.cpp
8224 
8225 // start catch_debugger.h
8226 
8227 namespace Catch {
8228  bool isDebuggerActive();
8229 }
8230 
8231 #ifdef CATCH_PLATFORM_MAC
8232 
8233 #if defined(__i386__) || defined(__x86_64__)
8234 #define CATCH_TRAP() __asm__("int $3\n" \
8235  : \
8236  :) /* NOLINT */
8237 #elif defined(__aarch64__)
8238 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
8239 #endif
8240 
8241 #elif defined(CATCH_PLATFORM_IPHONE)
8242 
8243 // use inline assembler
8244 #if defined(__i386__) || defined(__x86_64__)
8245 #define CATCH_TRAP() __asm__("int $3")
8246 #elif defined(__aarch64__)
8247 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
8248 #elif defined(__arm__) && !defined(__thumb__)
8249 #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
8250 #elif defined(__arm__) && defined(__thumb__)
8251 #define CATCH_TRAP() __asm__(".inst 0xde01")
8252 #endif
8253 
8254 #elif defined(CATCH_PLATFORM_LINUX)
8255 // If we can use inline assembler, do it because this allows us to break
8256 // directly at the location of the failing check instead of breaking inside
8257 // raise() called from it, i.e. one stack frame below.
8258 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
8259 #define CATCH_TRAP() asm volatile("int $3") /* NOLINT */
8260 #else // Fall back to the generic way.
8261 #include <signal.h>
8262 
8263 #define CATCH_TRAP() raise(SIGTRAP)
8264 #endif
8265 #elif defined(_MSC_VER)
8266 #define CATCH_TRAP() __debugbreak()
8267 #elif defined(__MINGW32__)
8268 extern "C" __declspec(dllimport) void __stdcall DebugBreak();
8269 #define CATCH_TRAP() DebugBreak()
8270 #endif
8271 
8272 #ifndef CATCH_BREAK_INTO_DEBUGGER
8273 #ifdef CATCH_TRAP
8274 #define CATCH_BREAK_INTO_DEBUGGER() \
8275  [] { \
8276  if (Catch::isDebuggerActive()) { \
8277  CATCH_TRAP(); \
8278  } \
8279  }()
8280 #else
8281 #define CATCH_BREAK_INTO_DEBUGGER() [] {}()
8282 #endif
8283 #endif
8284 
8285 // end catch_debugger.h
8286 // start catch_run_context.h
8287 
8288 // start catch_fatal_condition.h
8289 
8290 #include <cassert>
8291 
8292 namespace Catch {
8293  // Wrapper for platform-specific fatal error (signals/SEH) handlers
8294  //
8295  // Tries to be cooperative with other handlers, and not step over
8296  // other handlers. This means that unknown structured exceptions
8297  // are passed on, previous signal handlers are called, and so on.
8298  //
8299  // Can only be instantiated once, and assumes that once a signal
8300  // is caught, the binary will end up terminating. Thus, there
8301  class FatalConditionHandler {
8302  bool m_started = false;
8303 
8304  // Install/disengage implementation for specific platform.
8305  // Should be if-defed to work on current platform, can assume
8306  // engage-disengage 1:1 pairing.
8307  void engage_platform();
8308  void disengage_platform();
8309 
8310  public:
8311  // Should also have platform-specific implementations as needed
8312  FatalConditionHandler();
8313  ~FatalConditionHandler();
8314 
8315  void engage() {
8316  assert(!m_started && "Handler cannot be installed twice.");
8317  m_started = true;
8318  engage_platform();
8319  }
8320 
8321  void disengage() {
8322  assert(m_started && "Handler cannot be uninstalled without being installed first");
8323  m_started = false;
8324  disengage_platform();
8325  }
8326  };
8327 
8329  class FatalConditionHandlerGuard {
8330  FatalConditionHandler *m_handler;
8331 
8332  public:
8333  FatalConditionHandlerGuard(FatalConditionHandler *handler)
8334  : m_handler(handler) {
8335  m_handler->engage();
8336  }
8337  ~FatalConditionHandlerGuard() { m_handler->disengage(); }
8338  };
8339 
8340 } // end namespace Catch
8341 
8342 // end catch_fatal_condition.h
8343 #include <string>
8344 
8345 namespace Catch {
8346  struct IMutableContext;
8347 
8349 
8350  class RunContext : public IResultCapture, public IRunner {
8351  public:
8352  RunContext(RunContext const &) = delete;
8353  RunContext &operator=(RunContext const &) = delete;
8354 
8355  explicit RunContext(IConfigPtr const &_config, IStreamingReporterPtr &&reporter);
8356 
8357  ~RunContext() override;
8358 
8359  void testGroupStarting(std::string const &testSpec, std::size_t groupIndex, std::size_t groupsCount);
8360  void testGroupEnded(std::string const &testSpec, Totals const &totals, std::size_t groupIndex, std::size_t groupsCount);
8361 
8362  Totals runTest(TestCase const &testCase);
8363 
8364  IConfigPtr config() const;
8365  IStreamingReporter &reporter() const;
8366 
8367  public: // IResultCapture
8368  // Assertion handlers
8369  void handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction) override;
8370  void handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, AssertionReaction &reaction) override;
8371  void handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction) override;
8372  void handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, AssertionReaction &reaction) override;
8373  void handleIncomplete(AssertionInfo const &info) override;
8374  void handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction) override;
8375 
8376  bool sectionStarted(SectionInfo const &sectionInfo, Counts &assertions) override;
8377 
8378  void sectionEnded(SectionEndInfo const &endInfo) override;
8379  void sectionEndedEarly(SectionEndInfo const &endInfo) override;
8380 
8381  auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker & override;
8382 
8383 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
8384  void benchmarkPreparing(std::string const &name) override;
8385  void benchmarkStarting(BenchmarkInfo const &info) override;
8386  void benchmarkEnded(BenchmarkStats<> const &stats) override;
8387  void benchmarkFailed(std::string const &error) override;
8388 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
8389 
8390  void pushScopedMessage(MessageInfo const &message) override;
8391  void popScopedMessage(MessageInfo const &message) override;
8392 
8393  void emplaceUnscopedMessage(MessageBuilder const &builder) override;
8394 
8395  std::string getCurrentTestName() const override;
8396 
8397  const AssertionResult *getLastResult() const override;
8398 
8399  void exceptionEarlyReported() override;
8400 
8401  void handleFatalErrorCondition(StringRef message) override;
8402 
8403  bool lastAssertionPassed() override;
8404 
8405  void assertionPassed() override;
8406 
8407  public:
8408  // !TBD We need to do this another way!
8409  bool aborting() const final;
8410 
8411  private:
8412  void runCurrentTest(std::string &redirectedCout, std::string &redirectedCerr);
8413  void invokeActiveTestCase();
8414 
8415  void resetAssertionInfo();
8416  bool testForMissingAssertions(Counts &assertions);
8417 
8418  void assertionEnded(AssertionResult const &result);
8419  void reportExpr(AssertionInfo const &info, ResultWas::OfType resultType, ITransientExpression const *expr, bool negated);
8420 
8421  void populateReaction(AssertionReaction &reaction);
8422 
8423  private:
8424  void handleUnfinishedSections();
8425 
8426  TestRunInfo m_runInfo;
8427  IMutableContext &m_context;
8428  TestCase const *m_activeTestCase = nullptr;
8429  ITracker *m_testCaseTracker = nullptr;
8430  Option<AssertionResult> m_lastResult;
8431 
8432  IConfigPtr m_config;
8433  Totals m_totals;
8434  IStreamingReporterPtr m_reporter;
8435  std::vector<MessageInfo> m_messages;
8436  std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
8437  AssertionInfo m_lastAssertionInfo;
8438  std::vector<SectionEndInfo> m_unfinishedSections;
8439  std::vector<ITracker *> m_activeSections;
8440  TrackerContext m_trackerContext;
8441  FatalConditionHandler m_fatalConditionhandler;
8442  bool m_lastAssertionPassed = false;
8443  bool m_shouldReportUnexpected = true;
8444  bool m_includeSuccessfulResults;
8445  };
8446 
8447  void seedRng(IConfig const &config);
8448  unsigned int rngSeed();
8449 } // end namespace Catch
8450 
8451 // end catch_run_context.h
8452 namespace Catch {
8453  namespace {
8454  auto operator<<(std::ostream &os, ITransientExpression const &expr) -> std::ostream & {
8455  expr.streamReconstructedExpression(os);
8456  return os;
8457  }
8458  } // namespace
8459 
8460  LazyExpression::LazyExpression(bool isNegated)
8461  : m_isNegated(isNegated) {
8462  }
8463 
8464  LazyExpression::LazyExpression(LazyExpression const &other)
8465  : m_isNegated(other.m_isNegated) {
8466  }
8467 
8468  LazyExpression::operator bool() const {
8469  return m_transientExpression != nullptr;
8470  }
8471 
8472  auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream & {
8473  if (lazyExpr.m_isNegated)
8474  os << "!";
8475 
8476  if (lazyExpr) {
8477  if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression())
8478  os << "(" << *lazyExpr.m_transientExpression << ")";
8479  else
8480  os << *lazyExpr.m_transientExpression;
8481  } else {
8482  os << "{** error - unchecked empty expression requested **}";
8483  }
8484  return os;
8485  }
8486 
8487  AssertionHandler::AssertionHandler(StringRef const &macroName,
8488  SourceLineInfo const &lineInfo,
8489  StringRef capturedExpression,
8490  ResultDisposition::Flags resultDisposition)
8491  : m_assertionInfo{macroName, lineInfo, capturedExpression, resultDisposition}
8492  , m_resultCapture(getResultCapture()) {
8493  }
8494 
8495  void AssertionHandler::handleExpr(ITransientExpression const &expr) {
8496  m_resultCapture.handleExpr(m_assertionInfo, expr, m_reaction);
8497  }
8498  void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const &message) {
8499  m_resultCapture.handleMessage(m_assertionInfo, resultType, message, m_reaction);
8500  }
8501 
8502  auto AssertionHandler::allowThrows() const -> bool {
8503  return getCurrentContext().getConfig()->allowThrows();
8504  }
8505 
8506  void AssertionHandler::complete() {
8507  setCompleted();
8508  if (m_reaction.shouldDebugBreak) {
8509  // If you find your debugger stopping you here then go one level up on the
8510  // call-stack for the code that caused it (typically a failed assertion)
8511 
8512  // (To go back to the test and change execution, jump over the throw, next)
8513  CATCH_BREAK_INTO_DEBUGGER();
8514  }
8515  if (m_reaction.shouldThrow) {
8516 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8518 #else
8519  CATCH_ERROR("Test failure requires aborting test!");
8520 #endif
8521  }
8522  }
8523  void AssertionHandler::setCompleted() {
8524  m_completed = true;
8525  }
8526 
8527  void AssertionHandler::handleUnexpectedInflightException() {
8528  m_resultCapture.handleUnexpectedInflightException(m_assertionInfo, Catch::translateActiveException(), m_reaction);
8529  }
8530 
8531  void AssertionHandler::handleExceptionThrownAsExpected() {
8532  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8533  }
8534  void AssertionHandler::handleExceptionNotThrownAsExpected() {
8535  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8536  }
8537 
8538  void AssertionHandler::handleUnexpectedExceptionNotThrown() {
8539  m_resultCapture.handleUnexpectedExceptionNotThrown(m_assertionInfo, m_reaction);
8540  }
8541 
8542  void AssertionHandler::handleThrowingCallSkipped() {
8543  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
8544  }
8545 
8546  // This is the overload that takes a string and infers the Equals matcher from it
8547  // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
8548  void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef const &matcherString) {
8549  handleExceptionMatchExpr(handler, Matchers::Equals(str), matcherString);
8550  }
8551 
8552 } // namespace Catch
8553 // end catch_assertionhandler.cpp
8554 // start catch_assertionresult.cpp
8555 
8556 namespace Catch {
8557  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const &_lazyExpression)
8558  : lazyExpression(_lazyExpression)
8559  , resultType(_resultType) {
8560  }
8561 
8562  std::string AssertionResultData::reconstructExpression() const {
8563  if (reconstructedExpression.empty()) {
8564  if (lazyExpression) {
8566  rss << lazyExpression;
8567  reconstructedExpression = rss.str();
8568  }
8569  }
8570  return reconstructedExpression;
8571  }
8572 
8573  AssertionResult::AssertionResult(AssertionInfo const &info, AssertionResultData const &data)
8574  : m_info(info)
8575  , m_resultData(data) {
8576  }
8577 
8578  // Result was a success
8579  bool AssertionResult::succeeded() const {
8580  return Catch::isOk(m_resultData.resultType);
8581  }
8582 
8583  // Result was a success, or failure is suppressed
8584  bool AssertionResult::isOk() const {
8585  return Catch::isOk(m_resultData.resultType) || shouldSuppressFailure(m_info.resultDisposition);
8586  }
8587 
8588  ResultWas::OfType AssertionResult::getResultType() const {
8589  return m_resultData.resultType;
8590  }
8591 
8592  bool AssertionResult::hasExpression() const {
8593  return !m_info.capturedExpression.empty();
8594  }
8595 
8596  bool AssertionResult::hasMessage() const {
8597  return !m_resultData.message.empty();
8598  }
8599 
8600  std::string AssertionResult::getExpression() const {
8601  // Possibly overallocating by 3 characters should be basically free
8602  std::string expr;
8603  expr.reserve(m_info.capturedExpression.size() + 3);
8604  if (isFalseTest(m_info.resultDisposition)) {
8605  expr += "!(";
8606  }
8607  expr += m_info.capturedExpression;
8608  if (isFalseTest(m_info.resultDisposition)) {
8609  expr += ')';
8610  }
8611  return expr;
8612  }
8613 
8614  std::string AssertionResult::getExpressionInMacro() const {
8615  std::string expr;
8616  if (m_info.macroName.empty())
8617  expr = static_cast<std::string>(m_info.capturedExpression);
8618  else {
8619  expr.reserve(m_info.macroName.size() + m_info.capturedExpression.size() + 4);
8620  expr += m_info.macroName;
8621  expr += "( ";
8622  expr += m_info.capturedExpression;
8623  expr += " )";
8624  }
8625  return expr;
8626  }
8627 
8628  bool AssertionResult::hasExpandedExpression() const {
8629  return hasExpression() && getExpandedExpression() != getExpression();
8630  }
8631 
8632  std::string AssertionResult::getExpandedExpression() const {
8633  std::string expr = m_resultData.reconstructExpression();
8634  return expr.empty() ? getExpression() : expr;
8635  }
8636 
8637  std::string AssertionResult::getMessage() const {
8638  return m_resultData.message;
8639  }
8640  SourceLineInfo AssertionResult::getSourceInfo() const {
8641  return m_info.lineInfo;
8642  }
8643 
8644  StringRef AssertionResult::getTestMacroName() const {
8645  return m_info.macroName;
8646  }
8647 
8648 } // end namespace Catch
8649 // end catch_assertionresult.cpp
8650 // start catch_capture_matchers.cpp
8651 
8652 namespace Catch {
8654 
8655  // This is the general overload that takes a any string matcher
8656  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
8657  // the Equals matcher (so the header does not mention matchers)
8658  void handleExceptionMatchExpr(AssertionHandler &handler, StringMatcher const &matcher, StringRef const &matcherString) {
8659  std::string exceptionMessage = Catch::translateActiveException();
8660  MatchExpr<std::string, StringMatcher const &> expr(exceptionMessage, matcher, matcherString);
8661  handler.handleExpr(expr);
8662  }
8663 
8664 } // namespace Catch
8665 // end catch_capture_matchers.cpp
8666 // start catch_commandline.cpp
8667 
8668 // start catch_commandline.h
8669 
8670 // start catch_clara.h
8671 
8672 // Use Catch's value for console width (store Clara's off to the side, if present)
8673 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
8674 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8675 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8676 #endif
8677 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - 1
8678 
8679 #ifdef __clang__
8680 #pragma clang diagnostic push
8681 #pragma clang diagnostic ignored "-Wweak-vtables"
8682 #pragma clang diagnostic ignored "-Wexit-time-destructors"
8683 #pragma clang diagnostic ignored "-Wshadow"
8684 #endif
8685 
8686 // start clara.hpp
8687 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
8688 //
8689 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8690 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8691 //
8692 // See https://github.com/philsquared/Clara for more details
8693 
8694 // Clara v1.1.5
8695 
8696 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8697 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
8698 #endif
8699 
8700 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8701 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
8702 #endif
8703 
8704 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
8705 #ifdef __has_include
8706 #if __has_include(<optional>) && __cplusplus >= 201703L
8707 #include <optional>
8708 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
8709 #endif
8710 #endif
8711 #endif
8712 
8713 // ----------- #included from clara_textflow.hpp -----------
8714 
8715 // TextFlowCpp
8716 //
8717 // A single-header library for wrapping and laying out basic text, by Phil Nash
8718 //
8719 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8720 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8721 //
8722 // This project is hosted at https://github.com/philsquared/textflowcpp
8723 
8724 #include <cassert>
8725 #include <ostream>
8726 #include <sstream>
8727 #include <vector>
8728 
8729 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
8730 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
8731 #endif
8732 
8733 namespace Catch {
8734  namespace clara {
8735  namespace TextFlow {
8736  inline auto isWhitespace(char c) -> bool {
8737  static std::string chars = " \t\n\r";
8738  return chars.find(c) != std::string::npos;
8739  }
8740  inline auto isBreakableBefore(char c) -> bool {
8741  static std::string chars = "[({<|";
8742  return chars.find(c) != std::string::npos;
8743  }
8744  inline auto isBreakableAfter(char c) -> bool {
8745  static std::string chars = "])}>.,:;*+-=&/\\";
8746  return chars.find(c) != std::string::npos;
8747  }
8748 
8749  class Columns;
8750 
8751  class Column {
8752  std::vector<std::string> m_strings;
8753  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
8754  size_t m_indent = 0;
8755  size_t m_initialIndent = std::string::npos;
8756 
8757  public:
8758  class iterator {
8759  friend Column;
8760 
8761  Column const &m_column;
8762  size_t m_stringIndex = 0;
8763  size_t m_pos = 0;
8764 
8765  size_t m_len = 0;
8766  size_t m_end = 0;
8767  bool m_suffix = false;
8768 
8769  iterator(Column const &column, size_t stringIndex)
8770  : m_column(column)
8771  , m_stringIndex(stringIndex) {
8772  }
8773 
8774  auto line() const -> std::string const & { return m_column.m_strings[m_stringIndex]; }
8775 
8776  auto isBoundary(size_t at) const -> bool {
8777  assert(at > 0);
8778  assert(at <= line().size());
8779 
8780  return at == line().size() || (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) || isBreakableBefore(line()[at])
8781  || isBreakableAfter(line()[at - 1]);
8782  }
8783 
8784  void calcLength() {
8785  assert(m_stringIndex < m_column.m_strings.size());
8786 
8787  m_suffix = false;
8788  auto width = m_column.m_width - indent();
8789  m_end = m_pos;
8790  if (line()[m_pos] == '\n') {
8791  ++m_end;
8792  }
8793  while (m_end < line().size() && line()[m_end] != '\n')
8794  ++m_end;
8795 
8796  if (m_end < m_pos + width) {
8797  m_len = m_end - m_pos;
8798  } else {
8799  size_t len = width;
8800  while (len > 0 && !isBoundary(m_pos + len))
8801  --len;
8802  while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
8803  --len;
8804 
8805  if (len > 0) {
8806  m_len = len;
8807  } else {
8808  m_suffix = true;
8809  m_len = width - 1;
8810  }
8811  }
8812  }
8813 
8814  auto indent() const -> size_t {
8815  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
8816  return initial == std::string::npos ? m_column.m_indent : initial;
8817  }
8818 
8819  auto addIndentAndSuffix(std::string const &plain) const -> std::string {
8820  return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
8821  }
8822 
8823  public:
8824  using difference_type = std::ptrdiff_t;
8825  using value_type = std::string;
8826  using pointer = value_type *;
8827  using reference = value_type &;
8828  using iterator_category = std::forward_iterator_tag;
8829 
8830  explicit iterator(Column const &column)
8831  : m_column(column) {
8832  assert(m_column.m_width > m_column.m_indent);
8833  assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
8834  calcLength();
8835  if (m_len == 0)
8836  m_stringIndex++; // Empty string
8837  }
8838 
8839  auto operator*() const -> std::string {
8840  assert(m_stringIndex < m_column.m_strings.size());
8841  assert(m_pos <= m_end);
8842  return addIndentAndSuffix(line().substr(m_pos, m_len));
8843  }
8844 
8845  auto operator++() -> iterator & {
8846  m_pos += m_len;
8847  if (m_pos < line().size() && line()[m_pos] == '\n')
8848  m_pos += 1;
8849  else
8850  while (m_pos < line().size() && isWhitespace(line()[m_pos]))
8851  ++m_pos;
8852 
8853  if (m_pos == line().size()) {
8854  m_pos = 0;
8855  ++m_stringIndex;
8856  }
8857  if (m_stringIndex < m_column.m_strings.size())
8858  calcLength();
8859  return *this;
8860  }
8861  auto operator++(int) -> iterator {
8862  iterator prev(*this);
8863  operator++();
8864  return prev;
8865  }
8866 
8867  auto operator==(iterator const &other) const -> bool {
8868  return m_pos == other.m_pos && m_stringIndex == other.m_stringIndex && &m_column == &other.m_column;
8869  }
8870  auto operator!=(iterator const &other) const -> bool { return !operator==(other); }
8871  };
8872  using const_iterator = iterator;
8873 
8874  explicit Column(std::string const &text) { m_strings.push_back(text); }
8875 
8876  auto width(size_t newWidth) -> Column & {
8877  assert(newWidth > 0);
8878  m_width = newWidth;
8879  return *this;
8880  }
8881  auto indent(size_t newIndent) -> Column & {
8882  m_indent = newIndent;
8883  return *this;
8884  }
8885  auto initialIndent(size_t newIndent) -> Column & {
8886  m_initialIndent = newIndent;
8887  return *this;
8888  }
8889 
8890  auto width() const -> size_t { return m_width; }
8891  auto begin() const -> iterator { return iterator(*this); }
8892  auto end() const -> iterator { return {*this, m_strings.size()}; }
8893 
8894  inline friend std::ostream &operator<<(std::ostream &os, Column const &col) {
8895  bool first = true;
8896  for (auto line : col) {
8897  if (first)
8898  first = false;
8899  else
8900  os << "\n";
8901  os << line;
8902  }
8903  return os;
8904  }
8905 
8906  auto operator+(Column const &other) -> Columns;
8907 
8908  auto toString() const -> std::string {
8909  std::ostringstream oss;
8910  oss << *this;
8911  return oss.str();
8912  }
8913  };
8914 
8915  class Spacer : public Column {
8916  public:
8917  explicit Spacer(size_t spaceWidth)
8918  : Column("") {
8919  width(spaceWidth);
8920  }
8921  };
8922 
8923  class Columns {
8924  std::vector<Column> m_columns;
8925 
8926  public:
8927  class iterator {
8928  friend Columns;
8929  struct EndTag {
8930  };
8931 
8932  std::vector<Column> const &m_columns;
8933  std::vector<Column::iterator> m_iterators;
8934  size_t m_activeIterators;
8935 
8936  iterator(Columns const &columns, EndTag)
8937  : m_columns(columns.m_columns)
8938  , m_activeIterators(0) {
8939  m_iterators.reserve(m_columns.size());
8940 
8941  for (auto const &col : m_columns)
8942  m_iterators.push_back(col.end());
8943  }
8944 
8945  public:
8946  using difference_type = std::ptrdiff_t;
8947  using value_type = std::string;
8948  using pointer = value_type *;
8949  using reference = value_type &;
8950  using iterator_category = std::forward_iterator_tag;
8951 
8952  explicit iterator(Columns const &columns)
8953  : m_columns(columns.m_columns)
8954  , m_activeIterators(m_columns.size()) {
8955  m_iterators.reserve(m_columns.size());
8956 
8957  for (auto const &col : m_columns)
8958  m_iterators.push_back(col.begin());
8959  }
8960 
8961  auto operator==(iterator const &other) const -> bool { return m_iterators == other.m_iterators; }
8962  auto operator!=(iterator const &other) const -> bool { return m_iterators != other.m_iterators; }
8963  auto operator*() const -> std::string {
8964  std::string row, padding;
8965 
8966  for (size_t i = 0; i < m_columns.size(); ++i) {
8967  auto width = m_columns[i].width();
8968  if (m_iterators[i] != m_columns[i].end()) {
8969  std::string col = *m_iterators[i];
8970  row += padding + col;
8971  if (col.size() < width)
8972  padding = std::string(width - col.size(), ' ');
8973  else
8974  padding = "";
8975  } else {
8976  padding += std::string(width, ' ');
8977  }
8978  }
8979  return row;
8980  }
8981  auto operator++() -> iterator & {
8982  for (size_t i = 0; i < m_columns.size(); ++i) {
8983  if (m_iterators[i] != m_columns[i].end())
8984  ++m_iterators[i];
8985  }
8986  return *this;
8987  }
8988  auto operator++(int) -> iterator {
8989  iterator prev(*this);
8990  operator++();
8991  return prev;
8992  }
8993  };
8994  using const_iterator = iterator;
8995 
8996  auto begin() const -> iterator { return iterator(*this); }
8997  auto end() const -> iterator { return {*this, iterator::EndTag()}; }
8998 
8999  auto operator+=(Column const &col) -> Columns & {
9000  m_columns.push_back(col);
9001  return *this;
9002  }
9003  auto operator+(Column const &col) -> Columns {
9004  Columns combined = *this;
9005  combined += col;
9006  return combined;
9007  }
9008 
9009  inline friend std::ostream &operator<<(std::ostream &os, Columns const &cols) {
9010  bool first = true;
9011  for (auto line : cols) {
9012  if (first)
9013  first = false;
9014  else
9015  os << "\n";
9016  os << line;
9017  }
9018  return os;
9019  }
9020 
9021  auto toString() const -> std::string {
9022  std::ostringstream oss;
9023  oss << *this;
9024  return oss.str();
9025  }
9026  };
9027 
9028  inline auto Column::operator+(Column const &other) -> Columns {
9029  Columns cols;
9030  cols += *this;
9031  cols += other;
9032  return cols;
9033  }
9034  } // namespace TextFlow
9035  } // namespace clara
9036 } // namespace Catch
9037 
9038 // ----------- end of #include from clara_textflow.hpp -----------
9039 // ........... back in clara.hpp
9040 
9041 #include <algorithm>
9042 #include <cctype>
9043 #include <memory>
9044 #include <set>
9045 #include <string>
9046 
9047 #if !defined(CATCH_PLATFORM_WINDOWS) && (defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER))
9048 #define CATCH_PLATFORM_WINDOWS
9049 #endif
9050 
9051 namespace Catch {
9052  namespace clara {
9053  namespace detail {
9054  // Traits for extracting arg and return type of lambdas (for single argument lambdas)
9055  template<typename L>
9056  struct UnaryLambdaTraits : UnaryLambdaTraits<decltype(&L::operator())> {
9057  };
9058 
9059  template<typename ClassT, typename ReturnT, typename... Args>
9060  struct UnaryLambdaTraits<ReturnT (ClassT::*)(Args...) const> {
9061  static const bool isValid = false;
9062  };
9063 
9064  template<typename ClassT, typename ReturnT, typename ArgT>
9065  struct UnaryLambdaTraits<ReturnT (ClassT::*)(ArgT) const> {
9066  static const bool isValid = true;
9067  using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
9068  using ReturnType = ReturnT;
9069  };
9070 
9071  class TokenStream;
9072 
9073  // Transport for raw args (copied from main args, or supplied via init list for testing)
9074  class Args {
9075  friend TokenStream;
9076  std::string m_exeName;
9077  std::vector<std::string> m_args;
9078 
9079  public:
9080  Args(int argc, char const *const *argv)
9081  : m_exeName(argv[0])
9082  , m_args(argv + 1, argv + argc) {
9083  }
9084 
9085  Args(std::initializer_list<std::string> args)
9086  : m_exeName(*args.begin())
9087  , m_args(args.begin() + 1, args.end()) {
9088  }
9089 
9090  auto exeName() const -> std::string { return m_exeName; }
9091  };
9092 
9093  // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
9094  // may encode an option + its argument if the : or = form is used
9095  enum class TokenType {
9096  Option,
9097  Argument
9098  };
9099  struct Token {
9100  TokenType type;
9101  std::string token;
9102  };
9103 
9104  inline auto isOptPrefix(char c) -> bool {
9105  return c == '-'
9106 #ifdef CATCH_PLATFORM_WINDOWS
9107  || c == '/'
9108 #endif
9109  ;
9110  }
9111 
9112  // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
9113  class TokenStream {
9114  using Iterator = std::vector<std::string>::const_iterator;
9115  Iterator it;
9116  Iterator itEnd;
9117  std::vector<Token> m_tokenBuffer;
9118 
9119  void loadBuffer() {
9120  m_tokenBuffer.resize(0);
9121 
9122  // Skip any empty strings
9123  while (it != itEnd && it->empty())
9124  ++it;
9125 
9126  if (it != itEnd) {
9127  auto const &next = *it;
9128  if (isOptPrefix(next[0])) {
9129  auto delimiterPos = next.find_first_of(" :=");
9130  if (delimiterPos != std::string::npos) {
9131  m_tokenBuffer.push_back({TokenType::Option, next.substr(0, delimiterPos)});
9132  m_tokenBuffer.push_back({TokenType::Argument, next.substr(delimiterPos + 1)});
9133  } else {
9134  if (next[1] != '-' && next.size() > 2) {
9135  std::string opt = "- ";
9136  for (size_t i = 1; i < next.size(); ++i) {
9137  opt[1] = next[i];
9138  m_tokenBuffer.push_back({TokenType::Option, opt});
9139  }
9140  } else {
9141  m_tokenBuffer.push_back({TokenType::Option, next});
9142  }
9143  }
9144  } else {
9145  m_tokenBuffer.push_back({TokenType::Argument, next});
9146  }
9147  }
9148  }
9149 
9150  public:
9151  explicit TokenStream(Args const &args)
9152  : TokenStream(args.m_args.begin(), args.m_args.end()) {
9153  }
9154 
9155  TokenStream(Iterator it, Iterator itEnd)
9156  : it(it)
9157  , itEnd(itEnd) {
9158  loadBuffer();
9159  }
9160 
9161  explicit operator bool() const { return !m_tokenBuffer.empty() || it != itEnd; }
9162 
9163  auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
9164 
9165  auto operator*() const -> Token {
9166  assert(!m_tokenBuffer.empty());
9167  return m_tokenBuffer.front();
9168  }
9169 
9170  auto operator->() const -> Token const * {
9171  assert(!m_tokenBuffer.empty());
9172  return &m_tokenBuffer.front();
9173  }
9174 
9175  auto operator++() -> TokenStream & {
9176  if (m_tokenBuffer.size() >= 2) {
9177  m_tokenBuffer.erase(m_tokenBuffer.begin());
9178  } else {
9179  if (it != itEnd)
9180  ++it;
9181  loadBuffer();
9182  }
9183  return *this;
9184  }
9185  };
9186 
9187  class ResultBase {
9188  public:
9189  enum Type {
9190  Ok,
9191  LogicError,
9192  RuntimeError
9193  };
9194 
9195  protected:
9196  ResultBase(Type type)
9197  : m_type(type) {
9198  }
9199  virtual ~ResultBase() = default;
9200 
9201  virtual void enforceOk() const = 0;
9202 
9203  Type m_type;
9204  };
9205 
9206  template<typename T>
9207  class ResultValueBase : public ResultBase {
9208  public:
9209  auto value() const -> T const & {
9210  enforceOk();
9211  return m_value;
9212  }
9213 
9214  protected:
9215  ResultValueBase(Type type)
9216  : ResultBase(type) {
9217  }
9218 
9219  ResultValueBase(ResultValueBase const &other)
9220  : ResultBase(other) {
9221  if (m_type == ResultBase::Ok)
9222  new (&m_value) T(other.m_value);
9223  }
9224 
9225  ResultValueBase(Type, T const &value)
9226  : ResultBase(Ok) {
9227  new (&m_value) T(value);
9228  }
9229 
9230  auto operator=(ResultValueBase const &other) -> ResultValueBase & {
9231  if (m_type == ResultBase::Ok)
9232  m_value.~T();
9233  ResultBase::operator=(other);
9234  if (m_type == ResultBase::Ok)
9235  new (&m_value) T(other.m_value);
9236  return *this;
9237  }
9238 
9239  ~ResultValueBase() override {
9240  if (m_type == Ok)
9241  m_value.~T();
9242  }
9243 
9244  union {
9245  T m_value;
9246  };
9247  };
9248 
9249  template<>
9250  class ResultValueBase<void> : public ResultBase {
9251  protected:
9252  using ResultBase::ResultBase;
9253  };
9254 
9255  template<typename T = void>
9256  class BasicResult : public ResultValueBase<T> {
9257  public:
9258  template<typename U>
9259  explicit BasicResult(BasicResult<U> const &other)
9260  : ResultValueBase<T>(other.type())
9261  , m_errorMessage(other.errorMessage()) {
9262  assert(type() != ResultBase::Ok);
9263  }
9264 
9265  template<typename U>
9266  static auto ok(U const &value) -> BasicResult {
9267  return {ResultBase::Ok, value};
9268  }
9269  static auto ok() -> BasicResult { return {ResultBase::Ok}; }
9270  static auto logicError(std::string const &message) -> BasicResult { return {ResultBase::LogicError, message}; }
9271  static auto runtimeError(std::string const &message) -> BasicResult { return {ResultBase::RuntimeError, message}; }
9272 
9273  explicit operator bool() const { return m_type == ResultBase::Ok; }
9274  auto type() const -> ResultBase::Type { return m_type; }
9275  auto errorMessage() const -> std::string { return m_errorMessage; }
9276 
9277  protected:
9278  void enforceOk() const override {
9279  // Errors shouldn't reach this point, but if they do
9280  // the actual error message will be in m_errorMessage
9281  assert(m_type != ResultBase::LogicError);
9282  assert(m_type != ResultBase::RuntimeError);
9283  if (m_type != ResultBase::Ok)
9284  std::abort();
9285  }
9286 
9287  std::string m_errorMessage; // Only populated if resultType is an error
9288 
9289  BasicResult(ResultBase::Type type, std::string const &message)
9290  : ResultValueBase<T>(type)
9291  , m_errorMessage(message) {
9292  assert(m_type != ResultBase::Ok);
9293  }
9294 
9295  using ResultValueBase<T>::ResultValueBase;
9296  using ResultBase::m_type;
9297  };
9298 
9299  enum class ParseResultType {
9300  Matched,
9301  NoMatch,
9302  ShortCircuitAll,
9303  ShortCircuitSame
9304  };
9305 
9306  class ParseState {
9307  public:
9308  ParseState(ParseResultType type, TokenStream const &remainingTokens)
9309  : m_type(type)
9310  , m_remainingTokens(remainingTokens) {
9311  }
9312 
9313  auto type() const -> ParseResultType { return m_type; }
9314  auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
9315 
9316  private:
9317  ParseResultType m_type;
9318  TokenStream m_remainingTokens;
9319  };
9320 
9321  using Result = BasicResult<void>;
9322  using ParserResult = BasicResult<ParseResultType>;
9323  using InternalParseResult = BasicResult<ParseState>;
9324 
9325  struct HelpColumns {
9326  std::string left;
9327  std::string right;
9328  };
9329 
9330  template<typename T>
9331  inline auto convertInto(std::string const &source, T &target) -> ParserResult {
9332  std::stringstream ss;
9333  ss << source;
9334  ss >> target;
9335  if (ss.fail())
9336  return ParserResult::runtimeError("Unable to convert '" + source + "' to destination type");
9337  else
9338  return ParserResult::ok(ParseResultType::Matched);
9339  }
9340  inline auto convertInto(std::string const &source, std::string &target) -> ParserResult {
9341  target = source;
9342  return ParserResult::ok(ParseResultType::Matched);
9343  }
9344  inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
9345  std::string srcLC = source;
9346  std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
9347  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
9348  target = true;
9349  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
9350  target = false;
9351  else
9352  return ParserResult::runtimeError("Expected a boolean value but did not recognise: '" + source + "'");
9353  return ParserResult::ok(ParseResultType::Matched);
9354  }
9355 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
9356  template<typename T>
9357  inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T> &target) -> ParserResult {
9358  T temp;
9359  auto result = convertInto(source, temp);
9360  if (result)
9361  target = std::move(temp);
9362  return result;
9363  }
9364 #endif // CLARA_CONFIG_OPTIONAL_TYPE
9365 
9366  struct NonCopyable {
9367  NonCopyable() = default;
9368  NonCopyable(NonCopyable const &) = delete;
9369  NonCopyable(NonCopyable &&) = delete;
9370  NonCopyable &operator=(NonCopyable const &) = delete;
9371  NonCopyable &operator=(NonCopyable &&) = delete;
9372  };
9373 
9374  struct BoundRef : NonCopyable {
9375  virtual ~BoundRef() = default;
9376  virtual auto isContainer() const -> bool { return false; }
9377  virtual auto isFlag() const -> bool { return false; }
9378  };
9379  struct BoundValueRefBase : BoundRef {
9380  virtual auto setValue(std::string const &arg) -> ParserResult = 0;
9381  };
9382  struct BoundFlagRefBase : BoundRef {
9383  virtual auto setFlag(bool flag) -> ParserResult = 0;
9384  virtual auto isFlag() const -> bool { return true; }
9385  };
9386 
9387  template<typename T>
9388  struct BoundValueRef : BoundValueRefBase {
9389  T &m_ref;
9390 
9391  explicit BoundValueRef(T &ref)
9392  : m_ref(ref) {
9393  }
9394 
9395  auto setValue(std::string const &arg) -> ParserResult override { return convertInto(arg, m_ref); }
9396  };
9397 
9398  template<typename T>
9399  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
9400  std::vector<T> &m_ref;
9401 
9402  explicit BoundValueRef(std::vector<T> &ref)
9403  : m_ref(ref) {
9404  }
9405 
9406  auto isContainer() const -> bool override { return true; }
9407 
9408  auto setValue(std::string const &arg) -> ParserResult override {
9409  T temp;
9410  auto result = convertInto(arg, temp);
9411  if (result)
9412  m_ref.push_back(temp);
9413  return result;
9414  }
9415  };
9416 
9417  struct BoundFlagRef : BoundFlagRefBase {
9418  bool &m_ref;
9419 
9420  explicit BoundFlagRef(bool &ref)
9421  : m_ref(ref) {
9422  }
9423 
9424  auto setFlag(bool flag) -> ParserResult override {
9425  m_ref = flag;
9426  return ParserResult::ok(ParseResultType::Matched);
9427  }
9428  };
9429 
9430  template<typename ReturnType>
9431  struct LambdaInvoker {
9432  static_assert(std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult");
9433 
9434  template<typename L, typename ArgType>
9435  static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
9436  return lambda(arg);
9437  }
9438  };
9439 
9440  template<>
9441  struct LambdaInvoker<void> {
9442  template<typename L, typename ArgType>
9443  static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
9444  lambda(arg);
9445  return ParserResult::ok(ParseResultType::Matched);
9446  }
9447  };
9448 
9449  template<typename ArgType, typename L>
9450  inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult {
9451  ArgType temp{};
9452  auto result = convertInto(arg, temp);
9453  return !result ? result : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(lambda, temp);
9454  }
9455 
9456  template<typename L>
9457  struct BoundLambda : BoundValueRefBase {
9458  L m_lambda;
9459 
9460  static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
9461  explicit BoundLambda(L const &lambda)
9462  : m_lambda(lambda) {
9463  }
9464 
9465  auto setValue(std::string const &arg) -> ParserResult override {
9466  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
9467  }
9468  };
9469 
9470  template<typename L>
9471  struct BoundFlagLambda : BoundFlagRefBase {
9472  L m_lambda;
9473 
9474  static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
9475  static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean");
9476 
9477  explicit BoundFlagLambda(L const &lambda)
9478  : m_lambda(lambda) {
9479  }
9480 
9481  auto setFlag(bool flag) -> ParserResult override {
9482  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
9483  }
9484  };
9485 
9486  enum class Optionality {
9487  Optional,
9488  Required
9489  };
9490 
9491  struct Parser;
9492 
9493  class ParserBase {
9494  public:
9495  virtual ~ParserBase() = default;
9496  virtual auto validate() const -> Result { return Result::ok(); }
9497  virtual auto parse(std::string const &exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
9498  virtual auto cardinality() const -> size_t { return 1; }
9499 
9500  auto parse(Args const &args) const -> InternalParseResult { return parse(args.exeName(), TokenStream(args)); }
9501  };
9502 
9503  template<typename DerivedT>
9504  class ComposableParserImpl : public ParserBase {
9505  public:
9506  template<typename T>
9507  auto operator|(T const &other) const -> Parser;
9508 
9509  template<typename T>
9510  auto operator+(T const &other) const -> Parser;
9511  };
9512 
9513  // Common code and state for Args and Opts
9514  template<typename DerivedT>
9515  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
9516  protected:
9517  Optionality m_optionality = Optionality::Optional;
9518  std::shared_ptr<BoundRef> m_ref;
9519  std::string m_hint;
9520  std::string m_description;
9521 
9522  explicit ParserRefImpl(std::shared_ptr<BoundRef> const &ref)
9523  : m_ref(ref) {
9524  }
9525 
9526  public:
9527  template<typename T>
9528  ParserRefImpl(T &ref, std::string const &hint)
9529  : m_ref(std::make_shared<BoundValueRef<T>>(ref))
9530  , m_hint(hint) {
9531  }
9532 
9533  template<typename LambdaT>
9534  ParserRefImpl(LambdaT const &ref, std::string const &hint)
9535  : m_ref(std::make_shared<BoundLambda<LambdaT>>(ref))
9536  , m_hint(hint) {
9537  }
9538 
9539  auto operator()(std::string const &description) -> DerivedT & {
9540  m_description = description;
9541  return static_cast<DerivedT &>(*this);
9542  }
9543 
9544  auto optional() -> DerivedT & {
9545  m_optionality = Optionality::Optional;
9546  return static_cast<DerivedT &>(*this);
9547  };
9548 
9549  auto required() -> DerivedT & {
9550  m_optionality = Optionality::Required;
9551  return static_cast<DerivedT &>(*this);
9552  };
9553 
9554  auto isOptional() const -> bool { return m_optionality == Optionality::Optional; }
9555 
9556  auto cardinality() const -> size_t override {
9557  if (m_ref->isContainer())
9558  return 0;
9559  else
9560  return 1;
9561  }
9562 
9563  auto hint() const -> std::string { return m_hint; }
9564  };
9565 
9566  class ExeName : public ComposableParserImpl<ExeName> {
9567  std::shared_ptr<std::string> m_name;
9568  std::shared_ptr<BoundValueRefBase> m_ref;
9569 
9570  template<typename LambdaT>
9571  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
9572  return std::make_shared<BoundLambda<LambdaT>>(lambda);
9573  }
9574 
9575  public:
9576  ExeName()
9577  : m_name(std::make_shared<std::string>("<executable>")) {
9578  }
9579 
9580  explicit ExeName(std::string &ref)
9581  : ExeName() {
9582  m_ref = std::make_shared<BoundValueRef<std::string>>(ref);
9583  }
9584 
9585  template<typename LambdaT>
9586  explicit ExeName(LambdaT const &lambda)
9587  : ExeName() {
9588  m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
9589  }
9590 
9591  // The exe name is not parsed out of the normal tokens, but is handled specially
9592  auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
9593  return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
9594  }
9595 
9596  auto name() const -> std::string { return *m_name; }
9597  auto set(std::string const &newName) -> ParserResult {
9598  auto lastSlash = newName.find_last_of("\\/");
9599  auto filename = (lastSlash == std::string::npos) ? newName : newName.substr(lastSlash + 1);
9600 
9601  *m_name = filename;
9602  if (m_ref)
9603  return m_ref->setValue(filename);
9604  else
9605  return ParserResult::ok(ParseResultType::Matched);
9606  }
9607  };
9608 
9609  class Arg : public ParserRefImpl<Arg> {
9610  public:
9611  using ParserRefImpl::ParserRefImpl;
9612 
9613  auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
9614  auto validationResult = validate();
9615  if (!validationResult)
9616  return InternalParseResult(validationResult);
9617 
9618  auto remainingTokens = tokens;
9619  auto const &token = *remainingTokens;
9620  if (token.type != TokenType::Argument)
9621  return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
9622 
9623  assert(!m_ref->isFlag());
9624  auto valueRef = static_cast<detail::BoundValueRefBase *>(m_ref.get());
9625 
9626  auto result = valueRef->setValue(remainingTokens->token);
9627  if (!result)
9628  return InternalParseResult(result);
9629  else
9630  return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
9631  }
9632  };
9633 
9634  inline auto normaliseOpt(std::string const &optName) -> std::string {
9635 #ifdef CATCH_PLATFORM_WINDOWS
9636  if (optName[0] == '/')
9637  return "-" + optName.substr(1);
9638  else
9639 #endif
9640  return optName;
9641  }
9642 
9643  class Opt : public ParserRefImpl<Opt> {
9644  protected:
9645  std::vector<std::string> m_optNames;
9646 
9647  public:
9648  template<typename LambdaT>
9649  explicit Opt(LambdaT const &ref)
9650  : ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {
9651  }
9652 
9653  explicit Opt(bool &ref)
9654  : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {
9655  }
9656 
9657  template<typename LambdaT>
9658  Opt(LambdaT const &ref, std::string const &hint)
9659  : ParserRefImpl(ref, hint) {
9660  }
9661 
9662  template<typename T>
9663  Opt(T &ref, std::string const &hint)
9664  : ParserRefImpl(ref, hint) {
9665  }
9666 
9667  auto operator[](std::string const &optName) -> Opt & {
9668  m_optNames.push_back(optName);
9669  return *this;
9670  }
9671 
9672  auto getHelpColumns() const -> std::vector<HelpColumns> {
9673  std::ostringstream oss;
9674  bool first = true;
9675  for (auto const &opt : m_optNames) {
9676  if (first)
9677  first = false;
9678  else
9679  oss << ", ";
9680  oss << opt;
9681  }
9682  if (!m_hint.empty())
9683  oss << " <" << m_hint << ">";
9684  return {{oss.str(), m_description}};
9685  }
9686 
9687  auto isMatch(std::string const &optToken) const -> bool {
9688  auto normalisedToken = normaliseOpt(optToken);
9689  for (auto const &name : m_optNames) {
9690  if (normaliseOpt(name) == normalisedToken)
9691  return true;
9692  }
9693  return false;
9694  }
9695 
9696  using ParserBase::parse;
9697 
9698  auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
9699  auto validationResult = validate();
9700  if (!validationResult)
9701  return InternalParseResult(validationResult);
9702 
9703  auto remainingTokens = tokens;
9704  if (remainingTokens && remainingTokens->type == TokenType::Option) {
9705  auto const &token = *remainingTokens;
9706  if (isMatch(token.token)) {
9707  if (m_ref->isFlag()) {
9708  auto flagRef = static_cast<detail::BoundFlagRefBase *>(m_ref.get());
9709  auto result = flagRef->setFlag(true);
9710  if (!result)
9711  return InternalParseResult(result);
9712  if (result.value() == ParseResultType::ShortCircuitAll)
9713  return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
9714  } else {
9715  auto valueRef = static_cast<detail::BoundValueRefBase *>(m_ref.get());
9716  ++remainingTokens;
9717  if (!remainingTokens)
9718  return InternalParseResult::runtimeError("Expected argument following " + token.token);
9719  auto const &argToken = *remainingTokens;
9720  if (argToken.type != TokenType::Argument)
9721  return InternalParseResult::runtimeError("Expected argument following " + token.token);
9722  auto result = valueRef->setValue(argToken.token);
9723  if (!result)
9724  return InternalParseResult(result);
9725  if (result.value() == ParseResultType::ShortCircuitAll)
9726  return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
9727  }
9728  return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
9729  }
9730  }
9731  return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
9732  }
9733 
9734  auto validate() const -> Result override {
9735  if (m_optNames.empty())
9736  return Result::logicError("No options supplied to Opt");
9737  for (auto const &name : m_optNames) {
9738  if (name.empty())
9739  return Result::logicError("Option name cannot be empty");
9740 #ifdef CATCH_PLATFORM_WINDOWS
9741  if (name[0] != '-' && name[0] != '/')
9742  return Result::logicError("Option name must begin with '-' or '/'");
9743 #else
9744  if (name[0] != '-')
9745  return Result::logicError("Option name must begin with '-'");
9746 #endif
9747  }
9748  return ParserRefImpl::validate();
9749  }
9750  };
9751 
9752  struct Help : Opt {
9753  Help(bool &showHelpFlag)
9754  : Opt([&](bool flag) {
9755  showHelpFlag = flag;
9756  return ParserResult::ok(ParseResultType::ShortCircuitAll);
9757  }) {
9758  static_cast<Opt &> (*this)("display usage information")["-?"]["-h"]["--help"].optional();
9759  }
9760  };
9761 
9762  struct Parser : ParserBase {
9763  mutable ExeName m_exeName;
9764  std::vector<Opt> m_options;
9765  std::vector<Arg> m_args;
9766 
9767  auto operator|=(ExeName const &exeName) -> Parser & {
9768  m_exeName = exeName;
9769  return *this;
9770  }
9771 
9772  auto operator|=(Arg const &arg) -> Parser & {
9773  m_args.push_back(arg);
9774  return *this;
9775  }
9776 
9777  auto operator|=(Opt const &opt) -> Parser & {
9778  m_options.push_back(opt);
9779  return *this;
9780  }
9781 
9782  auto operator|=(Parser const &other) -> Parser & {
9783  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
9784  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
9785  return *this;
9786  }
9787 
9788  template<typename T>
9789  auto operator|(T const &other) const -> Parser {
9790  return Parser(*this) |= other;
9791  }
9792 
9793  // Forward deprecated interface with '+' instead of '|'
9794  template<typename T>
9795  auto operator+=(T const &other) -> Parser & {
9796  return operator|=(other);
9797  }
9798  template<typename T>
9799  auto operator+(T const &other) const -> Parser {
9800  return operator|(other);
9801  }
9802 
9803  auto getHelpColumns() const -> std::vector<HelpColumns> {
9804  std::vector<HelpColumns> cols;
9805  for (auto const &o : m_options) {
9806  auto childCols = o.getHelpColumns();
9807  cols.insert(cols.end(), childCols.begin(), childCols.end());
9808  }
9809  return cols;
9810  }
9811 
9812  void writeToStream(std::ostream &os) const {
9813  if (!m_exeName.name().empty()) {
9814  os << "usage:\n"
9815  << " " << m_exeName.name() << " ";
9816  bool required = true, first = true;
9817  for (auto const &arg : m_args) {
9818  if (first)
9819  first = false;
9820  else
9821  os << " ";
9822  if (arg.isOptional() && required) {
9823  os << "[";
9824  required = false;
9825  }
9826  os << "<" << arg.hint() << ">";
9827  if (arg.cardinality() == 0)
9828  os << " ... ";
9829  }
9830  if (!required)
9831  os << "]";
9832  if (!m_options.empty())
9833  os << " options";
9834  os << "\n\nwhere options are:" << std::endl;
9835  }
9836 
9837  auto rows = getHelpColumns();
9838  size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
9839  size_t optWidth = 0;
9840  for (auto const &cols : rows)
9841  optWidth = (std::max)(optWidth, cols.left.size() + 2);
9842 
9843  optWidth = (std::min)(optWidth, consoleWidth / 2);
9844 
9845  for (auto const &cols : rows) {
9846  auto row = TextFlow::Column(cols.left).width(optWidth).indent(2) + TextFlow::Spacer(4)
9847  + TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
9848  os << row << std::endl;
9849  }
9850  }
9851 
9852  friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream & {
9853  parser.writeToStream(os);
9854  return os;
9855  }
9856 
9857  auto validate() const -> Result override {
9858  for (auto const &opt : m_options) {
9859  auto result = opt.validate();
9860  if (!result)
9861  return result;
9862  }
9863  for (auto const &arg : m_args) {
9864  auto result = arg.validate();
9865  if (!result)
9866  return result;
9867  }
9868  return Result::ok();
9869  }
9870 
9871  using ParserBase::parse;
9872 
9873  auto parse(std::string const &exeName, TokenStream const &tokens) const -> InternalParseResult override {
9874  struct ParserInfo {
9875  ParserBase const *parser = nullptr;
9876  size_t count = 0;
9877  };
9878  const size_t totalParsers = m_options.size() + m_args.size();
9879  assert(totalParsers < 512);
9880  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
9881  ParserInfo parseInfos[512];
9882 
9883  {
9884  size_t i = 0;
9885  for (auto const &opt : m_options)
9886  parseInfos[i++].parser = &opt;
9887  for (auto const &arg : m_args)
9888  parseInfos[i++].parser = &arg;
9889  }
9890 
9891  m_exeName.set(exeName);
9892 
9893  auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
9894  while (result.value().remainingTokens()) {
9895  bool tokenParsed = false;
9896 
9897  for (size_t i = 0; i < totalParsers; ++i) {
9898  auto &parseInfo = parseInfos[i];
9899  if (parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality()) {
9900  result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
9901  if (!result)
9902  return result;
9903  if (result.value().type() != ParseResultType::NoMatch) {
9904  tokenParsed = true;
9905  ++parseInfo.count;
9906  break;
9907  }
9908  }
9909  }
9910 
9911  if (result.value().type() == ParseResultType::ShortCircuitAll)
9912  return result;
9913  if (!tokenParsed)
9914  return InternalParseResult::runtimeError("Unrecognised token: " + result.value().remainingTokens()->token);
9915  }
9916  // !TBD Check missing required options
9917  return result;
9918  }
9919  };
9920 
9921  template<typename DerivedT>
9922  template<typename T>
9923  auto ComposableParserImpl<DerivedT>::operator|(T const &other) const -> Parser {
9924  return Parser() | static_cast<DerivedT const &>(*this) | other;
9925  }
9926  } // namespace detail
9927 
9928  // A Combined parser
9929  using detail::Parser;
9930 
9931  // A parser for options
9932  using detail::Opt;
9933 
9934  // A parser for arguments
9935  using detail::Arg;
9936 
9937  // Wrapper for argc, argv from main()
9938  using detail::Args;
9939 
9940  // Specifies the name of the executable
9941  using detail::ExeName;
9942 
9943  // Convenience wrapper for option parser that specifies the help option
9944  using detail::Help;
9945 
9946  // enum of result types from a parse
9947  using detail::ParseResultType;
9948 
9949  // Result type for parser operation
9950  using detail::ParserResult;
9951 
9952  } // namespace clara
9953 } // namespace Catch
9954 
9955 // end clara.hpp
9956 #ifdef __clang__
9957 #pragma clang diagnostic pop
9958 #endif
9959 
9960 // Restore Clara's value for console width, if present
9961 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9962 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9963 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
9964 #endif
9965 
9966 // end catch_clara.h
9967 namespace Catch {
9968  clara::Parser makeCommandLineParser(ConfigData &config);
9969 
9970 } // end namespace Catch
9971 
9972 // end catch_commandline.h
9973 #include <ctime>
9974 #include <fstream>
9975 
9976 namespace Catch {
9977  clara::Parser makeCommandLineParser(ConfigData &config) {
9978  using namespace clara;
9979 
9980  auto const setWarning = [&](std::string const &warning) {
9981  auto warningSet = [&]() {
9982  if (warning == "NoAssertions")
9983  return WarnAbout::NoAssertions;
9984 
9985  if (warning == "NoTests")
9986  return WarnAbout::NoTests;
9987 
9988  return WarnAbout::Nothing;
9989  }();
9990 
9991  if (warningSet == WarnAbout::Nothing)
9992  return ParserResult::runtimeError("Unrecognised warning: '" + warning + "'");
9993  config.warnings = static_cast<WarnAbout::What>(config.warnings | warningSet);
9994  return ParserResult::ok(ParseResultType::Matched);
9995  };
9996  auto const loadTestNamesFromFile = [&](std::string const &filename) {
9997  std::ifstream f(filename.c_str());
9998  if (!f.is_open())
9999  return ParserResult::runtimeError("Unable to load input file: '" + filename + "'");
10000 
10001  std::string line;
10002  while (std::getline(f, line)) {
10003  line = trim(line);
10004  if (!line.empty() && !startsWith(line, '#')) {
10005  if (!startsWith(line, '"'))
10006  line = '"' + line + '"';
10007  config.testsOrTags.push_back(line);
10008  config.testsOrTags.emplace_back(",");
10009  }
10010  }
10011  // Remove comma in the end
10012  if (!config.testsOrTags.empty())
10013  config.testsOrTags.erase(config.testsOrTags.end() - 1);
10014 
10015  return ParserResult::ok(ParseResultType::Matched);
10016  };
10017  auto const setTestOrder = [&](std::string const &order) {
10018  if (startsWith("declared", order))
10019  config.runOrder = RunTests::InDeclarationOrder;
10020  else if (startsWith("lexical", order))
10021  config.runOrder = RunTests::InLexicographicalOrder;
10022  else if (startsWith("random", order))
10023  config.runOrder = RunTests::InRandomOrder;
10024  else
10025  return clara::ParserResult::runtimeError("Unrecognised ordering: '" + order + "'");
10026  return ParserResult::ok(ParseResultType::Matched);
10027  };
10028  auto const setRngSeed = [&](std::string const &seed) {
10029  if (seed != "time")
10030  return clara::detail::convertInto(seed, config.rngSeed);
10031  config.rngSeed = static_cast<unsigned int>(std::time(nullptr));
10032  return ParserResult::ok(ParseResultType::Matched);
10033  };
10034  auto const setColourUsage = [&](std::string const &useColour) {
10035  auto mode = toLower(useColour);
10036 
10037  if (mode == "yes")
10038  config.useColour = UseColour::Yes;
10039  else if (mode == "no")
10040  config.useColour = UseColour::No;
10041  else if (mode == "auto")
10042  config.useColour = UseColour::Auto;
10043  else
10044  return ParserResult::runtimeError("colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised");
10045  return ParserResult::ok(ParseResultType::Matched);
10046  };
10047  auto const setWaitForKeypress = [&](std::string const &keypress) {
10048  auto keypressLc = toLower(keypress);
10049  if (keypressLc == "never")
10050  config.waitForKeypress = WaitForKeypress::Never;
10051  else if (keypressLc == "start")
10052  config.waitForKeypress = WaitForKeypress::BeforeStart;
10053  else if (keypressLc == "exit")
10054  config.waitForKeypress = WaitForKeypress::BeforeExit;
10055  else if (keypressLc == "both")
10056  config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
10057  else
10058  return ParserResult::runtimeError("keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised");
10059  return ParserResult::ok(ParseResultType::Matched);
10060  };
10061  auto const setVerbosity = [&](std::string const &verbosity) {
10062  auto lcVerbosity = toLower(verbosity);
10063  if (lcVerbosity == "quiet")
10064  config.verbosity = Verbosity::Quiet;
10065  else if (lcVerbosity == "normal")
10066  config.verbosity = Verbosity::Normal;
10067  else if (lcVerbosity == "high")
10068  config.verbosity = Verbosity::High;
10069  else
10070  return ParserResult::runtimeError("Unrecognised verbosity, '" + verbosity + "'");
10071  return ParserResult::ok(ParseResultType::Matched);
10072  };
10073  auto const setReporter = [&](std::string const &reporter) {
10074  IReporterRegistry::FactoryMap const &factories = getRegistryHub().getReporterRegistry().getFactories();
10075 
10076  auto lcReporter = toLower(reporter);
10077  auto result = factories.find(lcReporter);
10078 
10079  if (factories.end() != result)
10080  config.reporterName = lcReporter;
10081  else
10082  return ParserResult::runtimeError("Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters");
10083  return ParserResult::ok(ParseResultType::Matched);
10084  };
10085 
10086  auto cli = ExeName(config.processName) | Help(config.showHelp)
10087  | Opt(config.listTests)["-l"]["--list-tests"]("list all/matching test cases")
10088  | Opt(config.listTags)["-t"]["--list-tags"]("list all/matching tags")
10089  | Opt(config.showSuccessfulTests)["-s"]["--success"]("include successful tests in output")
10090  | Opt(config.shouldDebugBreak)["-b"]["--break"]("break into debugger on failure")
10091  | Opt(config.noThrow)["-e"]["--nothrow"]("skip exception tests")
10092  | Opt(config.showInvisibles)["-i"]["--invisibles"]("show invisibles (tabs, newlines)")
10093  | Opt(config.outputFilename, "filename")["-o"]["--out"]("output filename")
10094  | Opt(setReporter, "name")["-r"]["--reporter"]("reporter to use (defaults to console)")
10095  | Opt(config.name, "name")["-n"]["--name"]("suite name")
10096  | Opt([&](bool) { config.abortAfter = 1; })["-a"]["--abort"]("abort at first failure")
10097  | Opt([&](int x) { config.abortAfter = x; }, "no. failures")["-x"]["--abortx"]("abort after x failures")
10098  | Opt(setWarning, "warning name")["-w"]["--warn"]("enable warnings")
10099  | Opt([&](bool flag) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; },
10100  "yes|no")["-d"]["--durations"]("show test durations")
10101  | Opt(config.minDuration,
10102  "seconds")["-D"]["--min-duration"]("show test durations for tests taking at least the given number of seconds")
10103  | Opt(loadTestNamesFromFile, "filename")["-f"]["--input-file"]("load test names to run from a file")
10104  | Opt(config.filenamesAsTags)["-#"]["--filenames-as-tags"]("adds a tag for the filename")
10105  | Opt(config.sectionsToRun, "section name")["-c"]["--section"]("specify section to run")
10106  | Opt(setVerbosity, "quiet|normal|high")["-v"]["--verbosity"]("set output verbosity")
10107  | Opt(config.listTestNamesOnly)["--list-test-names-only"]("list all/matching test cases names only")
10108  | Opt(config.listReporters)["--list-reporters"]("list all reporters")
10109  | Opt(setTestOrder, "decl|lex|rand")["--order"]("test case order (defaults to decl)")
10110  | Opt(setRngSeed, "'time'|number")["--rng-seed"]("set a specific seed for random numbers")
10111  | Opt(setColourUsage, "yes|no")["--use-colour"]("should output be colourised")
10112  | Opt(config.libIdentify)["--libidentify"]("report name and version according to libidentify standard")
10113  | Opt(setWaitForKeypress, "never|start|exit|both")["--wait-for-keypress"]("waits for a keypress before exiting")
10114  | Opt(config.benchmarkSamples, "samples")["--benchmark-samples"]("number of samples to collect (default: 100)")
10115  | Opt(config.benchmarkResamples, "resamples")["--benchmark-resamples"]("number of resamples for the bootstrap (default: 100000)")
10116  | Opt(config.benchmarkConfidenceInterval, "confidence interval")["--benchmark-confidence-interval"](
10117  "confidence interval for the bootstrap (between 0 and 1, default: 0.95)")
10118  | Opt(config.benchmarkNoAnalysis)["--benchmark-no-analysis"]("perform only measurements; do not perform any analysis")
10119  | Opt(config.benchmarkWarmupTime, "benchmarkWarmupTime")["--benchmark-warmup-time"](
10120  "amount of time in milliseconds spent on warming up each test (default: 100)")
10121  | Arg(config.testsOrTags, "test name|pattern|tags")("which test or tests to use");
10122 
10123  return cli;
10124  }
10125 
10126 } // end namespace Catch
10127 // end catch_commandline.cpp
10128 // start catch_common.cpp
10129 
10130 #include <cstring>
10131 #include <ostream>
10132 
10133 namespace Catch {
10134  bool SourceLineInfo::operator==(SourceLineInfo const &other) const noexcept {
10135  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
10136  }
10137  bool SourceLineInfo::operator<(SourceLineInfo const &other) const noexcept {
10138  // We can assume that the same file will usually have the same pointer.
10139  // Thus, if the pointers are the same, there is no point in calling the strcmp
10140  return line < other.line || (line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
10141  }
10142 
10143  std::ostream &operator<<(std::ostream &os, SourceLineInfo const &info) {
10144 #ifndef __GNUG__
10145  os << info.file << '(' << info.line << ')';
10146 #else
10147  os << info.file << ':' << info.line;
10148 #endif
10149  return os;
10150  }
10151 
10152  std::string StreamEndStop::operator+() const {
10153  return std::string();
10154  }
10155 
10156  NonCopyable::NonCopyable() = default;
10157  NonCopyable::~NonCopyable() = default;
10158 
10159 } // namespace Catch
10160 // end catch_common.cpp
10161 // start catch_config.cpp
10162 
10163 namespace Catch {
10164  Config::Config(ConfigData const &data)
10165  : m_data(data)
10166  , m_stream(openStream()) {
10167  // We need to trim filter specs to avoid trouble with superfluous
10168  // whitespace (esp. important for bdd macros, as those are manually
10169  // aligned with whitespace).
10170 
10171  for (auto &elem : m_data.testsOrTags) {
10172  elem = trim(elem);
10173  }
10174  for (auto &elem : m_data.sectionsToRun) {
10175  elem = trim(elem);
10176  }
10177 
10178  TestSpecParser parser(ITagAliasRegistry::get());
10179  if (!m_data.testsOrTags.empty()) {
10180  m_hasTestFilters = true;
10181  for (auto const &testOrTags : m_data.testsOrTags) {
10182  parser.parse(testOrTags);
10183  }
10184  }
10185  m_testSpec = parser.testSpec();
10186  }
10187 
10188  std::string const &Config::getFilename() const {
10189  return m_data.outputFilename;
10190  }
10191 
10192  bool Config::listTests() const {
10193  return m_data.listTests;
10194  }
10195  bool Config::listTestNamesOnly() const {
10196  return m_data.listTestNamesOnly;
10197  }
10198  bool Config::listTags() const {
10199  return m_data.listTags;
10200  }
10201  bool Config::listReporters() const {
10202  return m_data.listReporters;
10203  }
10204 
10205  std::string Config::getProcessName() const {
10206  return m_data.processName;
10207  }
10208  std::string const &Config::getReporterName() const {
10209  return m_data.reporterName;
10210  }
10211 
10212  std::vector<std::string> const &Config::getTestsOrTags() const {
10213  return m_data.testsOrTags;
10214  }
10215  std::vector<std::string> const &Config::getSectionsToRun() const {
10216  return m_data.sectionsToRun;
10217  }
10218 
10219  TestSpec const &Config::testSpec() const {
10220  return m_testSpec;
10221  }
10222  bool Config::hasTestFilters() const {
10223  return m_hasTestFilters;
10224  }
10225 
10226  bool Config::showHelp() const {
10227  return m_data.showHelp;
10228  }
10229 
10230  // IConfig interface
10231  bool Config::allowThrows() const {
10232  return !m_data.noThrow;
10233  }
10234  std::ostream &Config::stream() const {
10235  return m_stream->stream();
10236  }
10237  std::string Config::name() const {
10238  return m_data.name.empty() ? m_data.processName : m_data.name;
10239  }
10240  bool Config::includeSuccessfulResults() const {
10241  return m_data.showSuccessfulTests;
10242  }
10243  bool Config::warnAboutMissingAssertions() const {
10244  return !!(m_data.warnings & WarnAbout::NoAssertions);
10245  }
10246  bool Config::warnAboutNoTests() const {
10247  return !!(m_data.warnings & WarnAbout::NoTests);
10248  }
10249  ShowDurations::OrNot Config::showDurations() const {
10250  return m_data.showDurations;
10251  }
10252  double Config::minDuration() const {
10253  return m_data.minDuration;
10254  }
10255  RunTests::InWhatOrder Config::runOrder() const {
10256  return m_data.runOrder;
10257  }
10258  unsigned int Config::rngSeed() const {
10259  return m_data.rngSeed;
10260  }
10261  UseColour::YesOrNo Config::useColour() const {
10262  return m_data.useColour;
10263  }
10264  bool Config::shouldDebugBreak() const {
10265  return m_data.shouldDebugBreak;
10266  }
10267  int Config::abortAfter() const {
10268  return m_data.abortAfter;
10269  }
10270  bool Config::showInvisibles() const {
10271  return m_data.showInvisibles;
10272  }
10273  Verbosity Config::verbosity() const {
10274  return m_data.verbosity;
10275  }
10276 
10277  bool Config::benchmarkNoAnalysis() const {
10278  return m_data.benchmarkNoAnalysis;
10279  }
10280  int Config::benchmarkSamples() const {
10281  return m_data.benchmarkSamples;
10282  }
10283  double Config::benchmarkConfidenceInterval() const {
10284  return m_data.benchmarkConfidenceInterval;
10285  }
10286  unsigned int Config::benchmarkResamples() const {
10287  return m_data.benchmarkResamples;
10288  }
10289  std::chrono::milliseconds Config::benchmarkWarmupTime() const {
10290  return std::chrono::milliseconds(m_data.benchmarkWarmupTime);
10291  }
10292 
10293  IStream const *Config::openStream() {
10294  return Catch::makeStream(m_data.outputFilename);
10295  }
10296 
10297 } // end namespace Catch
10298 // end catch_config.cpp
10299 // start catch_console_colour.cpp
10300 
10301 #if defined(__clang__)
10302 #pragma clang diagnostic push
10303 #pragma clang diagnostic ignored "-Wexit-time-destructors"
10304 #endif
10305 
10306 // start catch_errno_guard.h
10307 
10308 namespace Catch {
10309  class ErrnoGuard {
10310  public:
10311  ErrnoGuard();
10312  ~ErrnoGuard();
10313 
10314  private:
10315  int m_oldErrno;
10316  };
10317 
10318 } // namespace Catch
10319 
10320 // end catch_errno_guard.h
10321 // start catch_windows_h_proxy.h
10322 
10323 #if defined(CATCH_PLATFORM_WINDOWS)
10324 
10325 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
10326 #define CATCH_DEFINED_NOMINMAX
10327 #define NOMINMAX
10328 #endif
10329 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
10330 #define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
10331 #define WIN32_LEAN_AND_MEAN
10332 #endif
10333 
10334 #ifdef __AFXDLL
10335 #include <AfxWin.h>
10336 #else
10337 #include <windows.h>
10338 #endif
10339 
10340 #ifdef CATCH_DEFINED_NOMINMAX
10341 #undef NOMINMAX
10342 #endif
10343 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
10344 #undef WIN32_LEAN_AND_MEAN
10345 #endif
10346 
10347 #endif // defined(CATCH_PLATFORM_WINDOWS)
10348 
10349 // end catch_windows_h_proxy.h
10350 #include <sstream>
10351 
10352 namespace Catch {
10353  namespace {
10354  struct IColourImpl {
10355  virtual ~IColourImpl() = default;
10356  virtual void use(Colour::Code _colourCode) = 0;
10357  };
10358 
10359  struct NoColourImpl : IColourImpl {
10360  void use(Colour::Code) override {}
10361 
10362  static IColourImpl *instance() {
10363  static NoColourImpl s_instance;
10364  return &s_instance;
10365  }
10366  };
10367 
10368  } // namespace
10369 } // namespace Catch
10370 
10371 #if !defined(CATCH_CONFIG_COLOUR_NONE) && !defined(CATCH_CONFIG_COLOUR_WINDOWS) && !defined(CATCH_CONFIG_COLOUR_ANSI)
10372 #ifdef CATCH_PLATFORM_WINDOWS
10373 #define CATCH_CONFIG_COLOUR_WINDOWS
10374 #else
10375 #define CATCH_CONFIG_COLOUR_ANSI
10376 #endif
10377 #endif
10378 
10379 #if defined(CATCH_CONFIG_COLOUR_WINDOWS)
10380 
10381 namespace Catch {
10382  namespace {
10383  class Win32ColourImpl : public IColourImpl {
10384  public:
10385  Win32ColourImpl()
10386  : stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)) {
10387  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
10388  GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
10389  originalForegroundAttributes = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
10390  originalBackgroundAttributes = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
10391  }
10392 
10393  void use(Colour::Code _colourCode) override {
10394  switch (_colourCode) {
10395  case Colour::None:
10396  return setTextAttribute(originalForegroundAttributes);
10397  case Colour::White:
10398  return setTextAttribute(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
10399  case Colour::Red:
10400  return setTextAttribute(FOREGROUND_RED);
10401  case Colour::Green:
10402  return setTextAttribute(FOREGROUND_GREEN);
10403  case Colour::Blue:
10404  return setTextAttribute(FOREGROUND_BLUE);
10405  case Colour::Cyan:
10406  return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN);
10407  case Colour::Yellow:
10408  return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN);
10409  case Colour::Grey:
10410  return setTextAttribute(0);
10411 
10412  case Colour::LightGrey:
10413  return setTextAttribute(FOREGROUND_INTENSITY);
10414  case Colour::BrightRed:
10415  return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED);
10416  case Colour::BrightGreen:
10417  return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN);
10418  case Colour::BrightWhite:
10419  return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
10420  case Colour::BrightYellow:
10421  return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
10422 
10423  case Colour::Bright:
10424  CATCH_INTERNAL_ERROR("not a colour");
10425 
10426  default:
10427  CATCH_ERROR("Unknown colour requested");
10428  }
10429  }
10430 
10431  private:
10432  void setTextAttribute(WORD _textAttribute) { SetConsoleTextAttribute(stdoutHandle, _textAttribute | originalBackgroundAttributes); }
10433  HANDLE stdoutHandle;
10434  WORD originalForegroundAttributes;
10435  WORD originalBackgroundAttributes;
10436  };
10437 
10438  IColourImpl *platformColourInstance() {
10439  static Win32ColourImpl s_instance;
10440 
10441  IConfigPtr config = getCurrentContext().getConfig();
10442  UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto;
10443  if (colourMode == UseColour::Auto)
10444  colourMode = UseColour::Yes;
10445  return colourMode == UseColour::Yes ? &s_instance : NoColourImpl::instance();
10446  }
10447 
10448  } // namespace
10449 } // namespace Catch
10450 
10451 #elif defined(CATCH_CONFIG_COLOUR_ANSI)
10452 
10453 #include <unistd.h>
10454 
10455 namespace Catch {
10456  namespace {
10457  // use POSIX/ ANSI console terminal codes
10458  // Thanks to Adam Strzelecki for original contribution
10459  // (http://github.com/nanoant)
10460  // https://github.com/philsquared/Catch/pull/131
10461  class PosixColourImpl : public IColourImpl {
10462  public:
10463  void use(Colour::Code _colourCode) override {
10464  switch (_colourCode) {
10465  case Colour::None:
10466  case Colour::White:
10467  return setColour("[0m");
10468  case Colour::Red:
10469  return setColour("[0;31m");
10470  case Colour::Green:
10471  return setColour("[0;32m");
10472  case Colour::Blue:
10473  return setColour("[0;34m");
10474  case Colour::Cyan:
10475  return setColour("[0;36m");
10476  case Colour::Yellow:
10477  return setColour("[0;33m");
10478  case Colour::Grey:
10479  return setColour("[1;30m");
10480 
10481  case Colour::LightGrey:
10482  return setColour("[0;37m");
10483  case Colour::BrightRed:
10484  return setColour("[1;31m");
10485  case Colour::BrightGreen:
10486  return setColour("[1;32m");
10487  case Colour::BrightWhite:
10488  return setColour("[1;37m");
10489  case Colour::BrightYellow:
10490  return setColour("[1;33m");
10491 
10492  case Colour::Bright:
10493  CATCH_INTERNAL_ERROR("not a colour");
10494  default:
10495  CATCH_INTERNAL_ERROR("Unknown colour requested");
10496  }
10497  }
10498  static IColourImpl *instance() {
10499  static PosixColourImpl s_instance;
10500  return &s_instance;
10501  }
10502 
10503  private:
10504  void setColour(const char *_escapeCode) { getCurrentContext().getConfig()->stream() << '\033' << _escapeCode; }
10505  };
10506 
10507  bool useColourOnPlatform() {
10508  return
10509 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10510  !isDebuggerActive() &&
10511 #endif
10512 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
10513  isatty(STDOUT_FILENO)
10514 #else
10515  false
10516 #endif
10517  ;
10518  }
10519  IColourImpl *platformColourInstance() {
10520  ErrnoGuard guard;
10521  IConfigPtr config = getCurrentContext().getConfig();
10522  UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto;
10523  if (colourMode == UseColour::Auto)
10524  colourMode = useColourOnPlatform() ? UseColour::Yes : UseColour::No;
10525  return colourMode == UseColour::Yes ? PosixColourImpl::instance() : NoColourImpl::instance();
10526  }
10527 
10528  } // namespace
10529 } // namespace Catch
10530 
10531 #else // not Windows or ANSI
10532 
10533 namespace Catch {
10534  static IColourImpl *platformColourInstance() {
10535  return NoColourImpl::instance();
10536  }
10537 
10538 } // end namespace Catch
10539 
10540 #endif // Windows/ ANSI/ None
10541 
10542 namespace Catch {
10543  Colour::Colour(Code _colourCode) {
10544  use(_colourCode);
10545  }
10546  Colour::Colour(Colour &&other) noexcept {
10547  m_moved = other.m_moved;
10548  other.m_moved = true;
10549  }
10550  Colour &Colour::operator=(Colour &&other) noexcept {
10551  m_moved = other.m_moved;
10552  other.m_moved = true;
10553  return *this;
10554  }
10555 
10556  Colour::~Colour() {
10557  if (!m_moved)
10558  use(None);
10559  }
10560 
10561  void Colour::use(Code _colourCode) {
10562  static IColourImpl *impl = platformColourInstance();
10563  // Strictly speaking, this cannot possibly happen.
10564  // However, under some conditions it does happen (see #1626),
10565  // and this change is small enough that we can let practicality
10566  // triumph over purity in this case.
10567  if (impl != nullptr) {
10568  impl->use(_colourCode);
10569  }
10570  }
10571 
10572  std::ostream &operator<<(std::ostream &os, Colour const &) {
10573  return os;
10574  }
10575 
10576 } // end namespace Catch
10577 
10578 #if defined(__clang__)
10579 #pragma clang diagnostic pop
10580 #endif
10581 
10582 // end catch_console_colour.cpp
10583 // start catch_context.cpp
10584 
10585 namespace Catch {
10586  class Context : public IMutableContext, NonCopyable {
10587  public: // IContext
10588  IResultCapture *getResultCapture() override { return m_resultCapture; }
10589  IRunner *getRunner() override { return m_runner; }
10590 
10591  IConfigPtr const &getConfig() const override { return m_config; }
10592 
10593  ~Context() override;
10594 
10595  public: // IMutableContext
10596  void setResultCapture(IResultCapture *resultCapture) override { m_resultCapture = resultCapture; }
10597  void setRunner(IRunner *runner) override { m_runner = runner; }
10598  void setConfig(IConfigPtr const &config) override { m_config = config; }
10599 
10600  friend IMutableContext &getCurrentMutableContext();
10601 
10602  private:
10603  IConfigPtr m_config;
10604  IRunner *m_runner = nullptr;
10605  IResultCapture *m_resultCapture = nullptr;
10606  };
10607 
10608  IMutableContext *IMutableContext::currentContext = nullptr;
10609 
10610  void IMutableContext::createContext() {
10611  currentContext = new Context();
10612  }
10613 
10614  void cleanUpContext() {
10615  delete IMutableContext::currentContext;
10616  IMutableContext::currentContext = nullptr;
10617  }
10618  IContext::~IContext() = default;
10619  IMutableContext::~IMutableContext() = default;
10620  Context::~Context() = default;
10621 
10622  SimplePcg32 &rng() {
10623  static SimplePcg32 s_rng;
10624  return s_rng;
10625  }
10626 
10627 } // namespace Catch
10628 // end catch_context.cpp
10629 // start catch_debug_console.cpp
10630 
10631 // start catch_debug_console.h
10632 
10633 #include <string>
10634 
10635 namespace Catch {
10636  void writeToDebugConsole(std::string const &text);
10637 }
10638 
10639 // end catch_debug_console.h
10640 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
10641 #include <android/log.h>
10642 
10643 namespace Catch {
10644  void writeToDebugConsole(std::string const &text) {
10645  __android_log_write(ANDROID_LOG_DEBUG, "Catch", text.c_str());
10646  }
10647 } // namespace Catch
10648 
10649 #elif defined(CATCH_PLATFORM_WINDOWS)
10650 
10651 namespace Catch {
10652  void writeToDebugConsole(std::string const &text) {
10653  ::OutputDebugStringA(text.c_str());
10654  }
10655 } // namespace Catch
10656 
10657 #else
10658 
10659 namespace Catch {
10660  void writeToDebugConsole(std::string const &text) {
10661  // !TBD: Need a version for Mac/ XCode and other IDEs
10662  Catch::cout() << text;
10663  }
10664 } // namespace Catch
10665 
10666 #endif // Platform \
10667  // end catch_debug_console.cpp
10668 // start catch_debugger.cpp
10669 
10670 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
10671 
10672 #include <cassert>
10673 #include <cstddef>
10674 #include <ostream>
10675 #include <sys/types.h>
10676 #include <unistd.h>
10677 
10678 #ifdef __apple_build_version__
10679 // These headers will only compile with AppleClang (XCode)
10680 // For other compilers (Clang, GCC, ... ) we need to exclude them
10681 #include <sys/sysctl.h>
10682 #endif
10683 
10684 namespace Catch {
10685 #ifdef __apple_build_version__
10686  // The following function is taken directly from the following technical note:
10687  // https://developer.apple.com/library/archive/qa/qa1361/_index.html
10688 
10689  // Returns true if the current process is being debugged (either
10690  // running under the debugger or has a debugger attached post facto).
10691  bool isDebuggerActive() {
10692  int mib[4];
10693  struct kinfo_proc info;
10694  std::size_t size;
10695 
10696  // Initialize the flags so that, if sysctl fails for some bizarre
10697  // reason, we get a predictable result.
10698 
10699  info.kp_proc.p_flag = 0;
10700 
10701  // Initialize mib, which tells sysctl the info we want, in this case
10702  // we're looking for information about a specific process ID.
10703 
10704  mib[0] = CTL_KERN;
10705  mib[1] = KERN_PROC;
10706  mib[2] = KERN_PROC_PID;
10707  mib[3] = getpid();
10708 
10709  // Call sysctl.
10710 
10711  size = sizeof(info);
10712  if (sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0) {
10713  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n"
10714  << std::endl;
10715  return false;
10716  }
10717 
10718  // We're being debugged if the P_TRACED flag is set.
10719 
10720  return ((info.kp_proc.p_flag & P_TRACED) != 0);
10721  }
10722 #else
10723  bool isDebuggerActive() {
10724  // We need to find another way to determine this for non-appleclang compilers on macOS
10725  return false;
10726  }
10727 #endif
10728 } // namespace Catch
10729 
10730 #elif defined(CATCH_PLATFORM_LINUX)
10731 #include <fstream>
10732 #include <string>
10733 
10734 namespace Catch {
10735  // The standard POSIX way of detecting a debugger is to attempt to
10736  // ptrace() the process, but this needs to be done from a child and not
10737  // this process itself to still allow attaching to this process later
10738  // if wanted, so is rather heavy. Under Linux we have the PID of the
10739  // "debugger" (which doesn't need to be gdb, of course, it could also
10740  // be strace, for example) in /proc/$PID/status, so just get it from
10741  // there instead.
10742  bool isDebuggerActive() {
10743  // Libstdc++ has a bug, where std::ifstream sets errno to 0
10744  // This way our users can properly assert over errno values
10745  ErrnoGuard guard;
10746  std::ifstream in("/proc/self/status");
10747  for (std::string line; std::getline(in, line);) {
10748  static const int PREFIX_LEN = 11;
10749  if (line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
10750  // We're traced if the PID is not 0 and no other PID starts
10751  // with 0 digit, so it's enough to check for just a single
10752  // character.
10753  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
10754  }
10755  }
10756 
10757  return false;
10758  }
10759 } // namespace Catch
10760 #elif defined(_MSC_VER)
10761 extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10762 namespace Catch {
10763  bool isDebuggerActive() {
10764  return IsDebuggerPresent() != 0;
10765  }
10766 } // namespace Catch
10767 #elif defined(__MINGW32__)
10768 extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
10769 namespace Catch {
10770  bool isDebuggerActive() {
10771  return IsDebuggerPresent() != 0;
10772  }
10773 } // namespace Catch
10774 #else
10775 namespace Catch {
10776  bool isDebuggerActive() {
10777  return false;
10778  }
10779 } // namespace Catch
10780 #endif // Platform
10781 // end catch_debugger.cpp
10782 // start catch_decomposer.cpp
10783 
10784 namespace Catch {
10785  ITransientExpression::~ITransientExpression() = default;
10786 
10787  void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs) {
10788  if (lhs.size() + rhs.size() < 40 && lhs.find('\n') == std::string::npos && rhs.find('\n') == std::string::npos)
10789  os << lhs << " " << op << " " << rhs;
10790  else
10791  os << lhs << "\n"
10792  << op << "\n"
10793  << rhs;
10794  }
10795 } // namespace Catch
10796 // end catch_decomposer.cpp
10797 // start catch_enforce.cpp
10798 
10799 #include <stdexcept>
10800 
10801 namespace Catch {
10802 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
10803  [[noreturn]] void throw_exception(std::exception const &e) {
10804  Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
10805  << "The message was: " << e.what() << '\n';
10806  std::terminate();
10807  }
10808 #endif
10809 
10810  [[noreturn]] void throw_logic_error(std::string const &msg) {
10811  throw_exception(std::logic_error(msg));
10812  }
10813 
10814  [[noreturn]] void throw_domain_error(std::string const &msg) {
10815  throw_exception(std::domain_error(msg));
10816  }
10817 
10818  [[noreturn]] void throw_runtime_error(std::string const &msg) {
10819  throw_exception(std::runtime_error(msg));
10820  }
10821 
10822 } // namespace Catch
10823 // end catch_enforce.cpp
10824 // start catch_enum_values_registry.cpp
10825 // start catch_enum_values_registry.h
10826 
10827 #include <memory>
10828 #include <vector>
10829 
10830 namespace Catch {
10831  namespace Detail {
10832  std::unique_ptr<EnumInfo> makeEnumInfo(StringRef enumName, StringRef allValueNames, std::vector<int> const &values);
10833 
10834  class EnumValuesRegistry : public IMutableEnumValuesRegistry {
10835  std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
10836 
10837  EnumInfo const &registerEnum(StringRef enumName, StringRef allEnums, std::vector<int> const &values) override;
10838  };
10839 
10840  std::vector<StringRef> parseEnums(StringRef enums);
10841 
10842  } // namespace Detail
10843 } // namespace Catch
10844 
10845 // end catch_enum_values_registry.h
10846 
10847 #include <cassert>
10848 #include <map>
10849 
10850 namespace Catch {
10851  IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
10852 
10853  namespace Detail {
10854  namespace {
10855  // Extracts the actual name part of an enum instance
10856  // In other words, it returns the Blue part of Bikeshed::Colour::Blue
10857  StringRef extractInstanceName(StringRef enumInstance) {
10858  // Find last occurrence of ":"
10859  size_t name_start = enumInstance.size();
10860  while (name_start > 0 && enumInstance[name_start - 1] != ':') {
10861  --name_start;
10862  }
10863  return enumInstance.substr(name_start, enumInstance.size() - name_start);
10864  }
10865  } // namespace
10866 
10867  std::vector<StringRef> parseEnums(StringRef enums) {
10868  auto enumValues = splitStringRef(enums, ',');
10869  std::vector<StringRef> parsed;
10870  parsed.reserve(enumValues.size());
10871  for (auto const &enumValue : enumValues) {
10872  parsed.push_back(trim(extractInstanceName(enumValue)));
10873  }
10874  return parsed;
10875  }
10876 
10877  EnumInfo::~EnumInfo() {}
10878 
10879  StringRef EnumInfo::lookup(int value) const {
10880  for (auto const &valueToName : m_values) {
10881  if (valueToName.first == value)
10882  return valueToName.second;
10883  }
10884  return "{** unexpected enum value **}"_sr;
10885  }
10886 
10887  std::unique_ptr<EnumInfo> makeEnumInfo(StringRef enumName, StringRef allValueNames, std::vector<int> const &values) {
10888  std::unique_ptr<EnumInfo> enumInfo(new EnumInfo);
10889  enumInfo->m_name = enumName;
10890  enumInfo->m_values.reserve(values.size());
10891 
10892  const auto valueNames = Catch::Detail::parseEnums(allValueNames);
10893  assert(valueNames.size() == values.size());
10894  std::size_t i = 0;
10895  for (auto value : values)
10896  enumInfo->m_values.emplace_back(value, valueNames[i++]);
10897 
10898  return enumInfo;
10899  }
10900 
10901  EnumInfo const &EnumValuesRegistry::registerEnum(StringRef enumName, StringRef allValueNames, std::vector<int> const &values) {
10902  m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
10903  return *m_enumInfos.back();
10904  }
10905 
10906  } // namespace Detail
10907 } // namespace Catch
10908 
10909 // end catch_enum_values_registry.cpp
10910 // start catch_errno_guard.cpp
10911 
10912 #include <cerrno>
10913 
10914 namespace Catch {
10915  ErrnoGuard::ErrnoGuard()
10916  : m_oldErrno(errno) {
10917  }
10918  ErrnoGuard::~ErrnoGuard() {
10919  errno = m_oldErrno;
10920  }
10921 } // namespace Catch
10922 // end catch_errno_guard.cpp
10923 // start catch_exception_translator_registry.cpp
10924 
10925 // start catch_exception_translator_registry.h
10926 
10927 #include <memory>
10928 #include <string>
10929 #include <vector>
10930 
10931 namespace Catch {
10932  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
10933  public:
10934  ~ExceptionTranslatorRegistry();
10935  virtual void registerTranslator(const IExceptionTranslator *translator);
10936  std::string translateActiveException() const override;
10937  std::string tryTranslators() const;
10938 
10939  private:
10940  std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
10941  };
10942 } // namespace Catch
10943 
10944 // end catch_exception_translator_registry.h
10945 #ifdef __OBJC__
10946 #import "Foundation/Foundation.h"
10947 #endif
10948 
10949 namespace Catch {
10950  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {}
10951 
10952  void ExceptionTranslatorRegistry::registerTranslator(const IExceptionTranslator *translator) {
10953  m_translators.push_back(std::unique_ptr<const IExceptionTranslator>(translator));
10954  }
10955 
10956 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10957  std::string ExceptionTranslatorRegistry::translateActiveException() const {
10958  try {
10959 #ifdef __OBJC__
10960  // In Objective-C try objective-c exceptions first
10961  @try {
10962  return tryTranslators();
10963  } @catch (NSException *exception) {
10964  return Catch::Detail::stringify([exception description]);
10965  }
10966 #else
10967  // Compiling a mixed mode project with MSVC means that CLR
10968  // exceptions will be caught in (...) as well. However, these
10969  // do not fill-in std::current_exception and thus lead to crash
10970  // when attempting rethrow.
10971  // /EHa switch also causes structured exceptions to be caught
10972  // here, but they fill-in current_exception properly, so
10973  // at worst the output should be a little weird, instead of
10974  // causing a crash.
10975  if (std::current_exception() == nullptr) {
10976  return "Non C++ exception. Possibly a CLR exception.";
10977  }
10978  return tryTranslators();
10979 #endif
10980  } catch (TestFailureException &) {
10981  std::rethrow_exception(std::current_exception());
10982  } catch (std::exception &ex) {
10983  return ex.what();
10984  } catch (std::string &msg) {
10985  return msg;
10986  } catch (const char *msg) {
10987  return msg;
10988  } catch (...) {
10989  return "Unknown exception";
10990  }
10991  }
10992 
10993  std::string ExceptionTranslatorRegistry::tryTranslators() const {
10994  if (m_translators.empty()) {
10995  std::rethrow_exception(std::current_exception());
10996  } else {
10997  return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
10998  }
10999  }
11000 
11001 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
11002  std::string ExceptionTranslatorRegistry::translateActiveException() const {
11003  CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
11004  }
11005 
11006  std::string ExceptionTranslatorRegistry::tryTranslators() const {
11007  CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
11008  }
11009 #endif
11010 
11011 } // namespace Catch
11012 // end catch_exception_translator_registry.cpp
11013 // start catch_fatal_condition.cpp
11014 
11015 #include <algorithm>
11016 
11017 #if !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
11018 
11019 namespace Catch {
11020  // If neither SEH nor signal handling is required, the handler impls
11021  // do not have to do anything, and can be empty.
11022  void FatalConditionHandler::engage_platform() {}
11023  void FatalConditionHandler::disengage_platform() {}
11024  FatalConditionHandler::FatalConditionHandler() = default;
11025  FatalConditionHandler::~FatalConditionHandler() = default;
11026 
11027 } // end namespace Catch
11028 
11029 #endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
11030 
11031 #if defined(CATCH_CONFIG_WINDOWS_SEH) && defined(CATCH_CONFIG_POSIX_SIGNALS)
11032 #error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
11033 #endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
11034 
11035 #if defined(CATCH_CONFIG_WINDOWS_SEH) || defined(CATCH_CONFIG_POSIX_SIGNALS)
11036 
11037 namespace {
11039  void reportFatal(char const *const message) {
11040  Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition(message);
11041  }
11042 
11046  constexpr std::size_t minStackSizeForErrors = 32 * 1024;
11047 } // end unnamed namespace
11048 
11049 #endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
11050 
11051 #if defined(CATCH_CONFIG_WINDOWS_SEH)
11052 
11053 namespace Catch {
11054  struct SignalDefs {
11055  DWORD id;
11056  const char *name;
11057  };
11058 
11059  // There is no 1-1 mapping between signals and windows exceptions.
11060  // Windows can easily distinguish between SO and SigSegV,
11061  // but SigInt, SigTerm, etc are handled differently.
11062  static SignalDefs signalDefs[] = {
11063  {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal"},
11064  {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
11065  {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal"},
11066  {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
11067  };
11068 
11069  static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
11070  for (auto const &def : signalDefs) {
11071  if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
11072  reportFatal(def.name);
11073  }
11074  }
11075  // If its not an exception we care about, pass it along.
11076  // This stops us from eating debugger breaks etc.
11077  return EXCEPTION_CONTINUE_SEARCH;
11078  }
11079 
11080  // Since we do not support multiple instantiations, we put these
11081  // into global variables and rely on cleaning them up in outlined
11082  // constructors/destructors
11083  static PVOID exceptionHandlerHandle = nullptr;
11084 
11085  // For MSVC, we reserve part of the stack memory for handling
11086  // memory overflow structured exception.
11087  FatalConditionHandler::FatalConditionHandler() {
11088  ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);
11089  if (!SetThreadStackGuarantee(&guaranteeSize)) {
11090  // We do not want to fully error out, because needing
11091  // the stack reserve should be rare enough anyway.
11092  Catch::cerr() << "Failed to reserve piece of stack."
11093  << " Stack overflows will not be reported successfully.";
11094  }
11095  }
11096 
11097  // We do not attempt to unset the stack guarantee, because
11098  // Windows does not support lowering the stack size guarantee.
11099  FatalConditionHandler::~FatalConditionHandler() = default;
11100 
11101  void FatalConditionHandler::engage_platform() {
11102  // Register as first handler in current chain
11103  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
11104  if (!exceptionHandlerHandle) {
11105  CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
11106  }
11107  }
11108 
11109  void FatalConditionHandler::disengage_platform() {
11110  if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
11111  CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
11112  }
11113  exceptionHandlerHandle = nullptr;
11114  }
11115 
11116 } // end namespace Catch
11117 
11118 #endif // CATCH_CONFIG_WINDOWS_SEH
11119 
11120 #if defined(CATCH_CONFIG_POSIX_SIGNALS)
11121 
11122 #include <signal.h>
11123 
11124 namespace Catch {
11125  struct SignalDefs {
11126  int id;
11127  const char *name;
11128  };
11129 
11130  static SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"},
11131  {SIGILL, "SIGILL - Illegal instruction signal"},
11132  {SIGFPE, "SIGFPE - Floating point error signal"},
11133  {SIGSEGV, "SIGSEGV - Segmentation violation signal"},
11134  {SIGTERM, "SIGTERM - Termination request signal"},
11135  {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
11136 
11137 // Older GCCs trigger -Wmissing-field-initializers for T foo = {}
11138 // which is zero initialization, but not explicit. We want to avoid
11139 // that.
11140 #if defined(__GNUC__)
11141 #pragma GCC diagnostic push
11142 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
11143 #endif
11144 
11145  static char *altStackMem = nullptr;
11146  static std::size_t altStackSize = 0;
11147  static stack_t oldSigStack{};
11148  static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
11149 
11150  static void restorePreviousSignalHandlers() {
11151  // We set signal handlers back to the previous ones. Hopefully
11152  // nobody overwrote them in the meantime, and doesn't expect
11153  // their signal handlers to live past ours given that they
11154  // installed them after ours..
11155  for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
11156  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
11157  }
11158  // Return the old stack
11159  sigaltstack(&oldSigStack, nullptr);
11160  }
11161 
11162  static void handleSignal(int sig) {
11163  char const *name = "<unknown signal>";
11164  for (auto const &def : signalDefs) {
11165  if (sig == def.id) {
11166  name = def.name;
11167  break;
11168  }
11169  }
11170  // We need to restore previous signal handlers and let them do
11171  // their thing, so that the users can have the debugger break
11172  // when a signal is raised, and so on.
11173  restorePreviousSignalHandlers();
11174  reportFatal(name);
11175  raise(sig);
11176  }
11177 
11178  FatalConditionHandler::FatalConditionHandler() {
11179  assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
11180  if (altStackSize == 0) {
11181  altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);
11182  }
11183  altStackMem = new char[altStackSize]();
11184  }
11185 
11186  FatalConditionHandler::~FatalConditionHandler() {
11187  delete[] altStackMem;
11188  // We signal that another instance can be constructed by zeroing
11189  // out the pointer.
11190  altStackMem = nullptr;
11191  }
11192 
11193  void FatalConditionHandler::engage_platform() {
11194  stack_t sigStack;
11195  sigStack.ss_sp = altStackMem;
11196  sigStack.ss_size = altStackSize;
11197  sigStack.ss_flags = 0;
11198  sigaltstack(&sigStack, &oldSigStack);
11199  struct sigaction sa = {};
11200 
11201  sa.sa_handler = handleSignal;
11202  sa.sa_flags = SA_ONSTACK;
11203  for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
11204  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
11205  }
11206  }
11207 
11208 #if defined(__GNUC__)
11209 #pragma GCC diagnostic pop
11210 #endif
11211 
11212  void FatalConditionHandler::disengage_platform() {
11213  restorePreviousSignalHandlers();
11214  }
11215 
11216 } // end namespace Catch
11217 
11218 #endif // CATCH_CONFIG_POSIX_SIGNALS \
11219  // end catch_fatal_condition.cpp
11220 // start catch_generators.cpp
11221 
11222 #include <limits>
11223 #include <set>
11224 
11225 namespace Catch {
11226  IGeneratorTracker::~IGeneratorTracker() {}
11227 
11228  const char *GeneratorException::what() const noexcept {
11229  return m_msg;
11230  }
11231 
11232  namespace Generators {
11233  GeneratorUntypedBase::~GeneratorUntypedBase() {}
11234 
11235  auto acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker & {
11236  return getResultCapture().acquireGeneratorTracker(generatorName, lineInfo);
11237  }
11238 
11239  } // namespace Generators
11240 } // namespace Catch
11241 // end catch_generators.cpp
11242 // start catch_interfaces_capture.cpp
11243 
11244 namespace Catch {
11245  IResultCapture::~IResultCapture() = default;
11246 }
11247 // end catch_interfaces_capture.cpp
11248 // start catch_interfaces_config.cpp
11249 
11250 namespace Catch {
11251  IConfig::~IConfig() = default;
11252 }
11253 // end catch_interfaces_config.cpp
11254 // start catch_interfaces_exception.cpp
11255 
11256 namespace Catch {
11257  IExceptionTranslator::~IExceptionTranslator() = default;
11258  IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
11259 } // namespace Catch
11260 // end catch_interfaces_exception.cpp
11261 // start catch_interfaces_registry_hub.cpp
11262 
11263 namespace Catch {
11264  IRegistryHub::~IRegistryHub() = default;
11265  IMutableRegistryHub::~IMutableRegistryHub() = default;
11266 } // namespace Catch
11267 // end catch_interfaces_registry_hub.cpp
11268 // start catch_interfaces_reporter.cpp
11269 
11270 // start catch_reporter_listening.h
11271 
11272 namespace Catch {
11273  class ListeningReporter : public IStreamingReporter {
11274  using Reporters = std::vector<IStreamingReporterPtr>;
11275  Reporters m_listeners;
11276  IStreamingReporterPtr m_reporter = nullptr;
11277  ReporterPreferences m_preferences;
11278 
11279  public:
11280  ListeningReporter();
11281 
11282  void addListener(IStreamingReporterPtr &&listener);
11283  void addReporter(IStreamingReporterPtr &&reporter);
11284 
11285  public: // IStreamingReporter
11286  ReporterPreferences getPreferences() const override;
11287 
11288  void noMatchingTestCases(std::string const &spec) override;
11289 
11290  void reportInvalidArguments(std::string const &arg) override;
11291 
11292  static std::set<Verbosity> getSupportedVerbosities();
11293 
11294 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
11295  void benchmarkPreparing(std::string const &name) override;
11296  void benchmarkStarting(BenchmarkInfo const &benchmarkInfo) override;
11297  void benchmarkEnded(BenchmarkStats<> const &benchmarkStats) override;
11298  void benchmarkFailed(std::string const &) override;
11299 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
11300 
11301  void testRunStarting(TestRunInfo const &testRunInfo) override;
11302  void testGroupStarting(GroupInfo const &groupInfo) override;
11303  void testCaseStarting(TestCaseInfo const &testInfo) override;
11304  void sectionStarting(SectionInfo const &sectionInfo) override;
11305  void assertionStarting(AssertionInfo const &assertionInfo) override;
11306 
11307  // The return value indicates if the messages buffer should be cleared:
11308  bool assertionEnded(AssertionStats const &assertionStats) override;
11309  void sectionEnded(SectionStats const &sectionStats) override;
11310  void testCaseEnded(TestCaseStats const &testCaseStats) override;
11311  void testGroupEnded(TestGroupStats const &testGroupStats) override;
11312  void testRunEnded(TestRunStats const &testRunStats) override;
11313 
11314  void skipTest(TestCaseInfo const &testInfo) override;
11315  bool isMulti() const override;
11316  };
11317 
11318 } // end namespace Catch
11319 
11320 // end catch_reporter_listening.h
11321 namespace Catch {
11322  ReporterConfig::ReporterConfig(IConfigPtr const &_fullConfig)
11323  : m_stream(&_fullConfig->stream())
11324  , m_fullConfig(_fullConfig) {
11325  }
11326 
11327  ReporterConfig::ReporterConfig(IConfigPtr const &_fullConfig, std::ostream &_stream)
11328  : m_stream(&_stream)
11329  , m_fullConfig(_fullConfig) {
11330  }
11331 
11332  std::ostream &ReporterConfig::stream() const {
11333  return *m_stream;
11334  }
11335  IConfigPtr ReporterConfig::fullConfig() const {
11336  return m_fullConfig;
11337  }
11338 
11339  TestRunInfo::TestRunInfo(std::string const &_name)
11340  : name(_name) {
11341  }
11342 
11343  GroupInfo::GroupInfo(std::string const &_name, std::size_t _groupIndex, std::size_t _groupsCount)
11344  : name(_name)
11345  , groupIndex(_groupIndex)
11346  , groupsCounts(_groupsCount) {
11347  }
11348 
11349  AssertionStats::AssertionStats(AssertionResult const &_assertionResult, std::vector<MessageInfo> const &_infoMessages, Totals const &_totals)
11350  : assertionResult(_assertionResult)
11351  , infoMessages(_infoMessages)
11352  , totals(_totals) {
11353  assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
11354 
11355  if (assertionResult.hasMessage()) {
11356  // Copy message into messages list.
11357  // !TBD This should have been done earlier, somewhere
11358  MessageBuilder builder(assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType());
11359  builder << assertionResult.getMessage();
11360  builder.m_info.message = builder.m_stream.str();
11361 
11362  infoMessages.push_back(builder.m_info);
11363  }
11364  }
11365 
11366  AssertionStats::~AssertionStats() = default;
11367 
11368  SectionStats::SectionStats(SectionInfo const &_sectionInfo, Counts const &_assertions, double _durationInSeconds, bool _missingAssertions)
11369  : sectionInfo(_sectionInfo)
11370  , assertions(_assertions)
11371  , durationInSeconds(_durationInSeconds)
11372  , missingAssertions(_missingAssertions) {
11373  }
11374 
11375  SectionStats::~SectionStats() = default;
11376 
11377  TestCaseStats::TestCaseStats(TestCaseInfo const &_testInfo, Totals const &_totals, std::string const &_stdOut, std::string const &_stdErr, bool _aborting)
11378  : testInfo(_testInfo)
11379  , totals(_totals)
11380  , stdOut(_stdOut)
11381  , stdErr(_stdErr)
11382  , aborting(_aborting) {
11383  }
11384 
11385  TestCaseStats::~TestCaseStats() = default;
11386 
11387  TestGroupStats::TestGroupStats(GroupInfo const &_groupInfo, Totals const &_totals, bool _aborting)
11388  : groupInfo(_groupInfo)
11389  , totals(_totals)
11390  , aborting(_aborting) {
11391  }
11392 
11393  TestGroupStats::TestGroupStats(GroupInfo const &_groupInfo)
11394  : groupInfo(_groupInfo)
11395  , aborting(false) {
11396  }
11397 
11398  TestGroupStats::~TestGroupStats() = default;
11399 
11400  TestRunStats::TestRunStats(TestRunInfo const &_runInfo, Totals const &_totals, bool _aborting)
11401  : runInfo(_runInfo)
11402  , totals(_totals)
11403  , aborting(_aborting) {
11404  }
11405 
11406  TestRunStats::~TestRunStats() = default;
11407 
11408  void IStreamingReporter::fatalErrorEncountered(StringRef) {}
11409  bool IStreamingReporter::isMulti() const {
11410  return false;
11411  }
11412 
11413  IReporterFactory::~IReporterFactory() = default;
11414  IReporterRegistry::~IReporterRegistry() = default;
11415 
11416 } // end namespace Catch
11417 // end catch_interfaces_reporter.cpp
11418 // start catch_interfaces_runner.cpp
11419 
11420 namespace Catch {
11421  IRunner::~IRunner() = default;
11422 }
11423 // end catch_interfaces_runner.cpp
11424 // start catch_interfaces_testcase.cpp
11425 
11426 namespace Catch {
11427  ITestInvoker::~ITestInvoker() = default;
11428  ITestCaseRegistry::~ITestCaseRegistry() = default;
11429 } // namespace Catch
11430 // end catch_interfaces_testcase.cpp
11431 // start catch_leak_detector.cpp
11432 
11433 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
11434 #include <crtdbg.h>
11435 
11436 namespace Catch {
11437  LeakDetector::LeakDetector() {
11438  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
11439  flag |= _CRTDBG_LEAK_CHECK_DF;
11440  flag |= _CRTDBG_ALLOC_MEM_DF;
11441  _CrtSetDbgFlag(flag);
11442  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
11443  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
11444  // Change this to leaking allocation's number to break there
11445  _CrtSetBreakAlloc(-1);
11446  }
11447 } // namespace Catch
11448 
11449 #else
11450 
11451 Catch::LeakDetector::LeakDetector() {
11452 }
11453 
11454 #endif
11455 
11456 Catch::LeakDetector::~LeakDetector() {
11457  Catch::cleanUp();
11458 }
11459 // end catch_leak_detector.cpp
11460 // start catch_list.cpp
11461 
11462 // start catch_list.h
11463 
11464 #include <set>
11465 
11466 namespace Catch {
11467  std::size_t listTests(Config const &config);
11468 
11469  std::size_t listTestsNamesOnly(Config const &config);
11470 
11471  struct TagInfo {
11472  void add(std::string const &spelling);
11473  std::string all() const;
11474 
11475  std::set<std::string> spellings;
11476  std::size_t count = 0;
11477  };
11478 
11479  std::size_t listTags(Config const &config);
11480 
11481  std::size_t listReporters();
11482 
11483  Option<std::size_t> list(std::shared_ptr<Config> const &config);
11484 
11485 } // end namespace Catch
11486 
11487 // end catch_list.h
11488 // start catch_text.h
11489 
11490 namespace Catch {
11491  using namespace clara::TextFlow;
11492 }
11493 
11494 // end catch_text.h
11495 #include <algorithm>
11496 #include <iomanip>
11497 #include <limits>
11498 
11499 namespace Catch {
11500  std::size_t listTests(Config const &config) {
11501  TestSpec const &testSpec = config.testSpec();
11502  if (config.hasTestFilters())
11503  Catch::cout() << "Matching test cases:\n";
11504  else {
11505  Catch::cout() << "All available test cases:\n";
11506  }
11507 
11508  auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
11509  for (auto const &testCaseInfo : matchedTestCases) {
11510  Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None;
11511  Colour colourGuard(colour);
11512 
11513  Catch::cout() << Column(testCaseInfo.name).initialIndent(2).indent(4) << "\n";
11514  if (config.verbosity() >= Verbosity::High) {
11515  Catch::cout() << Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl;
11516  std::string description = testCaseInfo.description;
11517  if (description.empty())
11518  description = "(NO DESCRIPTION)";
11519  Catch::cout() << Column(description).indent(4) << std::endl;
11520  }
11521  if (!testCaseInfo.tags.empty())
11522  Catch::cout() << Column(testCaseInfo.tagsAsString()).indent(6) << "\n";
11523  }
11524 
11525  if (!config.hasTestFilters())
11526  Catch::cout() << pluralise(matchedTestCases.size(), "test case") << '\n'
11527  << std::endl;
11528  else
11529  Catch::cout() << pluralise(matchedTestCases.size(), "matching test case") << '\n'
11530  << std::endl;
11531  return matchedTestCases.size();
11532  }
11533 
11534  std::size_t listTestsNamesOnly(Config const &config) {
11535  TestSpec const &testSpec = config.testSpec();
11536  std::size_t matchedTests = 0;
11537  std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
11538  for (auto const &testCaseInfo : matchedTestCases) {
11539  matchedTests++;
11540  if (startsWith(testCaseInfo.name, '#'))
11541  Catch::cout() << '"' << testCaseInfo.name << '"';
11542  else
11543  Catch::cout() << testCaseInfo.name;
11544  if (config.verbosity() >= Verbosity::High)
11545  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
11546  Catch::cout() << std::endl;
11547  }
11548  return matchedTests;
11549  }
11550 
11551  void TagInfo::add(std::string const &spelling) {
11552  ++count;
11553  spellings.insert(spelling);
11554  }
11555 
11556  std::string TagInfo::all() const {
11557  size_t size = 0;
11558  for (auto const &spelling : spellings) {
11559  // Add 2 for the brackes
11560  size += spelling.size() + 2;
11561  }
11562 
11563  std::string out;
11564  out.reserve(size);
11565  for (auto const &spelling : spellings) {
11566  out += '[';
11567  out += spelling;
11568  out += ']';
11569  }
11570  return out;
11571  }
11572 
11573  std::size_t listTags(Config const &config) {
11574  TestSpec const &testSpec = config.testSpec();
11575  if (config.hasTestFilters())
11576  Catch::cout() << "Tags for matching test cases:\n";
11577  else {
11578  Catch::cout() << "All available tags:\n";
11579  }
11580 
11581  std::map<std::string, TagInfo> tagCounts;
11582 
11583  std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
11584  for (auto const &testCase : matchedTestCases) {
11585  for (auto const &tagName : testCase.getTestCaseInfo().tags) {
11586  std::string lcaseTagName = toLower(tagName);
11587  auto countIt = tagCounts.find(lcaseTagName);
11588  if (countIt == tagCounts.end())
11589  countIt = tagCounts.insert(std::make_pair(lcaseTagName, TagInfo())).first;
11590  countIt->second.add(tagName);
11591  }
11592  }
11593 
11594  for (auto const &tagCount : tagCounts) {
11596  rss << " " << std::setw(2) << tagCount.second.count << " ";
11597  auto str = rss.str();
11598  auto wrapper = Column(tagCount.second.all()).initialIndent(0).indent(str.size()).width(CATCH_CONFIG_CONSOLE_WIDTH - 10);
11599  Catch::cout() << str << wrapper << '\n';
11600  }
11601  Catch::cout() << pluralise(tagCounts.size(), "tag") << '\n'
11602  << std::endl;
11603  return tagCounts.size();
11604  }
11605 
11606  std::size_t listReporters() {
11607  Catch::cout() << "Available reporters:\n";
11608  IReporterRegistry::FactoryMap const &factories = getRegistryHub().getReporterRegistry().getFactories();
11609  std::size_t maxNameLen = 0;
11610  for (auto const &factoryKvp : factories)
11611  maxNameLen = (std::max)(maxNameLen, factoryKvp.first.size());
11612 
11613  for (auto const &factoryKvp : factories) {
11614  Catch::cout() << Column(factoryKvp.first + ":").indent(2).width(5 + maxNameLen)
11615  + Column(factoryKvp.second->getDescription()).initialIndent(0).indent(2).width(CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8)
11616  << "\n";
11617  }
11618  Catch::cout() << std::endl;
11619  return factories.size();
11620  }
11621 
11622  Option<std::size_t> list(std::shared_ptr<Config> const &config) {
11623  Option<std::size_t> listedCount;
11624  getCurrentMutableContext().setConfig(config);
11625  if (config->listTests())
11626  listedCount = listedCount.valueOr(0) + listTests(*config);
11627  if (config->listTestNamesOnly())
11628  listedCount = listedCount.valueOr(0) + listTestsNamesOnly(*config);
11629  if (config->listTags())
11630  listedCount = listedCount.valueOr(0) + listTags(*config);
11631  if (config->listReporters())
11632  listedCount = listedCount.valueOr(0) + listReporters();
11633  return listedCount;
11634  }
11635 
11636 } // end namespace Catch
11637 // end catch_list.cpp
11638 // start catch_matchers.cpp
11639 
11640 namespace Catch {
11641  namespace Matchers {
11642  namespace Impl {
11643  std::string MatcherUntypedBase::toString() const {
11644  if (m_cachedToString.empty())
11645  m_cachedToString = describe();
11646  return m_cachedToString;
11647  }
11648 
11649  MatcherUntypedBase::~MatcherUntypedBase() = default;
11650 
11651  } // namespace Impl
11652  } // namespace Matchers
11653 
11654  using namespace Matchers;
11656 
11657 } // namespace Catch
11658 // end catch_matchers.cpp
11659 // start catch_matchers_exception.cpp
11660 
11661 namespace Catch {
11662  namespace Matchers {
11663  namespace Exception {
11664  bool ExceptionMessageMatcher::match(std::exception const &ex) const {
11665  return ex.what() == m_message;
11666  }
11667 
11668  std::string ExceptionMessageMatcher::describe() const {
11669  return "exception message matches \"" + m_message + "\"";
11670  }
11671 
11672  } // namespace Exception
11673  Exception::ExceptionMessageMatcher Message(std::string const &message) {
11674  return Exception::ExceptionMessageMatcher(message);
11675  }
11676 
11677  // namespace Exception
11678  } // namespace Matchers
11679 } // namespace Catch
11680 // end catch_matchers_exception.cpp
11681 // start catch_matchers_floating.cpp
11682 
11683 // start catch_polyfills.hpp
11684 
11685 namespace Catch {
11686  bool isnan(float f);
11687  bool isnan(double d);
11688 } // namespace Catch
11689 
11690 // end catch_polyfills.hpp
11691 // start catch_to_string.hpp
11692 
11693 #include <string>
11694 
11695 namespace Catch {
11696  template<typename T>
11697  std::string to_string(T const &t) {
11698 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
11699  return std::to_string(t);
11700 #else
11702  rss << t;
11703  return rss.str();
11704 #endif
11705  }
11706 } // end namespace Catch
11707 
11708 // end catch_to_string.hpp
11709 #include <algorithm>
11710 #include <cmath>
11711 #include <cstdint>
11712 #include <cstdlib>
11713 #include <cstring>
11714 #include <iomanip>
11715 #include <limits>
11716 #include <sstream>
11717 #include <type_traits>
11718 
11719 namespace Catch {
11720  namespace {
11721  int32_t convert(float f) {
11722  static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
11723  int32_t i;
11724  std::memcpy(&i, &f, sizeof(f));
11725  return i;
11726  }
11727 
11728  int64_t convert(double d) {
11729  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
11730  int64_t i;
11731  std::memcpy(&i, &d, sizeof(d));
11732  return i;
11733  }
11734 
11735  template<typename FP>
11736  bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
11737  // Comparison with NaN should always be false.
11738  // This way we can rule it out before getting into the ugly details
11739  if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
11740  return false;
11741  }
11742 
11743  auto lc = convert(lhs);
11744  auto rc = convert(rhs);
11745 
11746  if ((lc < 0) != (rc < 0)) {
11747  // Potentially we can have +0 and -0
11748  return lhs == rhs;
11749  }
11750 
11751  // static cast as a workaround for IBM XLC
11752  auto ulpDiff = std::abs(static_cast<FP>(lc - rc));
11753  return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
11754  }
11755 
11756 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11757 
11758  float nextafter(float x, float y) {
11759  return ::nextafterf(x, y);
11760  }
11761 
11762  double nextafter(double x, double y) {
11763  return ::nextafter(x, y);
11764  }
11765 
11766 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
11767 
11768  template<typename FP>
11769  FP step(FP start, FP direction, uint64_t steps) {
11770  for (uint64_t i = 0; i < steps; ++i) {
11771 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
11772  start = Catch::nextafter(start, direction);
11773 #else
11774  start = std::nextafter(start, direction);
11775 #endif
11776  }
11777  return start;
11778  }
11779 
11780  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11781  // But without the subtraction to allow for INFINITY in comparison
11782  bool marginComparison(double lhs, double rhs, double margin) {
11783  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
11784  }
11785 
11786  template<typename FloatingPoint>
11787  void write(std::ostream &out, FloatingPoint num) {
11788  out << std::scientific << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1) << num;
11789  }
11790 
11791  } // end anonymous namespace
11792 
11793  namespace Matchers {
11794  namespace Floating {
11795  enum class FloatingPointKind : uint8_t {
11796  Float,
11797  Double
11798  };
11799 
11800  WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
11801  : m_target{target}
11802  , m_margin{margin} {
11803  CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.' << " Margin has to be non-negative.");
11804  }
11805 
11806  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
11807  // But without the subtraction to allow for INFINITY in comparison
11808  bool WithinAbsMatcher::match(double const &matchee) const {
11809  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
11810  }
11811 
11812  std::string WithinAbsMatcher::describe() const {
11813  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
11814  }
11815 
11816  WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
11817  : m_target{target}
11818  , m_ulps{ulps}
11819  , m_type{baseType} {
11820  CATCH_ENFORCE(m_type == FloatingPointKind::Double || m_ulps < (std::numeric_limits<uint32_t>::max)(),
11821  "Provided ULP is impossibly large for a float comparison.");
11822  }
11823 
11824 #if defined(__clang__)
11825 #pragma clang diagnostic push
11826 // Clang <3.5 reports on the default branch in the switch below
11827 #pragma clang diagnostic ignored "-Wunreachable-code"
11828 #endif
11829 
11830  bool WithinUlpsMatcher::match(double const &matchee) const {
11831  switch (m_type) {
11832  case FloatingPointKind::Float:
11833  return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
11834  case FloatingPointKind::Double:
11835  return almostEqualUlps<double>(matchee, m_target, m_ulps);
11836  default:
11837  CATCH_INTERNAL_ERROR("Unknown FloatingPointKind value");
11838  }
11839  }
11840 
11841 #if defined(__clang__)
11842 #pragma clang diagnostic pop
11843 #endif
11844 
11845  std::string WithinUlpsMatcher::describe() const {
11846  std::stringstream ret;
11847 
11848  ret << "is within " << m_ulps << " ULPs of ";
11849 
11850  if (m_type == FloatingPointKind::Float) {
11851  write(ret, static_cast<float>(m_target));
11852  ret << 'f';
11853  } else {
11854  write(ret, m_target);
11855  }
11856 
11857  ret << " ([";
11858  if (m_type == FloatingPointKind::Double) {
11859  write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
11860  ret << ", ";
11861  write(ret, step(m_target, static_cast<double>(INFINITY), m_ulps));
11862  } else {
11863  // We have to cast INFINITY to float because of MinGW, see #1782
11864  write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
11865  ret << ", ";
11866  write(ret, step(static_cast<float>(m_target), static_cast<float>(INFINITY), m_ulps));
11867  }
11868  ret << "])";
11869 
11870  return ret.str();
11871  }
11872 
11873  WithinRelMatcher::WithinRelMatcher(double target, double epsilon)
11874  : m_target(target)
11875  , m_epsilon(epsilon) {
11876  CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense.");
11877  CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
11878  }
11879 
11880  bool WithinRelMatcher::match(double const &matchee) const {
11881  const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
11882  return marginComparison(matchee, m_target, std::isinf(relMargin) ? 0 : relMargin);
11883  }
11884 
11885  std::string WithinRelMatcher::describe() const {
11886  Catch::ReusableStringStream sstr;
11887  sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
11888  return sstr.str();
11889  }
11890 
11891  } // namespace Floating
11892 
11893  Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
11894  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
11895  }
11896 
11897  Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
11898  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
11899  }
11900 
11901  Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
11902  return Floating::WithinAbsMatcher(target, margin);
11903  }
11904 
11905  Floating::WithinRelMatcher WithinRel(double target, double eps) {
11906  return Floating::WithinRelMatcher(target, eps);
11907  }
11908 
11909  Floating::WithinRelMatcher WithinRel(double target) {
11910  return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
11911  }
11912 
11913  Floating::WithinRelMatcher WithinRel(float target, float eps) {
11914  return Floating::WithinRelMatcher(target, eps);
11915  }
11916 
11917  Floating::WithinRelMatcher WithinRel(float target) {
11918  return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
11919  }
11920 
11921  } // namespace Matchers
11922 } // namespace Catch
11923 // end catch_matchers_floating.cpp
11924 // start catch_matchers_generic.cpp
11925 
11926 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string &desc) {
11927  if (desc.empty()) {
11928  return "matches undescribed predicate";
11929  } else {
11930  return "matches predicate: \"" + desc + '"';
11931  }
11932 }
11933 // end catch_matchers_generic.cpp
11934 // start catch_matchers_string.cpp
11935 
11936 #include <regex>
11937 
11938 namespace Catch {
11939  namespace Matchers {
11940  namespace StdString {
11941  CasedString::CasedString(std::string const &str, CaseSensitive::Choice caseSensitivity)
11942  : m_caseSensitivity(caseSensitivity)
11943  , m_str(adjustString(str)) {
11944  }
11945  std::string CasedString::adjustString(std::string const &str) const {
11946  return m_caseSensitivity == CaseSensitive::No ? toLower(str) : str;
11947  }
11948  std::string CasedString::caseSensitivitySuffix() const {
11949  return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" : std::string();
11950  }
11951 
11952  StringMatcherBase::StringMatcherBase(std::string const &operation, CasedString const &comparator)
11953  : m_comparator(comparator)
11954  , m_operation(operation) {
11955  }
11956 
11957  std::string StringMatcherBase::describe() const {
11958  std::string description;
11959  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + m_comparator.caseSensitivitySuffix().size());
11960  description += m_operation;
11961  description += ": \"";
11962  description += m_comparator.m_str;
11963  description += "\"";
11964  description += m_comparator.caseSensitivitySuffix();
11965  return description;
11966  }
11967 
11968  EqualsMatcher::EqualsMatcher(CasedString const &comparator)
11969  : StringMatcherBase("equals", comparator) {
11970  }
11971 
11972  bool EqualsMatcher::match(std::string const &source) const {
11973  return m_comparator.adjustString(source) == m_comparator.m_str;
11974  }
11975 
11976  ContainsMatcher::ContainsMatcher(CasedString const &comparator)
11977  : StringMatcherBase("contains", comparator) {
11978  }
11979 
11980  bool ContainsMatcher::match(std::string const &source) const {
11981  return contains(m_comparator.adjustString(source), m_comparator.m_str);
11982  }
11983 
11984  StartsWithMatcher::StartsWithMatcher(CasedString const &comparator)
11985  : StringMatcherBase("starts with", comparator) {
11986  }
11987 
11988  bool StartsWithMatcher::match(std::string const &source) const {
11989  return startsWith(m_comparator.adjustString(source), m_comparator.m_str);
11990  }
11991 
11992  EndsWithMatcher::EndsWithMatcher(CasedString const &comparator)
11993  : StringMatcherBase("ends with", comparator) {
11994  }
11995 
11996  bool EndsWithMatcher::match(std::string const &source) const {
11997  return endsWith(m_comparator.adjustString(source), m_comparator.m_str);
11998  }
11999 
12000  RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity)
12001  : m_regex(std::move(regex))
12002  , m_caseSensitivity(caseSensitivity) {
12003  }
12004 
12005  bool RegexMatcher::match(std::string const &matchee) const {
12006  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
12007  if (m_caseSensitivity == CaseSensitive::Choice::No) {
12008  flags |= std::regex::icase;
12009  }
12010  auto reg = std::regex(m_regex, flags);
12011  return std::regex_match(matchee, reg);
12012  }
12013 
12014  std::string RegexMatcher::describe() const {
12015  return "matches " + ::Catch::Detail::stringify(m_regex)
12016  + ((m_caseSensitivity == CaseSensitive::Choice::Yes) ? " case sensitively" : " case insensitively");
12017  }
12018 
12019  } // namespace StdString
12020 
12021  StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity) {
12022  return StdString::EqualsMatcher(StdString::CasedString(str, caseSensitivity));
12023  }
12024  StdString::ContainsMatcher Contains(std::string const &str, CaseSensitive::Choice caseSensitivity) {
12025  return StdString::ContainsMatcher(StdString::CasedString(str, caseSensitivity));
12026  }
12027  StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity) {
12028  return StdString::EndsWithMatcher(StdString::CasedString(str, caseSensitivity));
12029  }
12030  StdString::StartsWithMatcher StartsWith(std::string const &str, CaseSensitive::Choice caseSensitivity) {
12031  return StdString::StartsWithMatcher(StdString::CasedString(str, caseSensitivity));
12032  }
12033 
12034  StdString::RegexMatcher Matches(std::string const &regex, CaseSensitive::Choice caseSensitivity) {
12035  return StdString::RegexMatcher(regex, caseSensitivity);
12036  }
12037 
12038  } // namespace Matchers
12039 } // namespace Catch
12040 // end catch_matchers_string.cpp
12041 // start catch_message.cpp
12042 
12043 // start catch_uncaught_exceptions.h
12044 
12045 namespace Catch {
12046  bool uncaught_exceptions();
12047 } // end namespace Catch
12048 
12049 // end catch_uncaught_exceptions.h
12050 #include <cassert>
12051 #include <stack>
12052 
12053 namespace Catch {
12054  MessageInfo::MessageInfo(StringRef const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
12055  : macroName(_macroName)
12056  , lineInfo(_lineInfo)
12057  , type(_type)
12058  , sequence(++globalCount) {
12059  }
12060 
12061  bool MessageInfo::operator==(MessageInfo const &other) const {
12062  return sequence == other.sequence;
12063  }
12064 
12065  bool MessageInfo::operator<(MessageInfo const &other) const {
12066  return sequence < other.sequence;
12067  }
12068 
12069  // This may need protecting if threading support is added
12070  unsigned int MessageInfo::globalCount = 0;
12071 
12073 
12074  Catch::MessageBuilder::MessageBuilder(StringRef const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
12075  : m_info(macroName, lineInfo, type) {
12076  }
12077 
12079 
12080  ScopedMessage::ScopedMessage(MessageBuilder const &builder)
12081  : m_info(builder.m_info)
12082  , m_moved() {
12083  m_info.message = builder.m_stream.str();
12084  getResultCapture().pushScopedMessage(m_info);
12085  }
12086 
12087  ScopedMessage::ScopedMessage(ScopedMessage &&old)
12088  : m_info(old.m_info)
12089  , m_moved() {
12090  old.m_moved = true;
12091  }
12092 
12093  ScopedMessage::~ScopedMessage() {
12094  if (!uncaught_exceptions() && !m_moved) {
12095  getResultCapture().popScopedMessage(m_info);
12096  }
12097  }
12098 
12099  Capturer::Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names) {
12100  auto trimmed = [&](size_t start, size_t end) {
12101  while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
12102  ++start;
12103  }
12104  while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
12105  --end;
12106  }
12107  return names.substr(start, end - start + 1);
12108  };
12109  auto skipq = [&](size_t start, char quote) {
12110  for (auto i = start + 1; i < names.size(); ++i) {
12111  if (names[i] == quote)
12112  return i;
12113  if (names[i] == '\\')
12114  ++i;
12115  }
12116  CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
12117  };
12118 
12119  size_t start = 0;
12120  std::stack<char> openings;
12121  for (size_t pos = 0; pos < names.size(); ++pos) {
12122  char c = names[pos];
12123  switch (c) {
12124  case '[':
12125  case '{':
12126  case '(':
12127  // It is basically impossible to disambiguate between
12128  // comparison and start of template args in this context
12129  // case '<':
12130  openings.push(c);
12131  break;
12132  case ']':
12133  case '}':
12134  case ')':
12135  // case '>':
12136  openings.pop();
12137  break;
12138  case '"':
12139  case '\'':
12140  pos = skipq(pos, c);
12141  break;
12142  case ',':
12143  if (start != pos && openings.empty()) {
12144  m_messages.emplace_back(macroName, lineInfo, resultType);
12145  m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
12146  m_messages.back().message += " := ";
12147  start = pos;
12148  }
12149  }
12150  }
12151  assert(openings.empty() && "Mismatched openings");
12152  m_messages.emplace_back(macroName, lineInfo, resultType);
12153  m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
12154  m_messages.back().message += " := ";
12155  }
12156  Capturer::~Capturer() {
12157  if (!uncaught_exceptions()) {
12158  assert(m_captured == m_messages.size());
12159  for (size_t i = 0; i < m_captured; ++i)
12160  m_resultCapture.popScopedMessage(m_messages[i]);
12161  }
12162  }
12163 
12164  void Capturer::captureValue(size_t index, std::string const &value) {
12165  assert(index < m_messages.size());
12166  m_messages[index].message += value;
12167  m_resultCapture.pushScopedMessage(m_messages[index]);
12168  m_captured++;
12169  }
12170 
12171 } // end namespace Catch
12172 // end catch_message.cpp
12173 // start catch_output_redirect.cpp
12174 
12175 // start catch_output_redirect.h
12176 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
12177 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
12178 
12179 #include <cstdio>
12180 #include <iosfwd>
12181 #include <string>
12182 
12183 namespace Catch {
12184  class RedirectedStream {
12185  std::ostream &m_originalStream;
12186  std::ostream &m_redirectionStream;
12187  std::streambuf *m_prevBuf;
12188 
12189  public:
12190  RedirectedStream(std::ostream &originalStream, std::ostream &redirectionStream);
12191  ~RedirectedStream();
12192  };
12193 
12194  class RedirectedStdOut {
12195  ReusableStringStream m_rss;
12196  RedirectedStream m_cout;
12197 
12198  public:
12199  RedirectedStdOut();
12200  auto str() const -> std::string;
12201  };
12202 
12203  // StdErr has two constituent streams in C++, std::cerr and std::clog
12204  // This means that we need to redirect 2 streams into 1 to keep proper
12205  // order of writes
12206  class RedirectedStdErr {
12207  ReusableStringStream m_rss;
12208  RedirectedStream m_cerr;
12209  RedirectedStream m_clog;
12210 
12211  public:
12212  RedirectedStdErr();
12213  auto str() const -> std::string;
12214  };
12215 
12216  class RedirectedStreams {
12217  public:
12218  RedirectedStreams(RedirectedStreams const &) = delete;
12219  RedirectedStreams &operator=(RedirectedStreams const &) = delete;
12220  RedirectedStreams(RedirectedStreams &&) = delete;
12221  RedirectedStreams &operator=(RedirectedStreams &&) = delete;
12222 
12223  RedirectedStreams(std::string &redirectedCout, std::string &redirectedCerr);
12224  ~RedirectedStreams();
12225 
12226  private:
12227  std::string &m_redirectedCout;
12228  std::string &m_redirectedCerr;
12229  RedirectedStdOut m_redirectedStdOut;
12230  RedirectedStdErr m_redirectedStdErr;
12231  };
12232 
12233 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12234 
12235  // Windows's implementation of std::tmpfile is terrible (it tries
12236  // to create a file inside system folder, thus requiring elevated
12237  // privileges for the binary), so we have to use tmpnam(_s) and
12238  // create the file ourselves there.
12239  class TempFile {
12240  public:
12241  TempFile(TempFile const &) = delete;
12242  TempFile &operator=(TempFile const &) = delete;
12243  TempFile(TempFile &&) = delete;
12244  TempFile &operator=(TempFile &&) = delete;
12245 
12246  TempFile();
12247  ~TempFile();
12248 
12249  std::FILE *getFile();
12250  std::string getContents();
12251 
12252  private:
12253  std::FILE *m_file = nullptr;
12254 #if defined(_MSC_VER)
12255  char m_buffer[L_tmpnam] = {0};
12256 #endif
12257  };
12258 
12259  class OutputRedirect {
12260  public:
12261  OutputRedirect(OutputRedirect const &) = delete;
12262  OutputRedirect &operator=(OutputRedirect const &) = delete;
12263  OutputRedirect(OutputRedirect &&) = delete;
12264  OutputRedirect &operator=(OutputRedirect &&) = delete;
12265 
12266  OutputRedirect(std::string &stdout_dest, std::string &stderr_dest);
12267  ~OutputRedirect();
12268 
12269  private:
12270  int m_originalStdout = -1;
12271  int m_originalStderr = -1;
12272  TempFile m_stdoutFile;
12273  TempFile m_stderrFile;
12274  std::string &m_stdoutDest;
12275  std::string &m_stderrDest;
12276  };
12277 
12278 #endif
12279 
12280 } // end namespace Catch
12281 
12282 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H \
12283  // end catch_output_redirect.h
12284 #include <cstdio>
12285 #include <cstring>
12286 #include <fstream>
12287 #include <sstream>
12288 #include <stdexcept>
12289 
12290 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12291 #if defined(_MSC_VER)
12292 #include <io.h> //_dup and _dup2
12293 #define dup _dup
12294 #define dup2 _dup2
12295 #define fileno _fileno
12296 #else
12297 #include <unistd.h> // dup and dup2
12298 #endif
12299 #endif
12300 
12301 namespace Catch {
12302  RedirectedStream::RedirectedStream(std::ostream &originalStream, std::ostream &redirectionStream)
12303  : m_originalStream(originalStream)
12304  , m_redirectionStream(redirectionStream)
12305  , m_prevBuf(m_originalStream.rdbuf()) {
12306  m_originalStream.rdbuf(m_redirectionStream.rdbuf());
12307  }
12308 
12309  RedirectedStream::~RedirectedStream() {
12310  m_originalStream.rdbuf(m_prevBuf);
12311  }
12312 
12313  RedirectedStdOut::RedirectedStdOut()
12314  : m_cout(Catch::cout(), m_rss.get()) {
12315  }
12316  auto RedirectedStdOut::str() const -> std::string {
12317  return m_rss.str();
12318  }
12319 
12320  RedirectedStdErr::RedirectedStdErr()
12321  : m_cerr(Catch::cerr(), m_rss.get())
12322  , m_clog(Catch::clog(), m_rss.get()) {
12323  }
12324  auto RedirectedStdErr::str() const -> std::string {
12325  return m_rss.str();
12326  }
12327 
12328  RedirectedStreams::RedirectedStreams(std::string &redirectedCout, std::string &redirectedCerr)
12329  : m_redirectedCout(redirectedCout)
12330  , m_redirectedCerr(redirectedCerr) {
12331  }
12332 
12333  RedirectedStreams::~RedirectedStreams() {
12334  m_redirectedCout += m_redirectedStdOut.str();
12335  m_redirectedCerr += m_redirectedStdErr.str();
12336  }
12337 
12338 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12339 
12340 #if defined(_MSC_VER)
12341  TempFile::TempFile() {
12342  if (tmpnam_s(m_buffer)) {
12343  CATCH_RUNTIME_ERROR("Could not get a temp filename");
12344  }
12345  if (fopen_s(&m_file, m_buffer, "w+")) {
12346  char buffer[100];
12347  if (strerror_s(buffer, errno)) {
12348  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
12349  }
12350  CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
12351  }
12352  }
12353 #else
12354  TempFile::TempFile() {
12355  m_file = std::tmpfile();
12356  if (!m_file) {
12357  CATCH_RUNTIME_ERROR("Could not create a temp file.");
12358  }
12359  }
12360 
12361 #endif
12362 
12363  TempFile::~TempFile() {
12364  // TBD: What to do about errors here?
12365  std::fclose(m_file);
12366 // We manually create the file on Windows only, on Linux
12367 // it will be autodeleted
12368 #if defined(_MSC_VER)
12369  std::remove(m_buffer);
12370 #endif
12371  }
12372 
12373  FILE *TempFile::getFile() {
12374  return m_file;
12375  }
12376 
12377  std::string TempFile::getContents() {
12378  std::stringstream sstr;
12379  char buffer[100] = {};
12380  std::rewind(m_file);
12381  while (std::fgets(buffer, sizeof(buffer), m_file)) {
12382  sstr << buffer;
12383  }
12384  return sstr.str();
12385  }
12386 
12387  OutputRedirect::OutputRedirect(std::string &stdout_dest, std::string &stderr_dest)
12388  : m_originalStdout(dup(1))
12389  , m_originalStderr(dup(2))
12390  , m_stdoutDest(stdout_dest)
12391  , m_stderrDest(stderr_dest) {
12392  dup2(fileno(m_stdoutFile.getFile()), 1);
12393  dup2(fileno(m_stderrFile.getFile()), 2);
12394  }
12395 
12396  OutputRedirect::~OutputRedirect() {
12397  Catch::cout() << std::flush;
12398  fflush(stdout);
12399  // Since we support overriding these streams, we flush cerr
12400  // even though std::cerr is unbuffered
12401  Catch::cerr() << std::flush;
12402  Catch::clog() << std::flush;
12403  fflush(stderr);
12404 
12405  dup2(m_originalStdout, 1);
12406  dup2(m_originalStderr, 2);
12407 
12408  m_stdoutDest += m_stdoutFile.getContents();
12409  m_stderrDest += m_stderrFile.getContents();
12410  }
12411 
12412 #endif // CATCH_CONFIG_NEW_CAPTURE
12413 
12414 } // namespace Catch
12415 
12416 #if defined(CATCH_CONFIG_NEW_CAPTURE)
12417 #if defined(_MSC_VER)
12418 #undef dup
12419 #undef dup2
12420 #undef fileno
12421 #endif
12422 #endif
12423 // end catch_output_redirect.cpp
12424 // start catch_polyfills.cpp
12425 
12426 #include <cmath>
12427 
12428 namespace Catch {
12429 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
12430  bool isnan(float f) {
12431  return std::isnan(f);
12432  }
12433  bool isnan(double d) {
12434  return std::isnan(d);
12435  }
12436 #else
12437  // For now we only use this for embarcadero
12438  bool isnan(float f) {
12439  return std::_isnan(f);
12440  }
12441  bool isnan(double d) {
12442  return std::_isnan(d);
12443  }
12444 #endif
12445 
12446 } // end namespace Catch
12447 // end catch_polyfills.cpp
12448 // start catch_random_number_generator.cpp
12449 
12450 namespace Catch {
12451  namespace {
12452 #if defined(_MSC_VER)
12453 #pragma warning(push)
12454 #pragma warning(disable : 4146) // we negate uint32 during the rotate
12455 #endif
12456  // Safe rotr implementation thanks to John Regehr
12457  uint32_t rotate_right(uint32_t val, uint32_t count) {
12458  const uint32_t mask = 31;
12459  count &= mask;
12460  return (val >> count) | (val << (-count & mask));
12461  }
12462 
12463 #if defined(_MSC_VER)
12464 #pragma warning(pop)
12465 #endif
12466 
12467  } // namespace
12468 
12469  SimplePcg32::SimplePcg32(result_type seed_) {
12470  seed(seed_);
12471  }
12472 
12473  void SimplePcg32::seed(result_type seed_) {
12474  m_state = 0;
12475  (*this)();
12476  m_state += seed_;
12477  (*this)();
12478  }
12479 
12480  void SimplePcg32::discard(uint64_t skip) {
12481  // We could implement this to run in O(log n) steps, but this
12482  // should suffice for our use case.
12483  for (uint64_t s = 0; s < skip; ++s) {
12484  static_cast<void>((*this)());
12485  }
12486  }
12487 
12488  SimplePcg32::result_type SimplePcg32::operator()() {
12489  // prepare the output value
12490  const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
12491  const auto output = rotate_right(xorshifted, m_state >> 59u);
12492 
12493  // advance state
12494  m_state = m_state * 6364136223846793005ULL + s_inc;
12495 
12496  return output;
12497  }
12498 
12499  bool operator==(SimplePcg32 const &lhs, SimplePcg32 const &rhs) {
12500  return lhs.m_state == rhs.m_state;
12501  }
12502 
12503  bool operator!=(SimplePcg32 const &lhs, SimplePcg32 const &rhs) {
12504  return lhs.m_state != rhs.m_state;
12505  }
12506 } // namespace Catch
12507 // end catch_random_number_generator.cpp
12508 // start catch_registry_hub.cpp
12509 
12510 // start catch_test_case_registry_impl.h
12511 
12512 #include <algorithm>
12513 #include <ios>
12514 #include <set>
12515 #include <vector>
12516 
12517 namespace Catch {
12518  class TestCase;
12519  struct IConfig;
12520 
12521  std::vector<TestCase> sortTests(IConfig const &config, std::vector<TestCase> const &unsortedTestCases);
12522 
12523  bool isThrowSafe(TestCase const &testCase, IConfig const &config);
12524  bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config);
12525 
12526  void enforceNoDuplicateTestCases(std::vector<TestCase> const &functions);
12527 
12528  std::vector<TestCase> filterTests(std::vector<TestCase> const &testCases, TestSpec const &testSpec, IConfig const &config);
12529  std::vector<TestCase> const &getAllTestCasesSorted(IConfig const &config);
12530 
12531  class TestRegistry : public ITestCaseRegistry {
12532  public:
12533  virtual ~TestRegistry() = default;
12534 
12535  virtual void registerTest(TestCase const &testCase);
12536 
12537  std::vector<TestCase> const &getAllTests() const override;
12538  std::vector<TestCase> const &getAllTestsSorted(IConfig const &config) const override;
12539 
12540  private:
12541  std::vector<TestCase> m_functions;
12542  mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
12543  mutable std::vector<TestCase> m_sortedFunctions;
12544  std::size_t m_unnamedCount = 0;
12545  std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
12546  };
12547 
12549 
12550  class TestInvokerAsFunction : public ITestInvoker {
12551  void (*m_testAsFunction)();
12552 
12553  public:
12554  TestInvokerAsFunction(void (*testAsFunction)()) noexcept;
12555 
12556  void invoke() const override;
12557  };
12558 
12559  std::string extractClassName(StringRef const &classOrQualifiedMethodName);
12560 
12562 
12563 } // end namespace Catch
12564 
12565 // end catch_test_case_registry_impl.h
12566 // start catch_reporter_registry.h
12567 
12568 #include <map>
12569 
12570 namespace Catch {
12571  class ReporterRegistry : public IReporterRegistry {
12572  public:
12573  ~ReporterRegistry() override;
12574 
12575  IStreamingReporterPtr create(std::string const &name, IConfigPtr const &config) const override;
12576 
12577  void registerReporter(std::string const &name, IReporterFactoryPtr const &factory);
12578  void registerListener(IReporterFactoryPtr const &factory);
12579 
12580  FactoryMap const &getFactories() const override;
12581  Listeners const &getListeners() const override;
12582 
12583  private:
12584  FactoryMap m_factories;
12585  Listeners m_listeners;
12586  };
12587 } // namespace Catch
12588 
12589 // end catch_reporter_registry.h
12590 // start catch_tag_alias_registry.h
12591 
12592 // start catch_tag_alias.h
12593 
12594 #include <string>
12595 
12596 namespace Catch {
12597  struct TagAlias {
12598  TagAlias(std::string const &_tag, SourceLineInfo _lineInfo);
12599 
12600  std::string tag;
12601  SourceLineInfo lineInfo;
12602  };
12603 
12604 } // end namespace Catch
12605 
12606 // end catch_tag_alias.h
12607 #include <map>
12608 
12609 namespace Catch {
12610  class TagAliasRegistry : public ITagAliasRegistry {
12611  public:
12612  ~TagAliasRegistry() override;
12613  TagAlias const *find(std::string const &alias) const override;
12614  std::string expandAliases(std::string const &unexpandedTestSpec) const override;
12615  void add(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo);
12616 
12617  private:
12618  std::map<std::string, TagAlias> m_registry;
12619  };
12620 
12621 } // end namespace Catch
12622 
12623 // end catch_tag_alias_registry.h
12624 // start catch_startup_exception_registry.h
12625 
12626 #include <exception>
12627 #include <vector>
12628 
12629 namespace Catch {
12630  class StartupExceptionRegistry {
12631 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12632  public:
12633  void add(std::exception_ptr const &exception) noexcept;
12634  std::vector<std::exception_ptr> const &getExceptions() const noexcept;
12635 
12636  private:
12637  std::vector<std::exception_ptr> m_exceptions;
12638 #endif
12639  };
12640 
12641 } // end namespace Catch
12642 
12643 // end catch_startup_exception_registry.h
12644 // start catch_singletons.hpp
12645 
12646 namespace Catch {
12647  struct ISingleton {
12648  virtual ~ISingleton();
12649  };
12650 
12651  void addSingleton(ISingleton *singleton);
12652  void cleanupSingletons();
12653 
12654  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
12655  class Singleton : SingletonImplT, public ISingleton {
12656  static auto getInternal() -> Singleton * {
12657  static Singleton *s_instance = nullptr;
12658  if (!s_instance) {
12659  s_instance = new Singleton;
12660  addSingleton(s_instance);
12661  }
12662  return s_instance;
12663  }
12664 
12665  public:
12666  static auto get() -> InterfaceT const & { return *getInternal(); }
12667  static auto getMutable() -> MutableInterfaceT & { return *getInternal(); }
12668  };
12669 
12670 } // namespace Catch
12671 
12672 // end catch_singletons.hpp
12673 namespace Catch {
12674  namespace {
12675  class RegistryHub : public IRegistryHub, public IMutableRegistryHub, private NonCopyable {
12676  public: // IRegistryHub
12677  RegistryHub() = default;
12678  IReporterRegistry const &getReporterRegistry() const override { return m_reporterRegistry; }
12679  ITestCaseRegistry const &getTestCaseRegistry() const override { return m_testCaseRegistry; }
12680  IExceptionTranslatorRegistry const &getExceptionTranslatorRegistry() const override { return m_exceptionTranslatorRegistry; }
12681  ITagAliasRegistry const &getTagAliasRegistry() const override { return m_tagAliasRegistry; }
12682  StartupExceptionRegistry const &getStartupExceptionRegistry() const override { return m_exceptionRegistry; }
12683 
12684  public: // IMutableRegistryHub
12685  void registerReporter(std::string const &name, IReporterFactoryPtr const &factory) override {
12686  m_reporterRegistry.registerReporter(name, factory);
12687  }
12688  void registerListener(IReporterFactoryPtr const &factory) override { m_reporterRegistry.registerListener(factory); }
12689  void registerTest(TestCase const &testInfo) override { m_testCaseRegistry.registerTest(testInfo); }
12690  void registerTranslator(const IExceptionTranslator *translator) override {
12691  m_exceptionTranslatorRegistry.registerTranslator(translator);
12692  }
12693  void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) override {
12694  m_tagAliasRegistry.add(alias, tag, lineInfo);
12695  }
12696  void registerStartupException() noexcept override {
12697 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
12698  m_exceptionRegistry.add(std::current_exception());
12699 #else
12700  CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
12701 #endif
12702  }
12703  IMutableEnumValuesRegistry &getMutableEnumValuesRegistry() override { return m_enumValuesRegistry; }
12704 
12705  private:
12706  TestRegistry m_testCaseRegistry;
12707  ReporterRegistry m_reporterRegistry;
12708  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
12709  TagAliasRegistry m_tagAliasRegistry;
12710  StartupExceptionRegistry m_exceptionRegistry;
12711  Detail::EnumValuesRegistry m_enumValuesRegistry;
12712  };
12713  } // namespace
12714 
12715  using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
12716 
12717  IRegistryHub const &getRegistryHub() {
12718  return RegistryHubSingleton::get();
12719  }
12720  IMutableRegistryHub &getMutableRegistryHub() {
12721  return RegistryHubSingleton::getMutable();
12722  }
12723  void cleanUp() {
12724  cleanupSingletons();
12725  cleanUpContext();
12726  }
12727  std::string translateActiveException() {
12728  return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
12729  }
12730 
12731 } // end namespace Catch
12732 // end catch_registry_hub.cpp
12733 // start catch_reporter_registry.cpp
12734 
12735 namespace Catch {
12736  ReporterRegistry::~ReporterRegistry() = default;
12737 
12738  IStreamingReporterPtr ReporterRegistry::create(std::string const &name, IConfigPtr const &config) const {
12739  auto it = m_factories.find(name);
12740  if (it == m_factories.end())
12741  return nullptr;
12742  return it->second->create(ReporterConfig(config));
12743  }
12744 
12745  void ReporterRegistry::registerReporter(std::string const &name, IReporterFactoryPtr const &factory) {
12746  m_factories.emplace(name, factory);
12747  }
12748  void ReporterRegistry::registerListener(IReporterFactoryPtr const &factory) {
12749  m_listeners.push_back(factory);
12750  }
12751 
12752  IReporterRegistry::FactoryMap const &ReporterRegistry::getFactories() const {
12753  return m_factories;
12754  }
12755  IReporterRegistry::Listeners const &ReporterRegistry::getListeners() const {
12756  return m_listeners;
12757  }
12758 
12759 } // namespace Catch
12760 // end catch_reporter_registry.cpp
12761 // start catch_result_type.cpp
12762 
12763 namespace Catch {
12764  bool isOk(ResultWas::OfType resultType) {
12765  return (resultType & ResultWas::FailureBit) == 0;
12766  }
12767  bool isJustInfo(int flags) {
12768  return flags == ResultWas::Info;
12769  }
12770 
12771  ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs) {
12772  return static_cast<ResultDisposition::Flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
12773  }
12774 
12775  bool shouldContinueOnFailure(int flags) {
12776  return (flags & ResultDisposition::ContinueOnFailure) != 0;
12777  }
12778  bool shouldSuppressFailure(int flags) {
12779  return (flags & ResultDisposition::SuppressFail) != 0;
12780  }
12781 
12782 } // end namespace Catch
12783 // end catch_result_type.cpp
12784 // start catch_run_context.cpp
12785 
12786 #include <algorithm>
12787 #include <cassert>
12788 #include <sstream>
12789 
12790 namespace Catch {
12791  namespace Generators {
12792  struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
12793  GeneratorBasePtr m_generator;
12794 
12795  GeneratorTracker(TestCaseTracking::NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent)
12796  : TrackerBase(nameAndLocation, ctx, parent) {
12797  }
12798  ~GeneratorTracker();
12799 
12800  static GeneratorTracker &acquire(TrackerContext &ctx, TestCaseTracking::NameAndLocation const &nameAndLocation) {
12801  std::shared_ptr<GeneratorTracker> tracker;
12802 
12803  ITracker &currentTracker = ctx.currentTracker();
12804  // Under specific circumstances, the generator we want
12805  // to acquire is also the current tracker. If this is
12806  // the case, we have to avoid looking through current
12807  // tracker's children, and instead return the current
12808  // tracker.
12809  // A case where this check is important is e.g.
12810  // for (int i = 0; i < 5; ++i) {
12811  // int n = GENERATE(1, 2);
12812  // }
12813  //
12814  // without it, the code above creates 5 nested generators.
12815  if (currentTracker.nameAndLocation() == nameAndLocation) {
12816  auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
12817  assert(thisTracker);
12818  assert(thisTracker->isGeneratorTracker());
12819  tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
12820  } else if (TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
12821  assert(childTracker);
12822  assert(childTracker->isGeneratorTracker());
12823  tracker = std::static_pointer_cast<GeneratorTracker>(childTracker);
12824  } else {
12825  tracker = std::make_shared<GeneratorTracker>(nameAndLocation, ctx, &currentTracker);
12826  currentTracker.addChild(tracker);
12827  }
12828 
12829  if (!tracker->isComplete()) {
12830  tracker->open();
12831  }
12832 
12833  return *tracker;
12834  }
12835 
12836  // TrackerBase interface
12837  bool isGeneratorTracker() const override { return true; }
12838  auto hasGenerator() const -> bool override { return !!m_generator; }
12839  void close() override {
12840  TrackerBase::close();
12841  // If a generator has a child (it is followed by a section)
12842  // and none of its children have started, then we must wait
12843  // until later to start consuming its values.
12844  // This catches cases where `GENERATE` is placed between two
12845  // `SECTION`s.
12846  // **The check for m_children.empty cannot be removed**.
12847  // doing so would break `GENERATE` _not_ followed by `SECTION`s.
12848  const bool should_wait_for_child = [&]() {
12849  // No children -> nobody to wait for
12850  if (m_children.empty()) {
12851  return false;
12852  }
12853  // If at least one child started executing, don't wait
12854  if (std::find_if(m_children.begin(),
12855  m_children.end(),
12856  [](TestCaseTracking::ITrackerPtr tracker) { return tracker->hasStarted(); })
12857  != m_children.end()) {
12858  return false;
12859  }
12860 
12861  // No children have started. We need to check if they _can_
12862  // start, and thus we should wait for them, or they cannot
12863  // start (due to filters), and we shouldn't wait for them
12864  auto *parent = m_parent;
12865  // This is safe: there is always at least one section
12866  // tracker in a test case tracking tree
12867  while (!parent->isSectionTracker()) {
12868  parent = &(parent->parent());
12869  }
12870  assert(parent && "Missing root (test case) level section");
12871 
12872  auto const &parentSection = static_cast<SectionTracker &>(*parent);
12873  auto const &filters = parentSection.getFilters();
12874  // No filters -> no restrictions on running sections
12875  if (filters.empty()) {
12876  return true;
12877  }
12878 
12879  for (auto const &child : m_children) {
12880  if (child->isSectionTracker()
12881  && std::find(filters.begin(), filters.end(), static_cast<SectionTracker &>(*child).trimmedName()) != filters.end()) {
12882  return true;
12883  }
12884  }
12885  return false;
12886  }();
12887 
12888  // This check is a bit tricky, because m_generator->next()
12889  // has a side-effect, where it consumes generator's current
12890  // value, but we do not want to invoke the side-effect if
12891  // this generator is still waiting for any child to start.
12892  if (should_wait_for_child || (m_runState == CompletedSuccessfully && m_generator->next())) {
12893  m_children.clear();
12894  m_runState = Executing;
12895  }
12896  }
12897 
12898  // IGeneratorTracker interface
12899  auto getGenerator() const -> GeneratorBasePtr const & override { return m_generator; }
12900  void setGenerator(GeneratorBasePtr &&generator) override { m_generator = std::move(generator); }
12901  };
12902  GeneratorTracker::~GeneratorTracker() {}
12903  } // namespace Generators
12904 
12905  RunContext::RunContext(IConfigPtr const &_config, IStreamingReporterPtr &&reporter)
12906  : m_runInfo(_config->name())
12907  , m_context(getCurrentMutableContext())
12908  , m_config(_config)
12909  , m_reporter(std::move(reporter))
12910  , m_lastAssertionInfo{StringRef(), SourceLineInfo("", 0), StringRef(), ResultDisposition::Normal}
12911  , m_includeSuccessfulResults(m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions) {
12912  m_context.setRunner(this);
12913  m_context.setConfig(m_config);
12914  m_context.setResultCapture(this);
12915  m_reporter->testRunStarting(m_runInfo);
12916  }
12917 
12918  RunContext::~RunContext() {
12919  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
12920  }
12921 
12922  void RunContext::testGroupStarting(std::string const &testSpec, std::size_t groupIndex, std::size_t groupsCount) {
12923  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
12924  }
12925 
12926  void RunContext::testGroupEnded(std::string const &testSpec, Totals const &totals, std::size_t groupIndex, std::size_t groupsCount) {
12927  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
12928  }
12929 
12930  Totals RunContext::runTest(TestCase const &testCase) {
12931  Totals prevTotals = m_totals;
12932 
12933  std::string redirectedCout;
12934  std::string redirectedCerr;
12935 
12936  auto const &testInfo = testCase.getTestCaseInfo();
12937 
12938  m_reporter->testCaseStarting(testInfo);
12939 
12940  m_activeTestCase = &testCase;
12941 
12942  ITracker &rootTracker = m_trackerContext.startRun();
12943  assert(rootTracker.isSectionTracker());
12944  static_cast<SectionTracker &>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
12945  do {
12946  m_trackerContext.startCycle();
12947  m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
12948  runCurrentTest(redirectedCout, redirectedCerr);
12949  } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
12950 
12951  Totals deltaTotals = m_totals.delta(prevTotals);
12952  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
12953  deltaTotals.assertions.failed++;
12954  deltaTotals.testCases.passed--;
12955  deltaTotals.testCases.failed++;
12956  }
12957  m_totals.testCases += deltaTotals.testCases;
12958  m_reporter->testCaseEnded(TestCaseStats(testInfo, deltaTotals, redirectedCout, redirectedCerr, aborting()));
12959 
12960  m_activeTestCase = nullptr;
12961  m_testCaseTracker = nullptr;
12962 
12963  return deltaTotals;
12964  }
12965 
12966  IConfigPtr RunContext::config() const {
12967  return m_config;
12968  }
12969 
12970  IStreamingReporter &RunContext::reporter() const {
12971  return *m_reporter;
12972  }
12973 
12974  void RunContext::assertionEnded(AssertionResult const &result) {
12975  if (result.getResultType() == ResultWas::Ok) {
12976  m_totals.assertions.passed++;
12977  m_lastAssertionPassed = true;
12978  } else if (!result.isOk()) {
12979  m_lastAssertionPassed = false;
12980  if (m_activeTestCase->getTestCaseInfo().okToFail())
12981  m_totals.assertions.failedButOk++;
12982  else
12983  m_totals.assertions.failed++;
12984  } else {
12985  m_lastAssertionPassed = true;
12986  }
12987 
12988  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
12989  // and should be let to clear themselves out.
12990  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
12991 
12992  if (result.getResultType() != ResultWas::Warning)
12993  m_messageScopes.clear();
12994 
12995  // Reset working state
12996  resetAssertionInfo();
12997  m_lastResult = result;
12998  }
12999  void RunContext::resetAssertionInfo() {
13000  m_lastAssertionInfo.macroName = StringRef();
13001  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
13002  }
13003 
13004  bool RunContext::sectionStarted(SectionInfo const &sectionInfo, Counts &assertions) {
13005  ITracker &sectionTracker
13006  = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
13007  if (!sectionTracker.isOpen())
13008  return false;
13009  m_activeSections.push_back(&sectionTracker);
13010 
13011  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
13012 
13013  m_reporter->sectionStarting(sectionInfo);
13014 
13015  assertions = m_totals.assertions;
13016 
13017  return true;
13018  }
13019  auto RunContext::acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo) -> IGeneratorTracker & {
13020  using namespace Generators;
13021  GeneratorTracker &tracker
13022  = GeneratorTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(static_cast<std::string>(generatorName), lineInfo));
13023  m_lastAssertionInfo.lineInfo = lineInfo;
13024  return tracker;
13025  }
13026 
13027  bool RunContext::testForMissingAssertions(Counts &assertions) {
13028  if (assertions.total() != 0)
13029  return false;
13030  if (!m_config->warnAboutMissingAssertions())
13031  return false;
13032  if (m_trackerContext.currentTracker().hasChildren())
13033  return false;
13034  m_totals.assertions.failed++;
13035  assertions.failed++;
13036  return true;
13037  }
13038 
13039  void RunContext::sectionEnded(SectionEndInfo const &endInfo) {
13040  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
13041  bool missingAssertions = testForMissingAssertions(assertions);
13042 
13043  if (!m_activeSections.empty()) {
13044  m_activeSections.back()->close();
13045  m_activeSections.pop_back();
13046  }
13047 
13048  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
13049  m_messages.clear();
13050  m_messageScopes.clear();
13051  }
13052 
13053  void RunContext::sectionEndedEarly(SectionEndInfo const &endInfo) {
13054  if (m_unfinishedSections.empty())
13055  m_activeSections.back()->fail();
13056  else
13057  m_activeSections.back()->close();
13058  m_activeSections.pop_back();
13059 
13060  m_unfinishedSections.push_back(endInfo);
13061  }
13062 
13063 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
13064  void RunContext::benchmarkPreparing(std::string const &name) {
13065  m_reporter->benchmarkPreparing(name);
13066  }
13067  void RunContext::benchmarkStarting(BenchmarkInfo const &info) {
13068  m_reporter->benchmarkStarting(info);
13069  }
13070  void RunContext::benchmarkEnded(BenchmarkStats<> const &stats) {
13071  m_reporter->benchmarkEnded(stats);
13072  }
13073  void RunContext::benchmarkFailed(std::string const &error) {
13074  m_reporter->benchmarkFailed(error);
13075  }
13076 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
13077 
13078  void RunContext::pushScopedMessage(MessageInfo const &message) {
13079  m_messages.push_back(message);
13080  }
13081 
13082  void RunContext::popScopedMessage(MessageInfo const &message) {
13083  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
13084  }
13085 
13086  void RunContext::emplaceUnscopedMessage(MessageBuilder const &builder) {
13087  m_messageScopes.emplace_back(builder);
13088  }
13089 
13090  std::string RunContext::getCurrentTestName() const {
13091  return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name : std::string();
13092  }
13093 
13094  const AssertionResult *RunContext::getLastResult() const {
13095  return &(*m_lastResult);
13096  }
13097 
13098  void RunContext::exceptionEarlyReported() {
13099  m_shouldReportUnexpected = false;
13100  }
13101 
13102  void RunContext::handleFatalErrorCondition(StringRef message) {
13103  // First notify reporter that bad things happened
13104  m_reporter->fatalErrorEncountered(message);
13105 
13106  // Don't rebuild the result -- the stringification itself can cause more fatal errors
13107  // Instead, fake a result data.
13108  AssertionResultData tempResult(ResultWas::FatalErrorCondition, {false});
13109  tempResult.message = static_cast<std::string>(message);
13110  AssertionResult result(m_lastAssertionInfo, tempResult);
13111 
13112  assertionEnded(result);
13113 
13114  handleUnfinishedSections();
13115 
13116  // Recreate section for test case (as we will lose the one that was in scope)
13117  auto const &testCaseInfo = m_activeTestCase->getTestCaseInfo();
13118  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
13119 
13120  Counts assertions;
13121  assertions.failed = 1;
13122  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
13123  m_reporter->sectionEnded(testCaseSectionStats);
13124 
13125  auto const &testInfo = m_activeTestCase->getTestCaseInfo();
13126 
13127  Totals deltaTotals;
13128  deltaTotals.testCases.failed = 1;
13129  deltaTotals.assertions.failed = 1;
13130  m_reporter->testCaseEnded(TestCaseStats(testInfo, deltaTotals, std::string(), std::string(), false));
13131  m_totals.testCases.failed++;
13132  testGroupEnded(std::string(), m_totals, 1, 1);
13133  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
13134  }
13135 
13136  bool RunContext::lastAssertionPassed() {
13137  return m_lastAssertionPassed;
13138  }
13139 
13140  void RunContext::assertionPassed() {
13141  m_lastAssertionPassed = true;
13142  ++m_totals.assertions.passed;
13143  resetAssertionInfo();
13144  m_messageScopes.clear();
13145  }
13146 
13147  bool RunContext::aborting() const {
13148  return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
13149  }
13150 
13151  void RunContext::runCurrentTest(std::string &redirectedCout, std::string &redirectedCerr) {
13152  auto const &testCaseInfo = m_activeTestCase->getTestCaseInfo();
13153  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
13154  m_reporter->sectionStarting(testCaseSection);
13155  Counts prevAssertions = m_totals.assertions;
13156  double duration = 0;
13157  m_shouldReportUnexpected = true;
13158  m_lastAssertionInfo = {"TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal};
13159 
13160  seedRng(*m_config);
13161 
13162  Timer timer;
13163  CATCH_TRY {
13164  if (m_reporter->getPreferences().shouldRedirectStdOut) {
13165 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
13166  RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
13167 
13168  timer.start();
13169  invokeActiveTestCase();
13170 #else
13171  OutputRedirect r(redirectedCout, redirectedCerr);
13172  timer.start();
13173  invokeActiveTestCase();
13174 #endif
13175  } else {
13176  timer.start();
13177  invokeActiveTestCase();
13178  }
13179  duration = timer.getElapsedSeconds();
13180  }
13181  CATCH_CATCH_ANON(TestFailureException &) {
13182  // This just means the test was aborted due to failure
13183  }
13184  CATCH_CATCH_ALL {
13185  // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
13186  // are reported without translation at the point of origin.
13187  if (m_shouldReportUnexpected) {
13188  AssertionReaction dummyReaction;
13189  handleUnexpectedInflightException(m_lastAssertionInfo, translateActiveException(), dummyReaction);
13190  }
13191  }
13192  Counts assertions = m_totals.assertions - prevAssertions;
13193  bool missingAssertions = testForMissingAssertions(assertions);
13194 
13195  m_testCaseTracker->close();
13196  handleUnfinishedSections();
13197  m_messages.clear();
13198  m_messageScopes.clear();
13199 
13200  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
13201  m_reporter->sectionEnded(testCaseSectionStats);
13202  }
13203 
13204  void RunContext::invokeActiveTestCase() {
13205  FatalConditionHandlerGuard _(&m_fatalConditionhandler);
13206  m_activeTestCase->invoke();
13207  }
13208 
13209  void RunContext::handleUnfinishedSections() {
13210  // If sections ended prematurely due to an exception we stored their
13211  // infos here so we can tear them down outside the unwind process.
13212  for (auto it = m_unfinishedSections.rbegin(), itEnd = m_unfinishedSections.rend(); it != itEnd; ++it)
13213  sectionEnded(*it);
13214  m_unfinishedSections.clear();
13215  }
13216 
13217  void RunContext::handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction) {
13218  m_reporter->assertionStarting(info);
13219 
13220  bool negated = isFalseTest(info.resultDisposition);
13221  bool result = expr.getResult() != negated;
13222 
13223  if (result) {
13224  if (!m_includeSuccessfulResults) {
13225  assertionPassed();
13226  } else {
13227  reportExpr(info, ResultWas::Ok, &expr, negated);
13228  }
13229  } else {
13230  reportExpr(info, ResultWas::ExpressionFailed, &expr, negated);
13231  populateReaction(reaction);
13232  }
13233  }
13234  void RunContext::reportExpr(AssertionInfo const &info, ResultWas::OfType resultType, ITransientExpression const *expr, bool negated) {
13235  m_lastAssertionInfo = info;
13236  AssertionResultData data(resultType, LazyExpression(negated));
13237 
13238  AssertionResult assertionResult{info, data};
13239  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
13240 
13241  assertionEnded(assertionResult);
13242  }
13243 
13244  void RunContext::handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, AssertionReaction &reaction) {
13245  m_reporter->assertionStarting(info);
13246 
13247  m_lastAssertionInfo = info;
13248 
13249  AssertionResultData data(resultType, LazyExpression(false));
13250  data.message = static_cast<std::string>(message);
13251  AssertionResult assertionResult{m_lastAssertionInfo, data};
13252  assertionEnded(assertionResult);
13253  if (!assertionResult.isOk())
13254  populateReaction(reaction);
13255  }
13256  void RunContext::handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction) {
13257  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
13258  }
13259 
13260  void RunContext::handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, AssertionReaction &reaction) {
13261  m_lastAssertionInfo = info;
13262 
13263  AssertionResultData data(ResultWas::ThrewException, LazyExpression(false));
13264  data.message = message;
13265  AssertionResult assertionResult{info, data};
13266  assertionEnded(assertionResult);
13267  populateReaction(reaction);
13268  }
13269 
13270  void RunContext::populateReaction(AssertionReaction &reaction) {
13271  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
13272  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
13273  }
13274 
13275  void RunContext::handleIncomplete(AssertionInfo const &info) {
13276  m_lastAssertionInfo = info;
13277 
13278  AssertionResultData data(ResultWas::ThrewException, LazyExpression(false));
13279  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
13280  AssertionResult assertionResult{info, data};
13281  assertionEnded(assertionResult);
13282  }
13283  void RunContext::handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction) {
13284  m_lastAssertionInfo = info;
13285 
13286  AssertionResultData data(resultType, LazyExpression(false));
13287  AssertionResult assertionResult{info, data};
13288  assertionEnded(assertionResult);
13289 
13290  if (!assertionResult.isOk())
13291  populateReaction(reaction);
13292  }
13293 
13294  IResultCapture &getResultCapture() {
13295  if (auto *capture = getCurrentContext().getResultCapture())
13296  return *capture;
13297  else
13298  CATCH_INTERNAL_ERROR("No result capture instance");
13299  }
13300 
13301  void seedRng(IConfig const &config) {
13302  if (config.rngSeed() != 0) {
13303  std::srand(config.rngSeed());
13304  rng().seed(config.rngSeed());
13305  }
13306  }
13307 
13308  unsigned int rngSeed() {
13309  return getCurrentContext().getConfig()->rngSeed();
13310  }
13311 
13312 } // namespace Catch
13313 // end catch_run_context.cpp
13314 // start catch_section.cpp
13315 
13316 namespace Catch {
13317  Section::Section(SectionInfo const &info)
13318  : m_info(info)
13319  , m_sectionIncluded(getResultCapture().sectionStarted(m_info, m_assertions)) {
13320  m_timer.start();
13321  }
13322 
13323  Section::~Section() {
13324  if (m_sectionIncluded) {
13325  SectionEndInfo endInfo{m_info, m_assertions, m_timer.getElapsedSeconds()};
13326  if (uncaught_exceptions())
13327  getResultCapture().sectionEndedEarly(endInfo);
13328  else
13329  getResultCapture().sectionEnded(endInfo);
13330  }
13331  }
13332 
13333  // This indicates whether the section should be executed or not
13334  Section::operator bool() const {
13335  return m_sectionIncluded;
13336  }
13337 
13338 } // end namespace Catch
13339 // end catch_section.cpp
13340 // start catch_section_info.cpp
13341 
13342 namespace Catch {
13343  SectionInfo::SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name)
13344  : name(_name)
13345  , lineInfo(_lineInfo) {
13346  }
13347 
13348 } // end namespace Catch
13349 // end catch_section_info.cpp
13350 // start catch_session.cpp
13351 
13352 // start catch_session.h
13353 
13354 #include <memory>
13355 
13356 namespace Catch {
13357  class Session : NonCopyable {
13358  public:
13359  Session();
13360  ~Session() override;
13361 
13362  void showHelp() const;
13363  void libIdentify();
13364 
13365  int applyCommandLine(int argc, char const *const *argv);
13366 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13367  int applyCommandLine(int argc, wchar_t const *const *argv);
13368 #endif
13369 
13370  void useConfigData(ConfigData const &configData);
13371 
13372  template<typename CharT>
13373  int run(int argc, CharT const *const argv[]) {
13374  if (m_startupExceptions)
13375  return 1;
13376  int returnCode = applyCommandLine(argc, argv);
13377  if (returnCode == 0)
13378  returnCode = run();
13379  return returnCode;
13380  }
13381 
13382  int run();
13383 
13384  clara::Parser const &cli() const;
13385  void cli(clara::Parser const &newParser);
13386  ConfigData &configData();
13387  Config &config();
13388 
13389  private:
13390  int runInternal();
13391 
13392  clara::Parser m_cli;
13393  ConfigData m_configData;
13394  std::shared_ptr<Config> m_config;
13395  bool m_startupExceptions = false;
13396  };
13397 
13398 } // end namespace Catch
13399 
13400 // end catch_session.h
13401 // start catch_version.h
13402 
13403 #include <iosfwd>
13404 
13405 namespace Catch {
13406  // Versioning information
13407  struct Version {
13408  Version(Version const &) = delete;
13409  Version &operator=(Version const &) = delete;
13410  Version(unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, char const *const _branchName, unsigned int _buildNumber);
13411 
13412  unsigned int const majorVersion;
13413  unsigned int const minorVersion;
13414  unsigned int const patchNumber;
13415 
13416  // buildNumber is only used if branchName is not null
13417  char const *const branchName;
13418  unsigned int const buildNumber;
13419 
13420  friend std::ostream &operator<<(std::ostream &os, Version const &version);
13421  };
13422 
13423  Version const &libraryVersion();
13424 } // namespace Catch
13425 
13426 // end catch_version.h
13427 #include <cstdlib>
13428 #include <iomanip>
13429 #include <iterator>
13430 #include <set>
13431 
13432 namespace Catch {
13433  namespace {
13434  const int MaxExitCode = 255;
13435 
13436  IStreamingReporterPtr createReporter(std::string const &reporterName, IConfigPtr const &config) {
13437  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
13438  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
13439 
13440  return reporter;
13441  }
13442 
13443  IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const &config) {
13444  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
13445  return createReporter(config->getReporterName(), config);
13446  }
13447 
13448  // On older platforms, returning std::unique_ptr<ListeningReporter>
13449  // when the return type is std::unique_ptr<IStreamingReporter>
13450  // doesn't compile without a std::move call. However, this causes
13451  // a warning on newer platforms. Thus, we have to work around
13452  // it a bit and downcast the pointer manually.
13453  auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
13454  auto &multi = static_cast<ListeningReporter &>(*ret);
13455  auto const &listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
13456  for (auto const &listener : listeners) {
13457  multi.addListener(listener->create(Catch::ReporterConfig(config)));
13458  }
13459  multi.addReporter(createReporter(config->getReporterName(), config));
13460  return ret;
13461  }
13462 
13463  class TestGroup {
13464  public:
13465  explicit TestGroup(std::shared_ptr<Config> const &config)
13466  : m_config{config}
13467  , m_context{config, makeReporter(config)} {
13468  auto const &allTestCases = getAllTestCasesSorted(*m_config);
13469  m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
13470  auto const &invalidArgs = m_config->testSpec().getInvalidArgs();
13471 
13472  if (m_matches.empty() && invalidArgs.empty()) {
13473  for (auto const &test : allTestCases)
13474  if (!test.isHidden())
13475  m_tests.emplace(&test);
13476  } else {
13477  for (auto const &match : m_matches)
13478  m_tests.insert(match.tests.begin(), match.tests.end());
13479  }
13480  }
13481 
13482  Totals execute() {
13483  auto const &invalidArgs = m_config->testSpec().getInvalidArgs();
13484  Totals totals;
13485  m_context.testGroupStarting(m_config->name(), 1, 1);
13486  for (auto const &testCase : m_tests) {
13487  if (!m_context.aborting())
13488  totals += m_context.runTest(*testCase);
13489  else
13490  m_context.reporter().skipTest(*testCase);
13491  }
13492 
13493  for (auto const &match : m_matches) {
13494  if (match.tests.empty()) {
13495  m_context.reporter().noMatchingTestCases(match.name);
13496  totals.error = -1;
13497  }
13498  }
13499 
13500  if (!invalidArgs.empty()) {
13501  for (auto const &invalidArg : invalidArgs)
13502  m_context.reporter().reportInvalidArguments(invalidArg);
13503  }
13504 
13505  m_context.testGroupEnded(m_config->name(), totals, 1, 1);
13506  return totals;
13507  }
13508 
13509  private:
13510  using Tests = std::set<TestCase const *>;
13511 
13512  std::shared_ptr<Config> m_config;
13513  RunContext m_context;
13514  Tests m_tests;
13515  TestSpec::Matches m_matches;
13516  };
13517 
13518  void applyFilenamesAsTags(Catch::IConfig const &config) {
13519  auto &tests = const_cast<std::vector<TestCase> &>(getAllTestCasesSorted(config));
13520  for (auto &testCase : tests) {
13521  auto tags = testCase.tags;
13522 
13523  std::string filename = testCase.lineInfo.file;
13524  auto lastSlash = filename.find_last_of("\\/");
13525  if (lastSlash != std::string::npos) {
13526  filename.erase(0, lastSlash);
13527  filename[0] = '#';
13528  }
13529 
13530  auto lastDot = filename.find_last_of('.');
13531  if (lastDot != std::string::npos) {
13532  filename.erase(lastDot);
13533  }
13534 
13535  tags.push_back(std::move(filename));
13536  setTags(testCase, tags);
13537  }
13538  }
13539 
13540  } // namespace
13541 
13542  Session::Session() {
13543  static bool alreadyInstantiated = false;
13544  if (alreadyInstantiated) {
13545  CATCH_TRY { CATCH_INTERNAL_ERROR("Only one instance of Catch::Session can ever be used"); }
13546  CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
13547  }
13548 
13549 // There cannot be exceptions at startup in no-exception mode.
13550 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13551  const auto &exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
13552  if (!exceptions.empty()) {
13553  config();
13554  getCurrentMutableContext().setConfig(m_config);
13555 
13556  m_startupExceptions = true;
13557  Colour colourGuard(Colour::Red);
13558  Catch::cerr() << "Errors occurred during startup!" << '\n';
13559  // iterate over all exceptions and notify user
13560  for (const auto &ex_ptr : exceptions) {
13561  try {
13562  std::rethrow_exception(ex_ptr);
13563  } catch (std::exception const &ex) {
13564  Catch::cerr() << Column(ex.what()).indent(2) << '\n';
13565  }
13566  }
13567  }
13568 #endif
13569 
13570  alreadyInstantiated = true;
13571  m_cli = makeCommandLineParser(m_configData);
13572  }
13573  Session::~Session() {
13574  Catch::cleanUp();
13575  }
13576 
13577  void Session::showHelp() const {
13578  Catch::cout() << "\nCatch v" << libraryVersion() << "\n"
13579  << m_cli << std::endl
13580  << "For more detailed usage please see the project docs\n"
13581  << std::endl;
13582  }
13583  void Session::libIdentify() {
13584  Catch::cout() << std::left << std::setw(16) << "description: "
13585  << "A Catch2 test executable\n"
13586  << std::left << std::setw(16) << "category: "
13587  << "testframework\n"
13588  << std::left << std::setw(16) << "framework: "
13589  << "Catch Test\n"
13590  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
13591  }
13592 
13593  int Session::applyCommandLine(int argc, char const *const *argv) {
13594  if (m_startupExceptions)
13595  return 1;
13596 
13597  auto result = m_cli.parse(clara::Args(argc, argv));
13598  if (!result) {
13599  config();
13600  getCurrentMutableContext().setConfig(m_config);
13601  Catch::cerr() << Colour(Colour::Red) << "\nError(s) in input:\n"
13602  << Column(result.errorMessage()).indent(2) << "\n\n";
13603  Catch::cerr() << "Run with -? for usage\n"
13604  << std::endl;
13605  return MaxExitCode;
13606  }
13607 
13608  if (m_configData.showHelp)
13609  showHelp();
13610  if (m_configData.libIdentify)
13611  libIdentify();
13612  m_config.reset();
13613  return 0;
13614  }
13615 
13616 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
13617  int Session::applyCommandLine(int argc, wchar_t const *const *argv) {
13618  char **utf8Argv = new char *[argc];
13619 
13620  for (int i = 0; i < argc; ++i) {
13621  int bufSize = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr);
13622 
13623  utf8Argv[i] = new char[bufSize];
13624 
13625  WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr);
13626  }
13627 
13628  int returnCode = applyCommandLine(argc, utf8Argv);
13629 
13630  for (int i = 0; i < argc; ++i)
13631  delete[] utf8Argv[i];
13632 
13633  delete[] utf8Argv;
13634 
13635  return returnCode;
13636  }
13637 #endif
13638 
13639  void Session::useConfigData(ConfigData const &configData) {
13640  m_configData = configData;
13641  m_config.reset();
13642  }
13643 
13644  int Session::run() {
13645  if ((m_configData.waitForKeypress & WaitForKeypress::BeforeStart) != 0) {
13646  Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
13647  static_cast<void>(std::getchar());
13648  }
13649  int exitCode = runInternal();
13650  if ((m_configData.waitForKeypress & WaitForKeypress::BeforeExit) != 0) {
13651  Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
13652  static_cast<void>(std::getchar());
13653  }
13654  return exitCode;
13655  }
13656 
13657  clara::Parser const &Session::cli() const {
13658  return m_cli;
13659  }
13660  void Session::cli(clara::Parser const &newParser) {
13661  m_cli = newParser;
13662  }
13663  ConfigData &Session::configData() {
13664  return m_configData;
13665  }
13666  Config &Session::config() {
13667  if (!m_config)
13668  m_config = std::make_shared<Config>(m_configData);
13669  return *m_config;
13670  }
13671 
13672  int Session::runInternal() {
13673  if (m_startupExceptions)
13674  return 1;
13675 
13676  if (m_configData.showHelp || m_configData.libIdentify) {
13677  return 0;
13678  }
13679 
13680  CATCH_TRY {
13681  config(); // Force config to be constructed
13682 
13683  seedRng(*m_config);
13684 
13685  if (m_configData.filenamesAsTags)
13686  applyFilenamesAsTags(*m_config);
13687 
13688  // Handle list request
13689  if (Option<std::size_t> listed = list(m_config))
13690  return static_cast<int>(*listed);
13691 
13692  TestGroup tests{m_config};
13693  auto const totals = tests.execute();
13694 
13695  if (m_config->warnAboutNoTests() && totals.error == -1)
13696  return 2;
13697 
13698  // Note that on unices only the lower 8 bits are usually used, clamping
13699  // the return value to 255 prevents false negative when some multiple
13700  // of 256 tests has failed
13701  return (std::min)(MaxExitCode, (std::max)(totals.error, static_cast<int>(totals.assertions.failed)));
13702  }
13703 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13704  catch (std::exception &ex) {
13705  Catch::cerr() << ex.what() << std::endl;
13706  return MaxExitCode;
13707  }
13708 #endif
13709  }
13710 
13711 } // end namespace Catch
13712 // end catch_session.cpp
13713 // start catch_singletons.cpp
13714 
13715 #include <vector>
13716 
13717 namespace Catch {
13718  namespace {
13719  static auto getSingletons() -> std::vector<ISingleton *> *& {
13720  static std::vector<ISingleton *> *g_singletons = nullptr;
13721  if (!g_singletons)
13722  g_singletons = new std::vector<ISingleton *>();
13723  return g_singletons;
13724  }
13725  } // namespace
13726 
13727  ISingleton::~ISingleton() {}
13728 
13729  void addSingleton(ISingleton *singleton) {
13730  getSingletons()->push_back(singleton);
13731  }
13732  void cleanupSingletons() {
13733  auto &singletons = getSingletons();
13734  for (auto singleton : *singletons)
13735  delete singleton;
13736  delete singletons;
13737  singletons = nullptr;
13738  }
13739 
13740 } // namespace Catch
13741 // end catch_singletons.cpp
13742 // start catch_startup_exception_registry.cpp
13743 
13744 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
13745 namespace Catch {
13746  void StartupExceptionRegistry::add(std::exception_ptr const &exception) noexcept {
13747  CATCH_TRY { m_exceptions.push_back(exception); }
13748  CATCH_CATCH_ALL {
13749  // If we run out of memory during start-up there's really not a lot more we can do about it
13750  std::terminate();
13751  }
13752  }
13753 
13754  std::vector<std::exception_ptr> const &StartupExceptionRegistry::getExceptions() const noexcept {
13755  return m_exceptions;
13756  }
13757 
13758 } // end namespace Catch
13759 #endif
13760 // end catch_startup_exception_registry.cpp
13761 // start catch_stream.cpp
13762 
13763 #include <cstdio>
13764 #include <fstream>
13765 #include <iostream>
13766 #include <memory>
13767 #include <sstream>
13768 #include <vector>
13769 
13770 namespace Catch {
13771  Catch::IStream::~IStream() = default;
13772 
13773  namespace Detail {
13774  namespace {
13775  template<typename WriterF, std::size_t bufferSize = 256>
13776  class StreamBufImpl : public std::streambuf {
13777  char data[bufferSize];
13778  WriterF m_writer;
13779 
13780  public:
13781  StreamBufImpl() { setp(data, data + sizeof(data)); }
13782 
13783  ~StreamBufImpl() noexcept { StreamBufImpl::sync(); }
13784 
13785  private:
13786  int overflow(int c) override {
13787  sync();
13788 
13789  if (c != EOF) {
13790  if (pbase() == epptr())
13791  m_writer(std::string(1, static_cast<char>(c)));
13792  else
13793  sputc(static_cast<char>(c));
13794  }
13795  return 0;
13796  }
13797 
13798  int sync() override {
13799  if (pbase() != pptr()) {
13800  m_writer(std::string(pbase(), static_cast<std::string::size_type>(pptr() - pbase())));
13801  setp(pbase(), epptr());
13802  }
13803  return 0;
13804  }
13805  };
13806 
13808 
13809  struct OutputDebugWriter {
13810  void operator()(std::string const &str) { writeToDebugConsole(str); }
13811  };
13812 
13814 
13815  class FileStream : public IStream {
13816  mutable std::ofstream m_ofs;
13817 
13818  public:
13819  FileStream(StringRef filename) {
13820  m_ofs.open(filename.c_str());
13821  CATCH_ENFORCE(!m_ofs.fail(), "Unable to open file: '" << filename << "'");
13822  }
13823  ~FileStream() override = default;
13824 
13825  public: // IStream
13826  std::ostream &stream() const override { return m_ofs; }
13827  };
13828 
13830 
13831  class CoutStream : public IStream {
13832  mutable std::ostream m_os;
13833 
13834  public:
13835  // Store the streambuf from cout up-front because
13836  // cout may get redirected when running tests
13837  CoutStream()
13838  : m_os(Catch::cout().rdbuf()) {
13839  }
13840  ~CoutStream() override = default;
13841 
13842  public: // IStream
13843  std::ostream &stream() const override { return m_os; }
13844  };
13845 
13847 
13848  class DebugOutStream : public IStream {
13849  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
13850  mutable std::ostream m_os;
13851 
13852  public:
13853  DebugOutStream()
13854  : m_streamBuf(new StreamBufImpl<OutputDebugWriter>())
13855  , m_os(m_streamBuf.get()) {
13856  }
13857 
13858  ~DebugOutStream() override = default;
13859 
13860  public: // IStream
13861  std::ostream &stream() const override { return m_os; }
13862  };
13863 
13864  } // namespace
13865  } // namespace Detail
13866 
13868 
13869  auto makeStream(StringRef const &filename) -> IStream const * {
13870  if (filename.empty())
13871  return new Detail::CoutStream();
13872  else if (filename[0] == '%') {
13873  if (filename == "%debug")
13874  return new Detail::DebugOutStream();
13875  else
13876  CATCH_ERROR("Unrecognised stream: '" << filename << "'");
13877  } else
13878  return new Detail::FileStream(filename);
13879  }
13880 
13881  // This class encapsulates the idea of a pool of ostringstreams that can be reused.
13882  struct StringStreams {
13883  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
13884  std::vector<std::size_t> m_unused;
13885  std::ostringstream m_referenceStream; // Used for copy state/ flags from
13886 
13887  auto add() -> std::size_t {
13888  if (m_unused.empty()) {
13889  m_streams.push_back(std::unique_ptr<std::ostringstream>(new std::ostringstream));
13890  return m_streams.size() - 1;
13891  } else {
13892  auto index = m_unused.back();
13893  m_unused.pop_back();
13894  return index;
13895  }
13896  }
13897 
13898  void release(std::size_t index) {
13899  m_streams[index]->copyfmt(m_referenceStream); // Restore initial flags and other state
13900  m_unused.push_back(index);
13901  }
13902  };
13903 
13904  ReusableStringStream::ReusableStringStream()
13905  : m_index(Singleton<StringStreams>::getMutable().add())
13906  , m_oss(Singleton<StringStreams>::getMutable().m_streams[m_index].get()) {
13907  }
13908 
13909  ReusableStringStream::~ReusableStringStream() {
13910  static_cast<std::ostringstream *>(m_oss)->str("");
13911  m_oss->clear();
13912  Singleton<StringStreams>::getMutable().release(m_index);
13913  }
13914 
13915  auto ReusableStringStream::str() const -> std::string {
13916  return static_cast<std::ostringstream *>(m_oss)->str();
13917  }
13918 
13920 
13921 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
13922  std::ostream &cout() {
13923  return std::cout;
13924  }
13925  std::ostream &cerr() {
13926  return std::cerr;
13927  }
13928  std::ostream &clog() {
13929  return std::clog;
13930  }
13931 #endif
13932 } // namespace Catch
13933 // end catch_stream.cpp
13934 // start catch_string_manip.cpp
13935 
13936 #include <algorithm>
13937 #include <cctype>
13938 #include <cstring>
13939 #include <ostream>
13940 #include <vector>
13941 
13942 namespace Catch {
13943  namespace {
13944  char toLowerCh(char c) {
13945  return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
13946  }
13947  } // namespace
13948 
13949  bool startsWith(std::string const &s, std::string const &prefix) {
13950  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
13951  }
13952  bool startsWith(std::string const &s, char prefix) {
13953  return !s.empty() && s[0] == prefix;
13954  }
13955  bool endsWith(std::string const &s, std::string const &suffix) {
13956  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
13957  }
13958  bool endsWith(std::string const &s, char suffix) {
13959  return !s.empty() && s[s.size() - 1] == suffix;
13960  }
13961  bool contains(std::string const &s, std::string const &infix) {
13962  return s.find(infix) != std::string::npos;
13963  }
13964  void toLowerInPlace(std::string &s) {
13965  std::transform(s.begin(), s.end(), s.begin(), toLowerCh);
13966  }
13967  std::string toLower(std::string const &s) {
13968  std::string lc = s;
13969  toLowerInPlace(lc);
13970  return lc;
13971  }
13972  std::string trim(std::string const &str) {
13973  static char const *whitespaceChars = "\n\r\t ";
13974  std::string::size_type start = str.find_first_not_of(whitespaceChars);
13975  std::string::size_type end = str.find_last_not_of(whitespaceChars);
13976 
13977  return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
13978  }
13979 
13980  StringRef trim(StringRef ref) {
13981  const auto is_ws = [](char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; };
13982  size_t real_begin = 0;
13983  while (real_begin < ref.size() && is_ws(ref[real_begin])) {
13984  ++real_begin;
13985  }
13986  size_t real_end = ref.size();
13987  while (real_end > real_begin && is_ws(ref[real_end - 1])) {
13988  --real_end;
13989  }
13990 
13991  return ref.substr(real_begin, real_end - real_begin);
13992  }
13993 
13994  bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis) {
13995  bool replaced = false;
13996  std::size_t i = str.find(replaceThis);
13997  while (i != std::string::npos) {
13998  replaced = true;
13999  str = str.substr(0, i) + withThis + str.substr(i + replaceThis.size());
14000  if (i < str.size() - withThis.size())
14001  i = str.find(replaceThis, i + withThis.size());
14002  else
14003  i = std::string::npos;
14004  }
14005  return replaced;
14006  }
14007 
14008  std::vector<StringRef> splitStringRef(StringRef str, char delimiter) {
14009  std::vector<StringRef> subStrings;
14010  std::size_t start = 0;
14011  for (std::size_t pos = 0; pos < str.size(); ++pos) {
14012  if (str[pos] == delimiter) {
14013  if (pos - start > 1)
14014  subStrings.push_back(str.substr(start, pos - start));
14015  start = pos + 1;
14016  }
14017  }
14018  if (start < str.size())
14019  subStrings.push_back(str.substr(start, str.size() - start));
14020  return subStrings;
14021  }
14022 
14023  pluralise::pluralise(std::size_t count, std::string const &label)
14024  : m_count(count)
14025  , m_label(label) {
14026  }
14027 
14028  std::ostream &operator<<(std::ostream &os, pluralise const &pluraliser) {
14029  os << pluraliser.m_count << ' ' << pluraliser.m_label;
14030  if (pluraliser.m_count != 1)
14031  os << 's';
14032  return os;
14033  }
14034 
14035 } // namespace Catch
14036 // end catch_string_manip.cpp
14037 // start catch_stringref.cpp
14038 
14039 #include <algorithm>
14040 #include <cstdint>
14041 #include <cstring>
14042 #include <ostream>
14043 
14044 namespace Catch {
14045  StringRef::StringRef(char const *rawChars) noexcept
14046  : StringRef(rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars))) {
14047  }
14048 
14049  auto StringRef::c_str() const -> char const * {
14050  CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
14051  return m_start;
14052  }
14053  auto StringRef::data() const noexcept -> char const * {
14054  return m_start;
14055  }
14056 
14057  auto StringRef::substr(size_type start, size_type size) const noexcept -> StringRef {
14058  if (start < m_size) {
14059  return StringRef(m_start + start, (std::min)(m_size - start, size));
14060  } else {
14061  return StringRef();
14062  }
14063  }
14064  auto StringRef::operator==(StringRef const &other) const noexcept -> bool {
14065  return m_size == other.m_size && (std::memcmp(m_start, other.m_start, m_size) == 0);
14066  }
14067 
14068  auto operator<<(std::ostream &os, StringRef const &str) -> std::ostream & {
14069  return os.write(str.data(), str.size());
14070  }
14071 
14072  auto operator+=(std::string &lhs, StringRef const &rhs) -> std::string & {
14073  lhs.append(rhs.data(), rhs.size());
14074  return lhs;
14075  }
14076 
14077 } // namespace Catch
14078 // end catch_stringref.cpp
14079 // start catch_tag_alias.cpp
14080 
14081 namespace Catch {
14082  TagAlias::TagAlias(std::string const &_tag, SourceLineInfo _lineInfo)
14083  : tag(_tag)
14084  , lineInfo(_lineInfo) {
14085  }
14086 } // namespace Catch
14087 // end catch_tag_alias.cpp
14088 // start catch_tag_alias_autoregistrar.cpp
14089 
14090 namespace Catch {
14091  RegistrarForTagAliases::RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo) {
14092  CATCH_TRY { getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); }
14093  CATCH_CATCH_ALL {
14094  // Do not throw when constructing global objects, instead register the exception to be processed later
14095  getMutableRegistryHub().registerStartupException();
14096  }
14097  }
14098 
14099 } // namespace Catch
14100 // end catch_tag_alias_autoregistrar.cpp
14101 // start catch_tag_alias_registry.cpp
14102 
14103 #include <sstream>
14104 
14105 namespace Catch {
14106  TagAliasRegistry::~TagAliasRegistry() {}
14107 
14108  TagAlias const *TagAliasRegistry::find(std::string const &alias) const {
14109  auto it = m_registry.find(alias);
14110  if (it != m_registry.end())
14111  return &(it->second);
14112  else
14113  return nullptr;
14114  }
14115 
14116  std::string TagAliasRegistry::expandAliases(std::string const &unexpandedTestSpec) const {
14117  std::string expandedTestSpec = unexpandedTestSpec;
14118  for (auto const &registryKvp : m_registry) {
14119  std::size_t pos = expandedTestSpec.find(registryKvp.first);
14120  if (pos != std::string::npos) {
14121  expandedTestSpec
14122  = expandedTestSpec.substr(0, pos) + registryKvp.second.tag + expandedTestSpec.substr(pos + registryKvp.first.size());
14123  }
14124  }
14125  return expandedTestSpec;
14126  }
14127 
14128  void TagAliasRegistry::add(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) {
14129  CATCH_ENFORCE(startsWith(alias, "[@") && endsWith(alias, ']'),
14130  "error: tag alias, '" << alias << "' is not of the form [@alias name].\n"
14131  << lineInfo);
14132 
14133  CATCH_ENFORCE(m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
14134  "error: tag alias, '" << alias << "' already registered.\n"
14135  << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
14136  << "\tRedefined at: " << lineInfo);
14137  }
14138 
14139  ITagAliasRegistry::~ITagAliasRegistry() {}
14140 
14141  ITagAliasRegistry const &ITagAliasRegistry::get() {
14142  return getRegistryHub().getTagAliasRegistry();
14143  }
14144 
14145 } // end namespace Catch
14146 // end catch_tag_alias_registry.cpp
14147 // start catch_test_case_info.cpp
14148 
14149 #include <algorithm>
14150 #include <cctype>
14151 #include <exception>
14152 #include <sstream>
14153 
14154 namespace Catch {
14155  namespace {
14156  TestCaseInfo::SpecialProperties parseSpecialTag(std::string const &tag) {
14157  if (startsWith(tag, '.') || tag == "!hide")
14158  return TestCaseInfo::IsHidden;
14159  else if (tag == "!throws")
14160  return TestCaseInfo::Throws;
14161  else if (tag == "!shouldfail")
14162  return TestCaseInfo::ShouldFail;
14163  else if (tag == "!mayfail")
14164  return TestCaseInfo::MayFail;
14165  else if (tag == "!nonportable")
14166  return TestCaseInfo::NonPortable;
14167  else if (tag == "!benchmark")
14168  return static_cast<TestCaseInfo::SpecialProperties>(TestCaseInfo::Benchmark | TestCaseInfo::IsHidden);
14169  else
14170  return TestCaseInfo::None;
14171  }
14172  bool isReservedTag(std::string const &tag) {
14173  return parseSpecialTag(tag) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum(static_cast<unsigned char>(tag[0]));
14174  }
14175  void enforceNotReservedTag(std::string const &tag, SourceLineInfo const &_lineInfo) {
14176  CATCH_ENFORCE(!isReservedTag(tag),
14177  "Tag name: [" << tag << "] is not allowed.\n"
14178  << "Tag names starting with non alphanumeric characters are reserved\n"
14179  << _lineInfo);
14180  }
14181  } // namespace
14182 
14183  TestCase makeTestCase(ITestInvoker *_testCase, std::string const &_className, NameAndTags const &nameAndTags, SourceLineInfo const &_lineInfo) {
14184  bool isHidden = false;
14185 
14186  // Parse out tags
14187  std::vector<std::string> tags;
14188  std::string desc, tag;
14189  bool inTag = false;
14190  for (char c : nameAndTags.tags) {
14191  if (!inTag) {
14192  if (c == '[')
14193  inTag = true;
14194  else
14195  desc += c;
14196  } else {
14197  if (c == ']') {
14198  TestCaseInfo::SpecialProperties prop = parseSpecialTag(tag);
14199  if ((prop & TestCaseInfo::IsHidden) != 0)
14200  isHidden = true;
14201  else if (prop == TestCaseInfo::None)
14202  enforceNotReservedTag(tag, _lineInfo);
14203 
14204  // Merged hide tags like `[.approvals]` should be added as
14205  // `[.][approvals]`. The `[.]` is added at later point, so
14206  // we only strip the prefix
14207  if (startsWith(tag, '.') && tag.size() > 1) {
14208  tag.erase(0, 1);
14209  }
14210  tags.push_back(tag);
14211  tag.clear();
14212  inTag = false;
14213  } else
14214  tag += c;
14215  }
14216  }
14217  if (isHidden) {
14218  // Add all "hidden" tags to make them behave identically
14219  tags.insert(tags.end(), {".", "!hide"});
14220  }
14221 
14222  TestCaseInfo info(static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo);
14223  return TestCase(_testCase, std::move(info));
14224  }
14225 
14226  void setTags(TestCaseInfo &testCaseInfo, std::vector<std::string> tags) {
14227  std::sort(begin(tags), end(tags));
14228  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
14229  testCaseInfo.lcaseTags.clear();
14230 
14231  for (auto const &tag : tags) {
14232  std::string lcaseTag = toLower(tag);
14233  testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>(testCaseInfo.properties | parseSpecialTag(lcaseTag));
14234  testCaseInfo.lcaseTags.push_back(lcaseTag);
14235  }
14236  testCaseInfo.tags = std::move(tags);
14237  }
14238 
14239  TestCaseInfo::TestCaseInfo(std::string const &_name,
14240  std::string const &_className,
14241  std::string const &_description,
14242  std::vector<std::string> const &_tags,
14243  SourceLineInfo const &_lineInfo)
14244  : name(_name)
14245  , className(_className)
14246  , description(_description)
14247  , lineInfo(_lineInfo)
14248  , properties(None) {
14249  setTags(*this, _tags);
14250  }
14251 
14252  bool TestCaseInfo::isHidden() const {
14253  return (properties & IsHidden) != 0;
14254  }
14255  bool TestCaseInfo::throws() const {
14256  return (properties & Throws) != 0;
14257  }
14258  bool TestCaseInfo::okToFail() const {
14259  return (properties & (ShouldFail | MayFail)) != 0;
14260  }
14261  bool TestCaseInfo::expectedToFail() const {
14262  return (properties & (ShouldFail)) != 0;
14263  }
14264 
14265  std::string TestCaseInfo::tagsAsString() const {
14266  std::string ret;
14267  // '[' and ']' per tag
14268  std::size_t full_size = 2 * tags.size();
14269  for (const auto &tag : tags) {
14270  full_size += tag.size();
14271  }
14272  ret.reserve(full_size);
14273  for (const auto &tag : tags) {
14274  ret.push_back('[');
14275  ret.append(tag);
14276  ret.push_back(']');
14277  }
14278 
14279  return ret;
14280  }
14281 
14282  TestCase::TestCase(ITestInvoker *testCase, TestCaseInfo &&info)
14283  : TestCaseInfo(std::move(info))
14284  , test(testCase) {
14285  }
14286 
14287  TestCase TestCase::withName(std::string const &_newName) const {
14288  TestCase other(*this);
14289  other.name = _newName;
14290  return other;
14291  }
14292 
14293  void TestCase::invoke() const {
14294  test->invoke();
14295  }
14296 
14297  bool TestCase::operator==(TestCase const &other) const {
14298  return test.get() == other.test.get() && name == other.name && className == other.className;
14299  }
14300 
14301  bool TestCase::operator<(TestCase const &other) const {
14302  return name < other.name;
14303  }
14304 
14305  TestCaseInfo const &TestCase::getTestCaseInfo() const {
14306  return *this;
14307  }
14308 
14309 } // end namespace Catch
14310 // end catch_test_case_info.cpp
14311 // start catch_test_case_registry_impl.cpp
14312 
14313 #include <algorithm>
14314 #include <sstream>
14315 
14316 namespace Catch {
14317  namespace {
14318  struct TestHasher {
14319  using hash_t = uint64_t;
14320 
14321  explicit TestHasher(hash_t hashSuffix)
14322  : m_hashSuffix{hashSuffix} {
14323  }
14324 
14325  uint32_t operator()(TestCase const &t) const {
14326  // FNV-1a hash with multiplication fold.
14327  const hash_t prime = 1099511628211u;
14328  hash_t hash = 14695981039346656037u;
14329  for (const char c : t.name) {
14330  hash ^= c;
14331  hash *= prime;
14332  }
14333  hash ^= m_hashSuffix;
14334  hash *= prime;
14335  const uint32_t low{static_cast<uint32_t>(hash)};
14336  const uint32_t high{static_cast<uint32_t>(hash >> 32)};
14337  return low * high;
14338  }
14339 
14340  private:
14341  hash_t m_hashSuffix;
14342  };
14343  } // end unnamed namespace
14344 
14345  std::vector<TestCase> sortTests(IConfig const &config, std::vector<TestCase> const &unsortedTestCases) {
14346  switch (config.runOrder()) {
14347  case RunTests::InDeclarationOrder:
14348  // already in declaration order
14349  break;
14350 
14351  case RunTests::InLexicographicalOrder: {
14352  std::vector<TestCase> sorted = unsortedTestCases;
14353  std::sort(sorted.begin(), sorted.end());
14354  return sorted;
14355  }
14356 
14357  case RunTests::InRandomOrder: {
14358  seedRng(config);
14359  TestHasher h{config.rngSeed()};
14360 
14361  using hashedTest = std::pair<TestHasher::hash_t, TestCase const *>;
14362  std::vector<hashedTest> indexed_tests;
14363  indexed_tests.reserve(unsortedTestCases.size());
14364 
14365  for (auto const &testCase : unsortedTestCases) {
14366  indexed_tests.emplace_back(h(testCase), &testCase);
14367  }
14368 
14369  std::sort(indexed_tests.begin(), indexed_tests.end(), [](hashedTest const &lhs, hashedTest const &rhs) {
14370  if (lhs.first == rhs.first) {
14371  return lhs.second->name < rhs.second->name;
14372  }
14373  return lhs.first < rhs.first;
14374  });
14375 
14376  std::vector<TestCase> sorted;
14377  sorted.reserve(indexed_tests.size());
14378 
14379  for (auto const &hashed : indexed_tests) {
14380  sorted.emplace_back(*hashed.second);
14381  }
14382 
14383  return sorted;
14384  }
14385  }
14386  return unsortedTestCases;
14387  }
14388 
14389  bool isThrowSafe(TestCase const &testCase, IConfig const &config) {
14390  return !testCase.throws() || config.allowThrows();
14391  }
14392 
14393  bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config) {
14394  return testSpec.matches(testCase) && isThrowSafe(testCase, config);
14395  }
14396 
14397  void enforceNoDuplicateTestCases(std::vector<TestCase> const &functions) {
14398  std::set<TestCase> seenFunctions;
14399  for (auto const &function : functions) {
14400  auto prev = seenFunctions.insert(function);
14401  CATCH_ENFORCE(prev.second,
14402  "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
14403  << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
14404  << "\tRedefined at " << function.getTestCaseInfo().lineInfo);
14405  }
14406  }
14407 
14408  std::vector<TestCase> filterTests(std::vector<TestCase> const &testCases, TestSpec const &testSpec, IConfig const &config) {
14409  std::vector<TestCase> filtered;
14410  filtered.reserve(testCases.size());
14411  for (auto const &testCase : testCases) {
14412  if ((!testSpec.hasFilters() && !testCase.isHidden()) || (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
14413  filtered.push_back(testCase);
14414  }
14415  }
14416  return filtered;
14417  }
14418  std::vector<TestCase> const &getAllTestCasesSorted(IConfig const &config) {
14419  return getRegistryHub().getTestCaseRegistry().getAllTestsSorted(config);
14420  }
14421 
14422  void TestRegistry::registerTest(TestCase const &testCase) {
14423  std::string name = testCase.getTestCaseInfo().name;
14424  if (name.empty()) {
14426  rss << "Anonymous test case " << ++m_unnamedCount;
14427  return registerTest(testCase.withName(rss.str()));
14428  }
14429  m_functions.push_back(testCase);
14430  }
14431 
14432  std::vector<TestCase> const &TestRegistry::getAllTests() const {
14433  return m_functions;
14434  }
14435  std::vector<TestCase> const &TestRegistry::getAllTestsSorted(IConfig const &config) const {
14436  if (m_sortedFunctions.empty())
14437  enforceNoDuplicateTestCases(m_functions);
14438 
14439  if (m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty()) {
14440  m_sortedFunctions = sortTests(config, m_functions);
14441  m_currentSortOrder = config.runOrder();
14442  }
14443  return m_sortedFunctions;
14444  }
14445 
14447  TestInvokerAsFunction::TestInvokerAsFunction(void (*testAsFunction)()) noexcept
14448  : m_testAsFunction(testAsFunction) {
14449  }
14450 
14451  void TestInvokerAsFunction::invoke() const {
14452  m_testAsFunction();
14453  }
14454 
14455  std::string extractClassName(StringRef const &classOrQualifiedMethodName) {
14456  std::string className(classOrQualifiedMethodName);
14457  if (startsWith(className, '&')) {
14458  std::size_t lastColons = className.rfind("::");
14459  std::size_t penultimateColons = className.rfind("::", lastColons - 1);
14460  if (penultimateColons == std::string::npos)
14461  penultimateColons = 1;
14462  className = className.substr(penultimateColons, lastColons - penultimateColons);
14463  }
14464  return className;
14465  }
14466 
14467 } // end namespace Catch
14468 // end catch_test_case_registry_impl.cpp
14469 // start catch_test_case_tracker.cpp
14470 
14471 #include <algorithm>
14472 #include <cassert>
14473 #include <memory>
14474 #include <sstream>
14475 #include <stdexcept>
14476 
14477 #if defined(__clang__)
14478 #pragma clang diagnostic push
14479 #pragma clang diagnostic ignored "-Wexit-time-destructors"
14480 #endif
14481 
14482 namespace Catch {
14483  namespace TestCaseTracking {
14484  NameAndLocation::NameAndLocation(std::string const &_name, SourceLineInfo const &_location)
14485  : name(_name)
14486  , location(_location) {
14487  }
14488 
14489  ITracker::~ITracker() = default;
14490 
14491  ITracker &TrackerContext::startRun() {
14492  m_rootTracker = std::make_shared<SectionTracker>(NameAndLocation("{root}", CATCH_INTERNAL_LINEINFO), *this, nullptr);
14493  m_currentTracker = nullptr;
14494  m_runState = Executing;
14495  return *m_rootTracker;
14496  }
14497 
14498  void TrackerContext::endRun() {
14499  m_rootTracker.reset();
14500  m_currentTracker = nullptr;
14501  m_runState = NotStarted;
14502  }
14503 
14504  void TrackerContext::startCycle() {
14505  m_currentTracker = m_rootTracker.get();
14506  m_runState = Executing;
14507  }
14508  void TrackerContext::completeCycle() {
14509  m_runState = CompletedCycle;
14510  }
14511 
14512  bool TrackerContext::completedCycle() const {
14513  return m_runState == CompletedCycle;
14514  }
14515  ITracker &TrackerContext::currentTracker() {
14516  return *m_currentTracker;
14517  }
14518  void TrackerContext::setCurrentTracker(ITracker *tracker) {
14519  m_currentTracker = tracker;
14520  }
14521 
14522  TrackerBase::TrackerBase(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent)
14523  : ITracker(nameAndLocation)
14524  , m_ctx(ctx)
14525  , m_parent(parent) {
14526  }
14527 
14528  bool TrackerBase::isComplete() const {
14529  return m_runState == CompletedSuccessfully || m_runState == Failed;
14530  }
14531  bool TrackerBase::isSuccessfullyCompleted() const {
14532  return m_runState == CompletedSuccessfully;
14533  }
14534  bool TrackerBase::isOpen() const {
14535  return m_runState != NotStarted && !isComplete();
14536  }
14537  bool TrackerBase::hasChildren() const {
14538  return !m_children.empty();
14539  }
14540 
14541  void TrackerBase::addChild(ITrackerPtr const &child) {
14542  m_children.push_back(child);
14543  }
14544 
14545  ITrackerPtr TrackerBase::findChild(NameAndLocation const &nameAndLocation) {
14546  auto it = std::find_if(m_children.begin(), m_children.end(), [&nameAndLocation](ITrackerPtr const &tracker) {
14547  return tracker->nameAndLocation().location == nameAndLocation.location && tracker->nameAndLocation().name == nameAndLocation.name;
14548  });
14549  return (it != m_children.end()) ? *it : nullptr;
14550  }
14551  ITracker &TrackerBase::parent() {
14552  assert(m_parent); // Should always be non-null except for root
14553  return *m_parent;
14554  }
14555 
14556  void TrackerBase::openChild() {
14557  if (m_runState != ExecutingChildren) {
14558  m_runState = ExecutingChildren;
14559  if (m_parent)
14560  m_parent->openChild();
14561  }
14562  }
14563 
14564  bool TrackerBase::isSectionTracker() const {
14565  return false;
14566  }
14567  bool TrackerBase::isGeneratorTracker() const {
14568  return false;
14569  }
14570 
14571  void TrackerBase::open() {
14572  m_runState = Executing;
14573  moveToThis();
14574  if (m_parent)
14575  m_parent->openChild();
14576  }
14577 
14578  void TrackerBase::close() {
14579  // Close any still open children (e.g. generators)
14580  while (&m_ctx.currentTracker() != this)
14581  m_ctx.currentTracker().close();
14582 
14583  switch (m_runState) {
14584  case NeedsAnotherRun:
14585  break;
14586 
14587  case Executing:
14588  m_runState = CompletedSuccessfully;
14589  break;
14590  case ExecutingChildren:
14591  if (std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const &t) { return t->isComplete(); }))
14592  m_runState = CompletedSuccessfully;
14593  break;
14594 
14595  case NotStarted:
14596  case CompletedSuccessfully:
14597  case Failed:
14598  CATCH_INTERNAL_ERROR("Illogical state: " << m_runState);
14599 
14600  default:
14601  CATCH_INTERNAL_ERROR("Unknown state: " << m_runState);
14602  }
14603  moveToParent();
14604  m_ctx.completeCycle();
14605  }
14606  void TrackerBase::fail() {
14607  m_runState = Failed;
14608  if (m_parent)
14609  m_parent->markAsNeedingAnotherRun();
14610  moveToParent();
14611  m_ctx.completeCycle();
14612  }
14613  void TrackerBase::markAsNeedingAnotherRun() {
14614  m_runState = NeedsAnotherRun;
14615  }
14616 
14617  void TrackerBase::moveToParent() {
14618  assert(m_parent);
14619  m_ctx.setCurrentTracker(m_parent);
14620  }
14621  void TrackerBase::moveToThis() {
14622  m_ctx.setCurrentTracker(this);
14623  }
14624 
14625  SectionTracker::SectionTracker(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent)
14626  : TrackerBase(nameAndLocation, ctx, parent)
14627  , m_trimmed_name(trim(nameAndLocation.name)) {
14628  if (parent) {
14629  while (!parent->isSectionTracker())
14630  parent = &parent->parent();
14631 
14632  SectionTracker &parentSection = static_cast<SectionTracker &>(*parent);
14633  addNextFilters(parentSection.m_filters);
14634  }
14635  }
14636 
14637  bool SectionTracker::isComplete() const {
14638  bool complete = true;
14639 
14640  if (m_filters.empty() || m_filters[0] == "" || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
14641  complete = TrackerBase::isComplete();
14642  }
14643  return complete;
14644  }
14645 
14646  bool SectionTracker::isSectionTracker() const {
14647  return true;
14648  }
14649 
14650  SectionTracker &SectionTracker::acquire(TrackerContext &ctx, NameAndLocation const &nameAndLocation) {
14651  std::shared_ptr<SectionTracker> section;
14652 
14653  ITracker &currentTracker = ctx.currentTracker();
14654  if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
14655  assert(childTracker);
14656  assert(childTracker->isSectionTracker());
14657  section = std::static_pointer_cast<SectionTracker>(childTracker);
14658  } else {
14659  section = std::make_shared<SectionTracker>(nameAndLocation, ctx, &currentTracker);
14660  currentTracker.addChild(section);
14661  }
14662  if (!ctx.completedCycle())
14663  section->tryOpen();
14664  return *section;
14665  }
14666 
14667  void SectionTracker::tryOpen() {
14668  if (!isComplete())
14669  open();
14670  }
14671 
14672  void SectionTracker::addInitialFilters(std::vector<std::string> const &filters) {
14673  if (!filters.empty()) {
14674  m_filters.reserve(m_filters.size() + filters.size() + 2);
14675  m_filters.emplace_back(""); // Root - should never be consulted
14676  m_filters.emplace_back(""); // Test Case - not a section filter
14677  m_filters.insert(m_filters.end(), filters.begin(), filters.end());
14678  }
14679  }
14680  void SectionTracker::addNextFilters(std::vector<std::string> const &filters) {
14681  if (filters.size() > 1)
14682  m_filters.insert(m_filters.end(), filters.begin() + 1, filters.end());
14683  }
14684 
14685  std::vector<std::string> const &SectionTracker::getFilters() const {
14686  return m_filters;
14687  }
14688 
14689  std::string const &SectionTracker::trimmedName() const {
14690  return m_trimmed_name;
14691  }
14692 
14693  } // namespace TestCaseTracking
14694 
14695  using TestCaseTracking::ITracker;
14696  using TestCaseTracking::SectionTracker;
14697  using TestCaseTracking::TrackerContext;
14698 
14699 } // namespace Catch
14700 
14701 #if defined(__clang__)
14702 #pragma clang diagnostic pop
14703 #endif
14704 // end catch_test_case_tracker.cpp
14705 // start catch_test_registry.cpp
14706 
14707 namespace Catch {
14708  auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker * {
14709  return new (std::nothrow) TestInvokerAsFunction(testAsFunction);
14710  }
14711 
14712  NameAndTags::NameAndTags(StringRef const &name_, StringRef const &tags_) noexcept
14713  : name(name_)
14714  , tags(tags_) {
14715  }
14716 
14717  AutoReg::AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags) noexcept {
14718  CATCH_TRY { getMutableRegistryHub().registerTest(makeTestCase(invoker, extractClassName(classOrMethod), nameAndTags, lineInfo)); }
14719  CATCH_CATCH_ALL {
14720  // Do not throw when constructing global objects, instead register the exception to be processed later
14721  getMutableRegistryHub().registerStartupException();
14722  }
14723  }
14724 
14725  AutoReg::~AutoReg() = default;
14726 } // namespace Catch
14727 // end catch_test_registry.cpp
14728 // start catch_test_spec.cpp
14729 
14730 #include <algorithm>
14731 #include <memory>
14732 #include <string>
14733 #include <vector>
14734 
14735 namespace Catch {
14736  TestSpec::Pattern::Pattern(std::string const &name)
14737  : m_name(name) {
14738  }
14739 
14740  TestSpec::Pattern::~Pattern() = default;
14741 
14742  std::string const &TestSpec::Pattern::name() const {
14743  return m_name;
14744  }
14745 
14746  TestSpec::NamePattern::NamePattern(std::string const &name, std::string const &filterString)
14747  : Pattern(filterString)
14748  , m_wildcardPattern(toLower(name), CaseSensitive::No) {
14749  }
14750 
14751  bool TestSpec::NamePattern::matches(TestCaseInfo const &testCase) const {
14752  return m_wildcardPattern.matches(testCase.name);
14753  }
14754 
14755  TestSpec::TagPattern::TagPattern(std::string const &tag, std::string const &filterString)
14756  : Pattern(filterString)
14757  , m_tag(toLower(tag)) {
14758  }
14759 
14760  bool TestSpec::TagPattern::matches(TestCaseInfo const &testCase) const {
14761  return std::find(begin(testCase.lcaseTags), end(testCase.lcaseTags), m_tag) != end(testCase.lcaseTags);
14762  }
14763 
14764  TestSpec::ExcludedPattern::ExcludedPattern(PatternPtr const &underlyingPattern)
14765  : Pattern(underlyingPattern->name())
14766  , m_underlyingPattern(underlyingPattern) {
14767  }
14768 
14769  bool TestSpec::ExcludedPattern::matches(TestCaseInfo const &testCase) const {
14770  return !m_underlyingPattern->matches(testCase);
14771  }
14772 
14773  bool TestSpec::Filter::matches(TestCaseInfo const &testCase) const {
14774  return std::all_of(m_patterns.begin(), m_patterns.end(), [&](PatternPtr const &p) { return p->matches(testCase); });
14775  }
14776 
14777  std::string TestSpec::Filter::name() const {
14778  std::string name;
14779  for (auto const &p : m_patterns)
14780  name += p->name();
14781  return name;
14782  }
14783 
14784  bool TestSpec::hasFilters() const {
14785  return !m_filters.empty();
14786  }
14787 
14788  bool TestSpec::matches(TestCaseInfo const &testCase) const {
14789  return std::any_of(m_filters.begin(), m_filters.end(), [&](Filter const &f) { return f.matches(testCase); });
14790  }
14791 
14792  TestSpec::Matches TestSpec::matchesByFilter(std::vector<TestCase> const &testCases, IConfig const &config) const {
14793  Matches matches(m_filters.size());
14794  std::transform(m_filters.begin(), m_filters.end(), matches.begin(), [&](Filter const &filter) {
14795  std::vector<TestCase const *> currentMatches;
14796  for (auto const &test : testCases)
14797  if (isThrowSafe(test, config) && filter.matches(test))
14798  currentMatches.emplace_back(&test);
14799  return FilterMatch{filter.name(), currentMatches};
14800  });
14801  return matches;
14802  }
14803 
14804  const TestSpec::vectorStrings &TestSpec::getInvalidArgs() const {
14805  return (m_invalidArgs);
14806  }
14807 
14808 } // namespace Catch
14809 // end catch_test_spec.cpp
14810 // start catch_test_spec_parser.cpp
14811 
14812 namespace Catch {
14813  TestSpecParser::TestSpecParser(ITagAliasRegistry const &tagAliases)
14814  : m_tagAliases(&tagAliases) {
14815  }
14816 
14817  TestSpecParser &TestSpecParser::parse(std::string const &arg) {
14818  m_mode = None;
14819  m_exclusion = false;
14820  m_arg = m_tagAliases->expandAliases(arg);
14821  m_escapeChars.clear();
14822  m_substring.reserve(m_arg.size());
14823  m_patternName.reserve(m_arg.size());
14824  m_realPatternPos = 0;
14825 
14826  for (m_pos = 0; m_pos < m_arg.size(); ++m_pos)
14827  // if visitChar fails
14828  if (!visitChar(m_arg[m_pos])) {
14829  m_testSpec.m_invalidArgs.push_back(arg);
14830  break;
14831  }
14832  endMode();
14833  return *this;
14834  }
14835  TestSpec TestSpecParser::testSpec() {
14836  addFilter();
14837  return m_testSpec;
14838  }
14839  bool TestSpecParser::visitChar(char c) {
14840  if ((m_mode != EscapedName) && (c == '\\')) {
14841  escape();
14842  addCharToPattern(c);
14843  return true;
14844  } else if ((m_mode != EscapedName) && (c == ',')) {
14845  return separate();
14846  }
14847 
14848  switch (m_mode) {
14849  case None:
14850  if (processNoneChar(c))
14851  return true;
14852  break;
14853  case Name:
14854  processNameChar(c);
14855  break;
14856  case EscapedName:
14857  endMode();
14858  addCharToPattern(c);
14859  return true;
14860  default:
14861  case Tag:
14862  case QuotedName:
14863  if (processOtherChar(c))
14864  return true;
14865  break;
14866  }
14867 
14868  m_substring += c;
14869  if (!isControlChar(c)) {
14870  m_patternName += c;
14871  m_realPatternPos++;
14872  }
14873  return true;
14874  }
14875  // Two of the processing methods return true to signal the caller to return
14876  // without adding the given character to the current pattern strings
14877  bool TestSpecParser::processNoneChar(char c) {
14878  switch (c) {
14879  case ' ':
14880  return true;
14881  case '~':
14882  m_exclusion = true;
14883  return false;
14884  case '[':
14885  startNewMode(Tag);
14886  return false;
14887  case '"':
14888  startNewMode(QuotedName);
14889  return false;
14890  default:
14891  startNewMode(Name);
14892  return false;
14893  }
14894  }
14895  void TestSpecParser::processNameChar(char c) {
14896  if (c == '[') {
14897  if (m_substring == "exclude:")
14898  m_exclusion = true;
14899  else
14900  endMode();
14901  startNewMode(Tag);
14902  }
14903  }
14904  bool TestSpecParser::processOtherChar(char c) {
14905  if (!isControlChar(c))
14906  return false;
14907  m_substring += c;
14908  endMode();
14909  return true;
14910  }
14911  void TestSpecParser::startNewMode(Mode mode) {
14912  m_mode = mode;
14913  }
14914  void TestSpecParser::endMode() {
14915  switch (m_mode) {
14916  case Name:
14917  case QuotedName:
14918  return addNamePattern();
14919  case Tag:
14920  return addTagPattern();
14921  case EscapedName:
14922  revertBackToLastMode();
14923  return;
14924  case None:
14925  default:
14926  return startNewMode(None);
14927  }
14928  }
14929  void TestSpecParser::escape() {
14930  saveLastMode();
14931  m_mode = EscapedName;
14932  m_escapeChars.push_back(m_realPatternPos);
14933  }
14934  bool TestSpecParser::isControlChar(char c) const {
14935  switch (m_mode) {
14936  default:
14937  return false;
14938  case None:
14939  return c == '~';
14940  case Name:
14941  return c == '[';
14942  case EscapedName:
14943  return true;
14944  case QuotedName:
14945  return c == '"';
14946  case Tag:
14947  return c == '[' || c == ']';
14948  }
14949  }
14950 
14951  void TestSpecParser::addFilter() {
14952  if (!m_currentFilter.m_patterns.empty()) {
14953  m_testSpec.m_filters.push_back(m_currentFilter);
14954  m_currentFilter = TestSpec::Filter();
14955  }
14956  }
14957 
14958  void TestSpecParser::saveLastMode() {
14959  lastMode = m_mode;
14960  }
14961 
14962  void TestSpecParser::revertBackToLastMode() {
14963  m_mode = lastMode;
14964  }
14965 
14966  bool TestSpecParser::separate() {
14967  if ((m_mode == QuotedName) || (m_mode == Tag)) {
14968  // invalid argument, signal failure to previous scope.
14969  m_mode = None;
14970  m_pos = m_arg.size();
14971  m_substring.clear();
14972  m_patternName.clear();
14973  m_realPatternPos = 0;
14974  return false;
14975  }
14976  endMode();
14977  addFilter();
14978  return true; // success
14979  }
14980 
14981  std::string TestSpecParser::preprocessPattern() {
14982  std::string token = m_patternName;
14983  for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
14984  token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
14985  m_escapeChars.clear();
14986  if (startsWith(token, "exclude:")) {
14987  m_exclusion = true;
14988  token = token.substr(8);
14989  }
14990 
14991  m_patternName.clear();
14992  m_realPatternPos = 0;
14993 
14994  return token;
14995  }
14996 
14997  void TestSpecParser::addNamePattern() {
14998  auto token = preprocessPattern();
14999 
15000  if (!token.empty()) {
15001  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
15002  if (m_exclusion)
15003  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
15004  m_currentFilter.m_patterns.push_back(pattern);
15005  }
15006  m_substring.clear();
15007  m_exclusion = false;
15008  m_mode = None;
15009  }
15010 
15011  void TestSpecParser::addTagPattern() {
15012  auto token = preprocessPattern();
15013 
15014  if (!token.empty()) {
15015  // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
15016  // we have to create a separate hide tag and shorten the real one
15017  if (token.size() > 1 && token[0] == '.') {
15018  token.erase(token.begin());
15019  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
15020  if (m_exclusion) {
15021  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
15022  }
15023  m_currentFilter.m_patterns.push_back(pattern);
15024  }
15025 
15026  TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
15027 
15028  if (m_exclusion) {
15029  pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
15030  }
15031  m_currentFilter.m_patterns.push_back(pattern);
15032  }
15033  m_substring.clear();
15034  m_exclusion = false;
15035  m_mode = None;
15036  }
15037 
15038  TestSpec parseTestSpec(std::string const &arg) {
15039  return TestSpecParser(ITagAliasRegistry::get()).parse(arg).testSpec();
15040  }
15041 
15042 } // namespace Catch
15043 // end catch_test_spec_parser.cpp
15044 // start catch_timer.cpp
15045 
15046 #include <chrono>
15047 
15048 static const uint64_t nanosecondsInSecond = 1000000000;
15049 
15050 namespace Catch {
15051  auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
15052  return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
15053  }
15054 
15055  namespace {
15056  auto estimateClockResolution() -> uint64_t {
15057  uint64_t sum = 0;
15058  static const uint64_t iterations = 1000000;
15059 
15060  auto startTime = getCurrentNanosecondsSinceEpoch();
15061 
15062  for (std::size_t i = 0; i < iterations; ++i) {
15063  uint64_t ticks;
15064  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
15065  do {
15066  ticks = getCurrentNanosecondsSinceEpoch();
15067  } while (ticks == baseTicks);
15068 
15069  auto delta = ticks - baseTicks;
15070  sum += delta;
15071 
15072  // If we have been calibrating for over 3 seconds -- the clock
15073  // is terrible and we should move on.
15074  // TBD: How to signal that the measured resolution is probably wrong?
15075  if (ticks > startTime + 3 * nanosecondsInSecond) {
15076  return sum / (i + 1u);
15077  }
15078  }
15079 
15080  // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
15081  // - and potentially do more iterations if there's a high variance.
15082  return sum / iterations;
15083  }
15084  } // namespace
15085  auto getEstimatedClockResolution() -> uint64_t {
15086  static auto s_resolution = estimateClockResolution();
15087  return s_resolution;
15088  }
15089 
15090  void Timer::start() {
15091  m_nanoseconds = getCurrentNanosecondsSinceEpoch();
15092  }
15093  auto Timer::getElapsedNanoseconds() const -> uint64_t {
15094  return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
15095  }
15096  auto Timer::getElapsedMicroseconds() const -> uint64_t {
15097  return getElapsedNanoseconds() / 1000;
15098  }
15099  auto Timer::getElapsedMilliseconds() const -> unsigned int {
15100  return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
15101  }
15102  auto Timer::getElapsedSeconds() const -> double {
15103  return getElapsedMicroseconds() / 1000000.0;
15104  }
15105 
15106 } // namespace Catch
15107 // end catch_timer.cpp
15108 // start catch_tostring.cpp
15109 
15110 #if defined(__clang__)
15111 #pragma clang diagnostic push
15112 #pragma clang diagnostic ignored "-Wexit-time-destructors"
15113 #pragma clang diagnostic ignored "-Wglobal-constructors"
15114 #endif
15115 
15116 // Enable specific decls locally
15117 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
15118 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
15119 #endif
15120 
15121 #include <cmath>
15122 #include <iomanip>
15123 
15124 namespace Catch {
15125  namespace Detail {
15126  const std::string unprintableString = "{?}";
15127 
15128  namespace {
15129  const int hexThreshold = 255;
15130 
15131  struct Endianness {
15132  enum Arch {
15133  Big,
15134  Little
15135  };
15136 
15137  static Arch which() {
15138  int one = 1;
15139  // If the lowest byte we read is non-zero, we can assume
15140  // that little endian format is used.
15141  auto value = *reinterpret_cast<char *>(&one);
15142  return value ? Little : Big;
15143  }
15144  };
15145  } // namespace
15146 
15147  std::string rawMemoryToString(const void *object, std::size_t size) {
15148  // Reverse order for little endian architectures
15149  int i = 0, end = static_cast<int>(size), inc = 1;
15150  if (Endianness::which() == Endianness::Little) {
15151  i = end - 1;
15152  end = inc = -1;
15153  }
15154 
15155  unsigned char const *bytes = static_cast<unsigned char const *>(object);
15157  rss << "0x" << std::setfill('0') << std::hex;
15158  for (; i != end; i += inc)
15159  rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
15160  return rss.str();
15161  }
15162  } // namespace Detail
15163 
15164  template<typename T>
15165  std::string fpToString(T value, int precision) {
15166  if (Catch::isnan(value)) {
15167  return "nan";
15168  }
15169 
15171  rss << std::setprecision(precision) << std::fixed << value;
15172  std::string d = rss.str();
15173  std::size_t i = d.find_last_not_of('0');
15174  if (i != std::string::npos && i != d.size() - 1) {
15175  if (d[i] == '.')
15176  i++;
15177  d = d.substr(0, i + 1);
15178  }
15179  return d;
15180  }
15181 
15183  //
15184  // Out-of-line defs for full specialization of StringMaker
15185  //
15187 
15188  std::string StringMaker<std::string>::convert(const std::string &str) {
15189  if (!getCurrentContext().getConfig()->showInvisibles()) {
15190  return '"' + str + '"';
15191  }
15192 
15193  std::string s("\"");
15194  for (char c : str) {
15195  switch (c) {
15196  case '\n':
15197  s.append("\\n");
15198  break;
15199  case '\t':
15200  s.append("\\t");
15201  break;
15202  default:
15203  s.push_back(c);
15204  break;
15205  }
15206  }
15207  s.append("\"");
15208  return s;
15209  }
15210 
15211 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15212  std::string StringMaker<std::string_view>::convert(std::string_view str) {
15213  return ::Catch::Detail::stringify(std::string{str});
15214  }
15215 #endif
15216 
15217  std::string StringMaker<char const *>::convert(char const *str) {
15218  if (str) {
15219  return ::Catch::Detail::stringify(std::string{str});
15220  } else {
15221  return {"{null string}"};
15222  }
15223  }
15224  std::string StringMaker<char *>::convert(char *str) {
15225  if (str) {
15226  return ::Catch::Detail::stringify(std::string{str});
15227  } else {
15228  return {"{null string}"};
15229  }
15230  }
15231 
15232 #ifdef CATCH_CONFIG_WCHAR
15233  std::string StringMaker<std::wstring>::convert(const std::wstring &wstr) {
15234  std::string s;
15235  s.reserve(wstr.size());
15236  for (auto c : wstr) {
15237  s += (c <= 0xff) ? static_cast<char>(c) : '?';
15238  }
15239  return ::Catch::Detail::stringify(s);
15240  }
15241 
15242 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
15243  std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
15244  return StringMaker<std::wstring>::convert(std::wstring(str));
15245  }
15246 #endif
15247 
15248  std::string StringMaker<wchar_t const *>::convert(wchar_t const *str) {
15249  if (str) {
15250  return ::Catch::Detail::stringify(std::wstring{str});
15251  } else {
15252  return {"{null string}"};
15253  }
15254  }
15255  std::string StringMaker<wchar_t *>::convert(wchar_t *str) {
15256  if (str) {
15257  return ::Catch::Detail::stringify(std::wstring{str});
15258  } else {
15259  return {"{null string}"};
15260  }
15261  }
15262 #endif
15263 
15264 #if defined(CATCH_CONFIG_CPP17_BYTE)
15265 #include <cstddef>
15266  std::string StringMaker<std::byte>::convert(std::byte value) {
15267  return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
15268  }
15269 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
15270 
15271  std::string StringMaker<int>::convert(int value) {
15272  return ::Catch::Detail::stringify(static_cast<long long>(value));
15273  }
15274  std::string StringMaker<long>::convert(long value) {
15275  return ::Catch::Detail::stringify(static_cast<long long>(value));
15276  }
15277  std::string StringMaker<long long>::convert(long long value) {
15279  rss << value;
15280  if (value > Detail::hexThreshold) {
15281  rss << " (0x" << std::hex << value << ')';
15282  }
15283  return rss.str();
15284  }
15285 
15286  std::string StringMaker<unsigned int>::convert(unsigned int value) {
15287  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15288  }
15289  std::string StringMaker<unsigned long>::convert(unsigned long value) {
15290  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
15291  }
15292  std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
15294  rss << value;
15295  if (value > Detail::hexThreshold) {
15296  rss << " (0x" << std::hex << value << ')';
15297  }
15298  return rss.str();
15299  }
15300 
15301  std::string StringMaker<bool>::convert(bool b) {
15302  return b ? "true" : "false";
15303  }
15304 
15305  std::string StringMaker<signed char>::convert(signed char value) {
15306  if (value == '\r') {
15307  return "'\\r'";
15308  } else if (value == '\f') {
15309  return "'\\f'";
15310  } else if (value == '\n') {
15311  return "'\\n'";
15312  } else if (value == '\t') {
15313  return "'\\t'";
15314  } else if ('\0' <= value && value < ' ') {
15315  return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
15316  } else {
15317  char chstr[] = "' '";
15318  chstr[1] = value;
15319  return chstr;
15320  }
15321  }
15322  std::string StringMaker<char>::convert(char c) {
15323  return ::Catch::Detail::stringify(static_cast<signed char>(c));
15324  }
15325  std::string StringMaker<unsigned char>::convert(unsigned char c) {
15326  return ::Catch::Detail::stringify(static_cast<char>(c));
15327  }
15328 
15329  std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
15330  return "nullptr";
15331  }
15332 
15334 
15335  std::string StringMaker<float>::convert(float value) {
15336  return fpToString(value, precision) + 'f';
15337  }
15338 
15340 
15341  std::string StringMaker<double>::convert(double value) {
15342  return fpToString(value, precision);
15343  }
15344 
15345  std::string ratio_string<std::atto>::symbol() {
15346  return "a";
15347  }
15348  std::string ratio_string<std::femto>::symbol() {
15349  return "f";
15350  }
15351  std::string ratio_string<std::pico>::symbol() {
15352  return "p";
15353  }
15354  std::string ratio_string<std::nano>::symbol() {
15355  return "n";
15356  }
15357  std::string ratio_string<std::micro>::symbol() {
15358  return "u";
15359  }
15360  std::string ratio_string<std::milli>::symbol() {
15361  return "m";
15362  }
15363 
15364 } // end namespace Catch
15365 
15366 #if defined(__clang__)
15367 #pragma clang diagnostic pop
15368 #endif
15369 
15370 // end catch_tostring.cpp
15371 // start catch_totals.cpp
15372 
15373 namespace Catch {
15374  Counts Counts::operator-(Counts const &other) const {
15375  Counts diff;
15376  diff.passed = passed - other.passed;
15377  diff.failed = failed - other.failed;
15378  diff.failedButOk = failedButOk - other.failedButOk;
15379  return diff;
15380  }
15381 
15382  Counts &Counts::operator+=(Counts const &other) {
15383  passed += other.passed;
15384  failed += other.failed;
15385  failedButOk += other.failedButOk;
15386  return *this;
15387  }
15388 
15389  std::size_t Counts::total() const {
15390  return passed + failed + failedButOk;
15391  }
15392  bool Counts::allPassed() const {
15393  return failed == 0 && failedButOk == 0;
15394  }
15395  bool Counts::allOk() const {
15396  return failed == 0;
15397  }
15398 
15399  Totals Totals::operator-(Totals const &other) const {
15400  Totals diff;
15401  diff.assertions = assertions - other.assertions;
15402  diff.testCases = testCases - other.testCases;
15403  return diff;
15404  }
15405 
15406  Totals &Totals::operator+=(Totals const &other) {
15407  assertions += other.assertions;
15408  testCases += other.testCases;
15409  return *this;
15410  }
15411 
15412  Totals Totals::delta(Totals const &prevTotals) const {
15413  Totals diff = *this - prevTotals;
15414  if (diff.assertions.failed > 0)
15415  ++diff.testCases.failed;
15416  else if (diff.assertions.failedButOk > 0)
15417  ++diff.testCases.failedButOk;
15418  else
15419  ++diff.testCases.passed;
15420  return diff;
15421  }
15422 
15423 } // namespace Catch
15424 // end catch_totals.cpp
15425 // start catch_uncaught_exceptions.cpp
15426 
15427 // start catch_config_uncaught_exceptions.hpp
15428 
15429 // Copyright Catch2 Authors
15430 // Distributed under the Boost Software License, Version 1.0.
15431 // (See accompanying file LICENSE_1_0.txt or copy at
15432 // https://www.boost.org/LICENSE_1_0.txt)
15433 
15434 // SPDX-License-Identifier: BSL-1.0
15435 
15436 #ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15437 #define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
15438 
15439 #if defined(_MSC_VER)
15440 #if _MSC_VER >= 1900 // Visual Studio 2015 or newer
15441 #define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15442 #endif
15443 #endif
15444 
15445 #include <exception>
15446 
15447 #if defined(__cpp_lib_uncaught_exceptions) && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15448 
15449 #define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15450 #endif // __cpp_lib_uncaught_exceptions
15451 
15452 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
15453  && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15454 
15455 #define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
15456 #endif
15457 
15458 #endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP \
15459  // end catch_config_uncaught_exceptions.hpp
15460 #include <exception>
15461 
15462 namespace Catch {
15463  bool uncaught_exceptions() {
15464 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
15465  return false;
15466 #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
15467  return std::uncaught_exceptions() > 0;
15468 #else
15469  return std::uncaught_exception();
15470 #endif
15471  }
15472 } // end namespace Catch
15473 // end catch_uncaught_exceptions.cpp
15474 // start catch_version.cpp
15475 
15476 #include <ostream>
15477 
15478 namespace Catch {
15479  Version::Version(unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, char const *const _branchName, unsigned int _buildNumber)
15480  : majorVersion(_majorVersion)
15481  , minorVersion(_minorVersion)
15482  , patchNumber(_patchNumber)
15483  , branchName(_branchName)
15484  , buildNumber(_buildNumber) {
15485  }
15486 
15487  std::ostream &operator<<(std::ostream &os, Version const &version) {
15488  os << version.majorVersion << '.' << version.minorVersion << '.' << version.patchNumber;
15489  // branchName is never null -> 0th char is \0 if it is empty
15490  if (version.branchName[0]) {
15491  os << '-' << version.branchName << '.' << version.buildNumber;
15492  }
15493  return os;
15494  }
15495 
15496  Version const &libraryVersion() {
15497  static Version version(2, 13, 6, "", 0);
15498  return version;
15499  }
15500 
15501 } // namespace Catch
15502 // end catch_version.cpp
15503 // start catch_wildcard_pattern.cpp
15504 
15505 namespace Catch {
15506  WildcardPattern::WildcardPattern(std::string const &pattern, CaseSensitive::Choice caseSensitivity)
15507  : m_caseSensitivity(caseSensitivity)
15508  , m_pattern(normaliseString(pattern)) {
15509  if (startsWith(m_pattern, '*')) {
15510  m_pattern = m_pattern.substr(1);
15511  m_wildcard = WildcardAtStart;
15512  }
15513  if (endsWith(m_pattern, '*')) {
15514  m_pattern = m_pattern.substr(0, m_pattern.size() - 1);
15515  m_wildcard = static_cast<WildcardPosition>(m_wildcard | WildcardAtEnd);
15516  }
15517  }
15518 
15519  bool WildcardPattern::matches(std::string const &str) const {
15520  switch (m_wildcard) {
15521  case NoWildcard:
15522  return m_pattern == normaliseString(str);
15523  case WildcardAtStart:
15524  return endsWith(normaliseString(str), m_pattern);
15525  case WildcardAtEnd:
15526  return startsWith(normaliseString(str), m_pattern);
15527  case WildcardAtBothEnds:
15528  return contains(normaliseString(str), m_pattern);
15529  default:
15530  CATCH_INTERNAL_ERROR("Unknown enum");
15531  }
15532  }
15533 
15534  std::string WildcardPattern::normaliseString(std::string const &str) const {
15535  return trim(m_caseSensitivity == CaseSensitive::No ? toLower(str) : str);
15536  }
15537 } // namespace Catch
15538 // end catch_wildcard_pattern.cpp
15539 // start catch_xmlwriter.cpp
15540 
15541 #include <iomanip>
15542 #include <type_traits>
15543 
15544 namespace Catch {
15545  namespace {
15546  size_t trailingBytes(unsigned char c) {
15547  if ((c & 0xE0) == 0xC0) {
15548  return 2;
15549  }
15550  if ((c & 0xF0) == 0xE0) {
15551  return 3;
15552  }
15553  if ((c & 0xF8) == 0xF0) {
15554  return 4;
15555  }
15556  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15557  }
15558 
15559  uint32_t headerValue(unsigned char c) {
15560  if ((c & 0xE0) == 0xC0) {
15561  return c & 0x1F;
15562  }
15563  if ((c & 0xF0) == 0xE0) {
15564  return c & 0x0F;
15565  }
15566  if ((c & 0xF8) == 0xF0) {
15567  return c & 0x07;
15568  }
15569  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
15570  }
15571 
15572  void hexEscapeChar(std::ostream &os, unsigned char c) {
15573  std::ios_base::fmtflags f(os.flags());
15574  os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(c);
15575  os.flags(f);
15576  }
15577 
15578  bool shouldNewline(XmlFormatting fmt) {
15579  return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
15580  }
15581 
15582  bool shouldIndent(XmlFormatting fmt) {
15583  return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
15584  }
15585 
15586  } // anonymous namespace
15587 
15588  XmlFormatting operator|(XmlFormatting lhs, XmlFormatting rhs) {
15589  return static_cast<XmlFormatting>(static_cast<std::underlying_type<XmlFormatting>::type>(lhs)
15590  | static_cast<std::underlying_type<XmlFormatting>::type>(rhs));
15591  }
15592 
15593  XmlFormatting operator&(XmlFormatting lhs, XmlFormatting rhs) {
15594  return static_cast<XmlFormatting>(static_cast<std::underlying_type<XmlFormatting>::type>(lhs)
15595  & static_cast<std::underlying_type<XmlFormatting>::type>(rhs));
15596  }
15597 
15598  XmlEncode::XmlEncode(std::string const &str, ForWhat forWhat)
15599  : m_str(str)
15600  , m_forWhat(forWhat) {
15601  }
15602 
15603  void XmlEncode::encodeTo(std::ostream &os) const {
15604  // Apostrophe escaping not necessary if we always use " to write attributes
15605  // (see: http://www.w3.org/TR/xml/#syntax)
15606 
15607  for (std::size_t idx = 0; idx < m_str.size(); ++idx) {
15608  unsigned char c = m_str[idx];
15609  switch (c) {
15610  case '<':
15611  os << "&lt;";
15612  break;
15613  case '&':
15614  os << "&amp;";
15615  break;
15616 
15617  case '>':
15618  // See: http://www.w3.org/TR/xml/#syntax
15619  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
15620  os << "&gt;";
15621  else
15622  os << c;
15623  break;
15624 
15625  case '\"':
15626  if (m_forWhat == ForAttributes)
15627  os << "&quot;";
15628  else
15629  os << c;
15630  break;
15631 
15632  default:
15633  // Check for control characters and invalid utf-8
15634 
15635  // Escape control characters in standard ascii
15636  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
15637  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
15638  hexEscapeChar(os, c);
15639  break;
15640  }
15641 
15642  // Plain ASCII: Write it to stream
15643  if (c < 0x7F) {
15644  os << c;
15645  break;
15646  }
15647 
15648  // UTF-8 territory
15649  // Check if the encoding is valid and if it is not, hex escape bytes.
15650  // Important: We do not check the exact decoded values for validity, only the encoding format
15651  // First check that this bytes is a valid lead byte:
15652  // This means that it is not encoded as 1111 1XXX
15653  // Or as 10XX XXXX
15654  if (c < 0xC0 || c >= 0xF8) {
15655  hexEscapeChar(os, c);
15656  break;
15657  }
15658 
15659  auto encBytes = trailingBytes(c);
15660  // Are there enough bytes left to avoid accessing out-of-bounds memory?
15661  if (idx + encBytes - 1 >= m_str.size()) {
15662  hexEscapeChar(os, c);
15663  break;
15664  }
15665  // The header is valid, check data
15666  // The next encBytes bytes must together be a valid utf-8
15667  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
15668  bool valid = true;
15669  uint32_t value = headerValue(c);
15670  for (std::size_t n = 1; n < encBytes; ++n) {
15671  unsigned char nc = m_str[idx + n];
15672  valid &= ((nc & 0xC0) == 0x80);
15673  value = (value << 6) | (nc & 0x3F);
15674  }
15675 
15676  if (
15677  // Wrong bit pattern of following bytes
15678  (!valid) ||
15679  // Overlong encodings
15680  (value < 0x80) || (0x80 <= value && value < 0x800 && encBytes > 2) || (0x800 < value && value < 0x10000 && encBytes > 3) ||
15681  // Encoded value out of range
15682  (value >= 0x110000)) {
15683  hexEscapeChar(os, c);
15684  break;
15685  }
15686 
15687  // If we got here, this is in fact a valid(ish) utf-8 sequence
15688  for (std::size_t n = 0; n < encBytes; ++n) {
15689  os << m_str[idx + n];
15690  }
15691  idx += encBytes - 1;
15692  break;
15693  }
15694  }
15695  }
15696 
15697  std::ostream &operator<<(std::ostream &os, XmlEncode const &xmlEncode) {
15698  xmlEncode.encodeTo(os);
15699  return os;
15700  }
15701 
15702  XmlWriter::ScopedElement::ScopedElement(XmlWriter *writer, XmlFormatting fmt)
15703  : m_writer(writer)
15704  , m_fmt(fmt) {
15705  }
15706 
15707  XmlWriter::ScopedElement::ScopedElement(ScopedElement &&other) noexcept
15708  : m_writer(other.m_writer)
15709  , m_fmt(other.m_fmt) {
15710  other.m_writer = nullptr;
15711  other.m_fmt = XmlFormatting::None;
15712  }
15713  XmlWriter::ScopedElement &XmlWriter::ScopedElement::operator=(ScopedElement &&other) noexcept {
15714  if (m_writer) {
15715  m_writer->endElement();
15716  }
15717  m_writer = other.m_writer;
15718  other.m_writer = nullptr;
15719  m_fmt = other.m_fmt;
15720  other.m_fmt = XmlFormatting::None;
15721  return *this;
15722  }
15723 
15724  XmlWriter::ScopedElement::~ScopedElement() {
15725  if (m_writer) {
15726  m_writer->endElement(m_fmt);
15727  }
15728  }
15729 
15730  XmlWriter::ScopedElement &XmlWriter::ScopedElement::writeText(std::string const &text, XmlFormatting fmt) {
15731  m_writer->writeText(text, fmt);
15732  return *this;
15733  }
15734 
15735  XmlWriter::XmlWriter(std::ostream &os)
15736  : m_os(os) {
15737  writeDeclaration();
15738  }
15739 
15740  XmlWriter::~XmlWriter() {
15741  while (!m_tags.empty()) {
15742  endElement();
15743  }
15744  newlineIfNecessary();
15745  }
15746 
15747  XmlWriter &XmlWriter::startElement(std::string const &name, XmlFormatting fmt) {
15748  ensureTagClosed();
15749  newlineIfNecessary();
15750  if (shouldIndent(fmt)) {
15751  m_os << m_indent;
15752  m_indent += " ";
15753  }
15754  m_os << '<' << name;
15755  m_tags.push_back(name);
15756  m_tagIsOpen = true;
15757  applyFormatting(fmt);
15758  return *this;
15759  }
15760 
15761  XmlWriter::ScopedElement XmlWriter::scopedElement(std::string const &name, XmlFormatting fmt) {
15762  ScopedElement scoped(this, fmt);
15763  startElement(name, fmt);
15764  return scoped;
15765  }
15766 
15767  XmlWriter &XmlWriter::endElement(XmlFormatting fmt) {
15768  m_indent = m_indent.substr(0, m_indent.size() - 2);
15769 
15770  if (m_tagIsOpen) {
15771  m_os << "/>";
15772  m_tagIsOpen = false;
15773  } else {
15774  newlineIfNecessary();
15775  if (shouldIndent(fmt)) {
15776  m_os << m_indent;
15777  }
15778  m_os << "</" << m_tags.back() << ">";
15779  }
15780  m_os << std::flush;
15781  applyFormatting(fmt);
15782  m_tags.pop_back();
15783  return *this;
15784  }
15785 
15786  XmlWriter &XmlWriter::writeAttribute(std::string const &name, std::string const &attribute) {
15787  if (!name.empty() && !attribute.empty())
15788  m_os << ' ' << name << "=\"" << XmlEncode(attribute, XmlEncode::ForAttributes) << '"';
15789  return *this;
15790  }
15791 
15792  XmlWriter &XmlWriter::writeAttribute(std::string const &name, bool attribute) {
15793  m_os << ' ' << name << "=\"" << (attribute ? "true" : "false") << '"';
15794  return *this;
15795  }
15796 
15797  XmlWriter &XmlWriter::writeText(std::string const &text, XmlFormatting fmt) {
15798  if (!text.empty()) {
15799  bool tagWasOpen = m_tagIsOpen;
15800  ensureTagClosed();
15801  if (tagWasOpen && shouldIndent(fmt)) {
15802  m_os << m_indent;
15803  }
15804  m_os << XmlEncode(text);
15805  applyFormatting(fmt);
15806  }
15807  return *this;
15808  }
15809 
15810  XmlWriter &XmlWriter::writeComment(std::string const &text, XmlFormatting fmt) {
15811  ensureTagClosed();
15812  if (shouldIndent(fmt)) {
15813  m_os << m_indent;
15814  }
15815  m_os << "<!--" << text << "-->";
15816  applyFormatting(fmt);
15817  return *this;
15818  }
15819 
15820  void XmlWriter::writeStylesheetRef(std::string const &url) {
15821  m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
15822  }
15823 
15824  XmlWriter &XmlWriter::writeBlankLine() {
15825  ensureTagClosed();
15826  m_os << '\n';
15827  return *this;
15828  }
15829 
15830  void XmlWriter::ensureTagClosed() {
15831  if (m_tagIsOpen) {
15832  m_os << '>' << std::flush;
15833  newlineIfNecessary();
15834  m_tagIsOpen = false;
15835  }
15836  }
15837 
15838  void XmlWriter::applyFormatting(XmlFormatting fmt) {
15839  m_needsNewline = shouldNewline(fmt);
15840  }
15841 
15842  void XmlWriter::writeDeclaration() {
15843  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
15844  }
15845 
15846  void XmlWriter::newlineIfNecessary() {
15847  if (m_needsNewline) {
15848  m_os << std::endl;
15849  m_needsNewline = false;
15850  }
15851  }
15852 } // namespace Catch
15853 // end catch_xmlwriter.cpp
15854 // start catch_reporter_bases.cpp
15855 
15856 #include <cassert>
15857 #include <cfloat>
15858 #include <cstdio>
15859 #include <cstring>
15860 #include <memory>
15861 
15862 namespace Catch {
15863  void prepareExpandedExpression(AssertionResult &result) {
15864  result.getExpandedExpression();
15865  }
15866 
15867  // Because formatting using c++ streams is stateful, drop down to C is required
15868  // Alternatively we could use stringstream, but its performance is... not good.
15869  std::string getFormattedDuration(double duration) {
15870  // Max exponent + 1 is required to represent the whole part
15871  // + 1 for decimal point
15872  // + 3 for the 3 decimal places
15873  // + 1 for null terminator
15874  const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
15875  char buffer[maxDoubleSize];
15876 
15877  // Save previous errno, to prevent sprintf from overwriting it
15878  ErrnoGuard guard;
15879 #ifdef _MSC_VER
15880  sprintf_s(buffer, "%.3f", duration);
15881 #else
15882  std::sprintf(buffer, "%.3f", duration);
15883 #endif
15884  return std::string(buffer);
15885  }
15886 
15887  bool shouldShowDuration(IConfig const &config, double duration) {
15888  if (config.showDurations() == ShowDurations::Always) {
15889  return true;
15890  }
15891  if (config.showDurations() == ShowDurations::Never) {
15892  return false;
15893  }
15894  const double min = config.minDuration();
15895  return min >= 0 && duration >= min;
15896  }
15897 
15898  std::string serializeFilters(std::vector<std::string> const &container) {
15899  ReusableStringStream oss;
15900  bool first = true;
15901  for (auto &&filter : container) {
15902  if (!first)
15903  oss << ' ';
15904  else
15905  first = false;
15906 
15907  oss << filter;
15908  }
15909  return oss.str();
15910  }
15911 
15912  TestEventListenerBase::TestEventListenerBase(ReporterConfig const &_config)
15913  : StreamingReporterBase(_config) {
15914  }
15915 
15916  std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
15917  return {Verbosity::Quiet, Verbosity::Normal, Verbosity::High};
15918  }
15919 
15920  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
15921 
15922  bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
15923  return false;
15924  }
15925 
15926 } // end namespace Catch
15927 // end catch_reporter_bases.cpp
15928 // start catch_reporter_compact.cpp
15929 
15930 namespace {
15931 #ifdef CATCH_PLATFORM_MAC
15932  const char *failedString() {
15933  return "FAILED";
15934  }
15935  const char *passedString() {
15936  return "PASSED";
15937  }
15938 #else
15939  const char *failedString() {
15940  return "failed";
15941  }
15942  const char *passedString() {
15943  return "passed";
15944  }
15945 #endif
15946 
15947  // Colour::LightGrey
15948  Catch::Colour::Code dimColour() {
15949  return Catch::Colour::FileName;
15950  }
15951 
15952  std::string bothOrAll(std::size_t count) {
15953  return count == 1 ? std::string() : count == 2 ? "both "
15954  : "all ";
15955  }
15956 
15957 } // namespace
15958 
15959 namespace Catch {
15960  namespace {
15961  // Colour, message variants:
15962  // - white: No tests ran.
15963  // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
15964  // - white: Passed [both/all] N test cases (no assertions).
15965  // - red: Failed N tests cases, failed M assertions.
15966  // - green: Passed [both/all] N tests cases with M assertions.
15967  void printTotals(std::ostream &out, const Totals &totals) {
15968  if (totals.testCases.total() == 0) {
15969  out << "No tests ran.";
15970  } else if (totals.testCases.failed == totals.testCases.total()) {
15971  Colour colour(Colour::ResultError);
15972  const std::string qualify_assertions_failed
15973  = totals.assertions.failed == totals.assertions.total() ? bothOrAll(totals.assertions.failed) : std::string();
15974  out << "Failed " << bothOrAll(totals.testCases.failed) << pluralise(totals.testCases.failed, "test case")
15975  << ", "
15976  "failed "
15977  << qualify_assertions_failed << pluralise(totals.assertions.failed, "assertion") << '.';
15978  } else if (totals.assertions.total() == 0) {
15979  out << "Passed " << bothOrAll(totals.testCases.total()) << pluralise(totals.testCases.total(), "test case") << " (no assertions).";
15980  } else if (totals.assertions.failed) {
15981  Colour colour(Colour::ResultError);
15982  out << "Failed " << pluralise(totals.testCases.failed, "test case")
15983  << ", "
15984  "failed "
15985  << pluralise(totals.assertions.failed, "assertion") << '.';
15986  } else {
15987  Colour colour(Colour::ResultSuccess);
15988  out << "Passed " << bothOrAll(totals.testCases.passed) << pluralise(totals.testCases.passed, "test case") << " with "
15989  << pluralise(totals.assertions.passed, "assertion") << '.';
15990  }
15991  }
15992 
15993  // Implementation of CompactReporter formatting
15994  class AssertionPrinter {
15995  public:
15996  AssertionPrinter &operator=(AssertionPrinter const &) = delete;
15997  AssertionPrinter(AssertionPrinter const &) = delete;
15998  AssertionPrinter(std::ostream &_stream, AssertionStats const &_stats, bool _printInfoMessages)
15999  : stream(_stream)
16000  , result(_stats.assertionResult)
16001  , messages(_stats.infoMessages)
16002  , itMessage(_stats.infoMessages.begin())
16003  , printInfoMessages(_printInfoMessages) {
16004  }
16005 
16006  void print() {
16007  printSourceInfo();
16008 
16009  itMessage = messages.begin();
16010 
16011  switch (result.getResultType()) {
16012  case ResultWas::Ok:
16013  printResultType(Colour::ResultSuccess, passedString());
16014  printOriginalExpression();
16015  printReconstructedExpression();
16016  if (!result.hasExpression())
16017  printRemainingMessages(Colour::None);
16018  else
16019  printRemainingMessages();
16020  break;
16021  case ResultWas::ExpressionFailed:
16022  if (result.isOk())
16023  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
16024  else
16025  printResultType(Colour::Error, failedString());
16026  printOriginalExpression();
16027  printReconstructedExpression();
16028  printRemainingMessages();
16029  break;
16030  case ResultWas::ThrewException:
16031  printResultType(Colour::Error, failedString());
16032  printIssue("unexpected exception with message:");
16033  printMessage();
16034  printExpressionWas();
16035  printRemainingMessages();
16036  break;
16037  case ResultWas::FatalErrorCondition:
16038  printResultType(Colour::Error, failedString());
16039  printIssue("fatal error condition with message:");
16040  printMessage();
16041  printExpressionWas();
16042  printRemainingMessages();
16043  break;
16044  case ResultWas::DidntThrowException:
16045  printResultType(Colour::Error, failedString());
16046  printIssue("expected exception, got none");
16047  printExpressionWas();
16048  printRemainingMessages();
16049  break;
16050  case ResultWas::Info:
16051  printResultType(Colour::None, "info");
16052  printMessage();
16053  printRemainingMessages();
16054  break;
16055  case ResultWas::Warning:
16056  printResultType(Colour::None, "warning");
16057  printMessage();
16058  printRemainingMessages();
16059  break;
16060  case ResultWas::ExplicitFailure:
16061  printResultType(Colour::Error, failedString());
16062  printIssue("explicitly");
16063  printRemainingMessages(Colour::None);
16064  break;
16065  // These cases are here to prevent compiler warnings
16066  case ResultWas::Unknown:
16067  case ResultWas::FailureBit:
16068  case ResultWas::Exception:
16069  printResultType(Colour::Error, "** internal error **");
16070  break;
16071  }
16072  }
16073 
16074  private:
16075  void printSourceInfo() const {
16076  Colour colourGuard(Colour::FileName);
16077  stream << result.getSourceInfo() << ':';
16078  }
16079 
16080  void printResultType(Colour::Code colour, std::string const &passOrFail) const {
16081  if (!passOrFail.empty()) {
16082  {
16083  Colour colourGuard(colour);
16084  stream << ' ' << passOrFail;
16085  }
16086  stream << ':';
16087  }
16088  }
16089 
16090  void printIssue(std::string const &issue) const { stream << ' ' << issue; }
16091 
16092  void printExpressionWas() {
16093  if (result.hasExpression()) {
16094  stream << ';';
16095  {
16096  Colour colour(dimColour());
16097  stream << " expression was:";
16098  }
16099  printOriginalExpression();
16100  }
16101  }
16102 
16103  void printOriginalExpression() const {
16104  if (result.hasExpression()) {
16105  stream << ' ' << result.getExpression();
16106  }
16107  }
16108 
16109  void printReconstructedExpression() const {
16110  if (result.hasExpandedExpression()) {
16111  {
16112  Colour colour(dimColour());
16113  stream << " for: ";
16114  }
16115  stream << result.getExpandedExpression();
16116  }
16117  }
16118 
16119  void printMessage() {
16120  if (itMessage != messages.end()) {
16121  stream << " '" << itMessage->message << '\'';
16122  ++itMessage;
16123  }
16124  }
16125 
16126  void printRemainingMessages(Colour::Code colour = dimColour()) {
16127  if (itMessage == messages.end())
16128  return;
16129 
16130  const auto itEnd = messages.cend();
16131  const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
16132 
16133  {
16134  Colour colourGuard(colour);
16135  stream << " with " << pluralise(N, "message") << ':';
16136  }
16137 
16138  while (itMessage != itEnd) {
16139  // If this assertion is a warning ignore any INFO messages
16140  if (printInfoMessages || itMessage->type != ResultWas::Info) {
16141  printMessage();
16142  if (itMessage != itEnd) {
16143  Colour colourGuard(dimColour());
16144  stream << " and";
16145  }
16146  continue;
16147  }
16148  ++itMessage;
16149  }
16150  }
16151 
16152  private:
16153  std::ostream &stream;
16154  AssertionResult const &result;
16155  std::vector<MessageInfo> messages;
16156  std::vector<MessageInfo>::const_iterator itMessage;
16157  bool printInfoMessages;
16158  };
16159 
16160  } // namespace
16161 
16162  std::string CompactReporter::getDescription() {
16163  return "Reports test results on a single line, suitable for IDEs";
16164  }
16165 
16166  void CompactReporter::noMatchingTestCases(std::string const &spec) {
16167  stream << "No test cases matched '" << spec << '\'' << std::endl;
16168  }
16169 
16170  void CompactReporter::assertionStarting(AssertionInfo const &) {}
16171 
16172  bool CompactReporter::assertionEnded(AssertionStats const &_assertionStats) {
16173  AssertionResult const &result = _assertionStats.assertionResult;
16174 
16175  bool printInfoMessages = true;
16176 
16177  // Drop out if result was successful and we're not printing those
16178  if (!m_config->includeSuccessfulResults() && result.isOk()) {
16179  if (result.getResultType() != ResultWas::Warning)
16180  return false;
16181  printInfoMessages = false;
16182  }
16183 
16184  AssertionPrinter printer(stream, _assertionStats, printInfoMessages);
16185  printer.print();
16186 
16187  stream << std::endl;
16188  return true;
16189  }
16190 
16191  void CompactReporter::sectionEnded(SectionStats const &_sectionStats) {
16192  double dur = _sectionStats.durationInSeconds;
16193  if (shouldShowDuration(*m_config, dur)) {
16194  stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16195  }
16196  }
16197 
16198  void CompactReporter::testRunEnded(TestRunStats const &_testRunStats) {
16199  printTotals(stream, _testRunStats.totals);
16200  stream << '\n'
16201  << std::endl;
16202  StreamingReporterBase::testRunEnded(_testRunStats);
16203  }
16204 
16205  CompactReporter::~CompactReporter() {}
16206 
16207  CATCH_REGISTER_REPORTER("compact", CompactReporter)
16208 
16209 } // end namespace Catch
16210 // end catch_reporter_compact.cpp
16211 // start catch_reporter_console.cpp
16212 
16213 #include <cfloat>
16214 #include <cstdio>
16215 
16216 #if defined(_MSC_VER)
16217 #pragma warning(push)
16218 #pragma warning(disable : 4061) // Not all labels are EXPLICITLY handled in switch \
16219  // Note that 4062 (not all labels are handled and default is missing) is enabled
16220 #endif
16221 
16222 #if defined(__clang__)
16223 #pragma clang diagnostic push
16224 // For simplicity, benchmarking-only helpers are always enabled
16225 #pragma clang diagnostic ignored "-Wunused-function"
16226 #endif
16227 
16228 namespace Catch {
16229  namespace {
16230  // Formatter impl for ConsoleReporter
16231  class ConsoleAssertionPrinter {
16232  public:
16233  ConsoleAssertionPrinter &operator=(ConsoleAssertionPrinter const &) = delete;
16234  ConsoleAssertionPrinter(ConsoleAssertionPrinter const &) = delete;
16235  ConsoleAssertionPrinter(std::ostream &_stream, AssertionStats const &_stats, bool _printInfoMessages)
16236  : stream(_stream)
16237  , stats(_stats)
16238  , result(_stats.assertionResult)
16239  , colour(Colour::None)
16240  , message(result.getMessage())
16241  , messages(_stats.infoMessages)
16242  , printInfoMessages(_printInfoMessages) {
16243  switch (result.getResultType()) {
16244  case ResultWas::Ok:
16245  colour = Colour::Success;
16246  passOrFail = "PASSED";
16247  // if( result.hasMessage() )
16248  if (_stats.infoMessages.size() == 1)
16249  messageLabel = "with message";
16250  if (_stats.infoMessages.size() > 1)
16251  messageLabel = "with messages";
16252  break;
16253  case ResultWas::ExpressionFailed:
16254  if (result.isOk()) {
16255  colour = Colour::Success;
16256  passOrFail = "FAILED - but was ok";
16257  } else {
16258  colour = Colour::Error;
16259  passOrFail = "FAILED";
16260  }
16261  if (_stats.infoMessages.size() == 1)
16262  messageLabel = "with message";
16263  if (_stats.infoMessages.size() > 1)
16264  messageLabel = "with messages";
16265  break;
16266  case ResultWas::ThrewException:
16267  colour = Colour::Error;
16268  passOrFail = "FAILED";
16269  messageLabel = "due to unexpected exception with ";
16270  if (_stats.infoMessages.size() == 1)
16271  messageLabel += "message";
16272  if (_stats.infoMessages.size() > 1)
16273  messageLabel += "messages";
16274  break;
16275  case ResultWas::FatalErrorCondition:
16276  colour = Colour::Error;
16277  passOrFail = "FAILED";
16278  messageLabel = "due to a fatal error condition";
16279  break;
16280  case ResultWas::DidntThrowException:
16281  colour = Colour::Error;
16282  passOrFail = "FAILED";
16283  messageLabel = "because no exception was thrown where one was expected";
16284  break;
16285  case ResultWas::Info:
16286  messageLabel = "info";
16287  break;
16288  case ResultWas::Warning:
16289  messageLabel = "warning";
16290  break;
16291  case ResultWas::ExplicitFailure:
16292  passOrFail = "FAILED";
16293  colour = Colour::Error;
16294  if (_stats.infoMessages.size() == 1)
16295  messageLabel = "explicitly with message";
16296  if (_stats.infoMessages.size() > 1)
16297  messageLabel = "explicitly with messages";
16298  break;
16299  // These cases are here to prevent compiler warnings
16300  case ResultWas::Unknown:
16301  case ResultWas::FailureBit:
16302  case ResultWas::Exception:
16303  passOrFail = "** internal error **";
16304  colour = Colour::Error;
16305  break;
16306  }
16307  }
16308 
16309  void print() const {
16310  printSourceInfo();
16311  if (stats.totals.assertions.total() > 0) {
16312  printResultType();
16313  printOriginalExpression();
16314  printReconstructedExpression();
16315  } else {
16316  stream << '\n';
16317  }
16318  printMessage();
16319  }
16320 
16321  private:
16322  void printResultType() const {
16323  if (!passOrFail.empty()) {
16324  Colour colourGuard(colour);
16325  stream << passOrFail << ":\n";
16326  }
16327  }
16328  void printOriginalExpression() const {
16329  if (result.hasExpression()) {
16330  Colour colourGuard(Colour::OriginalExpression);
16331  stream << " ";
16332  stream << result.getExpressionInMacro();
16333  stream << '\n';
16334  }
16335  }
16336  void printReconstructedExpression() const {
16337  if (result.hasExpandedExpression()) {
16338  stream << "with expansion:\n";
16339  Colour colourGuard(Colour::ReconstructedExpression);
16340  stream << Column(result.getExpandedExpression()).indent(2) << '\n';
16341  }
16342  }
16343  void printMessage() const {
16344  if (!messageLabel.empty())
16345  stream << messageLabel << ':' << '\n';
16346  for (auto const &msg : messages) {
16347  // If this assertion is a warning ignore any INFO messages
16348  if (printInfoMessages || msg.type != ResultWas::Info)
16349  stream << Column(msg.message).indent(2) << '\n';
16350  }
16351  }
16352  void printSourceInfo() const {
16353  Colour colourGuard(Colour::FileName);
16354  stream << result.getSourceInfo() << ": ";
16355  }
16356 
16357  std::ostream &stream;
16358  AssertionStats const &stats;
16359  AssertionResult const &result;
16360  Colour::Code colour;
16361  std::string passOrFail;
16362  std::string messageLabel;
16363  std::string message;
16364  std::vector<MessageInfo> messages;
16365  bool printInfoMessages;
16366  };
16367 
16368  std::size_t makeRatio(std::size_t number, std::size_t total) {
16369  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
16370  return (ratio == 0 && number > 0) ? 1 : ratio;
16371  }
16372 
16373  std::size_t &findMax(std::size_t &i, std::size_t &j, std::size_t &k) {
16374  if (i > j && i > k)
16375  return i;
16376  else if (j > k)
16377  return j;
16378  else
16379  return k;
16380  }
16381 
16382  struct ColumnInfo {
16383  enum Justification {
16384  Left,
16385  Right
16386  };
16387  std::string name;
16388  int width;
16389  Justification justification;
16390  };
16391  struct ColumnBreak {
16392  };
16393  struct RowBreak {
16394  };
16395 
16396  class Duration {
16397  enum class Unit {
16398  Auto,
16399  Nanoseconds,
16400  Microseconds,
16401  Milliseconds,
16402  Seconds,
16403  Minutes
16404  };
16405  static const uint64_t s_nanosecondsInAMicrosecond = 1000;
16406  static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
16407  static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
16408  static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
16409 
16410  double m_inNanoseconds;
16411  Unit m_units;
16412 
16413  public:
16414  explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
16415  : m_inNanoseconds(inNanoseconds)
16416  , m_units(units) {
16417  if (m_units == Unit::Auto) {
16418  if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
16419  m_units = Unit::Nanoseconds;
16420  else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
16421  m_units = Unit::Microseconds;
16422  else if (m_inNanoseconds < s_nanosecondsInASecond)
16423  m_units = Unit::Milliseconds;
16424  else if (m_inNanoseconds < s_nanosecondsInAMinute)
16425  m_units = Unit::Seconds;
16426  else
16427  m_units = Unit::Minutes;
16428  }
16429  }
16430 
16431  auto value() const -> double {
16432  switch (m_units) {
16433  case Unit::Microseconds:
16434  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
16435  case Unit::Milliseconds:
16436  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
16437  case Unit::Seconds:
16438  return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
16439  case Unit::Minutes:
16440  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
16441  default:
16442  return m_inNanoseconds;
16443  }
16444  }
16445  auto unitsAsString() const -> std::string {
16446  switch (m_units) {
16447  case Unit::Nanoseconds:
16448  return "ns";
16449  case Unit::Microseconds:
16450  return "us";
16451  case Unit::Milliseconds:
16452  return "ms";
16453  case Unit::Seconds:
16454  return "s";
16455  case Unit::Minutes:
16456  return "m";
16457  default:
16458  return "** internal error **";
16459  }
16460  }
16461  friend auto operator<<(std::ostream &os, Duration const &duration) -> std::ostream & {
16462  return os << duration.value() << ' ' << duration.unitsAsString();
16463  }
16464  };
16465  } // namespace
16466 
16467  class TablePrinter {
16468  std::ostream &m_os;
16469  std::vector<ColumnInfo> m_columnInfos;
16470  std::ostringstream m_oss;
16471  int m_currentColumn = -1;
16472  bool m_isOpen = false;
16473 
16474  public:
16475  TablePrinter(std::ostream &os, std::vector<ColumnInfo> columnInfos)
16476  : m_os(os)
16477  , m_columnInfos(std::move(columnInfos)) {
16478  }
16479 
16480  auto columnInfos() const -> std::vector<ColumnInfo> const & { return m_columnInfos; }
16481 
16482  void open() {
16483  if (!m_isOpen) {
16484  m_isOpen = true;
16485  *this << RowBreak();
16486 
16487  Columns headerCols;
16488  Spacer spacer(2);
16489  for (auto const &info : m_columnInfos) {
16490  headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
16491  headerCols += spacer;
16492  }
16493  m_os << headerCols << '\n';
16494 
16495  m_os << Catch::getLineOfChars<'-'>() << '\n';
16496  }
16497  }
16498  void close() {
16499  if (m_isOpen) {
16500  *this << RowBreak();
16501  m_os << std::endl;
16502  m_isOpen = false;
16503  }
16504  }
16505 
16506  template<typename T>
16507  friend TablePrinter &operator<<(TablePrinter &tp, T const &value) {
16508  tp.m_oss << value;
16509  return tp;
16510  }
16511 
16512  friend TablePrinter &operator<<(TablePrinter &tp, ColumnBreak) {
16513  auto colStr = tp.m_oss.str();
16514  const auto strSize = colStr.size();
16515  tp.m_oss.str("");
16516  tp.open();
16517  if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
16518  tp.m_currentColumn = -1;
16519  tp.m_os << '\n';
16520  }
16521  tp.m_currentColumn++;
16522 
16523  auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
16524  auto padding
16525  = (strSize + 1 < static_cast<std::size_t>(colInfo.width)) ? std::string(colInfo.width - (strSize + 1), ' ') : std::string();
16526  if (colInfo.justification == ColumnInfo::Left)
16527  tp.m_os << colStr << padding << ' ';
16528  else
16529  tp.m_os << padding << colStr << ' ';
16530  return tp;
16531  }
16532 
16533  friend TablePrinter &operator<<(TablePrinter &tp, RowBreak) {
16534  if (tp.m_currentColumn > 0) {
16535  tp.m_os << '\n';
16536  tp.m_currentColumn = -1;
16537  }
16538  return tp;
16539  }
16540  };
16541 
16542  ConsoleReporter::ConsoleReporter(ReporterConfig const &config)
16543  : StreamingReporterBase(config)
16544  , m_tablePrinter(new TablePrinter(config.stream(), [&config]() -> std::vector<ColumnInfo> {
16545  if (config.fullConfig()->benchmarkNoAnalysis()) {
16546  return {{"benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left},
16547  {" samples", 14, ColumnInfo::Right},
16548  {" iterations", 14, ColumnInfo::Right},
16549  {" mean", 14, ColumnInfo::Right}};
16550  } else {
16551  return {{"benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left},
16552  {"samples mean std dev", 14, ColumnInfo::Right},
16553  {"iterations low mean low std dev", 14, ColumnInfo::Right},
16554  {"estimated high mean high std dev", 14, ColumnInfo::Right}};
16555  }
16556  }())) {
16557  }
16558  ConsoleReporter::~ConsoleReporter() = default;
16559 
16560  std::string ConsoleReporter::getDescription() {
16561  return "Reports test results as plain lines of text";
16562  }
16563 
16564  void ConsoleReporter::noMatchingTestCases(std::string const &spec) {
16565  stream << "No test cases matched '" << spec << '\'' << std::endl;
16566  }
16567 
16568  void ConsoleReporter::reportInvalidArguments(std::string const &arg) {
16569  stream << "Invalid Filter: " << arg << std::endl;
16570  }
16571 
16572  void ConsoleReporter::assertionStarting(AssertionInfo const &) {}
16573 
16574  bool ConsoleReporter::assertionEnded(AssertionStats const &_assertionStats) {
16575  AssertionResult const &result = _assertionStats.assertionResult;
16576 
16577  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
16578 
16579  // Drop out if result was successful but we're not printing them.
16580  if (!includeResults && result.getResultType() != ResultWas::Warning)
16581  return false;
16582 
16583  lazyPrint();
16584 
16585  ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
16586  printer.print();
16587  stream << std::endl;
16588  return true;
16589  }
16590 
16591  void ConsoleReporter::sectionStarting(SectionInfo const &_sectionInfo) {
16592  m_tablePrinter->close();
16593  m_headerPrinted = false;
16594  StreamingReporterBase::sectionStarting(_sectionInfo);
16595  }
16596  void ConsoleReporter::sectionEnded(SectionStats const &_sectionStats) {
16597  m_tablePrinter->close();
16598  if (_sectionStats.missingAssertions) {
16599  lazyPrint();
16600  Colour colour(Colour::ResultError);
16601  if (m_sectionStack.size() > 1)
16602  stream << "\nNo assertions in section";
16603  else
16604  stream << "\nNo assertions in test case";
16605  stream << " '" << _sectionStats.sectionInfo.name << "'\n"
16606  << std::endl;
16607  }
16608  double dur = _sectionStats.durationInSeconds;
16609  if (shouldShowDuration(*m_config, dur)) {
16610  stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
16611  }
16612  if (m_headerPrinted) {
16613  m_headerPrinted = false;
16614  }
16615  StreamingReporterBase::sectionEnded(_sectionStats);
16616  }
16617 
16618 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
16619  void ConsoleReporter::benchmarkPreparing(std::string const &name) {
16620  lazyPrintWithoutClosingBenchmarkTable();
16621 
16622  auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
16623 
16624  bool firstLine = true;
16625  for (auto line : nameCol) {
16626  if (!firstLine)
16627  (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
16628  else
16629  firstLine = false;
16630 
16631  (*m_tablePrinter) << line << ColumnBreak();
16632  }
16633  }
16634 
16635  void ConsoleReporter::benchmarkStarting(BenchmarkInfo const &info) {
16636  (*m_tablePrinter) << info.samples << ColumnBreak() << info.iterations << ColumnBreak();
16637  if (!m_config->benchmarkNoAnalysis())
16638  (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
16639  }
16640  void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const &stats) {
16641  if (m_config->benchmarkNoAnalysis()) {
16642  (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
16643  } else {
16644  (*m_tablePrinter) << ColumnBreak() << Duration(stats.mean.point.count()) << ColumnBreak()
16645  << Duration(stats.mean.lower_bound.count()) << ColumnBreak() << Duration(stats.mean.upper_bound.count())
16646  << ColumnBreak() << ColumnBreak() << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
16647  << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
16648  << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak()
16649  << ColumnBreak() << ColumnBreak();
16650  }
16651  }
16652 
16653  void ConsoleReporter::benchmarkFailed(std::string const &error) {
16654  Colour colour(Colour::Red);
16655  (*m_tablePrinter) << "Benchmark failed (" << error << ')' << ColumnBreak() << RowBreak();
16656  }
16657 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
16658 
16659  void ConsoleReporter::testCaseEnded(TestCaseStats const &_testCaseStats) {
16660  m_tablePrinter->close();
16661  StreamingReporterBase::testCaseEnded(_testCaseStats);
16662  m_headerPrinted = false;
16663  }
16664  void ConsoleReporter::testGroupEnded(TestGroupStats const &_testGroupStats) {
16665  if (currentGroupInfo.used) {
16666  printSummaryDivider();
16667  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
16668  printTotals(_testGroupStats.totals);
16669  stream << '\n'
16670  << std::endl;
16671  }
16672  StreamingReporterBase::testGroupEnded(_testGroupStats);
16673  }
16674  void ConsoleReporter::testRunEnded(TestRunStats const &_testRunStats) {
16675  printTotalsDivider(_testRunStats.totals);
16676  printTotals(_testRunStats.totals);
16677  stream << std::endl;
16678  StreamingReporterBase::testRunEnded(_testRunStats);
16679  }
16680  void ConsoleReporter::testRunStarting(TestRunInfo const &_testInfo) {
16681  StreamingReporterBase::testRunStarting(_testInfo);
16682  printTestFilters();
16683  }
16684 
16685  void ConsoleReporter::lazyPrint() {
16686  m_tablePrinter->close();
16687  lazyPrintWithoutClosingBenchmarkTable();
16688  }
16689 
16690  void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
16691  if (!currentTestRunInfo.used)
16692  lazyPrintRunInfo();
16693  if (!currentGroupInfo.used)
16694  lazyPrintGroupInfo();
16695 
16696  if (!m_headerPrinted) {
16697  printTestCaseAndSectionHeader();
16698  m_headerPrinted = true;
16699  }
16700  }
16701  void ConsoleReporter::lazyPrintRunInfo() {
16702  stream << '\n'
16703  << getLineOfChars<'~'>() << '\n';
16704  Colour colour(Colour::SecondaryText);
16705  stream << currentTestRunInfo->name << " is a Catch v" << libraryVersion() << " host application.\n"
16706  << "Run with -? for options\n\n";
16707 
16708  if (m_config->rngSeed() != 0)
16709  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
16710 
16711  currentTestRunInfo.used = true;
16712  }
16713  void ConsoleReporter::lazyPrintGroupInfo() {
16714  if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
16715  printClosedHeader("Group: " + currentGroupInfo->name);
16716  currentGroupInfo.used = true;
16717  }
16718  }
16719  void ConsoleReporter::printTestCaseAndSectionHeader() {
16720  assert(!m_sectionStack.empty());
16721  printOpenHeader(currentTestCaseInfo->name);
16722 
16723  if (m_sectionStack.size() > 1) {
16724  Colour colourGuard(Colour::Headers);
16725 
16726  auto it = m_sectionStack.begin() + 1, // Skip first section (test case)
16727  itEnd = m_sectionStack.end();
16728  for (; it != itEnd; ++it)
16729  printHeaderString(it->name, 2);
16730  }
16731 
16732  SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
16733 
16734  stream << getLineOfChars<'-'>() << '\n';
16735  Colour colourGuard(Colour::FileName);
16736  stream << lineInfo << '\n';
16737  stream << getLineOfChars<'.'>() << '\n'
16738  << std::endl;
16739  }
16740 
16741  void ConsoleReporter::printClosedHeader(std::string const &_name) {
16742  printOpenHeader(_name);
16743  stream << getLineOfChars<'.'>() << '\n';
16744  }
16745  void ConsoleReporter::printOpenHeader(std::string const &_name) {
16746  stream << getLineOfChars<'-'>() << '\n';
16747  {
16748  Colour colourGuard(Colour::Headers);
16749  printHeaderString(_name);
16750  }
16751  }
16752 
16753  // if string has a : in first line will set indent to follow it on
16754  // subsequent lines
16755  void ConsoleReporter::printHeaderString(std::string const &_string, std::size_t indent) {
16756  std::size_t i = _string.find(": ");
16757  if (i != std::string::npos)
16758  i += 2;
16759  else
16760  i = 0;
16761  stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
16762  }
16763 
16764  struct SummaryColumn {
16765  SummaryColumn(std::string _label, Colour::Code _colour)
16766  : label(std::move(_label))
16767  , colour(_colour) {
16768  }
16769  SummaryColumn addRow(std::size_t count) {
16771  rss << count;
16772  std::string row = rss.str();
16773  for (auto &oldRow : rows) {
16774  while (oldRow.size() < row.size())
16775  oldRow = ' ' + oldRow;
16776  while (oldRow.size() > row.size())
16777  row = ' ' + row;
16778  }
16779  rows.push_back(row);
16780  return *this;
16781  }
16782 
16783  std::string label;
16784  Colour::Code colour;
16785  std::vector<std::string> rows;
16786  };
16787 
16788  void ConsoleReporter::printTotals(Totals const &totals) {
16789  if (totals.testCases.total() == 0) {
16790  stream << Colour(Colour::Warning) << "No tests ran\n";
16791  } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
16792  stream << Colour(Colour::ResultSuccess) << "All tests passed";
16793  stream << " (" << pluralise(totals.assertions.passed, "assertion") << " in " << pluralise(totals.testCases.passed, "test case")
16794  << ')' << '\n';
16795  } else {
16796  std::vector<SummaryColumn> columns;
16797  columns.push_back(SummaryColumn("", Colour::None).addRow(totals.testCases.total()).addRow(totals.assertions.total()));
16798  columns.push_back(SummaryColumn("passed", Colour::Success).addRow(totals.testCases.passed).addRow(totals.assertions.passed));
16799  columns.push_back(SummaryColumn("failed", Colour::ResultError).addRow(totals.testCases.failed).addRow(totals.assertions.failed));
16800  columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
16801  .addRow(totals.testCases.failedButOk)
16802  .addRow(totals.assertions.failedButOk));
16803 
16804  printSummaryRow("test cases", columns, 0);
16805  printSummaryRow("assertions", columns, 1);
16806  }
16807  }
16808  void ConsoleReporter::printSummaryRow(std::string const &label, std::vector<SummaryColumn> const &cols, std::size_t row) {
16809  for (auto col : cols) {
16810  std::string value = col.rows[row];
16811  if (col.label.empty()) {
16812  stream << label << ": ";
16813  if (value != "0")
16814  stream << value;
16815  else
16816  stream << Colour(Colour::Warning) << "- none -";
16817  } else if (value != "0") {
16818  stream << Colour(Colour::LightGrey) << " | ";
16819  stream << Colour(col.colour) << value << ' ' << col.label;
16820  }
16821  }
16822  stream << '\n';
16823  }
16824 
16825  void ConsoleReporter::printTotalsDivider(Totals const &totals) {
16826  if (totals.testCases.total() > 0) {
16827  std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
16828  std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
16829  std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
16830  while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
16831  findMax(failedRatio, failedButOkRatio, passedRatio)++;
16832  while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
16833  findMax(failedRatio, failedButOkRatio, passedRatio)--;
16834 
16835  stream << Colour(Colour::Error) << std::string(failedRatio, '=');
16836  stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
16837  if (totals.testCases.allPassed())
16838  stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
16839  else
16840  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
16841  } else {
16842  stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
16843  }
16844  stream << '\n';
16845  }
16846  void ConsoleReporter::printSummaryDivider() {
16847  stream << getLineOfChars<'-'>() << '\n';
16848  }
16849 
16850  void ConsoleReporter::printTestFilters() {
16851  if (m_config->testSpec().hasFilters()) {
16852  Colour guard(Colour::BrightYellow);
16853  stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
16854  }
16855  }
16856 
16857  CATCH_REGISTER_REPORTER("console", ConsoleReporter)
16858 
16859 } // end namespace Catch
16860 
16861 #if defined(_MSC_VER)
16862 #pragma warning(pop)
16863 #endif
16864 
16865 #if defined(__clang__)
16866 #pragma clang diagnostic pop
16867 #endif
16868 // end catch_reporter_console.cpp
16869 // start catch_reporter_junit.cpp
16870 
16871 #include <algorithm>
16872 #include <cassert>
16873 #include <ctime>
16874 #include <sstream>
16875 
16876 namespace Catch {
16877  namespace {
16878  std::string getCurrentTimestamp() {
16879  // Beware, this is not reentrant because of backward compatibility issues
16880  // Also, UTC only, again because of backward compatibility (%z is C++11)
16881  time_t rawtime;
16882  std::time(&rawtime);
16883  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
16884 
16885 #ifdef _MSC_VER
16886  std::tm timeInfo = {};
16887  gmtime_s(&timeInfo, &rawtime);
16888 #else
16889  std::tm *timeInfo;
16890  timeInfo = std::gmtime(&rawtime);
16891 #endif
16892 
16893  char timeStamp[timeStampSize];
16894  const char *const fmt = "%Y-%m-%dT%H:%M:%SZ";
16895 
16896 #ifdef _MSC_VER
16897  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
16898 #else
16899  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
16900 #endif
16901  return std::string(timeStamp);
16902  }
16903 
16904  std::string fileNameTag(const std::vector<std::string> &tags) {
16905  auto it = std::find_if(begin(tags), end(tags), [](std::string const &tag) { return tag.front() == '#'; });
16906  if (it != tags.end())
16907  return it->substr(1);
16908  return std::string();
16909  }
16910  } // anonymous namespace
16911 
16912  JunitReporter::JunitReporter(ReporterConfig const &_config)
16913  : CumulativeReporterBase(_config)
16914  , xml(_config.stream()) {
16915  m_reporterPrefs.shouldRedirectStdOut = true;
16916  m_reporterPrefs.shouldReportAllAssertions = true;
16917  }
16918 
16919  JunitReporter::~JunitReporter() {}
16920 
16921  std::string JunitReporter::getDescription() {
16922  return "Reports test results in an XML format that looks like Ant's junitreport target";
16923  }
16924 
16925  void JunitReporter::noMatchingTestCases(std::string const & /*spec*/) {}
16926 
16927  void JunitReporter::testRunStarting(TestRunInfo const &runInfo) {
16928  CumulativeReporterBase::testRunStarting(runInfo);
16929  xml.startElement("testsuites");
16930  }
16931 
16932  void JunitReporter::testGroupStarting(GroupInfo const &groupInfo) {
16933  suiteTimer.start();
16934  stdOutForSuite.clear();
16935  stdErrForSuite.clear();
16936  unexpectedExceptions = 0;
16937  CumulativeReporterBase::testGroupStarting(groupInfo);
16938  }
16939 
16940  void JunitReporter::testCaseStarting(TestCaseInfo const &testCaseInfo) {
16941  m_okToFail = testCaseInfo.okToFail();
16942  }
16943 
16944  bool JunitReporter::assertionEnded(AssertionStats const &assertionStats) {
16945  if (assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail)
16946  unexpectedExceptions++;
16947  return CumulativeReporterBase::assertionEnded(assertionStats);
16948  }
16949 
16950  void JunitReporter::testCaseEnded(TestCaseStats const &testCaseStats) {
16951  stdOutForSuite += testCaseStats.stdOut;
16952  stdErrForSuite += testCaseStats.stdErr;
16953  CumulativeReporterBase::testCaseEnded(testCaseStats);
16954  }
16955 
16956  void JunitReporter::testGroupEnded(TestGroupStats const &testGroupStats) {
16957  double suiteTime = suiteTimer.getElapsedSeconds();
16958  CumulativeReporterBase::testGroupEnded(testGroupStats);
16959  writeGroup(*m_testGroups.back(), suiteTime);
16960  }
16961 
16962  void JunitReporter::testRunEndedCumulative() {
16963  xml.endElement();
16964  }
16965 
16966  void JunitReporter::writeGroup(TestGroupNode const &groupNode, double suiteTime) {
16967  XmlWriter::ScopedElement e = xml.scopedElement("testsuite");
16968 
16969  TestGroupStats const &stats = groupNode.value;
16970  xml.writeAttribute("name", stats.groupInfo.name);
16971  xml.writeAttribute("errors", unexpectedExceptions);
16972  xml.writeAttribute("failures", stats.totals.assertions.failed - unexpectedExceptions);
16973  xml.writeAttribute("tests", stats.totals.assertions.total());
16974  xml.writeAttribute("hostname", "tbd"); // !TBD
16975  if (m_config->showDurations() == ShowDurations::Never)
16976  xml.writeAttribute("time", "");
16977  else
16978  xml.writeAttribute("time", suiteTime);
16979  xml.writeAttribute("timestamp", getCurrentTimestamp());
16980 
16981  // Write properties if there are any
16982  if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
16983  auto properties = xml.scopedElement("properties");
16984  if (m_config->hasTestFilters()) {
16985  xml.scopedElement("property").writeAttribute("name", "filters").writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
16986  }
16987  if (m_config->rngSeed() != 0) {
16988  xml.scopedElement("property").writeAttribute("name", "random-seed").writeAttribute("value", m_config->rngSeed());
16989  }
16990  }
16991 
16992  // Write test cases
16993  for (auto const &child : groupNode.children)
16994  writeTestCase(*child);
16995 
16996  xml.scopedElement("system-out").writeText(trim(stdOutForSuite), XmlFormatting::Newline);
16997  xml.scopedElement("system-err").writeText(trim(stdErrForSuite), XmlFormatting::Newline);
16998  }
16999 
17000  void JunitReporter::writeTestCase(TestCaseNode const &testCaseNode) {
17001  TestCaseStats const &stats = testCaseNode.value;
17002 
17003  // All test cases have exactly one section - which represents the
17004  // test case itself. That section may have 0-n nested sections
17005  assert(testCaseNode.children.size() == 1);
17006  SectionNode const &rootSection = *testCaseNode.children.front();
17007 
17008  std::string className = stats.testInfo.className;
17009 
17010  if (className.empty()) {
17011  className = fileNameTag(stats.testInfo.tags);
17012  if (className.empty())
17013  className = "global";
17014  }
17015 
17016  if (!m_config->name().empty())
17017  className = m_config->name() + "." + className;
17018 
17019  writeSection(className, "", rootSection);
17020  }
17021 
17022  void JunitReporter::writeSection(std::string const &className, std::string const &rootName, SectionNode const &sectionNode) {
17023  std::string name = trim(sectionNode.stats.sectionInfo.name);
17024  if (!rootName.empty())
17025  name = rootName + '/' + name;
17026 
17027  if (!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) {
17028  XmlWriter::ScopedElement e = xml.scopedElement("testcase");
17029  if (className.empty()) {
17030  xml.writeAttribute("classname", name);
17031  xml.writeAttribute("name", "root");
17032  } else {
17033  xml.writeAttribute("classname", className);
17034  xml.writeAttribute("name", name);
17035  }
17036  xml.writeAttribute("time", ::Catch::Detail::stringify(sectionNode.stats.durationInSeconds));
17037  // This is not ideal, but it should be enough to mimic gtest's
17038  // junit output.
17039  // Ideally the JUnit reporter would also handle `skipTest`
17040  // events and write those out appropriately.
17041  xml.writeAttribute("status", "run");
17042 
17043  writeAssertions(sectionNode);
17044 
17045  if (!sectionNode.stdOut.empty())
17046  xml.scopedElement("system-out").writeText(trim(sectionNode.stdOut), XmlFormatting::Newline);
17047  if (!sectionNode.stdErr.empty())
17048  xml.scopedElement("system-err").writeText(trim(sectionNode.stdErr), XmlFormatting::Newline);
17049  }
17050  for (auto const &childNode : sectionNode.childSections)
17051  if (className.empty())
17052  writeSection(name, "", *childNode);
17053  else
17054  writeSection(className, name, *childNode);
17055  }
17056 
17057  void JunitReporter::writeAssertions(SectionNode const &sectionNode) {
17058  for (auto const &assertion : sectionNode.assertions)
17059  writeAssertion(assertion);
17060  }
17061 
17062  void JunitReporter::writeAssertion(AssertionStats const &stats) {
17063  AssertionResult const &result = stats.assertionResult;
17064  if (!result.isOk()) {
17065  std::string elementName;
17066  switch (result.getResultType()) {
17067  case ResultWas::ThrewException:
17068  case ResultWas::FatalErrorCondition:
17069  elementName = "error";
17070  break;
17071  case ResultWas::ExplicitFailure:
17072  case ResultWas::ExpressionFailed:
17073  case ResultWas::DidntThrowException:
17074  elementName = "failure";
17075  break;
17076 
17077  // We should never see these here:
17078  case ResultWas::Info:
17079  case ResultWas::Warning:
17080  case ResultWas::Ok:
17081  case ResultWas::Unknown:
17082  case ResultWas::FailureBit:
17083  case ResultWas::Exception:
17084  elementName = "internalError";
17085  break;
17086  }
17087 
17088  XmlWriter::ScopedElement e = xml.scopedElement(elementName);
17089 
17090  xml.writeAttribute("message", result.getExpression());
17091  xml.writeAttribute("type", result.getTestMacroName());
17092 
17094  if (stats.totals.assertions.total() > 0) {
17095  rss << "FAILED"
17096  << ":\n";
17097  if (result.hasExpression()) {
17098  rss << " ";
17099  rss << result.getExpressionInMacro();
17100  rss << '\n';
17101  }
17102  if (result.hasExpandedExpression()) {
17103  rss << "with expansion:\n";
17104  rss << Column(result.getExpandedExpression()).indent(2) << '\n';
17105  }
17106  } else {
17107  rss << '\n';
17108  }
17109 
17110  if (!result.getMessage().empty())
17111  rss << result.getMessage() << '\n';
17112  for (auto const &msg : stats.infoMessages)
17113  if (msg.type == ResultWas::Info)
17114  rss << msg.message << '\n';
17115 
17116  rss << "at " << result.getSourceInfo();
17117  xml.writeText(rss.str(), XmlFormatting::Newline);
17118  }
17119  }
17120 
17121  CATCH_REGISTER_REPORTER("junit", JunitReporter)
17122 
17123 } // end namespace Catch
17124 // end catch_reporter_junit.cpp
17125 // start catch_reporter_listening.cpp
17126 
17127 #include <cassert>
17128 
17129 namespace Catch {
17130  ListeningReporter::ListeningReporter() {
17131  // We will assume that listeners will always want all assertions
17132  m_preferences.shouldReportAllAssertions = true;
17133  }
17134 
17135  void ListeningReporter::addListener(IStreamingReporterPtr &&listener) {
17136  m_listeners.push_back(std::move(listener));
17137  }
17138 
17139  void ListeningReporter::addReporter(IStreamingReporterPtr &&reporter) {
17140  assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
17141  m_reporter = std::move(reporter);
17142  m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
17143  }
17144 
17145  ReporterPreferences ListeningReporter::getPreferences() const {
17146  return m_preferences;
17147  }
17148 
17149  std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
17150  return std::set<Verbosity>{};
17151  }
17152 
17153  void ListeningReporter::noMatchingTestCases(std::string const &spec) {
17154  for (auto const &listener : m_listeners) {
17155  listener->noMatchingTestCases(spec);
17156  }
17157  m_reporter->noMatchingTestCases(spec);
17158  }
17159 
17160  void ListeningReporter::reportInvalidArguments(std::string const &arg) {
17161  for (auto const &listener : m_listeners) {
17162  listener->reportInvalidArguments(arg);
17163  }
17164  m_reporter->reportInvalidArguments(arg);
17165  }
17166 
17167 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17168  void ListeningReporter::benchmarkPreparing(std::string const &name) {
17169  for (auto const &listener : m_listeners) {
17170  listener->benchmarkPreparing(name);
17171  }
17172  m_reporter->benchmarkPreparing(name);
17173  }
17174  void ListeningReporter::benchmarkStarting(BenchmarkInfo const &benchmarkInfo) {
17175  for (auto const &listener : m_listeners) {
17176  listener->benchmarkStarting(benchmarkInfo);
17177  }
17178  m_reporter->benchmarkStarting(benchmarkInfo);
17179  }
17180  void ListeningReporter::benchmarkEnded(BenchmarkStats<> const &benchmarkStats) {
17181  for (auto const &listener : m_listeners) {
17182  listener->benchmarkEnded(benchmarkStats);
17183  }
17184  m_reporter->benchmarkEnded(benchmarkStats);
17185  }
17186 
17187  void ListeningReporter::benchmarkFailed(std::string const &error) {
17188  for (auto const &listener : m_listeners) {
17189  listener->benchmarkFailed(error);
17190  }
17191  m_reporter->benchmarkFailed(error);
17192  }
17193 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17194 
17195  void ListeningReporter::testRunStarting(TestRunInfo const &testRunInfo) {
17196  for (auto const &listener : m_listeners) {
17197  listener->testRunStarting(testRunInfo);
17198  }
17199  m_reporter->testRunStarting(testRunInfo);
17200  }
17201 
17202  void ListeningReporter::testGroupStarting(GroupInfo const &groupInfo) {
17203  for (auto const &listener : m_listeners) {
17204  listener->testGroupStarting(groupInfo);
17205  }
17206  m_reporter->testGroupStarting(groupInfo);
17207  }
17208 
17209  void ListeningReporter::testCaseStarting(TestCaseInfo const &testInfo) {
17210  for (auto const &listener : m_listeners) {
17211  listener->testCaseStarting(testInfo);
17212  }
17213  m_reporter->testCaseStarting(testInfo);
17214  }
17215 
17216  void ListeningReporter::sectionStarting(SectionInfo const &sectionInfo) {
17217  for (auto const &listener : m_listeners) {
17218  listener->sectionStarting(sectionInfo);
17219  }
17220  m_reporter->sectionStarting(sectionInfo);
17221  }
17222 
17223  void ListeningReporter::assertionStarting(AssertionInfo const &assertionInfo) {
17224  for (auto const &listener : m_listeners) {
17225  listener->assertionStarting(assertionInfo);
17226  }
17227  m_reporter->assertionStarting(assertionInfo);
17228  }
17229 
17230  // The return value indicates if the messages buffer should be cleared:
17231  bool ListeningReporter::assertionEnded(AssertionStats const &assertionStats) {
17232  for (auto const &listener : m_listeners) {
17233  static_cast<void>(listener->assertionEnded(assertionStats));
17234  }
17235  return m_reporter->assertionEnded(assertionStats);
17236  }
17237 
17238  void ListeningReporter::sectionEnded(SectionStats const &sectionStats) {
17239  for (auto const &listener : m_listeners) {
17240  listener->sectionEnded(sectionStats);
17241  }
17242  m_reporter->sectionEnded(sectionStats);
17243  }
17244 
17245  void ListeningReporter::testCaseEnded(TestCaseStats const &testCaseStats) {
17246  for (auto const &listener : m_listeners) {
17247  listener->testCaseEnded(testCaseStats);
17248  }
17249  m_reporter->testCaseEnded(testCaseStats);
17250  }
17251 
17252  void ListeningReporter::testGroupEnded(TestGroupStats const &testGroupStats) {
17253  for (auto const &listener : m_listeners) {
17254  listener->testGroupEnded(testGroupStats);
17255  }
17256  m_reporter->testGroupEnded(testGroupStats);
17257  }
17258 
17259  void ListeningReporter::testRunEnded(TestRunStats const &testRunStats) {
17260  for (auto const &listener : m_listeners) {
17261  listener->testRunEnded(testRunStats);
17262  }
17263  m_reporter->testRunEnded(testRunStats);
17264  }
17265 
17266  void ListeningReporter::skipTest(TestCaseInfo const &testInfo) {
17267  for (auto const &listener : m_listeners) {
17268  listener->skipTest(testInfo);
17269  }
17270  m_reporter->skipTest(testInfo);
17271  }
17272 
17273  bool ListeningReporter::isMulti() const {
17274  return true;
17275  }
17276 
17277 } // end namespace Catch
17278 // end catch_reporter_listening.cpp
17279 // start catch_reporter_xml.cpp
17280 
17281 #if defined(_MSC_VER)
17282 #pragma warning(push)
17283 #pragma warning(disable : 4061) // Not all labels are EXPLICITLY handled in switch \
17284  // Note that 4062 (not all labels are handled \
17285  // and default is missing) is enabled
17286 #endif
17287 
17288 namespace Catch {
17289  XmlReporter::XmlReporter(ReporterConfig const &_config)
17290  : StreamingReporterBase(_config)
17291  , m_xml(_config.stream()) {
17292  m_reporterPrefs.shouldRedirectStdOut = true;
17293  m_reporterPrefs.shouldReportAllAssertions = true;
17294  }
17295 
17296  XmlReporter::~XmlReporter() = default;
17297 
17298  std::string XmlReporter::getDescription() {
17299  return "Reports test results as an XML document";
17300  }
17301 
17302  std::string XmlReporter::getStylesheetRef() const {
17303  return std::string();
17304  }
17305 
17306  void XmlReporter::writeSourceInfo(SourceLineInfo const &sourceInfo) {
17307  m_xml.writeAttribute("filename", sourceInfo.file).writeAttribute("line", sourceInfo.line);
17308  }
17309 
17310  void XmlReporter::noMatchingTestCases(std::string const &s) {
17311  StreamingReporterBase::noMatchingTestCases(s);
17312  }
17313 
17314  void XmlReporter::testRunStarting(TestRunInfo const &testInfo) {
17315  StreamingReporterBase::testRunStarting(testInfo);
17316  std::string stylesheetRef = getStylesheetRef();
17317  if (!stylesheetRef.empty())
17318  m_xml.writeStylesheetRef(stylesheetRef);
17319  m_xml.startElement("Catch");
17320  if (!m_config->name().empty())
17321  m_xml.writeAttribute("name", m_config->name());
17322  if (m_config->testSpec().hasFilters())
17323  m_xml.writeAttribute("filters", serializeFilters(m_config->getTestsOrTags()));
17324  if (m_config->rngSeed() != 0)
17325  m_xml.scopedElement("Randomness").writeAttribute("seed", m_config->rngSeed());
17326  }
17327 
17328  void XmlReporter::testGroupStarting(GroupInfo const &groupInfo) {
17329  StreamingReporterBase::testGroupStarting(groupInfo);
17330  m_xml.startElement("Group").writeAttribute("name", groupInfo.name);
17331  }
17332 
17333  void XmlReporter::testCaseStarting(TestCaseInfo const &testInfo) {
17334  StreamingReporterBase::testCaseStarting(testInfo);
17335  m_xml.startElement("TestCase")
17336  .writeAttribute("name", trim(testInfo.name))
17337  .writeAttribute("description", testInfo.description)
17338  .writeAttribute("tags", testInfo.tagsAsString());
17339 
17340  writeSourceInfo(testInfo.lineInfo);
17341 
17342  if (m_config->showDurations() == ShowDurations::Always)
17343  m_testCaseTimer.start();
17344  m_xml.ensureTagClosed();
17345  }
17346 
17347  void XmlReporter::sectionStarting(SectionInfo const &sectionInfo) {
17348  StreamingReporterBase::sectionStarting(sectionInfo);
17349  if (m_sectionDepth++ > 0) {
17350  m_xml.startElement("Section").writeAttribute("name", trim(sectionInfo.name));
17351  writeSourceInfo(sectionInfo.lineInfo);
17352  m_xml.ensureTagClosed();
17353  }
17354  }
17355 
17356  void XmlReporter::assertionStarting(AssertionInfo const &) {}
17357 
17358  bool XmlReporter::assertionEnded(AssertionStats const &assertionStats) {
17359  AssertionResult const &result = assertionStats.assertionResult;
17360 
17361  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
17362 
17363  if (includeResults || result.getResultType() == ResultWas::Warning) {
17364  // Print any info messages in <Info> tags.
17365  for (auto const &msg : assertionStats.infoMessages) {
17366  if (msg.type == ResultWas::Info && includeResults) {
17367  m_xml.scopedElement("Info").writeText(msg.message);
17368  } else if (msg.type == ResultWas::Warning) {
17369  m_xml.scopedElement("Warning").writeText(msg.message);
17370  }
17371  }
17372  }
17373 
17374  // Drop out if result was successful but we're not printing them.
17375  if (!includeResults && result.getResultType() != ResultWas::Warning)
17376  return true;
17377 
17378  // Print the expression if there is one.
17379  if (result.hasExpression()) {
17380  m_xml.startElement("Expression").writeAttribute("success", result.succeeded()).writeAttribute("type", result.getTestMacroName());
17381 
17382  writeSourceInfo(result.getSourceInfo());
17383 
17384  m_xml.scopedElement("Original").writeText(result.getExpression());
17385  m_xml.scopedElement("Expanded").writeText(result.getExpandedExpression());
17386  }
17387 
17388  // And... Print a result applicable to each result type.
17389  switch (result.getResultType()) {
17390  case ResultWas::ThrewException:
17391  m_xml.startElement("Exception");
17392  writeSourceInfo(result.getSourceInfo());
17393  m_xml.writeText(result.getMessage());
17394  m_xml.endElement();
17395  break;
17396  case ResultWas::FatalErrorCondition:
17397  m_xml.startElement("FatalErrorCondition");
17398  writeSourceInfo(result.getSourceInfo());
17399  m_xml.writeText(result.getMessage());
17400  m_xml.endElement();
17401  break;
17402  case ResultWas::Info:
17403  m_xml.scopedElement("Info").writeText(result.getMessage());
17404  break;
17405  case ResultWas::Warning:
17406  // Warning will already have been written
17407  break;
17408  case ResultWas::ExplicitFailure:
17409  m_xml.startElement("Failure");
17410  writeSourceInfo(result.getSourceInfo());
17411  m_xml.writeText(result.getMessage());
17412  m_xml.endElement();
17413  break;
17414  default:
17415  break;
17416  }
17417 
17418  if (result.hasExpression())
17419  m_xml.endElement();
17420 
17421  return true;
17422  }
17423 
17424  void XmlReporter::sectionEnded(SectionStats const &sectionStats) {
17425  StreamingReporterBase::sectionEnded(sectionStats);
17426  if (--m_sectionDepth > 0) {
17427  XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResults");
17428  e.writeAttribute("successes", sectionStats.assertions.passed);
17429  e.writeAttribute("failures", sectionStats.assertions.failed);
17430  e.writeAttribute("expectedFailures", sectionStats.assertions.failedButOk);
17431 
17432  if (m_config->showDurations() == ShowDurations::Always)
17433  e.writeAttribute("durationInSeconds", sectionStats.durationInSeconds);
17434 
17435  m_xml.endElement();
17436  }
17437  }
17438 
17439  void XmlReporter::testCaseEnded(TestCaseStats const &testCaseStats) {
17440  StreamingReporterBase::testCaseEnded(testCaseStats);
17441  XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResult");
17442  e.writeAttribute("success", testCaseStats.totals.assertions.allOk());
17443 
17444  if (m_config->showDurations() == ShowDurations::Always)
17445  e.writeAttribute("durationInSeconds", m_testCaseTimer.getElapsedSeconds());
17446 
17447  if (!testCaseStats.stdOut.empty())
17448  m_xml.scopedElement("StdOut").writeText(trim(testCaseStats.stdOut), XmlFormatting::Newline);
17449  if (!testCaseStats.stdErr.empty())
17450  m_xml.scopedElement("StdErr").writeText(trim(testCaseStats.stdErr), XmlFormatting::Newline);
17451 
17452  m_xml.endElement();
17453  }
17454 
17455  void XmlReporter::testGroupEnded(TestGroupStats const &testGroupStats) {
17456  StreamingReporterBase::testGroupEnded(testGroupStats);
17457  // TODO: Check testGroupStats.aborting and act accordingly.
17458  m_xml.scopedElement("OverallResults")
17459  .writeAttribute("successes", testGroupStats.totals.assertions.passed)
17460  .writeAttribute("failures", testGroupStats.totals.assertions.failed)
17461  .writeAttribute("expectedFailures", testGroupStats.totals.assertions.failedButOk);
17462  m_xml.scopedElement("OverallResultsCases")
17463  .writeAttribute("successes", testGroupStats.totals.testCases.passed)
17464  .writeAttribute("failures", testGroupStats.totals.testCases.failed)
17465  .writeAttribute("expectedFailures", testGroupStats.totals.testCases.failedButOk);
17466  m_xml.endElement();
17467  }
17468 
17469  void XmlReporter::testRunEnded(TestRunStats const &testRunStats) {
17470  StreamingReporterBase::testRunEnded(testRunStats);
17471  m_xml.scopedElement("OverallResults")
17472  .writeAttribute("successes", testRunStats.totals.assertions.passed)
17473  .writeAttribute("failures", testRunStats.totals.assertions.failed)
17474  .writeAttribute("expectedFailures", testRunStats.totals.assertions.failedButOk);
17475  m_xml.scopedElement("OverallResultsCases")
17476  .writeAttribute("successes", testRunStats.totals.testCases.passed)
17477  .writeAttribute("failures", testRunStats.totals.testCases.failed)
17478  .writeAttribute("expectedFailures", testRunStats.totals.testCases.failedButOk);
17479  m_xml.endElement();
17480  }
17481 
17482 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17483  void XmlReporter::benchmarkPreparing(std::string const &name) {
17484  m_xml.startElement("BenchmarkResults").writeAttribute("name", name);
17485  }
17486 
17487  void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
17488  m_xml.writeAttribute("samples", info.samples)
17489  .writeAttribute("resamples", info.resamples)
17490  .writeAttribute("iterations", info.iterations)
17491  .writeAttribute("clockResolution", info.clockResolution)
17492  .writeAttribute("estimatedDuration", info.estimatedDuration)
17493  .writeComment("All values in nano seconds");
17494  }
17495 
17496  void XmlReporter::benchmarkEnded(BenchmarkStats<> const &benchmarkStats) {
17497  m_xml.startElement("mean")
17498  .writeAttribute("value", benchmarkStats.mean.point.count())
17499  .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
17500  .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
17501  .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
17502  m_xml.endElement();
17503  m_xml.startElement("standardDeviation")
17504  .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
17505  .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
17506  .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
17507  .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
17508  m_xml.endElement();
17509  m_xml.startElement("outliers")
17510  .writeAttribute("variance", benchmarkStats.outlierVariance)
17511  .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
17512  .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
17513  .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
17514  .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
17515  m_xml.endElement();
17516  m_xml.endElement();
17517  }
17518 
17519  void XmlReporter::benchmarkFailed(std::string const &error) {
17520  m_xml.scopedElement("failed").writeAttribute("message", error);
17521  m_xml.endElement();
17522  }
17523 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17524 
17525  CATCH_REGISTER_REPORTER("xml", XmlReporter)
17526 
17527 } // end namespace Catch
17528 
17529 #if defined(_MSC_VER)
17530 #pragma warning(pop)
17531 #endif
17532 // end catch_reporter_xml.cpp
17533 
17534 namespace Catch {
17535  LeakDetector leakDetector;
17536 }
17537 
17538 #ifdef __clang__
17539 #pragma clang diagnostic pop
17540 #endif
17541 
17542 // end catch_impl.hpp
17543 #endif
17544 
17545 #ifdef CATCH_CONFIG_MAIN
17546 // start catch_default_main.hpp
17547 
17548 #ifndef __OBJC__
17549 
17550 #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
17551 // Standard C/C++ Win32 Unicode wmain entry point
17552 extern "C" int wmain(int argc, wchar_t *argv[], wchar_t *[]) {
17553 #else
17554 // Standard C/C++ main entry point
17555 int main(int argc, char *argv[]) {
17556 #endif
17557 
17558  return Catch::Session().run(argc, argv);
17559 }
17560 
17561 #else // __OBJC__
17562 
17563 // Objective-C entry point
17564 int main(int argc, char *const argv[]) {
17565 #if !CATCH_ARC_ENABLED
17566  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
17567 #endif
17568 
17569  Catch::registerTestMethods();
17570  int result = Catch::Session().run(argc, (char **)argv);
17571 
17572 #if !CATCH_ARC_ENABLED
17573  [pool drain];
17574 #endif
17575 
17576  return result;
17577 }
17578 
17579 #endif // __OBJC__
17580 
17581 // end catch_default_main.hpp
17582 #endif
17583 
17584 #if !defined(CATCH_CONFIG_IMPL_ONLY)
17585 
17586 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
17587 #undef CLARA_CONFIG_MAIN
17588 #endif
17589 
17590 #if !defined(CATCH_CONFIG_DISABLE)
17591 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17593 #ifdef CATCH_CONFIG_PREFIX_ALL
17594 
17595 #define CATCH_REQUIRE(...) INTERNAL_CATCH_TEST("CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__)
17596 #define CATCH_REQUIRE_FALSE(...) \
17597  INTERNAL_CATCH_TEST("CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
17598 
17599 #define CATCH_REQUIRE_THROWS(...) INTERNAL_CATCH_THROWS("CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__)
17600 #define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) \
17601  INTERNAL_CATCH_THROWS_AS("CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr)
17602 #define CATCH_REQUIRE_THROWS_WITH(expr, matcher) \
17603  INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr)
17604 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17605 #define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) \
17606  INTERNAL_CATCH_THROWS_MATCHES("CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr)
17607 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17608 #define CATCH_REQUIRE_NOTHROW(...) \
17609  INTERNAL_CATCH_NO_THROW("CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__)
17610 
17611 #define CATCH_CHECK(...) INTERNAL_CATCH_TEST("CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17612 #define CATCH_CHECK_FALSE(...) \
17613  INTERNAL_CATCH_TEST("CATCH_CHECK_FALSE", \
17614  Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, \
17615  __VA_ARGS__)
17616 #define CATCH_CHECKED_IF(...) INTERNAL_CATCH_IF("CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17617 #define CATCH_CHECKED_ELSE(...) \
17618  INTERNAL_CATCH_ELSE("CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17619 #define CATCH_CHECK_NOFAIL(...) \
17620  INTERNAL_CATCH_TEST("CATCH_CHECK_NOFAIL", \
17621  Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \
17622  __VA_ARGS__)
17623 
17624 #define CATCH_CHECK_THROWS(...) \
17625  INTERNAL_CATCH_THROWS("CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17626 #define CATCH_CHECK_THROWS_AS(expr, exceptionType) \
17627  INTERNAL_CATCH_THROWS_AS("CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr)
17628 #define CATCH_CHECK_THROWS_WITH(expr, matcher) \
17629  INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
17630 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17631 #define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) \
17632  INTERNAL_CATCH_THROWS_MATCHES("CATCH_CHECK_THROWS_MATCHES", \
17633  exceptionType, \
17634  Catch::ResultDisposition::ContinueOnFailure, \
17635  matcher, \
17636  expr)
17637 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17638 #define CATCH_CHECK_NOTHROW(...) \
17639  INTERNAL_CATCH_NO_THROW("CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17640 
17641 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17642 #define CATCH_CHECK_THAT(arg, matcher) \
17643  INTERNAL_CHECK_THAT("CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg)
17644 
17645 #define CATCH_REQUIRE_THAT(arg, matcher) \
17646  INTERNAL_CHECK_THAT("CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg)
17647 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17648 
17649 #define CATCH_INFO(msg) INTERNAL_CATCH_INFO("CATCH_INFO", msg)
17650 #define CATCH_UNSCOPED_INFO(msg) INTERNAL_CATCH_UNSCOPED_INFO("CATCH_UNSCOPED_INFO", msg)
17651 #define CATCH_WARN(msg) \
17652  INTERNAL_CATCH_MSG("CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg)
17653 #define CATCH_CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__)
17654 
17655 #define CATCH_TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__)
17656 #define CATCH_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__)
17657 #define CATCH_METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__)
17658 #define CATCH_REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__)
17659 #define CATCH_SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__)
17660 #define CATCH_DYNAMIC_SECTION(...) INTERNAL_CATCH_DYNAMIC_SECTION(__VA_ARGS__)
17661 #define CATCH_FAIL(...) \
17662  INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__)
17663 #define CATCH_FAIL_CHECK(...) \
17664  INTERNAL_CATCH_MSG("CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17665 #define CATCH_SUCCEED(...) \
17666  INTERNAL_CATCH_MSG("CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17667 
17668 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17669 
17670 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17671 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
17672 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
17673 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
17674 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
17675  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
17676 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
17677 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
17678 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) \
17679  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__)
17680 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) \
17681  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
17682 #else
17683 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__))
17684 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__))
17685 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) \
17686  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__))
17687 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
17688  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
17689 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) \
17690  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__))
17691 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) \
17692  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__))
17693 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) \
17694  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__))
17695 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) \
17696  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
17697 #endif
17698 
17699 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17700 #define CATCH_STATIC_REQUIRE(...) \
17701  static_assert(__VA_ARGS__, #__VA_ARGS__); \
17702  CATCH_SUCCEED(#__VA_ARGS__)
17703 #define CATCH_STATIC_REQUIRE_FALSE(...) \
17704  static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")"); \
17705  CATCH_SUCCEED(#__VA_ARGS__)
17706 #else
17707 #define CATCH_STATIC_REQUIRE(...) CATCH_REQUIRE(__VA_ARGS__)
17708 #define CATCH_STATIC_REQUIRE_FALSE(...) CATCH_REQUIRE_FALSE(__VA_ARGS__)
17709 #endif
17710 
17711 // "BDD-style" convenience wrappers
17712 #define CATCH_SCENARIO(...) CATCH_TEST_CASE("Scenario: " __VA_ARGS__)
17713 #define CATCH_SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
17714 #define CATCH_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Given: " << desc)
17715 #define CATCH_AND_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("And given: " << desc)
17716 #define CATCH_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" When: " << desc)
17717 #define CATCH_AND_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And when: " << desc)
17718 #define CATCH_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Then: " << desc)
17719 #define CATCH_AND_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And: " << desc)
17720 
17721 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17722 #define CATCH_BENCHMARK(...) \
17723  INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), \
17724  INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__, , ), \
17725  INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__, , ))
17726 #define CATCH_BENCHMARK_ADVANCED(name) \
17727  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17728 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17729 
17730 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17731 #else
17732 
17733 #define REQUIRE(...) INTERNAL_CATCH_TEST("REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__)
17734 #define REQUIRE_FALSE(...) \
17735  INTERNAL_CATCH_TEST("REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
17736 
17737 #define REQUIRE_THROWS(...) INTERNAL_CATCH_THROWS("REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__)
17738 #define REQUIRE_THROWS_AS(expr, exceptionType) \
17739  INTERNAL_CATCH_THROWS_AS("REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr)
17740 #define REQUIRE_THROWS_WITH(expr, matcher) \
17741  INTERNAL_CATCH_THROWS_STR_MATCHES("REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr)
17742 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17743 #define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) \
17744  INTERNAL_CATCH_THROWS_MATCHES("REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr)
17745 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17746 #define REQUIRE_NOTHROW(...) INTERNAL_CATCH_NO_THROW("REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__)
17747 
17748 #define CHECK(...) INTERNAL_CATCH_TEST("CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17749 #define CHECK_FALSE(...) \
17750  INTERNAL_CATCH_TEST("CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__)
17751 #define CHECKED_IF(...) INTERNAL_CATCH_IF("CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17752 #define CHECKED_ELSE(...) INTERNAL_CATCH_ELSE("CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17753 #define CHECK_NOFAIL(...) \
17754  INTERNAL_CATCH_TEST("CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__)
17755 
17756 #define CHECK_THROWS(...) INTERNAL_CATCH_THROWS("CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17757 #define CHECK_THROWS_AS(expr, exceptionType) \
17758  INTERNAL_CATCH_THROWS_AS("CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr)
17759 #define CHECK_THROWS_WITH(expr, matcher) \
17760  INTERNAL_CATCH_THROWS_STR_MATCHES("CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
17761 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17762 #define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) \
17763  INTERNAL_CATCH_THROWS_MATCHES("CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr)
17764 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17765 #define CHECK_NOTHROW(...) INTERNAL_CATCH_NO_THROW("CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17766 
17767 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17768 #define CHECK_THAT(arg, matcher) \
17769  INTERNAL_CHECK_THAT("CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg)
17770 
17771 #define REQUIRE_THAT(arg, matcher) INTERNAL_CHECK_THAT("REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg)
17772 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17773 
17774 #define INFO(msg) INTERNAL_CATCH_INFO("INFO", msg)
17775 #define UNSCOPED_INFO(msg) INTERNAL_CATCH_UNSCOPED_INFO("UNSCOPED_INFO", msg)
17776 #define WARN(msg) INTERNAL_CATCH_MSG("WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg)
17777 #define CAPTURE(...) INTERNAL_CATCH_CAPTURE(INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__)
17778 
17779 #define TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__)
17780 #define TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__)
17781 #define METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__)
17782 #define REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__)
17783 #define SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__)
17784 #define DYNAMIC_SECTION(...) INTERNAL_CATCH_DYNAMIC_SECTION(__VA_ARGS__)
17785 #define FAIL(...) INTERNAL_CATCH_MSG("FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__)
17786 #define FAIL_CHECK(...) \
17787  INTERNAL_CATCH_MSG("FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17788 #define SUCCEED(...) \
17789  INTERNAL_CATCH_MSG("SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__)
17790 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
17791 
17792 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17793 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
17794 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
17795 #define TEMPLATE_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
17796 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
17797 #define TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
17798 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
17799 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) \
17800  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__)
17801 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) \
17802  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__)
17803 #define TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
17804 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__)
17805 #else
17806 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__))
17807 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__))
17808 #define TEMPLATE_TEST_CASE_METHOD(className, ...) \
17809  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__))
17810 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
17811  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
17812 #define TEMPLATE_PRODUCT_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__))
17813 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) \
17814  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__))
17815 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) \
17816  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, __VA_ARGS__))
17817 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) \
17818  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, __VA_ARGS__))
17819 #define TEMPLATE_LIST_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__))
17820 #define TEMPLATE_LIST_TEST_CASE_METHOD(className, ...) \
17821  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(className, __VA_ARGS__))
17822 #endif
17823 
17824 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
17825 #define STATIC_REQUIRE(...) \
17826  static_assert(__VA_ARGS__, #__VA_ARGS__); \
17827  SUCCEED(#__VA_ARGS__)
17828 #define STATIC_REQUIRE_FALSE(...) \
17829  static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")"); \
17830  SUCCEED("!(" #__VA_ARGS__ ")")
17831 #else
17832 #define STATIC_REQUIRE(...) REQUIRE(__VA_ARGS__)
17833 #define STATIC_REQUIRE_FALSE(...) REQUIRE_FALSE(__VA_ARGS__)
17834 #endif
17835 
17836 #endif
17837 
17838 #define CATCH_TRANSLATE_EXCEPTION(signature) INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature)
17839 
17840 // "BDD-style" convenience wrappers
17841 #define SCENARIO(...) TEST_CASE("Scenario: " __VA_ARGS__)
17842 #define SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
17843 
17844 #define GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Given: " << desc)
17845 #define AND_GIVEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION("And given: " << desc)
17846 #define WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" When: " << desc)
17847 #define AND_WHEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And when: " << desc)
17848 #define THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" Then: " << desc)
17849 #define AND_THEN(desc) INTERNAL_CATCH_DYNAMIC_SECTION(" And: " << desc)
17850 
17851 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
17852 #define BENCHMARK(...) \
17853  INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), \
17854  INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__, , ), \
17855  INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__, , ))
17856 #define BENCHMARK_ADVANCED(name) \
17857  INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
17858 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
17859 
17860 using Catch::Detail::Approx;
17861 
17862 #else // CATCH_CONFIG_DISABLE
17863 
17865 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
17866 #ifdef CATCH_CONFIG_PREFIX_ALL
17867 
17868 #define CATCH_REQUIRE(...) (void)(0)
17869 #define CATCH_REQUIRE_FALSE(...) (void)(0)
17870 
17871 #define CATCH_REQUIRE_THROWS(...) (void)(0)
17872 #define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) (void)(0)
17873 #define CATCH_REQUIRE_THROWS_WITH(expr, matcher) (void)(0)
17874 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17875 #define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
17876 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17877 #define CATCH_REQUIRE_NOTHROW(...) (void)(0)
17878 
17879 #define CATCH_CHECK(...) (void)(0)
17880 #define CATCH_CHECK_FALSE(...) (void)(0)
17881 #define CATCH_CHECKED_IF(...) if (__VA_ARGS__)
17882 #define CATCH_CHECKED_ELSE(...) if (!(__VA_ARGS__))
17883 #define CATCH_CHECK_NOFAIL(...) (void)(0)
17884 
17885 #define CATCH_CHECK_THROWS(...) (void)(0)
17886 #define CATCH_CHECK_THROWS_AS(expr, exceptionType) (void)(0)
17887 #define CATCH_CHECK_THROWS_WITH(expr, matcher) (void)(0)
17888 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17889 #define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
17890 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17891 #define CATCH_CHECK_NOTHROW(...) (void)(0)
17892 
17893 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17894 #define CATCH_CHECK_THAT(arg, matcher) (void)(0)
17895 
17896 #define CATCH_REQUIRE_THAT(arg, matcher) (void)(0)
17897 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17898 
17899 #define CATCH_INFO(msg) (void)(0)
17900 #define CATCH_UNSCOPED_INFO(msg) (void)(0)
17901 #define CATCH_WARN(msg) (void)(0)
17902 #define CATCH_CAPTURE(msg) (void)(0)
17903 
17904 #define CATCH_TEST_CASE(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
17905 #define CATCH_TEST_CASE_METHOD(className, ...) \
17906  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
17907 #define CATCH_METHOD_AS_TEST_CASE(method, ...)
17908 #define CATCH_REGISTER_TEST_CASE(Function, ...) (void)(0)
17909 #define CATCH_SECTION(...)
17910 #define CATCH_DYNAMIC_SECTION(...)
17911 #define CATCH_FAIL(...) (void)(0)
17912 #define CATCH_FAIL_CHECK(...) (void)(0)
17913 #define CATCH_SUCCEED(...) (void)(0)
17914 
17915 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
17916 
17917 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
17918 #define CATCH_TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
17919 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
17920 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) \
17921  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
17922 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
17923  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__)
17924 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
17925 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
17926 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
17927 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
17928 #else
17929 #define CATCH_TEMPLATE_TEST_CASE(...) \
17930  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__))
17931 #define CATCH_TEMPLATE_TEST_CASE_SIG(...) \
17932  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__))
17933 #define CATCH_TEMPLATE_TEST_CASE_METHOD(className, ...) \
17934  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__))
17935 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
17936  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__))
17937 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
17938 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
17939 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
17940 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) CATCH_TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
17941 #endif
17942 
17943 // "BDD-style" convenience wrappers
17944 #define CATCH_SCENARIO(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
17945 #define CATCH_SCENARIO_METHOD(className, ...) \
17946  INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), className)
17947 #define CATCH_GIVEN(desc)
17948 #define CATCH_AND_GIVEN(desc)
17949 #define CATCH_WHEN(desc)
17950 #define CATCH_AND_WHEN(desc)
17951 #define CATCH_THEN(desc)
17952 #define CATCH_AND_THEN(desc)
17953 
17954 #define CATCH_STATIC_REQUIRE(...) (void)(0)
17955 #define CATCH_STATIC_REQUIRE_FALSE(...) (void)(0)
17956 
17957 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
17958 #else
17959 
17960 #define REQUIRE(...) (void)(0)
17961 #define REQUIRE_FALSE(...) (void)(0)
17962 
17963 #define REQUIRE_THROWS(...) (void)(0)
17964 #define REQUIRE_THROWS_AS(expr, exceptionType) (void)(0)
17965 #define REQUIRE_THROWS_WITH(expr, matcher) (void)(0)
17966 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17967 #define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
17968 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17969 #define REQUIRE_NOTHROW(...) (void)(0)
17970 
17971 #define CHECK(...) (void)(0)
17972 #define CHECK_FALSE(...) (void)(0)
17973 #define CHECKED_IF(...) if (__VA_ARGS__)
17974 #define CHECKED_ELSE(...) if (!(__VA_ARGS__))
17975 #define CHECK_NOFAIL(...) (void)(0)
17976 
17977 #define CHECK_THROWS(...) (void)(0)
17978 #define CHECK_THROWS_AS(expr, exceptionType) (void)(0)
17979 #define CHECK_THROWS_WITH(expr, matcher) (void)(0)
17980 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17981 #define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0)
17982 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17983 #define CHECK_NOTHROW(...) (void)(0)
17984 
17985 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
17986 #define CHECK_THAT(arg, matcher) (void)(0)
17987 
17988 #define REQUIRE_THAT(arg, matcher) (void)(0)
17989 #endif // CATCH_CONFIG_DISABLE_MATCHERS
17990 
17991 #define INFO(msg) (void)(0)
17992 #define UNSCOPED_INFO(msg) (void)(0)
17993 #define WARN(msg) (void)(0)
17994 #define CAPTURE(msg) (void)(0)
17995 
17996 #define TEST_CASE(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
17997 #define TEST_CASE_METHOD(className, ...) \
17998  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
17999 #define METHOD_AS_TEST_CASE(method, ...)
18000 #define REGISTER_TEST_CASE(Function, ...) (void)(0)
18001 #define SECTION(...)
18002 #define DYNAMIC_SECTION(...)
18003 #define FAIL(...) (void)(0)
18004 #define FAIL_CHECK(...) (void)(0)
18005 #define SUCCEED(...) (void)(0)
18006 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18007 
18008 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
18009 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
18010 #define TEMPLATE_TEST_CASE_SIG(...) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
18011 #define TEMPLATE_TEST_CASE_METHOD(className, ...) \
18012  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
18013 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
18014  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__)
18015 #define TEMPLATE_PRODUCT_TEST_CASE(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18016 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18017 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18018 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18019 #else
18020 #define TEMPLATE_TEST_CASE(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__))
18021 #define TEMPLATE_TEST_CASE_SIG(...) \
18022  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__))
18023 #define TEMPLATE_TEST_CASE_METHOD(className, ...) \
18024  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__))
18025 #define TEMPLATE_TEST_CASE_METHOD_SIG(className, ...) \
18026  INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__))
18027 #define TEMPLATE_PRODUCT_TEST_CASE(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18028 #define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) TEMPLATE_TEST_CASE(__VA_ARGS__)
18029 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18030 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(className, ...) TEMPLATE_TEST_CASE_METHOD(className, __VA_ARGS__)
18031 #endif
18032 
18033 #define STATIC_REQUIRE(...) (void)(0)
18034 #define STATIC_REQUIRE_FALSE(...) (void)(0)
18035 
18036 #endif
18037 
18038 #define CATCH_TRANSLATE_EXCEPTION(signature) \
18039  INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature)
18040 
18041 // "BDD-style" convenience wrappers
18042 #define SCENARIO(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____))
18043 #define SCENARIO_METHOD(className, ...) \
18044  INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), className)
18045 
18046 #define GIVEN(desc)
18047 #define AND_GIVEN(desc)
18048 #define WHEN(desc)
18049 #define AND_WHEN(desc)
18050 #define THEN(desc)
18051 #define AND_THEN(desc)
18052 
18053 using Catch::Detail::Approx;
18054 
18055 #endif
18056 
18057 #endif // ! CATCH_CONFIG_IMPL_ONLY
18058 
18059 // start catch_reenable_warnings.h
18060 
18061 #ifdef __clang__
18062 #ifdef __ICC // icpc defines the __clang__ macro
18063 #pragma warning(pop)
18064 #else
18065 #pragma clang diagnostic pop
18066 #endif
18067 #elif defined __GNUC__
18068 #pragma GCC diagnostic pop
18069 #endif
18070 
18071 // end catch_reenable_warnings.h
18072 // end catch.hpp
18073 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
Definition: catch.hpp:3695
Definition: catch.hpp:2731
Definition: catch.hpp:4945
Definition: catch.hpp:4351
Definition: catch.hpp:5040
Definition: catch.hpp:1874
Definition: catch.hpp:4417
Definition: catch.hpp:2952
Definition: catch.hpp:2946
Definition: catch.hpp:486
Definition: catch.hpp:2656
Definition: catch.hpp:3409
Definition: catch.hpp:3040
Definition: catch.hpp:548
Definition: catch.hpp:4276
Definition: catch.hpp:2975
Definition: catch.hpp:4396
Definition: catch.hpp:2084
Definition: catch.hpp:4525
Definition: catch.hpp:4376
Definition: catch.hpp:3073
Definition: catch.hpp:2901
Definition: catch.hpp:4890
Definition: catch.hpp:96
Definition: catch.hpp:3674
A non-owning string class (similar to the forthcoming std::string_view) Note that, because a StringRef may be a substring of another string, it may not be null terminated.
Definition: catch.hpp:605
Definition: catch.hpp:1852
Definition: catch.hpp:1244
Definition: catch.hpp:3447
Definition: catch.hpp:3672
Definition: catch.hpp:3326
Definition: catch.hpp:2970
Definition: catch.hpp:4461
Definition: catch.hpp:1217
Definition: catch.hpp:1183
Definition: catch.hpp:535
Definition: catch.hpp:3309
Definition: catch.hpp:4690
Definition: catch.hpp:3670
Definition: catch.hpp:1177
Definition: catch.hpp:4883
Definition: memory_leak_test.cpp:28
Definition: catch.hpp:2787
Definition: catch.hpp:580
Definition: catch.hpp:3280
Definition: catch.hpp:4559
Definition: catch.hpp:4363
Definition: catch.hpp:3398
Definition: catch.hpp:4861
Definition: catch.hpp:504
Definition: catch.hpp:4074
Definition: catch.hpp:4793
Definition: catch.hpp:1909
Definition: catch.hpp:3442
Definition: catch.hpp:1942
Definition: catch.hpp:493
Definition: catch.hpp:4096
Definition: catch.hpp:1916
Definition: catch.hpp:3343
Definition: catch.hpp:4869
Definition: catch.hpp:4901
Definition: catch.hpp:5201
Definition: catch.hpp:3713
Definition: catch.hpp:3958
Definition: catch.hpp:1191
Definition: catch.hpp:5082
Definition: catch.hpp:4184
Definition: catch.hpp:1826
Definition: catch.hpp:4876
Definition: catch.hpp:5138
Definition: catch.hpp:4330
Definition: catch.hpp:1952
Definition: catch.hpp:572
Definition: catch.hpp:1210
Definition: catch.hpp:2635
Definition: catch.hpp:5173
Definition: catch.hpp:4654
Definition: catch.hpp:4598
Definition: catch.hpp:3296
Definition: catch.hpp:4262
Definition: catch.hpp:3024
Definition: catch.hpp:2445
Definition: catch.hpp:1238
Definition: catch.hpp:3509
Definition: catch.hpp:3647
Definition: catch.hpp:4755
Definition: catch.hpp:3050
Definition: catch.hpp:2040
Definition: catch.hpp:2436
Definition: catch.hpp:481
Definition: catch.hpp:2431
Definition: catch.hpp:2860
Definition: catch.hpp:3453
Definition: catch.hpp:3267
Definition: catch.hpp:4747
Definition: catch.hpp:3062
Definition: catch.hpp:1181