Horizon
Loading...
Searching...
No Matches
catch_amalgamated.hpp
Go to the documentation of this file.
1// Copyright Catch2 Authors
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6// SPDX-License-Identifier: BSL-1.0
7
8// Catch v3.0.1
9// Generated: 2022-05-17 22:08:46.674860
10// ----------------------------------------------------------
11// This file is an amalgamation of multiple different files.
12// You probably shouldn't edit it directly.
13// ----------------------------------------------------------
14#ifndef CATCH_AMALGAMATED_HPP_INCLUDED
15#define CATCH_AMALGAMATED_HPP_INCLUDED
16
17
32#ifndef CATCH_ALL_HPP_INCLUDED
33#define CATCH_ALL_HPP_INCLUDED
34
35
36
50#ifndef CATCH_BENCHMARK_ALL_HPP_INCLUDED
51#define CATCH_BENCHMARK_ALL_HPP_INCLUDED
52
53
54
55// Adapted from donated nonius code.
56
57#ifndef CATCH_BENCHMARK_HPP_INCLUDED
58#define CATCH_BENCHMARK_HPP_INCLUDED
59
60
61
62#ifndef CATCH_INTERFACES_CONFIG_HPP_INCLUDED
63#define CATCH_INTERFACES_CONFIG_HPP_INCLUDED
64
65
66
67#ifndef CATCH_NONCOPYABLE_HPP_INCLUDED
68#define CATCH_NONCOPYABLE_HPP_INCLUDED
69
70namespace Catch {
71 namespace Detail {
72
75 NonCopyable( NonCopyable const& ) = delete;
76 NonCopyable( NonCopyable&& ) = delete;
77 NonCopyable& operator=( NonCopyable const& ) = delete;
78 NonCopyable& operator=( NonCopyable&& ) = delete;
79
80 protected:
81 NonCopyable() noexcept = default;
82 };
83
84 } // namespace Detail
85} // namespace Catch
86
87#endif // CATCH_NONCOPYABLE_HPP_INCLUDED
88
89
90#ifndef CATCH_STRINGREF_HPP_INCLUDED
91#define CATCH_STRINGREF_HPP_INCLUDED
92
93#include <cstddef>
94#include <string>
95#include <iosfwd>
96#include <cassert>
97
98namespace Catch {
99
103 class StringRef {
104 public:
105 using size_type = std::size_t;
106 using const_iterator = const char*;
107
108 private:
109 static constexpr char const* const s_empty = "";
110
111 char const* m_start = s_empty;
112 size_type m_size = 0;
113
114 public: // construction
115 constexpr StringRef() noexcept = default;
116
117 StringRef( char const* rawChars ) noexcept;
118
119 constexpr StringRef( char const* rawChars, size_type size ) noexcept
120 : m_start( rawChars ),
121 m_size( size )
122 {}
123
124 StringRef( std::string const& stdString ) noexcept
125 : m_start( stdString.c_str() ),
126 m_size( stdString.size() )
127 {}
128
129 explicit operator std::string() const {
130 return std::string(m_start, m_size);
131 }
132
133 public: // operators
134 auto operator == ( StringRef other ) const noexcept -> bool;
135 auto operator != (StringRef other) const noexcept -> bool {
136 return !(*this == other);
137 }
138
139 constexpr auto operator[] ( size_type index ) const noexcept -> char {
140 assert(index < m_size);
141 return m_start[index];
142 }
143
144 bool operator<(StringRef rhs) const noexcept;
145
146 public: // named queries
147 constexpr auto empty() const noexcept -> bool {
148 return m_size == 0;
149 }
150 constexpr auto size() const noexcept -> size_type {
151 return m_size;
152 }
153
154 // Returns a substring of [start, start + length).
155 // If start + length > size(), then the substring is [start, start + size()).
156 // If start > size(), then the substring is empty.
157 constexpr StringRef substr(size_type start, size_type length) const noexcept {
158 if (start < m_size) {
159 const auto shortened_size = m_size - start;
160 return StringRef(m_start + start, (shortened_size < length) ? shortened_size : length);
161 } else {
162 return StringRef();
163 }
164 }
165
166 // Returns the current start pointer. May not be null-terminated.
167 constexpr char const* data() const noexcept {
168 return m_start;
169 }
170
171 constexpr const_iterator begin() const { return m_start; }
172 constexpr const_iterator end() const { return m_start + m_size; }
173
174
175 friend std::string& operator += (std::string& lhs, StringRef sr);
176 friend std::ostream& operator << (std::ostream& os, StringRef sr);
177 friend std::string operator+(StringRef lhs, StringRef rhs);
178
185 int compare( StringRef rhs ) const;
186 };
187
188
189 constexpr auto operator ""_sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
190 return StringRef( rawChars, size );
191 }
192} // namespace Catch
193
194constexpr auto operator ""_catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
195 return Catch::StringRef( rawChars, size );
196}
197
198#endif // CATCH_STRINGREF_HPP_INCLUDED
199
200#include <chrono>
201#include <iosfwd>
202#include <string>
203#include <vector>
204
205namespace Catch {
206
207 enum class Verbosity {
208 Quiet = 0,
209 Normal,
210 High
211 };
212
213 struct WarnAbout { enum What {
214 Nothing = 0x00,
219 }; };
220
221 enum class ShowDurations {
222 DefaultForReporter,
223 Always,
224 Never
225 };
226 enum class TestRunOrder {
227 Declared,
228 LexicographicallySorted,
229 Randomized
230 };
231 enum class ColourMode : std::uint8_t {
235 ANSI,
237 Win32,
239 None
240 };
241 struct WaitForKeypress { enum When {
242 Never,
243 BeforeStart = 1,
244 BeforeExit = 2,
245 BeforeStartAndExit = BeforeStart | BeforeExit
246 }; };
247
248 class TestSpec;
249 class IStream;
250
252 public:
253 virtual ~IConfig();
254
255 virtual bool allowThrows() const = 0;
256 virtual StringRef name() const = 0;
257 virtual bool includeSuccessfulResults() const = 0;
258 virtual bool shouldDebugBreak() const = 0;
259 virtual bool warnAboutMissingAssertions() const = 0;
260 virtual bool warnAboutUnmatchedTestSpecs() const = 0;
261 virtual bool zeroTestsCountAsSuccess() const = 0;
262 virtual int abortAfter() const = 0;
263 virtual bool showInvisibles() const = 0;
264 virtual ShowDurations showDurations() const = 0;
265 virtual double minDuration() const = 0;
266 virtual TestSpec const& testSpec() const = 0;
267 virtual bool hasTestFilters() const = 0;
268 virtual std::vector<std::string> const& getTestsOrTags() const = 0;
269 virtual TestRunOrder runOrder() const = 0;
270 virtual uint32_t rngSeed() const = 0;
271 virtual unsigned int shardCount() const = 0;
272 virtual unsigned int shardIndex() const = 0;
273 virtual ColourMode defaultColourMode() const = 0;
274 virtual std::vector<std::string> const& getSectionsToRun() const = 0;
275 virtual Verbosity verbosity() const = 0;
276
277 virtual bool skipBenchmarks() const = 0;
278 virtual bool benchmarkNoAnalysis() const = 0;
279 virtual unsigned int benchmarkSamples() const = 0;
280 virtual double benchmarkConfidenceInterval() const = 0;
281 virtual unsigned int benchmarkResamples() const = 0;
282 virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
283 };
284}
285
286#endif // CATCH_INTERFACES_CONFIG_HPP_INCLUDED
287
288
289#ifndef CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
290#define CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
291
292// Detect a number of compiler features - by compiler
293// The following features are defined:
294//
295// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
296// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
297// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
298// ****************
299// Note to maintainers: if new toggles are added please document them
300// in configuration.md, too
301// ****************
302
303// In general each macro has a _NO_<feature name> form
304// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
305// Many features, at point of detection, define an _INTERNAL_ macro, so they
306// can be combined, en-mass, with the _NO_ forms later.
307
308
309
310#ifndef CATCH_PLATFORM_HPP_INCLUDED
311#define CATCH_PLATFORM_HPP_INCLUDED
312
313// See e.g.:
314// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
315#ifdef __APPLE__
316# include <TargetConditionals.h>
317# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
318 (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
319# define CATCH_PLATFORM_MAC
320# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
321# define CATCH_PLATFORM_IPHONE
322# endif
323
324#elif defined(linux) || defined(__linux) || defined(__linux__)
325# define CATCH_PLATFORM_LINUX
326
327#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
328# define CATCH_PLATFORM_WINDOWS
329#endif
330
331#endif // CATCH_PLATFORM_HPP_INCLUDED
332
333#ifdef __cplusplus
334
335# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
336# define CATCH_CPP14_OR_GREATER
337# endif
338
339# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
340# define CATCH_CPP17_OR_GREATER
341# endif
342
343#endif
344
345// Only GCC compiler should be used in this block, so other compilers trying to
346// mask themselves as GCC should be ignored.
347#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
348# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
349# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
350
351// This only works on GCC 9+. so we have to also add a global suppression of Wparentheses
352// for older versions of GCC.
353# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
354 _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
355
356# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
357 _Pragma( "GCC diagnostic ignored \"-Wunused-variable\"" )
358
359# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
360
361#endif
362
363#if defined(__clang__) && !defined(_MSC_VER)
364
365# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
366# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
367
368// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
369// which results in calls to destructors being emitted for each temporary,
370// without a matching initialization. In practice, this can result in something
371// like `std::string::~string` being called on an uninitialized value.
372//
373// For example, this code will likely segfault under IBM XL:
374// ```
375// REQUIRE(std::string("12") + "34" == "1234")
376// ```
377//
378// Similarly, NVHPC's implementation of `__builtin_constant_p` has a bug which
379// results in calls to the immediately evaluated lambda expressions to be
380// reported as unevaluated lambdas.
381// https://developer.nvidia.com/nvidia_bug/3321845.
382//
383// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
384# if !defined(__ibmxl__) && !defined(__CUDACC__) && !defined( __NVCOMPILER )
385# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
386# endif
387
388
389# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
390 _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
391 _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
392
393# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
394 _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
395
396# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
397 _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
398
399# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
400 _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
401
402# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
403 _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
404
405#endif // __clang__
406
407
409// Assume that non-Windows platforms support posix signals by default
410#if !defined(CATCH_PLATFORM_WINDOWS)
411 #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
412#endif
413
415// We know some environments not to support full POSIX signals
416#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
417 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
418#endif
419
420#ifdef __OS400__
421# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
422#endif
423
425// Android somehow still does not support std::to_string
426#if defined(__ANDROID__)
427# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
428#endif
429
431// Not all Windows environments support SEH properly
432#if defined(__MINGW32__)
433# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
434#endif
435
437// PS4
438#if defined(__ORBIS__)
439# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
440#endif
441
443// Cygwin
444#ifdef __CYGWIN__
445
446// Required for some versions of Cygwin to declare gettimeofday
447// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
448# define _BSD_SOURCE
449// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
450// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
451# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
452 && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
453
454# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
455
456# endif
457#endif // __CYGWIN__
458
460// Visual C++
461#if defined(_MSC_VER)
462
463# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
464# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
465
466// Universal Windows platform does not support SEH
467// Or console colours (or console at all...)
468# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
469# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
470# else
471# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
472# endif
473
474// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
475// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
476// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
477# if !defined(__clang__) // Handle Clang masquerading for msvc
478# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
479# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
480# endif // MSVC_TRADITIONAL
481# endif // __clang__
482
483#endif // _MSC_VER
484
485#if defined(_REENTRANT) || defined(_MSC_VER)
486// Enable async processing, as -pthread is specified or no additional linking is required
487# define CATCH_INTERNAL_CONFIG_USE_ASYNC
488#endif // _MSC_VER
489
491// Check if we are compiled with -fno-exceptions or equivalent
492#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
493# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
494#endif
495
496
498// Embarcadero C++Build
499#if defined(__BORLANDC__)
500 #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
501#endif
502
504
505// RTX is a special version of Windows that is real time.
506// This means that it is detected as Windows, but does not provide
507// the same set of capabilities as real Windows does.
508#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
509 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
510 #define CATCH_INTERNAL_CONFIG_NO_ASYNC
511 #define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
512#endif
513
514#if !defined(_GLIBCXX_USE_C99_MATH_TR1)
515#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
516#endif
517
518// Various stdlib support checks that require __has_include
519#if defined(__has_include)
520 // Check if string_view is available and usable
521 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
522 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
523 #endif
524
525 // Check if optional is available and usable
526 # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
527 # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
528 # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
529
530 // Check if byte is available and usable
531 # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
532 # include <cstddef>
533 # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
534 # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
535 # endif
536 # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
537
538 // Check if variant is available and usable
539 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
540 # if defined(__clang__) && (__clang_major__ < 8)
541 // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
542 // fix should be in clang 8, workaround in libstdc++ 8.2
543 # include <ciso646>
544 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
545 # define CATCH_CONFIG_NO_CPP17_VARIANT
546 # else
547 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
548 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
549 # else
550 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
551 # endif // defined(__clang__) && (__clang_major__ < 8)
552 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
553#endif // defined(__has_include)
554
555
556#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
557# define CATCH_CONFIG_WINDOWS_SEH
558#endif
559// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
560#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
561# define CATCH_CONFIG_POSIX_SIGNALS
562#endif
563
564#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
565# define CATCH_CONFIG_CPP11_TO_STRING
566#endif
567
568#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
569# define CATCH_CONFIG_CPP17_OPTIONAL
570#endif
571
572#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
573# define CATCH_CONFIG_CPP17_STRING_VIEW
574#endif
575
576#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
577# define CATCH_CONFIG_CPP17_VARIANT
578#endif
579
580#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
581# define CATCH_CONFIG_CPP17_BYTE
582#endif
583
584
585#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
586# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
587#endif
588
589#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
590# define CATCH_CONFIG_NEW_CAPTURE
591#endif
592
593#if !defined( CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED ) && \
594 !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS ) && \
595 !defined( CATCH_CONFIG_NO_DISABLE_EXCEPTIONS )
596# define CATCH_CONFIG_DISABLE_EXCEPTIONS
597#endif
598
599#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
600# define CATCH_CONFIG_POLYFILL_ISNAN
601#endif
602
603#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
604# define CATCH_CONFIG_USE_ASYNC
605#endif
606
607#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
608# define CATCH_CONFIG_GLOBAL_NEXTAFTER
609#endif
610
611
612// Even if we do not think the compiler has that warning, we still have
613// to provide a macro that can be used by the code.
614#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
615# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
616#endif
617#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
618# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
619#endif
620#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
621# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
622#endif
623#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
624# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
625#endif
626#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS)
627# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
628#endif
629#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
630# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
631#endif
632
633// The goal of this macro is to avoid evaluation of the arguments, but
634// still have the compiler warn on problems inside...
635#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
636# define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
637#endif
638
639#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
640# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
641#elif defined(__clang__) && (__clang_major__ < 5)
642# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
643#endif
644
645#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
646# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
647#endif
648
649#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
650#define CATCH_TRY if ((true))
651#define CATCH_CATCH_ALL if ((false))
652#define CATCH_CATCH_ANON(type) if ((false))
653#else
654#define CATCH_TRY try
655#define CATCH_CATCH_ALL catch (...)
656#define CATCH_CATCH_ANON(type) catch (type)
657#endif
658
659#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
660#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
661#endif
662
663#if defined( CATCH_PLATFORM_WINDOWS ) && \
664 !defined( CATCH_CONFIG_COLOUR_WIN32 ) && \
665 !defined( CATCH_CONFIG_NO_COLOUR_WIN32 ) && \
666 !defined( CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 )
667# define CATCH_CONFIG_COLOUR_WIN32
668#endif
669
670
671#endif // CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
672
673
674#ifndef CATCH_CONTEXT_HPP_INCLUDED
675#define CATCH_CONTEXT_HPP_INCLUDED
676
677namespace Catch {
678
679 class IResultCapture;
680 class IConfig;
681
682 class IContext {
683 public:
684 virtual ~IContext(); // = default
685
686 virtual IResultCapture* getResultCapture() = 0;
687 virtual IConfig const* getConfig() const = 0;
688 };
689
690 class IMutableContext : public IContext {
691 public:
692 ~IMutableContext() override; // = default
693 virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
694 virtual void setConfig( IConfig const* config ) = 0;
695
696 private:
697 static IMutableContext *currentContext;
698 friend IMutableContext& getCurrentMutableContext();
699 friend void cleanUpContext();
700 static void createContext();
701 };
702
703 inline IMutableContext& getCurrentMutableContext()
704 {
705 if( !IMutableContext::currentContext )
706 IMutableContext::createContext();
707 // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
708 return *IMutableContext::currentContext;
709 }
710
711 inline IContext& getCurrentContext()
712 {
713 return getCurrentMutableContext();
714 }
715
716 void cleanUpContext();
717
718 class SimplePcg32;
719 SimplePcg32& sharedRng();
720}
721
722#endif // CATCH_CONTEXT_HPP_INCLUDED
723
724
725#ifndef CATCH_INTERFACES_REPORTER_HPP_INCLUDED
726#define CATCH_INTERFACES_REPORTER_HPP_INCLUDED
727
728
729
730#ifndef CATCH_SECTION_INFO_HPP_INCLUDED
731#define CATCH_SECTION_INFO_HPP_INCLUDED
732
733
734
735#ifndef CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
736#define CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
737
738#include <type_traits>
739
741#define CATCH_MOVE(...) static_cast<std::remove_reference_t<decltype(__VA_ARGS__)>&&>(__VA_ARGS__)
742
744#define CATCH_FORWARD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
745
746#endif // CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
747
748
749#ifndef CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
750#define CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
751
752#include <cstddef>
753#include <iosfwd>
754
755namespace Catch {
756
757 struct SourceLineInfo {
758
759 SourceLineInfo() = delete;
760 constexpr SourceLineInfo( char const* _file, std::size_t _line ) noexcept:
761 file( _file ),
762 line( _line )
763 {}
764
765 bool operator == ( SourceLineInfo const& other ) const noexcept;
766 bool operator < ( SourceLineInfo const& other ) const noexcept;
767
768 char const* file;
769 std::size_t line;
770
771 friend std::ostream& operator << (std::ostream& os, SourceLineInfo const& info);
772 };
773}
774
775#define CATCH_INTERNAL_LINEINFO \
776 ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
777
778#endif // CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
779
780
781#ifndef CATCH_TOTALS_HPP_INCLUDED
782#define CATCH_TOTALS_HPP_INCLUDED
783
784#include <cstdint>
785
786namespace Catch {
787
788 struct Counts {
789 Counts operator - ( Counts const& other ) const;
790 Counts& operator += ( Counts const& other );
791
792 std::uint64_t total() const;
793 bool allPassed() const;
794 bool allOk() const;
795
796 std::uint64_t passed = 0;
797 std::uint64_t failed = 0;
798 std::uint64_t failedButOk = 0;
799 };
800
801 struct Totals {
802
803 Totals operator - ( Totals const& other ) const;
804 Totals& operator += ( Totals const& other );
805
806 Totals delta( Totals const& prevTotals ) const;
807
808 Counts assertions;
809 Counts testCases;
810 };
811}
812
813#endif // CATCH_TOTALS_HPP_INCLUDED
814
815#include <string>
816
817namespace Catch {
818
819 struct SectionInfo {
820 // The last argument is ignored, so that people can write
821 // SECTION("ShortName", "Proper description that is long") and
822 // still use the `-c` flag comfortably.
823 SectionInfo( SourceLineInfo const& _lineInfo, std::string _name,
824 const char* const = nullptr ):
825 name(CATCH_MOVE(_name)),
826 lineInfo(_lineInfo)
827 {}
828
829 std::string name;
830 SourceLineInfo lineInfo;
831 };
832
834 SectionInfo sectionInfo;
835 Counts prevAssertions;
836 double durationInSeconds;
837 };
838
839} // end namespace Catch
840
841#endif // CATCH_SECTION_INFO_HPP_INCLUDED
842
843
844#ifndef CATCH_ASSERTION_RESULT_HPP_INCLUDED
845#define CATCH_ASSERTION_RESULT_HPP_INCLUDED
846
847
848
849#ifndef CATCH_ASSERTION_INFO_HPP_INCLUDED
850#define CATCH_ASSERTION_INFO_HPP_INCLUDED
851
852
853
854#ifndef CATCH_RESULT_TYPE_HPP_INCLUDED
855#define CATCH_RESULT_TYPE_HPP_INCLUDED
856
857namespace Catch {
858
859 // ResultWas::OfType enum
860 struct ResultWas { enum OfType {
861 Unknown = -1,
862 Ok = 0,
863 Info = 1,
864 Warning = 2,
865
866 FailureBit = 0x10,
867
868 ExpressionFailed = FailureBit | 1,
869 ExplicitFailure = FailureBit | 2,
870
871 Exception = 0x100 | FailureBit,
872
873 ThrewException = Exception | 1,
874 DidntThrowException = Exception | 2,
875
876 FatalErrorCondition = 0x200 | FailureBit
877
878 }; };
879
880 bool isOk( ResultWas::OfType resultType );
881 bool isJustInfo( int flags );
882
883
884 // ResultDisposition::Flags enum
885 struct ResultDisposition { enum Flags {
886 Normal = 0x01,
887
888 ContinueOnFailure = 0x02, // Failures fail test, but execution continues
889 FalseTest = 0x04, // Prefix expression with !
890 SuppressFail = 0x08 // Failures are reported but do not fail the test
891 }; };
892
893 ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
894
895 bool shouldContinueOnFailure( int flags );
896 inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
897 bool shouldSuppressFailure( int flags );
898
899} // end namespace Catch
900
901#endif // CATCH_RESULT_TYPE_HPP_INCLUDED
902
903namespace Catch {
904
906 // AssertionInfo() = delete;
907
908 StringRef macroName;
909 SourceLineInfo lineInfo;
910 StringRef capturedExpression;
911 ResultDisposition::Flags resultDisposition;
912 };
913
914} // end namespace Catch
915
916#endif // CATCH_ASSERTION_INFO_HPP_INCLUDED
917
918
919#ifndef CATCH_LAZY_EXPR_HPP_INCLUDED
920#define CATCH_LAZY_EXPR_HPP_INCLUDED
921
922#include <iosfwd>
923
924namespace Catch {
925
926 class ITransientExpression;
927
929 friend class AssertionHandler;
930 friend struct AssertionStats;
931 friend class RunContext;
932
933 ITransientExpression const* m_transientExpression = nullptr;
934 bool m_isNegated;
935 public:
936 LazyExpression( bool isNegated ):
937 m_isNegated(isNegated)
938 {}
939 LazyExpression(LazyExpression const& other) = default;
940 LazyExpression& operator = ( LazyExpression const& ) = delete;
941
942 explicit operator bool() const {
943 return m_transientExpression != nullptr;
944 }
945
946 friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
947 };
948
949} // namespace Catch
950
951#endif // CATCH_LAZY_EXPR_HPP_INCLUDED
952
953#include <string>
954
955namespace Catch {
956
958 {
959 AssertionResultData() = delete;
960
961 AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
962
963 std::string message;
964 mutable std::string reconstructedExpression;
965 LazyExpression lazyExpression;
966 ResultWas::OfType resultType;
967
968 std::string reconstructExpression() const;
969 };
970
972 public:
973 AssertionResult() = delete;
974 AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
975
976 bool isOk() const;
977 bool succeeded() const;
978 ResultWas::OfType getResultType() const;
979 bool hasExpression() const;
980 bool hasMessage() const;
981 std::string getExpression() const;
982 std::string getExpressionInMacro() const;
983 bool hasExpandedExpression() const;
984 std::string getExpandedExpression() const;
985 StringRef getMessage() const;
986 SourceLineInfo getSourceInfo() const;
987 StringRef getTestMacroName() const;
988
989 //protected:
990 AssertionInfo m_info;
991 AssertionResultData m_resultData;
992 };
993
994} // end namespace Catch
995
996#endif // CATCH_ASSERTION_RESULT_HPP_INCLUDED
997
998
999#ifndef CATCH_MESSAGE_INFO_HPP_INCLUDED
1000#define CATCH_MESSAGE_INFO_HPP_INCLUDED
1001
1002
1003
1004#ifndef CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
1005#define CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
1006
1007#include <string>
1008#include <chrono>
1009
1010
1011namespace Catch {
1012
1013 class AssertionResult;
1014 struct AssertionInfo;
1015 struct SectionInfo;
1016 struct SectionEndInfo;
1017 struct MessageInfo;
1018 struct MessageBuilder;
1019 struct Counts;
1020 struct AssertionReaction;
1021 struct SourceLineInfo;
1022
1023 class ITransientExpression;
1024 class IGeneratorTracker;
1025
1026 struct BenchmarkInfo;
1027 template <typename Duration = std::chrono::duration<double, std::nano>>
1028 struct BenchmarkStats;
1029
1031 public:
1032 virtual ~IResultCapture();
1033
1034 virtual bool sectionStarted( SectionInfo const& sectionInfo,
1035 Counts& assertions ) = 0;
1036 virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
1037 virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
1038
1039 virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
1040
1041 virtual void benchmarkPreparing( StringRef name ) = 0;
1042 virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
1043 virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
1044 virtual void benchmarkFailed( StringRef error ) = 0;
1045
1046 virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1047 virtual void popScopedMessage( MessageInfo const& message ) = 0;
1048
1049 virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
1050
1051 virtual void handleFatalErrorCondition( StringRef message ) = 0;
1052
1053 virtual void handleExpr
1054 ( AssertionInfo const& info,
1055 ITransientExpression const& expr,
1056 AssertionReaction& reaction ) = 0;
1057 virtual void handleMessage
1058 ( AssertionInfo const& info,
1059 ResultWas::OfType resultType,
1060 StringRef message,
1061 AssertionReaction& reaction ) = 0;
1062 virtual void handleUnexpectedExceptionNotThrown
1063 ( AssertionInfo const& info,
1064 AssertionReaction& reaction ) = 0;
1065 virtual void handleUnexpectedInflightException
1066 ( AssertionInfo const& info,
1067 std::string const& message,
1068 AssertionReaction& reaction ) = 0;
1069 virtual void handleIncomplete
1070 ( AssertionInfo const& info ) = 0;
1071 virtual void handleNonExpr
1072 ( AssertionInfo const &info,
1073 ResultWas::OfType resultType,
1074 AssertionReaction &reaction ) = 0;
1075
1076
1077
1078 virtual bool lastAssertionPassed() = 0;
1079 virtual void assertionPassed() = 0;
1080
1081 // Deprecated, do not use:
1082 virtual std::string getCurrentTestName() const = 0;
1083 virtual const AssertionResult* getLastResult() const = 0;
1084 virtual void exceptionEarlyReported() = 0;
1085 };
1086
1087 IResultCapture& getResultCapture();
1088}
1089
1090#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
1091
1092#include <string>
1093
1094namespace Catch {
1095
1097 MessageInfo( StringRef _macroName,
1098 SourceLineInfo const& _lineInfo,
1099 ResultWas::OfType _type );
1100
1101 StringRef macroName;
1102 std::string message;
1103 SourceLineInfo lineInfo;
1104 ResultWas::OfType type;
1105 unsigned int sequence;
1106
1107 bool operator == (MessageInfo const& other) const {
1108 return sequence == other.sequence;
1109 }
1110 bool operator < (MessageInfo const& other) const {
1111 return sequence < other.sequence;
1112 }
1113 private:
1114 static unsigned int globalCount;
1115 };
1116
1117} // end namespace Catch
1118
1119#endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
1120
1121
1122#ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED
1123#define CATCH_UNIQUE_PTR_HPP_INCLUDED
1124
1125#include <cassert>
1126#include <type_traits>
1127
1128
1129namespace Catch {
1130namespace Detail {
1136 template <typename T>
1137 class unique_ptr {
1138 T* m_ptr;
1139 public:
1140 constexpr unique_ptr(std::nullptr_t = nullptr):
1141 m_ptr{}
1142 {}
1143 explicit constexpr unique_ptr(T* ptr):
1144 m_ptr(ptr)
1145 {}
1146
1147 template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
1148 unique_ptr(unique_ptr<U>&& from):
1149 m_ptr(from.release())
1150 {}
1151
1152 template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
1153 unique_ptr& operator=(unique_ptr<U>&& from) {
1154 reset(from.release());
1155
1156 return *this;
1157 }
1158
1159 unique_ptr(unique_ptr const&) = delete;
1160 unique_ptr& operator=(unique_ptr const&) = delete;
1161
1162 unique_ptr(unique_ptr&& rhs) noexcept:
1163 m_ptr(rhs.m_ptr) {
1164 rhs.m_ptr = nullptr;
1165 }
1166 unique_ptr& operator=(unique_ptr&& rhs) noexcept {
1167 reset(rhs.release());
1168
1169 return *this;
1170 }
1171
1172 ~unique_ptr() {
1173 delete m_ptr;
1174 }
1175
1176 T& operator*() {
1177 assert(m_ptr);
1178 return *m_ptr;
1179 }
1180 T const& operator*() const {
1181 assert(m_ptr);
1182 return *m_ptr;
1183 }
1184 T* operator->() noexcept {
1185 assert(m_ptr);
1186 return m_ptr;
1187 }
1188 T const* operator->() const noexcept {
1189 assert(m_ptr);
1190 return m_ptr;
1191 }
1192
1193 T* get() { return m_ptr; }
1194 T const* get() const { return m_ptr; }
1195
1196 void reset(T* ptr = nullptr) {
1197 delete m_ptr;
1198 m_ptr = ptr;
1199 }
1200
1201 T* release() {
1202 auto temp = m_ptr;
1203 m_ptr = nullptr;
1204 return temp;
1205 }
1206
1207 explicit operator bool() const {
1208 return m_ptr;
1209 }
1210
1211 friend void swap(unique_ptr& lhs, unique_ptr& rhs) {
1212 auto temp = lhs.m_ptr;
1213 lhs.m_ptr = rhs.m_ptr;
1214 rhs.m_ptr = temp;
1215 }
1216 };
1217
1219 template <typename T>
1220 class unique_ptr<T[]>;
1221
1222 template <typename T, typename... Args>
1223 unique_ptr<T> make_unique(Args&&... args) {
1224 return unique_ptr<T>(new T(CATCH_FORWARD(args)...));
1225 }
1226
1227
1228} // end namespace Detail
1229} // end namespace Catch
1230
1231#endif // CATCH_UNIQUE_PTR_HPP_INCLUDED
1232
1233
1234// Adapted from donated nonius code.
1235
1236#ifndef CATCH_ESTIMATE_HPP_INCLUDED
1237#define CATCH_ESTIMATE_HPP_INCLUDED
1238
1239namespace Catch {
1240 namespace Benchmark {
1241 template <typename Duration>
1242 struct Estimate {
1243 Duration point;
1244 Duration lower_bound;
1245 Duration upper_bound;
1246 double confidence_interval;
1247
1248 template <typename Duration2>
1249 operator Estimate<Duration2>() const {
1250 return { point, lower_bound, upper_bound, confidence_interval };
1251 }
1252 };
1253 } // namespace Benchmark
1254} // namespace Catch
1255
1256#endif // CATCH_ESTIMATE_HPP_INCLUDED
1257
1258
1259// Adapted from donated nonius code.
1260
1261#ifndef CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED
1262#define CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED
1263
1264namespace Catch {
1265 namespace Benchmark {
1267 int samples_seen = 0;
1268 int low_severe = 0; // more than 3 times IQR below Q1
1269 int low_mild = 0; // 1.5 to 3 times IQR below Q1
1270 int high_mild = 0; // 1.5 to 3 times IQR above Q3
1271 int high_severe = 0; // more than 3 times IQR above Q3
1272
1273 int total() const {
1274 return low_severe + low_mild + high_mild + high_severe;
1275 }
1276 };
1277 } // namespace Benchmark
1278} // namespace Catch
1279
1280#endif // CATCH_OUTLIERS_CLASSIFICATION_HPP_INCLUDED
1281
1282
1283#include <map>
1284#include <string>
1285#include <vector>
1286#include <iosfwd>
1287
1288namespace Catch {
1289
1290 struct ReporterDescription;
1291 struct ListenerDescription;
1292 struct TagInfo;
1293 struct TestCaseInfo;
1294 class TestCaseHandle;
1295 class IConfig;
1296 class IStream;
1297 enum class ColourMode : std::uint8_t;
1298
1300 ReporterConfig( IConfig const* _fullConfig,
1301 Detail::unique_ptr<IStream> _stream,
1302 ColourMode colourMode,
1303 std::map<std::string, std::string> customOptions );
1304
1305 ReporterConfig( ReporterConfig&& ) = default;
1306 ReporterConfig& operator=( ReporterConfig&& ) = default;
1307 ~ReporterConfig(); // = default
1308
1309 Detail::unique_ptr<IStream> takeStream() &&;
1310 IConfig const* fullConfig() const;
1311 ColourMode colourMode() const;
1312 std::map<std::string, std::string> const& customOptions() const;
1313
1314 private:
1315 Detail::unique_ptr<IStream> m_stream;
1316 IConfig const* m_fullConfig;
1317 ColourMode m_colourMode;
1318 std::map<std::string, std::string> m_customOptions;
1319 };
1320
1322 constexpr TestRunInfo(StringRef _name) : name(_name) {}
1323 StringRef name;
1324 };
1325
1327 AssertionStats( AssertionResult const& _assertionResult,
1328 std::vector<MessageInfo> const& _infoMessages,
1329 Totals const& _totals );
1330
1331 AssertionStats( AssertionStats const& ) = default;
1332 AssertionStats( AssertionStats && ) = default;
1333 AssertionStats& operator = ( AssertionStats const& ) = delete;
1334 AssertionStats& operator = ( AssertionStats && ) = delete;
1335
1336 AssertionResult assertionResult;
1337 std::vector<MessageInfo> infoMessages;
1338 Totals totals;
1339 };
1340
1342 SectionStats( SectionInfo const& _sectionInfo,
1343 Counts const& _assertions,
1344 double _durationInSeconds,
1345 bool _missingAssertions );
1346
1347 SectionInfo sectionInfo;
1348 Counts assertions;
1349 double durationInSeconds;
1350 bool missingAssertions;
1351 };
1352
1354 TestCaseStats( TestCaseInfo const& _testInfo,
1355 Totals const& _totals,
1356 std::string const& _stdOut,
1357 std::string const& _stdErr,
1358 bool _aborting );
1359
1360 TestCaseInfo const * testInfo;
1361 Totals totals;
1362 std::string stdOut;
1363 std::string stdErr;
1364 bool aborting;
1365 };
1366
1368 TestRunStats( TestRunInfo const& _runInfo,
1369 Totals const& _totals,
1370 bool _aborting );
1371
1372 TestRunInfo runInfo;
1373 Totals totals;
1374 bool aborting;
1375 };
1376
1377
1379 std::string name;
1380 double estimatedDuration;
1381 int iterations;
1382 unsigned int samples;
1383 unsigned int resamples;
1384 double clockResolution;
1385 double clockCost;
1386 };
1387
1388 template <class Duration>
1390 BenchmarkInfo info;
1391
1392 std::vector<Duration> samples;
1394 Benchmark::Estimate<Duration> standardDeviation;
1396 double outlierVariance;
1397
1398 template <typename Duration2>
1399 operator BenchmarkStats<Duration2>() const {
1400 std::vector<Duration2> samples2;
1401 samples2.reserve(samples.size());
1402 for (auto const& sample : samples) {
1403 samples2.push_back(Duration2(sample));
1404 }
1405 return {
1406 info,
1407 CATCH_MOVE(samples2),
1408 mean,
1409 standardDeviation,
1410 outliers,
1411 outlierVariance,
1412 };
1413 }
1414 };
1415
1427
1441 protected:
1446
1447 public:
1448 IEventListener( IConfig const* config ): m_config( config ) {}
1449
1450 virtual ~IEventListener(); // = default;
1451
1452 // Implementing class must also provide the following static methods:
1453 // static std::string getDescription();
1454
1455 ReporterPreferences const& getPreferences() const {
1456 return m_preferences;
1457 }
1458
1460 virtual void noMatchingTestCases( StringRef unmatchedSpec ) = 0;
1462 virtual void reportInvalidTestSpec( StringRef invalidArgument ) = 0;
1463
1469 virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
1470
1472 virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
1474 virtual void testCasePartialStarting( TestCaseInfo const& testInfo, uint64_t partNumber ) = 0;
1476 virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
1477
1479 virtual void benchmarkPreparing( StringRef benchmarkName ) = 0;
1481 virtual void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) = 0;
1483 virtual void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) = 0;
1485 virtual void benchmarkFailed( StringRef benchmarkName ) = 0;
1486
1488 virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
1489
1491 virtual void assertionEnded( AssertionStats const& assertionStats ) = 0;
1492
1494 virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
1496 virtual void testCasePartialEnded(TestCaseStats const& testCaseStats, uint64_t partNumber ) = 0;
1498 virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
1504 virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
1505
1507 virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
1508
1510 virtual void fatalErrorEncountered( StringRef error ) = 0;
1511
1513 virtual void listReporters(std::vector<ReporterDescription> const& descriptions) = 0;
1515 virtual void listListeners(std::vector<ListenerDescription> const& descriptions) = 0;
1517 virtual void listTests(std::vector<TestCaseHandle> const& tests) = 0;
1519 virtual void listTags(std::vector<TagInfo> const& tags) = 0;
1520 };
1521 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
1522
1523} // end namespace Catch
1524
1525#endif // CATCH_INTERFACES_REPORTER_HPP_INCLUDED
1526
1527
1528#ifndef CATCH_UNIQUE_NAME_HPP_INCLUDED
1529#define CATCH_UNIQUE_NAME_HPP_INCLUDED
1530
1531
1532
1533
1543#ifndef CATCH_CONFIG_COUNTER_HPP_INCLUDED
1544#define CATCH_CONFIG_COUNTER_HPP_INCLUDED
1545
1546#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
1547 #define CATCH_INTERNAL_CONFIG_COUNTER
1548#endif
1549
1550#if defined( CATCH_INTERNAL_CONFIG_COUNTER ) && \
1551 !defined( CATCH_CONFIG_NO_COUNTER ) && \
1552 !defined( CATCH_CONFIG_COUNTER )
1553# define CATCH_CONFIG_COUNTER
1554#endif
1555
1556
1557#endif // CATCH_CONFIG_COUNTER_HPP_INCLUDED
1558#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
1559#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
1560#ifdef CATCH_CONFIG_COUNTER
1561# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
1562#else
1563# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
1564#endif
1565
1566#endif // CATCH_UNIQUE_NAME_HPP_INCLUDED
1567
1568
1569// Adapted from donated nonius code.
1570
1571#ifndef CATCH_CHRONOMETER_HPP_INCLUDED
1572#define CATCH_CHRONOMETER_HPP_INCLUDED
1573
1574
1575
1576// Adapted from donated nonius code.
1577
1578#ifndef CATCH_CLOCK_HPP_INCLUDED
1579#define CATCH_CLOCK_HPP_INCLUDED
1580
1581#include <chrono>
1582#include <ratio>
1583
1584namespace Catch {
1585 namespace Benchmark {
1586 template <typename Clock>
1587 using ClockDuration = typename Clock::duration;
1588 template <typename Clock>
1589 using FloatDuration = std::chrono::duration<double, typename Clock::period>;
1590
1591 template <typename Clock>
1592 using TimePoint = typename Clock::time_point;
1593
1594 using default_clock = std::chrono::steady_clock;
1595
1596 template <typename Clock>
1597 struct now {
1598 TimePoint<Clock> operator()() const {
1599 return Clock::now();
1600 }
1601 };
1602
1603 using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
1604 } // namespace Benchmark
1605} // namespace Catch
1606
1607#endif // CATCH_CLOCK_HPP_INCLUDED
1608
1609
1610// Adapted from donated nonius code.
1611
1612#ifndef CATCH_OPTIMIZER_HPP_INCLUDED
1613#define CATCH_OPTIMIZER_HPP_INCLUDED
1614
1615#if defined(_MSC_VER)
1616# include <atomic> // atomic_thread_fence
1617#endif
1618
1619
1620#include <type_traits>
1621
1622namespace Catch {
1623 namespace Benchmark {
1624#if defined(__GNUC__) || defined(__clang__)
1625 template <typename T>
1626 inline void keep_memory(T* p) {
1627 asm volatile("" : : "g"(p) : "memory");
1628 }
1629 inline void keep_memory() {
1630 asm volatile("" : : : "memory");
1631 }
1632
1633 namespace Detail {
1634 inline void optimizer_barrier() { keep_memory(); }
1635 } // namespace Detail
1636#elif defined(_MSC_VER)
1637
1638#pragma optimize("", off)
1639 template <typename T>
1640 inline void keep_memory(T* p) {
1641 // thanks @milleniumbug
1642 *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
1643 }
1644 // TODO equivalent keep_memory()
1645#pragma optimize("", on)
1646
1647 namespace Detail {
1648 inline void optimizer_barrier() {
1649 std::atomic_thread_fence(std::memory_order_seq_cst);
1650 }
1651 } // namespace Detail
1652
1653#endif
1654
1655 template <typename T>
1656 inline void deoptimize_value(T&& x) {
1657 keep_memory(&x);
1658 }
1659
1660 template <typename Fn, typename... Args>
1661 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<!std::is_same<void, decltype(fn(args...))>::value> {
1662 deoptimize_value(CATCH_FORWARD(fn) (CATCH_FORWARD(args)...));
1663 }
1664
1665 template <typename Fn, typename... Args>
1666 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<std::is_same<void, decltype(fn(args...))>::value> {
1667 CATCH_FORWARD(fn) (CATCH_FORWARD(args)...);
1668 }
1669 } // namespace Benchmark
1670} // namespace Catch
1671
1672#endif // CATCH_OPTIMIZER_HPP_INCLUDED
1673
1674
1675// Adapted from donated nonius code.
1676
1677#ifndef CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1678#define CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1679
1680
1681
1682#ifndef CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
1683#define CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
1684
1685namespace Catch {
1686
1689
1690} // namespace Catch
1691
1692#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
1693
1694
1695#ifndef CATCH_META_HPP_INCLUDED
1696#define CATCH_META_HPP_INCLUDED
1697
1698#include <type_traits>
1699
1700namespace Catch {
1701 template<typename T>
1702 struct always_false : std::false_type {};
1703
1704 template <typename> struct true_given : std::true_type {};
1706 template <typename Fun, typename... Args>
1707 true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
1708 template <typename...>
1709 std::false_type static test(...);
1710 };
1711
1712 template <typename T>
1714
1715 template <typename Fun, typename... Args>
1716 struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
1717
1718
1719#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
1720 // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
1721 // replaced with std::invoke_result here.
1722 template <typename Func, typename... U>
1723 using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
1724#else
1725 template <typename Func, typename... U>
1726 using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::result_of_t<Func(U...)>>>;
1727#endif
1728
1729} // namespace Catch
1730
1731namespace mpl_{
1732 struct na;
1733}
1734
1735#endif // CATCH_META_HPP_INCLUDED
1736
1737
1738#ifndef CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1739#define CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1740
1741
1742#include <string>
1743
1744namespace Catch {
1745
1746 class TestCaseHandle;
1747 struct TestCaseInfo;
1748 class ITestCaseRegistry;
1749 class IExceptionTranslatorRegistry;
1750 class IExceptionTranslator;
1751 class IReporterRegistry;
1752 class IReporterFactory;
1753 class ITagAliasRegistry;
1754 class ITestInvoker;
1755 class IMutableEnumValuesRegistry;
1756 struct SourceLineInfo;
1757
1758 class StartupExceptionRegistry;
1759 class EventListenerFactory;
1760
1761 using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
1762
1764 public:
1765 virtual ~IRegistryHub(); // = default
1766
1767 virtual IReporterRegistry const& getReporterRegistry() const = 0;
1768 virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
1769 virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
1770 virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
1771
1772
1773 virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
1774 };
1775
1777 public:
1778 virtual ~IMutableRegistryHub(); // = default
1779 virtual void registerReporter( std::string const& name, IReporterFactoryPtr factory ) = 0;
1780 virtual void registerListener( Detail::unique_ptr<EventListenerFactory> factory ) = 0;
1781 virtual void registerTest(Detail::unique_ptr<TestCaseInfo>&& testInfo, Detail::unique_ptr<ITestInvoker>&& invoker) = 0;
1782 virtual void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator ) = 0;
1783 virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
1784 virtual void registerStartupException() noexcept = 0;
1785 virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
1786 };
1787
1788 IRegistryHub const& getRegistryHub();
1789 IMutableRegistryHub& getMutableRegistryHub();
1790 void cleanUp();
1791 std::string translateActiveException();
1792
1793}
1794
1795#endif // CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1796
1797#include <type_traits>
1798
1799namespace Catch {
1800 namespace Benchmark {
1801 namespace Detail {
1802 template <typename T>
1803 struct CompleteType { using type = T; };
1804 template <>
1805 struct CompleteType<void> { struct type {}; };
1806
1807 template <typename T>
1808 using CompleteType_t = typename CompleteType<T>::type;
1809
1810 template <typename Result>
1812 template <typename Fun, typename... Args>
1813 static Result invoke(Fun&& fun, Args&&... args) {
1814 return CATCH_FORWARD(fun)(CATCH_FORWARD(args)...);
1815 }
1816 };
1817 template <>
1818 struct CompleteInvoker<void> {
1819 template <typename Fun, typename... Args>
1820 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
1821 CATCH_FORWARD(fun)(CATCH_FORWARD(args)...);
1822 return {};
1823 }
1824 };
1825
1826 // invoke and not return void :(
1827 template <typename Fun, typename... Args>
1828 CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
1829 return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...);
1830 }
1831
1832 } // namespace Detail
1833
1834 template <typename Fun>
1835 Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
1836 return Detail::complete_invoke(CATCH_FORWARD(fun));
1837 }
1838 } // namespace Benchmark
1839} // namespace Catch
1840
1841#endif // CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1842
1843namespace Catch {
1844 namespace Benchmark {
1845 namespace Detail {
1847 virtual void start() = 0;
1848 virtual void finish() = 0;
1849 virtual ~ChronometerConcept(); // = default;
1850
1851 ChronometerConcept() = default;
1852 ChronometerConcept(ChronometerConcept const&) = default;
1853 ChronometerConcept& operator=(ChronometerConcept const&) = default;
1854 };
1855 template <typename Clock>
1856 struct ChronometerModel final : public ChronometerConcept {
1857 void start() override { started = Clock::now(); }
1858 void finish() override { finished = Clock::now(); }
1859
1860 ClockDuration<Clock> elapsed() const { return finished - started; }
1861
1862 TimePoint<Clock> started;
1863 TimePoint<Clock> finished;
1864 };
1865 } // namespace Detail
1866
1868 public:
1869 template <typename Fun>
1870 void measure(Fun&& fun) { measure(CATCH_FORWARD(fun), is_callable<Fun(int)>()); }
1871
1872 int runs() const { return repeats; }
1873
1874 Chronometer(Detail::ChronometerConcept& meter, int repeats_)
1875 : impl(&meter)
1876 , repeats(repeats_) {}
1877
1878 private:
1879 template <typename Fun>
1880 void measure(Fun&& fun, std::false_type) {
1881 measure([&fun](int) { return fun(); }, std::true_type());
1882 }
1883
1884 template <typename Fun>
1885 void measure(Fun&& fun, std::true_type) {
1886 Detail::optimizer_barrier();
1887 impl->start();
1888 for (int i = 0; i < repeats; ++i) invoke_deoptimized(fun, i);
1889 impl->finish();
1890 Detail::optimizer_barrier();
1891 }
1892
1894 int repeats;
1895 };
1896 } // namespace Benchmark
1897} // namespace Catch
1898
1899#endif // CATCH_CHRONOMETER_HPP_INCLUDED
1900
1901
1902// Adapted from donated nonius code.
1903
1904#ifndef CATCH_ENVIRONMENT_HPP_INCLUDED
1905#define CATCH_ENVIRONMENT_HPP_INCLUDED
1906
1907
1908namespace Catch {
1909 namespace Benchmark {
1910 template <typename Duration>
1911 struct EnvironmentEstimate {
1912 Duration mean;
1913 OutlierClassification outliers;
1914
1915 template <typename Duration2>
1916 operator EnvironmentEstimate<Duration2>() const {
1917 return { mean, outliers };
1918 }
1919 };
1920 template <typename Clock>
1921 struct Environment {
1922 using clock_type = Clock;
1923 EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
1924 EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
1925 };
1926 } // namespace Benchmark
1927} // namespace Catch
1928
1929#endif // CATCH_ENVIRONMENT_HPP_INCLUDED
1930
1931
1932// Adapted from donated nonius code.
1933
1934#ifndef CATCH_EXECUTION_PLAN_HPP_INCLUDED
1935#define CATCH_EXECUTION_PLAN_HPP_INCLUDED
1936
1937
1938
1939// Adapted from donated nonius code.
1940
1941#ifndef CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1942#define CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1943
1944
1945#include <type_traits>
1946
1947namespace Catch {
1948 namespace Benchmark {
1949 namespace Detail {
1950 template <typename T, typename U>
1952 : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
1953
1962 private:
1963 struct callable {
1964 virtual void call(Chronometer meter) const = 0;
1965 virtual Catch::Detail::unique_ptr<callable> clone() const = 0;
1966 virtual ~callable(); // = default;
1967
1968 callable() = default;
1969 callable(callable const&) = default;
1970 callable& operator=(callable const&) = default;
1971 };
1972 template <typename Fun>
1973 struct model : public callable {
1974 model(Fun&& fun_) : fun(CATCH_MOVE(fun_)) {}
1975 model(Fun const& fun_) : fun(fun_) {}
1976
1977 Catch::Detail::unique_ptr<callable> clone() const override {
1978 return Catch::Detail::make_unique<model<Fun>>( *this );
1979 }
1980
1981 void call(Chronometer meter) const override {
1982 call(meter, is_callable<Fun(Chronometer)>());
1983 }
1984 void call(Chronometer meter, std::true_type) const {
1985 fun(meter);
1986 }
1987 void call(Chronometer meter, std::false_type) const {
1988 meter.measure(fun);
1989 }
1990
1991 Fun fun;
1992 };
1993
1994 struct do_nothing { void operator()() const {} };
1995
1996 template <typename T>
1997 BenchmarkFunction(model<T>* c) : f(c) {}
1998
1999 public:
2001 : f(new model<do_nothing>{ {} }) {}
2002
2003 template <typename Fun,
2004 std::enable_if_t<!is_related<Fun, BenchmarkFunction>::value, int> = 0>
2005 BenchmarkFunction(Fun&& fun)
2006 : f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {}
2007
2008 BenchmarkFunction( BenchmarkFunction&& that ) noexcept:
2009 f( CATCH_MOVE( that.f ) ) {}
2010
2012 : f(that.f->clone()) {}
2013
2015 operator=( BenchmarkFunction&& that ) noexcept {
2016 f = CATCH_MOVE( that.f );
2017 return *this;
2018 }
2019
2020 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
2021 f = that.f->clone();
2022 return *this;
2023 }
2024
2025 void operator()(Chronometer meter) const { f->call(meter); }
2026
2027 private:
2028 Catch::Detail::unique_ptr<callable> f;
2029 };
2030 } // namespace Detail
2031 } // namespace Benchmark
2032} // namespace Catch
2033
2034#endif // CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
2035
2036
2037// Adapted from donated nonius code.
2038
2039#ifndef CATCH_REPEAT_HPP_INCLUDED
2040#define CATCH_REPEAT_HPP_INCLUDED
2041
2042#include <type_traits>
2043
2044namespace Catch {
2045 namespace Benchmark {
2046 namespace Detail {
2047 template <typename Fun>
2048 struct repeater {
2049 void operator()(int k) const {
2050 for (int i = 0; i < k; ++i) {
2051 fun();
2052 }
2053 }
2054 Fun fun;
2055 };
2056 template <typename Fun>
2057 repeater<std::decay_t<Fun>> repeat(Fun&& fun) {
2058 return { CATCH_FORWARD(fun) };
2059 }
2060 } // namespace Detail
2061 } // namespace Benchmark
2062} // namespace Catch
2063
2064#endif // CATCH_REPEAT_HPP_INCLUDED
2065
2066
2067// Adapted from donated nonius code.
2068
2069#ifndef CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
2070#define CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
2071
2072
2073
2074// Adapted from donated nonius code.
2075
2076#ifndef CATCH_MEASURE_HPP_INCLUDED
2077#define CATCH_MEASURE_HPP_INCLUDED
2078
2079
2080
2081// Adapted from donated nonius code.
2082
2083#ifndef CATCH_TIMING_HPP_INCLUDED
2084#define CATCH_TIMING_HPP_INCLUDED
2085
2086
2087#include <type_traits>
2088
2089namespace Catch {
2090 namespace Benchmark {
2091 template <typename Duration, typename Result>
2092 struct Timing {
2093 Duration elapsed;
2094 Result result;
2095 int iterations;
2096 };
2097 template <typename Clock, typename Func, typename... Args>
2098 using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
2099 } // namespace Benchmark
2100} // namespace Catch
2101
2102#endif // CATCH_TIMING_HPP_INCLUDED
2103
2104namespace Catch {
2105 namespace Benchmark {
2106 namespace Detail {
2107 template <typename Clock, typename Fun, typename... Args>
2108 TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
2109 auto start = Clock::now();
2110 auto&& r = Detail::complete_invoke(fun, CATCH_FORWARD(args)...);
2111 auto end = Clock::now();
2112 auto delta = end - start;
2113 return { delta, CATCH_FORWARD(r), 1 };
2114 }
2115 } // namespace Detail
2116 } // namespace Benchmark
2117} // namespace Catch
2118
2119#endif // CATCH_MEASURE_HPP_INCLUDED
2120
2121#include <type_traits>
2122
2123namespace Catch {
2124 namespace Benchmark {
2125 namespace Detail {
2126 template <typename Clock, typename Fun>
2127 TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
2128 return Detail::measure<Clock>(fun, iters);
2129 }
2130 template <typename Clock, typename Fun>
2131 TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
2132 Detail::ChronometerModel<Clock> meter;
2133 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
2134
2135 return { meter.elapsed(), CATCH_MOVE(result), iters };
2136 }
2137
2138 template <typename Clock, typename Fun>
2139 using run_for_at_least_argument_t = std::conditional_t<is_callable<Fun(Chronometer)>::value, Chronometer, int>;
2140
2141
2142 [[noreturn]]
2143 void throw_optimized_away_error();
2144
2145 template <typename Clock, typename Fun>
2146 TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>>
2147 run_for_at_least(ClockDuration<Clock> how_long,
2148 const int initial_iterations,
2149 Fun&& fun) {
2150 auto iters = initial_iterations;
2151 while (iters < (1 << 30)) {
2152 auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
2153
2154 if (Timing.elapsed >= how_long) {
2155 return { Timing.elapsed, CATCH_MOVE(Timing.result), iters };
2156 }
2157 iters *= 2;
2158 }
2159 throw_optimized_away_error();
2160 }
2161 } // namespace Detail
2162 } // namespace Benchmark
2163} // namespace Catch
2164
2165#endif // CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
2166
2167#include <algorithm>
2168#include <iterator>
2169
2170namespace Catch {
2171 namespace Benchmark {
2172 template <typename Duration>
2174 int iterations_per_sample;
2175 Duration estimated_duration;
2176 Detail::BenchmarkFunction benchmark;
2177 Duration warmup_time;
2178 int warmup_iterations;
2179
2180 template <typename Duration2>
2181 operator ExecutionPlan<Duration2>() const {
2182 return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
2183 }
2184
2185 template <typename Clock>
2186 std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
2187 // warmup a bit
2188 Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
2189
2190 std::vector<FloatDuration<Clock>> times;
2191 times.reserve(cfg.benchmarkSamples());
2192 std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
2193 Detail::ChronometerModel<Clock> model;
2194 this->benchmark(Chronometer(model, iterations_per_sample));
2195 auto sample_time = model.elapsed() - env.clock_cost.mean;
2196 if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
2197 return sample_time / iterations_per_sample;
2198 });
2199 return times;
2200 }
2201 };
2202 } // namespace Benchmark
2203} // namespace Catch
2204
2205#endif // CATCH_EXECUTION_PLAN_HPP_INCLUDED
2206
2207
2208// Adapted from donated nonius code.
2209
2210#ifndef CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
2211#define CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
2212
2213
2214
2215// Adapted from donated nonius code.
2216
2217#ifndef CATCH_STATS_HPP_INCLUDED
2218#define CATCH_STATS_HPP_INCLUDED
2219
2220
2221#include <algorithm>
2222#include <vector>
2223#include <numeric>
2224#include <tuple>
2225#include <cmath>
2226
2227namespace Catch {
2228 namespace Benchmark {
2229 namespace Detail {
2230 using sample = std::vector<double>;
2231
2232 // Used when we know we want == comparison of two doubles
2233 // to centralize warning suppression
2234 bool directCompare( double lhs, double rhs );
2235
2236 double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
2237
2238 template <typename Iterator>
2239 OutlierClassification classify_outliers(Iterator first, Iterator last) {
2240 std::vector<double> copy(first, last);
2241
2242 auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
2243 auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
2244 auto iqr = q3 - q1;
2245 auto los = q1 - (iqr * 3.);
2246 auto lom = q1 - (iqr * 1.5);
2247 auto him = q3 + (iqr * 1.5);
2248 auto his = q3 + (iqr * 3.);
2249
2250 OutlierClassification o;
2251 for (; first != last; ++first) {
2252 auto&& t = *first;
2253 if (t < los) ++o.low_severe;
2254 else if (t < lom) ++o.low_mild;
2255 else if (t > his) ++o.high_severe;
2256 else if (t > him) ++o.high_mild;
2257 ++o.samples_seen;
2258 }
2259 return o;
2260 }
2261
2262 template <typename Iterator>
2263 double mean(Iterator first, Iterator last) {
2264 auto count = last - first;
2265 double sum = std::accumulate(first, last, 0.);
2266 return sum / static_cast<double>(count);
2267 }
2268
2269 template <typename Estimator, typename Iterator>
2270 sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
2271 auto n = static_cast<size_t>(last - first);
2272 auto second = first;
2273 ++second;
2274 sample results;
2275 results.reserve(n);
2276
2277 for (auto it = first; it != last; ++it) {
2278 std::iter_swap(it, first);
2279 results.push_back(estimator(second, last));
2280 }
2281
2282 return results;
2283 }
2284
2285 inline double normal_cdf(double x) {
2286 return std::erfc(-x / std::sqrt(2.0)) / 2.0;
2287 }
2288
2289 double erfc_inv(double x);
2290
2291 double normal_quantile(double p);
2292
2293 template <typename Iterator, typename Estimator>
2294 Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
2295 auto n_samples = last - first;
2296
2297 double point = estimator(first, last);
2298 // Degenerate case with a single sample
2299 if (n_samples == 1) return { point, point, point, confidence_level };
2300
2301 sample jack = jackknife(estimator, first, last);
2302 double jack_mean = mean(jack.begin(), jack.end());
2303 double sum_squares, sum_cubes;
2304 std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
2305 auto d = jack_mean - x;
2306 auto d2 = d * d;
2307 auto d3 = d2 * d;
2308 return { sqcb.first + d2, sqcb.second + d3 };
2309 });
2310
2311 double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
2312 long n = static_cast<long>(resample.size());
2313 double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / static_cast<double>(n);
2314 // degenerate case with uniform samples
2315 if ( directCompare( prob_n, 0. ) ) {
2316 return { point, point, point, confidence_level };
2317 }
2318
2319 double bias = normal_quantile(prob_n);
2320 double z1 = normal_quantile((1. - confidence_level) / 2.);
2321
2322 auto cumn = [n]( double x ) -> long {
2323 return std::lround( normal_cdf( x ) * n );
2324 };
2325 auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
2326 double b1 = bias + z1;
2327 double b2 = bias - z1;
2328 double a1 = a(b1);
2329 double a2 = a(b2);
2330 auto lo = static_cast<size_t>((std::max)(cumn(a1), 0l));
2331 auto hi = static_cast<size_t>((std::min)(cumn(a2), n - 1));
2332
2333 return { point, resample[lo], resample[hi], confidence_level };
2334 }
2335
2336 double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
2337
2339 Estimate<double> mean;
2340 Estimate<double> standard_deviation;
2341 double outlier_variance;
2342 };
2343
2344 bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
2345 } // namespace Detail
2346 } // namespace Benchmark
2347} // namespace Catch
2348
2349#endif // CATCH_STATS_HPP_INCLUDED
2350
2351#include <algorithm>
2352#include <iterator>
2353#include <vector>
2354#include <cmath>
2355
2356namespace Catch {
2357 namespace Benchmark {
2358 namespace Detail {
2359 template <typename Clock>
2360 std::vector<double> resolution(int k) {
2361 std::vector<TimePoint<Clock>> times;
2362 times.reserve(static_cast<size_t>(k + 1));
2363 std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
2364
2365 std::vector<double> deltas;
2366 deltas.reserve(static_cast<size_t>(k));
2367 std::transform(std::next(times.begin()), times.end(), times.begin(),
2368 std::back_inserter(deltas),
2369 [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
2370
2371 return deltas;
2372 }
2373
2374 const auto warmup_iterations = 10000;
2375 const auto warmup_time = std::chrono::milliseconds(100);
2376 const auto minimum_ticks = 1000;
2377 const auto warmup_seed = 10000;
2378 const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
2379 const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
2380 const auto clock_cost_estimation_tick_limit = 100000;
2381 const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
2382 const auto clock_cost_estimation_iterations = 10000;
2383
2384 template <typename Clock>
2385 int warmup() {
2386 return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
2387 .iterations;
2388 }
2389 template <typename Clock>
2390 EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
2391 auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
2392 .result;
2393 return {
2394 FloatDuration<Clock>(mean(r.begin(), r.end())),
2395 classify_outliers(r.begin(), r.end()),
2396 };
2397 }
2398 template <typename Clock>
2399 EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
2400 auto time_limit = (std::min)(
2401 resolution * clock_cost_estimation_tick_limit,
2402 FloatDuration<Clock>(clock_cost_estimation_time_limit));
2403 auto time_clock = [](int k) {
2404 return Detail::measure<Clock>([k] {
2405 for (int i = 0; i < k; ++i) {
2406 volatile auto ignored = Clock::now();
2407 (void)ignored;
2408 }
2409 }).elapsed;
2410 };
2411 time_clock(1);
2412 int iters = clock_cost_estimation_iterations;
2413 auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
2414 std::vector<double> times;
2415 int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
2416 times.reserve(static_cast<size_t>(nsamples));
2417 std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
2418 return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
2419 });
2420 return {
2421 FloatDuration<Clock>(mean(times.begin(), times.end())),
2422 classify_outliers(times.begin(), times.end()),
2423 };
2424 }
2425
2426 template <typename Clock>
2427 Environment<FloatDuration<Clock>> measure_environment() {
2428#if defined(__clang__)
2429# pragma clang diagnostic push
2430# pragma clang diagnostic ignored "-Wexit-time-destructors"
2431#endif
2432 static Catch::Detail::unique_ptr<Environment<FloatDuration<Clock>>> env;
2433#if defined(__clang__)
2434# pragma clang diagnostic pop
2435#endif
2436 if (env) {
2437 return *env;
2438 }
2439
2440 auto iters = Detail::warmup<Clock>();
2441 auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
2442 auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
2443
2444 env = Catch::Detail::make_unique<Environment<FloatDuration<Clock>>>( Environment<FloatDuration<Clock>>{resolution, cost} );
2445 return *env;
2446 }
2447 } // namespace Detail
2448 } // namespace Benchmark
2449} // namespace Catch
2450
2451#endif // CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
2452
2453
2454// Adapted from donated nonius code.
2455
2456#ifndef CATCH_ANALYSE_HPP_INCLUDED
2457#define CATCH_ANALYSE_HPP_INCLUDED
2458
2459
2460
2461// Adapted from donated nonius code.
2462
2463#ifndef CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2464#define CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2465
2466
2467#include <algorithm>
2468#include <vector>
2469#include <iterator>
2470
2471namespace Catch {
2472 namespace Benchmark {
2473 template <typename Duration>
2475 std::vector<Duration> samples;
2476 Estimate<Duration> mean;
2477 Estimate<Duration> standard_deviation;
2478 OutlierClassification outliers;
2479 double outlier_variance;
2480
2481 template <typename Duration2>
2482 operator SampleAnalysis<Duration2>() const {
2483 std::vector<Duration2> samples2;
2484 samples2.reserve(samples.size());
2485 std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
2486 return {
2487 CATCH_MOVE(samples2),
2488 mean,
2489 standard_deviation,
2490 outliers,
2491 outlier_variance,
2492 };
2493 }
2494 };
2495 } // namespace Benchmark
2496} // namespace Catch
2497
2498#endif // CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2499
2500#include <algorithm>
2501#include <iterator>
2502#include <vector>
2503
2504namespace Catch {
2505 namespace Benchmark {
2506 namespace Detail {
2507 template <typename Duration, typename Iterator>
2508 SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
2509 if (!cfg.benchmarkNoAnalysis()) {
2510 std::vector<double> samples;
2511 samples.reserve(static_cast<size_t>(last - first));
2512 std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
2513
2514 auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
2515 auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
2516
2517 auto wrap_estimate = [](Estimate<double> e) {
2518 return Estimate<Duration> {
2519 Duration(e.point),
2520 Duration(e.lower_bound),
2521 Duration(e.upper_bound),
2522 e.confidence_interval,
2523 };
2524 };
2525 std::vector<Duration> samples2;
2526 samples2.reserve(samples.size());
2527 std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
2528 return {
2529 CATCH_MOVE(samples2),
2530 wrap_estimate(analysis.mean),
2531 wrap_estimate(analysis.standard_deviation),
2532 outliers,
2533 analysis.outlier_variance,
2534 };
2535 } else {
2536 std::vector<Duration> samples;
2537 samples.reserve(static_cast<size_t>(last - first));
2538
2539 Duration mean = Duration(0);
2540 int i = 0;
2541 for (auto it = first; it < last; ++it, ++i) {
2542 samples.push_back(Duration(*it));
2543 mean += Duration(*it);
2544 }
2545 mean /= i;
2546
2547 return {
2548 CATCH_MOVE(samples),
2549 Estimate<Duration>{mean, mean, mean, 0.0},
2550 Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
2551 OutlierClassification{},
2552 0.0
2553 };
2554 }
2555 }
2556 } // namespace Detail
2557 } // namespace Benchmark
2558} // namespace Catch
2559
2560#endif // CATCH_ANALYSE_HPP_INCLUDED
2561
2562#include <algorithm>
2563#include <functional>
2564#include <string>
2565#include <vector>
2566#include <cmath>
2567
2568namespace Catch {
2569 namespace Benchmark {
2570 struct Benchmark {
2571 Benchmark(std::string&& benchmarkName)
2572 : name(CATCH_MOVE(benchmarkName)) {}
2573
2574 template <class FUN>
2575 Benchmark(std::string&& benchmarkName , FUN &&func)
2576 : fun(CATCH_MOVE(func)), name(CATCH_MOVE(benchmarkName)) {}
2577
2578 template <typename Clock>
2579 ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
2580 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
2581 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
2582 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
2583 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
2584 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
2585 }
2586
2587 template <typename Clock = default_clock>
2588 void run() {
2589 auto const* cfg = getCurrentContext().getConfig();
2590
2591 auto env = Detail::measure_environment<Clock>();
2592
2593 getResultCapture().benchmarkPreparing(name);
2594 CATCH_TRY{
2595 auto plan = user_code([&] {
2596 return prepare<Clock>(*cfg, env);
2597 });
2598
2599 BenchmarkInfo info {
2600 name,
2601 plan.estimated_duration.count(),
2602 plan.iterations_per_sample,
2603 cfg->benchmarkSamples(),
2604 cfg->benchmarkResamples(),
2605 env.clock_resolution.mean.count(),
2606 env.clock_cost.mean.count()
2607 };
2608
2609 getResultCapture().benchmarkStarting(info);
2610
2611 auto samples = user_code([&] {
2612 return plan.template run<Clock>(*cfg, env);
2613 });
2614
2615 auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
2616 BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
2617 getResultCapture().benchmarkEnded(stats);
2618 } CATCH_CATCH_ANON (TestFailureException) {
2619 getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr);
2620 } CATCH_CATCH_ALL{
2621 getResultCapture().benchmarkFailed(translateActiveException());
2622 // We let the exception go further up so that the
2623 // test case is marked as failed.
2624 std::rethrow_exception(std::current_exception());
2625 }
2626 }
2627
2628 // sets lambda to be used in fun *and* executes benchmark!
2629 template <typename Fun, std::enable_if_t<!Detail::is_related<Fun, Benchmark>::value, int> = 0>
2630 Benchmark & operator=(Fun func) {
2631 auto const* cfg = getCurrentContext().getConfig();
2632 if (!cfg->skipBenchmarks()) {
2633 fun = Detail::BenchmarkFunction(func);
2634 run();
2635 }
2636 return *this;
2637 }
2638
2639 explicit operator bool() {
2640 return true;
2641 }
2642
2643 private:
2645 std::string name;
2646 };
2647 }
2648} // namespace Catch
2649
2650#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
2651#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
2652
2653#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
2654 if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
2655 BenchmarkName = [&](int benchmarkIndex)
2656
2657#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
2658 if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
2659 BenchmarkName = [&]
2660
2661#if defined(CATCH_CONFIG_PREFIX_ALL)
2662
2663#define CATCH_BENCHMARK(...) \
2664 INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
2665#define CATCH_BENCHMARK_ADVANCED(name) \
2666 INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name)
2667
2668#else
2669
2670#define BENCHMARK(...) \
2671 INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
2672#define BENCHMARK_ADVANCED(name) \
2673 INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name)
2674
2675#endif
2676
2677#endif // CATCH_BENCHMARK_HPP_INCLUDED
2678
2679
2680// Adapted from donated nonius code.
2681
2682#ifndef CATCH_CONSTRUCTOR_HPP_INCLUDED
2683#define CATCH_CONSTRUCTOR_HPP_INCLUDED
2684
2685
2686#include <type_traits>
2687
2688namespace Catch {
2689 namespace Benchmark {
2690 namespace Detail {
2691 template <typename T, bool Destruct>
2692 struct ObjectStorage
2693 {
2694 ObjectStorage() = default;
2695
2696 ObjectStorage(const ObjectStorage& other)
2697 {
2698 new(&data) T(other.stored_object());
2699 }
2700
2701 ObjectStorage(ObjectStorage&& other)
2702 {
2703 new(data) T(CATCH_MOVE(other.stored_object()));
2704 }
2705
2706 ~ObjectStorage() { destruct_on_exit<T>(); }
2707
2708 template <typename... Args>
2709 void construct(Args&&... args)
2710 {
2711 new (data) T(CATCH_FORWARD(args)...);
2712 }
2713
2714 template <bool AllowManualDestruction = !Destruct>
2715 std::enable_if_t<AllowManualDestruction> destruct()
2716 {
2717 stored_object().~T();
2718 }
2719
2720 private:
2721 // If this is a constructor benchmark, destruct the underlying object
2722 template <typename U>
2723 void destruct_on_exit(std::enable_if_t<Destruct, U>* = nullptr) { destruct<true>(); }
2724 // Otherwise, don't
2725 template <typename U>
2726 void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
2727
2728 T& stored_object() {
2729 return *static_cast<T*>(static_cast<void*>(data));
2730 }
2731
2732 T const& stored_object() const {
2733 return *static_cast<T*>(static_cast<void*>(data));
2734 }
2735
2736
2737 alignas( T ) unsigned char data[sizeof( T )]{};
2738 };
2739 } // namespace Detail
2740
2741 template <typename T>
2742 using storage_for = Detail::ObjectStorage<T, true>;
2743
2744 template <typename T>
2745 using destructable_object = Detail::ObjectStorage<T, false>;
2746 } // namespace Benchmark
2747} // namespace Catch
2748
2749#endif // CATCH_CONSTRUCTOR_HPP_INCLUDED
2750
2751#endif // CATCH_BENCHMARK_ALL_HPP_INCLUDED
2752
2753
2754#ifndef CATCH_APPROX_HPP_INCLUDED
2755#define CATCH_APPROX_HPP_INCLUDED
2756
2757
2758
2759#ifndef CATCH_TOSTRING_HPP_INCLUDED
2760#define CATCH_TOSTRING_HPP_INCLUDED
2761
2762
2763#include <vector>
2764#include <cstddef>
2765#include <type_traits>
2766#include <string>
2767#include <string.h>
2768
2769
2770
2771
2780#ifndef CATCH_CONFIG_WCHAR_HPP_INCLUDED
2781#define CATCH_CONFIG_WCHAR_HPP_INCLUDED
2782
2783// We assume that WCHAR should be enabled by default, and only disabled
2784// for a shortlist (so far only DJGPP) of compilers.
2785
2786#if defined(__DJGPP__)
2787# define CATCH_INTERNAL_CONFIG_NO_WCHAR
2788#endif // __DJGPP__
2789
2790#if !defined( CATCH_INTERNAL_CONFIG_NO_WCHAR ) && \
2791 !defined( CATCH_CONFIG_NO_WCHAR ) && \
2792 !defined( CATCH_CONFIG_WCHAR )
2793# define CATCH_CONFIG_WCHAR
2794#endif
2795
2796#endif // CATCH_CONFIG_WCHAR_HPP_INCLUDED
2797
2798
2799#ifndef CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2800#define CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2801
2802
2803#include <iosfwd>
2804#include <cstddef>
2805#include <ostream>
2806#include <string>
2807
2808namespace Catch {
2809
2810 class ReusableStringStream : Detail::NonCopyable {
2811 std::size_t m_index;
2812 std::ostream* m_oss;
2813 public:
2814 ReusableStringStream();
2815 ~ReusableStringStream();
2816
2818 std::string str() const;
2820 void str(std::string const& str);
2821
2822#if defined(__GNUC__) && !defined(__clang__)
2823#pragma GCC diagnostic push
2824// Old versions of GCC do not understand -Wnonnull-compare
2825#pragma GCC diagnostic ignored "-Wpragmas"
2826// Streaming a function pointer triggers Waddress and Wnonnull-compare
2827// on GCC, because it implicitly converts it to bool and then decides
2828// that the check it uses (a? true : false) is tautological and cannot
2829// be null...
2830#pragma GCC diagnostic ignored "-Waddress"
2831#pragma GCC diagnostic ignored "-Wnonnull-compare"
2832#endif
2833
2834 template<typename T>
2835 auto operator << ( T const& value ) -> ReusableStringStream& {
2836 *m_oss << value;
2837 return *this;
2838 }
2839
2840#if defined(__GNUC__) && !defined(__clang__)
2841#pragma GCC diagnostic pop
2842#endif
2843 auto get() -> std::ostream& { return *m_oss; }
2844 };
2845}
2846
2847#endif // CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2848
2849
2850#ifndef CATCH_VOID_TYPE_HPP_INCLUDED
2851#define CATCH_VOID_TYPE_HPP_INCLUDED
2852
2853
2854namespace Catch {
2855 namespace Detail {
2856
2857 template <typename...>
2858 struct make_void { using type = void; };
2859
2860 template <typename... Ts>
2861 using void_t = typename make_void<Ts...>::type;
2862
2863 } // namespace Detail
2864} // namespace Catch
2865
2866
2867#endif // CATCH_VOID_TYPE_HPP_INCLUDED
2868
2869
2870#ifndef CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2871#define CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2872
2873
2874#include <vector>
2875
2876namespace Catch {
2877
2878 namespace Detail {
2879 struct EnumInfo {
2880 StringRef m_name;
2881 std::vector<std::pair<int, StringRef>> m_values;
2882
2883 ~EnumInfo();
2884
2885 StringRef lookup( int value ) const;
2886 };
2887 } // namespace Detail
2888
2890 public:
2891 virtual ~IMutableEnumValuesRegistry(); // = default;
2892
2893 virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
2894
2895 template<typename E>
2896 Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
2897 static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
2898 std::vector<int> intValues;
2899 intValues.reserve( values.size() );
2900 for( auto enumValue : values )
2901 intValues.push_back( static_cast<int>( enumValue ) );
2902 return registerEnum( enumName, allEnums, intValues );
2903 }
2904 };
2905
2906} // Catch
2907
2908#endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2909
2910#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2911#include <string_view>
2912#endif
2913
2914#ifdef _MSC_VER
2915#pragma warning(push)
2916#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
2917#endif
2918
2919// We need a dummy global operator<< so we can bring it into Catch namespace later
2921std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
2922
2923namespace Catch {
2924 // Bring in global namespace operator<< for ADL lookup in
2925 // `IsStreamInsertable` below.
2926 using ::operator<<;
2927
2928 namespace Detail {
2929
2930
2931 constexpr StringRef unprintableString = "{?}"_sr;
2932
2934 std::string convertIntoString( StringRef string, bool escapeInvisibles );
2935
2938 std::string convertIntoString( StringRef string );
2939
2940 std::string rawMemoryToString( const void *object, std::size_t size );
2941
2942 template<typename T>
2943 std::string rawMemoryToString( const T& object ) {
2944 return rawMemoryToString( &object, sizeof(object) );
2945 }
2946
2947 template<typename T>
2949 template<typename Stream, typename U>
2950 static auto test(int)
2951 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
2952
2953 template<typename, typename>
2954 static auto test(...)->std::false_type;
2955
2956 public:
2957 static const bool value = decltype(test<std::ostream, const T&>(0))::value;
2958 };
2959
2960 template<typename E>
2961 std::string convertUnknownEnumToString( E e );
2962
2963 template<typename T>
2964 std::enable_if_t<
2965 !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
2966 std::string> convertUnstreamable( T const& ) {
2967 return std::string(Detail::unprintableString);
2968 }
2969 template<typename T>
2970 std::enable_if_t<
2971 !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
2972 std::string> convertUnstreamable(T const& ex) {
2973 return ex.what();
2974 }
2975
2976
2977 template<typename T>
2978 std::enable_if_t<
2979 std::is_enum<T>::value,
2980 std::string> convertUnstreamable( T const& value ) {
2981 return convertUnknownEnumToString( value );
2982 }
2983
2984#if defined(_MANAGED)
2986 template<typename T>
2987 std::string clrReferenceToString( T^ ref ) {
2988 if (ref == nullptr)
2989 return std::string("null");
2990 auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
2991 cli::pin_ptr<System::Byte> p = &bytes[0];
2992 return std::string(reinterpret_cast<char const *>(p), bytes->Length);
2993 }
2994#endif
2995
2996 } // namespace Detail
2997
2998
2999 // If we decide for C++14, change these to enable_if_ts
3000 template <typename T, typename = void>
3002 template <typename Fake = T>
3003 static
3004 std::enable_if_t<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>
3005 convert(const Fake& value) {
3006 ReusableStringStream rss;
3007 // NB: call using the function-like syntax to avoid ambiguity with
3008 // user-defined templated operator<< under clang.
3009 rss.operator<<(value);
3010 return rss.str();
3011 }
3012
3013 template <typename Fake = T>
3014 static
3015 std::enable_if_t<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>
3016 convert( const Fake& value ) {
3017#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
3018 return Detail::convertUnstreamable(value);
3019#else
3020 return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
3021#endif
3022 }
3023 };
3024
3025 namespace Detail {
3026
3027 // This function dispatches all stringification requests inside of Catch.
3028 // Should be preferably called fully qualified, like ::Catch::Detail::stringify
3029 template <typename T>
3030 std::string stringify(const T& e) {
3031 return ::Catch::StringMaker<std::remove_cv_t<std::remove_reference_t<T>>>::convert(e);
3032 }
3033
3034 template<typename E>
3035 std::string convertUnknownEnumToString( E e ) {
3036 return ::Catch::Detail::stringify(static_cast<std::underlying_type_t<E>>(e));
3037 }
3038
3039#if defined(_MANAGED)
3040 template <typename T>
3041 std::string stringify( T^ e ) {
3042 return ::Catch::StringMaker<T^>::convert(e);
3043 }
3044#endif
3045
3046 } // namespace Detail
3047
3048 // Some predefined specializations
3049
3050 template<>
3051 struct StringMaker<std::string> {
3052 static std::string convert(const std::string& str);
3053 };
3054
3055#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
3056 template<>
3057 struct StringMaker<std::string_view> {
3058 static std::string convert(std::string_view str);
3059 };
3060#endif
3061
3062 template<>
3063 struct StringMaker<char const *> {
3064 static std::string convert(char const * str);
3065 };
3066 template<>
3067 struct StringMaker<char *> {
3068 static std::string convert(char * str);
3069 };
3070
3071#if defined(CATCH_CONFIG_WCHAR)
3072 template<>
3073 struct StringMaker<std::wstring> {
3074 static std::string convert(const std::wstring& wstr);
3075 };
3076
3077# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
3078 template<>
3079 struct StringMaker<std::wstring_view> {
3080 static std::string convert(std::wstring_view str);
3081 };
3082# endif
3083
3084 template<>
3085 struct StringMaker<wchar_t const *> {
3086 static std::string convert(wchar_t const * str);
3087 };
3088 template<>
3089 struct StringMaker<wchar_t *> {
3090 static std::string convert(wchar_t * str);
3091 };
3092#endif // CATCH_CONFIG_WCHAR
3093
3094 template<size_t SZ>
3095 struct StringMaker<char[SZ]> {
3096 static std::string convert(char const* str) {
3097 // Note that `strnlen` is not actually part of standard C++,
3098 // but both POSIX and Windows cstdlib provide it.
3099 return Detail::convertIntoString(
3100 StringRef( str, strnlen( str, SZ ) ) );
3101 }
3102 };
3103 template<size_t SZ>
3104 struct StringMaker<signed char[SZ]> {
3105 static std::string convert(signed char const* str) {
3106 // See the plain `char const*` overload
3107 auto reinterpreted = reinterpret_cast<char const*>(str);
3108 return Detail::convertIntoString(
3109 StringRef(reinterpreted, strnlen(reinterpreted, SZ)));
3110 }
3111 };
3112 template<size_t SZ>
3113 struct StringMaker<unsigned char[SZ]> {
3114 static std::string convert(unsigned char const* str) {
3115 // See the plain `char const*` overload
3116 auto reinterpreted = reinterpret_cast<char const*>(str);
3117 return Detail::convertIntoString(
3118 StringRef(reinterpreted, strnlen(reinterpreted, SZ)));
3119 }
3120 };
3121
3122#if defined(CATCH_CONFIG_CPP17_BYTE)
3123 template<>
3124 struct StringMaker<std::byte> {
3125 static std::string convert(std::byte value);
3126 };
3127#endif // defined(CATCH_CONFIG_CPP17_BYTE)
3128 template<>
3129 struct StringMaker<int> {
3130 static std::string convert(int value);
3131 };
3132 template<>
3133 struct StringMaker<long> {
3134 static std::string convert(long value);
3135 };
3136 template<>
3137 struct StringMaker<long long> {
3138 static std::string convert(long long value);
3139 };
3140 template<>
3141 struct StringMaker<unsigned int> {
3142 static std::string convert(unsigned int value);
3143 };
3144 template<>
3145 struct StringMaker<unsigned long> {
3146 static std::string convert(unsigned long value);
3147 };
3148 template<>
3149 struct StringMaker<unsigned long long> {
3150 static std::string convert(unsigned long long value);
3151 };
3152
3153 template<>
3154 struct StringMaker<bool> {
3155 static std::string convert(bool b) {
3156 using namespace std::string_literals;
3157 return b ? "true"s : "false"s;
3158 }
3159 };
3160
3161 template<>
3162 struct StringMaker<char> {
3163 static std::string convert(char c);
3164 };
3165 template<>
3166 struct StringMaker<signed char> {
3167 static std::string convert(signed char c);
3168 };
3169 template<>
3170 struct StringMaker<unsigned char> {
3171 static std::string convert(unsigned char c);
3172 };
3173
3174 template<>
3175 struct StringMaker<std::nullptr_t> {
3176 static std::string convert(std::nullptr_t) {
3177 using namespace std::string_literals;
3178 return "nullptr"s;
3179 }
3180 };
3181
3182 template<>
3183 struct StringMaker<float> {
3184 static std::string convert(float value);
3185 static int precision;
3186 };
3187
3188 template<>
3189 struct StringMaker<double> {
3190 static std::string convert(double value);
3191 static int precision;
3192 };
3193
3194 template <typename T>
3195 struct StringMaker<T*> {
3196 template <typename U>
3197 static std::string convert(U* p) {
3198 if (p) {
3199 return ::Catch::Detail::rawMemoryToString(p);
3200 } else {
3201 return "nullptr";
3202 }
3203 }
3204 };
3205
3206 template <typename R, typename C>
3207 struct StringMaker<R C::*> {
3208 static std::string convert(R C::* p) {
3209 if (p) {
3210 return ::Catch::Detail::rawMemoryToString(p);
3211 } else {
3212 return "nullptr";
3213 }
3214 }
3215 };
3216
3217#if defined(_MANAGED)
3218 template <typename T>
3219 struct StringMaker<T^> {
3220 static std::string convert( T^ ref ) {
3221 return ::Catch::Detail::clrReferenceToString(ref);
3222 }
3223 };
3224#endif
3225
3226 namespace Detail {
3227 template<typename InputIterator, typename Sentinel = InputIterator>
3228 std::string rangeToString(InputIterator first, Sentinel last) {
3229 ReusableStringStream rss;
3230 rss << "{ ";
3231 if (first != last) {
3232 rss << ::Catch::Detail::stringify(*first);
3233 for (++first; first != last; ++first)
3234 rss << ", " << ::Catch::Detail::stringify(*first);
3235 }
3236 rss << " }";
3237 return rss.str();
3238 }
3239 }
3240
3241} // namespace Catch
3242
3244// Separate std-lib types stringification, so it can be selectively enabled
3245// This means that we do not bring in their headers
3246
3247#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
3248# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
3249# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
3250# define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
3251# define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
3252#endif
3253
3254// Separate std::pair specialization
3255#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
3256#include <utility>
3257namespace Catch {
3258 template<typename T1, typename T2>
3259 struct StringMaker<std::pair<T1, T2> > {
3260 static std::string convert(const std::pair<T1, T2>& pair) {
3261 ReusableStringStream rss;
3262 rss << "{ "
3263 << ::Catch::Detail::stringify(pair.first)
3264 << ", "
3265 << ::Catch::Detail::stringify(pair.second)
3266 << " }";
3267 return rss.str();
3268 }
3269 };
3270}
3271#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
3272
3273#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
3274#include <optional>
3275namespace Catch {
3276 template<typename T>
3277 struct StringMaker<std::optional<T> > {
3278 static std::string convert(const std::optional<T>& optional) {
3279 if (optional.has_value()) {
3280 return ::Catch::Detail::stringify(*optional);
3281 } else {
3282 return "{ }";
3283 }
3284 }
3285 };
3286}
3287#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
3288
3289// Separate std::tuple specialization
3290#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
3291#include <tuple>
3292namespace Catch {
3293 namespace Detail {
3294 template<
3295 typename Tuple,
3296 std::size_t N = 0,
3297 bool = (N < std::tuple_size<Tuple>::value)
3298 >
3299 struct TupleElementPrinter {
3300 static void print(const Tuple& tuple, std::ostream& os) {
3301 os << (N ? ", " : " ")
3302 << ::Catch::Detail::stringify(std::get<N>(tuple));
3303 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
3304 }
3305 };
3306
3307 template<
3308 typename Tuple,
3309 std::size_t N
3310 >
3311 struct TupleElementPrinter<Tuple, N, false> {
3312 static void print(const Tuple&, std::ostream&) {}
3313 };
3314
3315 }
3316
3317
3318 template<typename ...Types>
3319 struct StringMaker<std::tuple<Types...>> {
3320 static std::string convert(const std::tuple<Types...>& tuple) {
3321 ReusableStringStream rss;
3322 rss << '{';
3323 Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
3324 rss << " }";
3325 return rss.str();
3326 }
3327 };
3328}
3329#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
3330
3331#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
3332#include <variant>
3333namespace Catch {
3334 template<>
3335 struct StringMaker<std::monostate> {
3336 static std::string convert(const std::monostate&) {
3337 return "{ }";
3338 }
3339 };
3340
3341 template<typename... Elements>
3342 struct StringMaker<std::variant<Elements...>> {
3343 static std::string convert(const std::variant<Elements...>& variant) {
3344 if (variant.valueless_by_exception()) {
3345 return "{valueless variant}";
3346 } else {
3347 return std::visit(
3348 [](const auto& value) {
3349 return ::Catch::Detail::stringify(value);
3350 },
3351 variant
3352 );
3353 }
3354 }
3355 };
3356}
3357#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
3358
3359namespace Catch {
3360 // Import begin/ end from std here
3361 using std::begin;
3362 using std::end;
3363
3364 namespace Detail {
3365 template <typename T, typename = void>
3366 struct is_range_impl : std::false_type {};
3367
3368 template <typename T>
3369 struct is_range_impl<T, void_t<decltype(begin(std::declval<T>()))>> : std::true_type {};
3370 } // namespace Detail
3371
3372 template <typename T>
3374
3375#if defined(_MANAGED) // Managed types are never ranges
3376 template <typename T>
3377 struct is_range<T^> {
3378 static const bool value = false;
3379 };
3380#endif
3381
3382 template<typename Range>
3383 std::string rangeToString( Range const& range ) {
3384 return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
3385 }
3386
3387 // Handle vector<bool> specially
3388 template<typename Allocator>
3389 std::string rangeToString( std::vector<bool, Allocator> const& v ) {
3390 ReusableStringStream rss;
3391 rss << "{ ";
3392 bool first = true;
3393 for( bool b : v ) {
3394 if( first )
3395 first = false;
3396 else
3397 rss << ", ";
3398 rss << ::Catch::Detail::stringify( b );
3399 }
3400 rss << " }";
3401 return rss.str();
3402 }
3403
3404 template<typename R>
3405 struct StringMaker<R, std::enable_if_t<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>> {
3406 static std::string convert( R const& range ) {
3407 return rangeToString( range );
3408 }
3409 };
3410
3411 template <typename T, size_t SZ>
3412 struct StringMaker<T[SZ]> {
3413 static std::string convert(T const(&arr)[SZ]) {
3414 return rangeToString(arr);
3415 }
3416 };
3417
3418
3419} // namespace Catch
3420
3421// Separate std::chrono::duration specialization
3422#include <ctime>
3423#include <ratio>
3424#include <chrono>
3425
3426
3427namespace Catch {
3428
3429template <class Ratio>
3431 static std::string symbol() {
3432 Catch::ReusableStringStream rss;
3433 rss << '[' << Ratio::num << '/'
3434 << Ratio::den << ']';
3435 return rss.str();
3436 }
3437};
3438
3439template <>
3440struct ratio_string<std::atto> {
3441 static char symbol() { return 'a'; }
3442};
3443template <>
3444struct ratio_string<std::femto> {
3445 static char symbol() { return 'f'; }
3446};
3447template <>
3448struct ratio_string<std::pico> {
3449 static char symbol() { return 'p'; }
3450};
3451template <>
3452struct ratio_string<std::nano> {
3453 static char symbol() { return 'n'; }
3454};
3455template <>
3456struct ratio_string<std::micro> {
3457 static char symbol() { return 'u'; }
3458};
3459template <>
3460struct ratio_string<std::milli> {
3461 static char symbol() { return 'm'; }
3462};
3463
3465 // std::chrono::duration specializations
3466 template<typename Value, typename Ratio>
3467 struct StringMaker<std::chrono::duration<Value, Ratio>> {
3468 static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
3469 ReusableStringStream rss;
3470 rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
3471 return rss.str();
3472 }
3473 };
3474 template<typename Value>
3475 struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
3476 static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
3477 ReusableStringStream rss;
3478 rss << duration.count() << " s";
3479 return rss.str();
3480 }
3481 };
3482 template<typename Value>
3483 struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
3484 static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
3485 ReusableStringStream rss;
3486 rss << duration.count() << " m";
3487 return rss.str();
3488 }
3489 };
3490 template<typename Value>
3491 struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
3492 static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
3493 ReusableStringStream rss;
3494 rss << duration.count() << " h";
3495 return rss.str();
3496 }
3497 };
3498
3500 // std::chrono::time_point specialization
3501 // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
3502 template<typename Clock, typename Duration>
3503 struct StringMaker<std::chrono::time_point<Clock, Duration>> {
3504 static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
3505 return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
3506 }
3507 };
3508 // std::chrono::time_point<system_clock> specialization
3509 template<typename Duration>
3510 struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
3511 static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
3512 auto converted = std::chrono::system_clock::to_time_t(time_point);
3513
3514#ifdef _MSC_VER
3515 std::tm timeInfo = {};
3516 gmtime_s(&timeInfo, &converted);
3517#else
3518 std::tm* timeInfo = std::gmtime(&converted);
3519#endif
3520
3521 auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
3522 char timeStamp[timeStampSize];
3523 const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
3524
3525#ifdef _MSC_VER
3526 std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
3527#else
3528 std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
3529#endif
3530 return std::string(timeStamp, timeStampSize - 1);
3531 }
3532 };
3533}
3534
3535
3536#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
3537namespace Catch { \
3538 template<> struct StringMaker<enumName> { \
3539 static std::string convert( enumName value ) { \
3540 static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
3541 return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
3542 } \
3543 }; \
3544}
3545
3546#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
3547
3548#ifdef _MSC_VER
3549#pragma warning(pop)
3550#endif
3551
3552#endif // CATCH_TOSTRING_HPP_INCLUDED
3553
3554#include <type_traits>
3555
3556namespace Catch {
3557
3558 class Approx {
3559 private:
3560 bool equalityComparisonImpl(double other) const;
3561 // Sets and validates the new margin (margin >= 0)
3562 void setMargin(double margin);
3563 // Sets and validates the new epsilon (0 < epsilon < 1)
3564 void setEpsilon(double epsilon);
3565
3566 public:
3567 explicit Approx ( double value );
3568
3569 static Approx custom();
3570
3571 Approx operator-() const;
3572
3573 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3574 Approx operator()( T const& value ) const {
3575 Approx approx( static_cast<double>(value) );
3576 approx.m_epsilon = m_epsilon;
3577 approx.m_margin = m_margin;
3578 approx.m_scale = m_scale;
3579 return approx;
3580 }
3581
3582 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3583 explicit Approx( T const& value ): Approx(static_cast<double>(value))
3584 {}
3585
3586
3587 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3588 friend bool operator == ( const T& lhs, Approx const& rhs ) {
3589 auto lhs_v = static_cast<double>(lhs);
3590 return rhs.equalityComparisonImpl(lhs_v);
3591 }
3592
3593 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3594 friend bool operator == ( Approx const& lhs, const T& rhs ) {
3595 return operator==( rhs, lhs );
3596 }
3597
3598 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3599 friend bool operator != ( T const& lhs, Approx const& rhs ) {
3600 return !operator==( lhs, rhs );
3601 }
3602
3603 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3604 friend bool operator != ( Approx const& lhs, T const& rhs ) {
3605 return !operator==( rhs, lhs );
3606 }
3607
3608 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3609 friend bool operator <= ( T const& lhs, Approx const& rhs ) {
3610 return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3611 }
3612
3613 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3614 friend bool operator <= ( Approx const& lhs, T const& rhs ) {
3615 return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3616 }
3617
3618 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3619 friend bool operator >= ( T const& lhs, Approx const& rhs ) {
3620 return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3621 }
3622
3623 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3624 friend bool operator >= ( Approx const& lhs, T const& rhs ) {
3625 return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3626 }
3627
3628 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3629 Approx& epsilon( T const& newEpsilon ) {
3630 const auto epsilonAsDouble = static_cast<double>(newEpsilon);
3631 setEpsilon(epsilonAsDouble);
3632 return *this;
3633 }
3634
3635 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3636 Approx& margin( T const& newMargin ) {
3637 const auto marginAsDouble = static_cast<double>(newMargin);
3638 setMargin(marginAsDouble);
3639 return *this;
3640 }
3641
3642 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3643 Approx& scale( T const& newScale ) {
3644 m_scale = static_cast<double>(newScale);
3645 return *this;
3646 }
3647
3648 std::string toString() const;
3649
3650 private:
3651 double m_epsilon;
3652 double m_margin;
3653 double m_scale;
3654 double m_value;
3655 };
3656
3657namespace literals {
3658 Approx operator ""_a(long double val);
3659 Approx operator ""_a(unsigned long long val);
3660} // end namespace literals
3661
3662template<>
3663struct StringMaker<Catch::Approx> {
3664 static std::string convert(Catch::Approx const& value);
3665};
3666
3667} // end namespace Catch
3668
3669#endif // CATCH_APPROX_HPP_INCLUDED
3670
3671
3672#ifndef CATCH_CONFIG_HPP_INCLUDED
3673#define CATCH_CONFIG_HPP_INCLUDED
3674
3675
3676
3677#ifndef CATCH_TEST_SPEC_HPP_INCLUDED
3678#define CATCH_TEST_SPEC_HPP_INCLUDED
3679
3680#ifdef __clang__
3681#pragma clang diagnostic push
3682#pragma clang diagnostic ignored "-Wpadded"
3683#endif
3684
3685
3686
3687#ifndef CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3688#define CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3689
3690
3691
3692#ifndef CATCH_CASE_SENSITIVE_HPP_INCLUDED
3693#define CATCH_CASE_SENSITIVE_HPP_INCLUDED
3694
3695namespace Catch {
3696
3697 enum class CaseSensitive { Yes, No };
3698
3699} // namespace Catch
3700
3701#endif // CATCH_CASE_SENSITIVE_HPP_INCLUDED
3702
3703#include <string>
3704
3705namespace Catch
3706{
3708 enum WildcardPosition {
3709 NoWildcard = 0,
3710 WildcardAtStart = 1,
3711 WildcardAtEnd = 2,
3712 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3713 };
3714
3715 public:
3716
3717 WildcardPattern( std::string const& pattern, CaseSensitive caseSensitivity );
3718 bool matches( std::string const& str ) const;
3719
3720 private:
3721 std::string normaliseString( std::string const& str ) const;
3722 CaseSensitive m_caseSensitivity;
3723 WildcardPosition m_wildcard = NoWildcard;
3724 std::string m_pattern;
3725 };
3726}
3727
3728#endif // CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3729
3730#include <string>
3731#include <vector>
3732
3733namespace Catch {
3734
3735 class IConfig;
3736 struct TestCaseInfo;
3737 class TestCaseHandle;
3738
3739 class TestSpec {
3740
3741 class Pattern {
3742 public:
3743 explicit Pattern( std::string const& name );
3744 virtual ~Pattern();
3745 virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3746 std::string const& name() const;
3747 private:
3748 std::string const m_name;
3749 };
3750
3751 class NamePattern : public Pattern {
3752 public:
3753 explicit NamePattern( std::string const& name, std::string const& filterString );
3754 bool matches( TestCaseInfo const& testCase ) const override;
3755 private:
3756 WildcardPattern m_wildcardPattern;
3757 };
3758
3759 class TagPattern : public Pattern {
3760 public:
3761 explicit TagPattern( std::string const& tag, std::string const& filterString );
3762 bool matches( TestCaseInfo const& testCase ) const override;
3763 private:
3764 std::string m_tag;
3765 };
3766
3767 struct Filter {
3768 std::vector<Detail::unique_ptr<Pattern>> m_required;
3769 std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
3770
3771 bool matches( TestCaseInfo const& testCase ) const;
3772 std::string name() const;
3773 };
3774
3775 public:
3777 std::string name;
3778 std::vector<TestCaseHandle const*> tests;
3779 };
3780 using Matches = std::vector<FilterMatch>;
3781 using vectorStrings = std::vector<std::string>;
3782
3783 bool hasFilters() const;
3784 bool matches( TestCaseInfo const& testCase ) const;
3785 Matches matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const;
3786 const vectorStrings & getInvalidSpecs() const;
3787
3788 private:
3789 std::vector<Filter> m_filters;
3790 std::vector<std::string> m_invalidSpecs;
3791 friend class TestSpecParser;
3792 };
3793}
3794
3795#ifdef __clang__
3796#pragma clang diagnostic pop
3797#endif
3798
3799#endif // CATCH_TEST_SPEC_HPP_INCLUDED
3800
3801
3802#ifndef CATCH_OPTIONAL_HPP_INCLUDED
3803#define CATCH_OPTIONAL_HPP_INCLUDED
3804
3805#include <cassert>
3806
3807namespace Catch {
3808
3809 // An optional type
3810 template<typename T>
3811 class Optional {
3812 public:
3813 Optional() : nullableValue( nullptr ) {}
3814 Optional( T const& _value )
3815 : nullableValue( new( storage ) T( _value ) )
3816 {}
3817 Optional( Optional const& _other )
3818 : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
3819 {}
3820
3821 ~Optional() {
3822 reset();
3823 }
3824
3825 Optional& operator= ( Optional const& _other ) {
3826 if( &_other != this ) {
3827 reset();
3828 if( _other )
3829 nullableValue = new( storage ) T( *_other );
3830 }
3831 return *this;
3832 }
3833 Optional& operator = ( T const& _value ) {
3834 reset();
3835 nullableValue = new( storage ) T( _value );
3836 return *this;
3837 }
3838
3839 void reset() {
3840 if( nullableValue )
3841 nullableValue->~T();
3842 nullableValue = nullptr;
3843 }
3844
3845 T& operator*() {
3846 assert(nullableValue);
3847 return *nullableValue;
3848 }
3849 T const& operator*() const {
3850 assert(nullableValue);
3851 return *nullableValue;
3852 }
3853 T* operator->() {
3854 assert(nullableValue);
3855 return nullableValue;
3856 }
3857 const T* operator->() const {
3858 assert(nullableValue);
3859 return nullableValue;
3860 }
3861
3862 T valueOr( T const& defaultValue ) const {
3863 return nullableValue ? *nullableValue : defaultValue;
3864 }
3865
3866 bool some() const { return nullableValue != nullptr; }
3867 bool none() const { return nullableValue == nullptr; }
3868
3869 bool operator !() const { return nullableValue == nullptr; }
3870 explicit operator bool() const {
3871 return some();
3872 }
3873
3874 friend bool operator==(Optional const& a, Optional const& b) {
3875 if (a.none() && b.none()) {
3876 return true;
3877 } else if (a.some() && b.some()) {
3878 return *a == *b;
3879 } else {
3880 return false;
3881 }
3882 }
3883 friend bool operator!=(Optional const& a, Optional const& b) {
3884 return !( a == b );
3885 }
3886
3887 private:
3888 T *nullableValue;
3889 alignas(alignof(T)) char storage[sizeof(T)];
3890 };
3891
3892} // end namespace Catch
3893
3894#endif // CATCH_OPTIONAL_HPP_INCLUDED
3895
3896
3897#ifndef CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3898#define CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3899
3900#include <cstdint>
3901
3902namespace Catch {
3903
3904 enum class GenerateFrom {
3905 Time,
3906 RandomDevice,
3908 Default
3909 };
3910
3911 std::uint32_t generateRandomSeed(GenerateFrom from);
3912
3913} // end namespace Catch
3914
3915#endif // CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3916
3917
3918#ifndef CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3919#define CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3920
3921
3922
3923#ifndef CATCH_CONSOLE_COLOUR_HPP_INCLUDED
3924#define CATCH_CONSOLE_COLOUR_HPP_INCLUDED
3925
3926
3927#include <iosfwd>
3928#include <cstdint>
3929
3930namespace Catch {
3931
3932 enum class ColourMode : std::uint8_t;
3933 class IStream;
3934
3935 struct Colour {
3936 enum Code {
3937 None = 0,
3938
3939 White,
3940 Red,
3941 Green,
3942 Blue,
3943 Cyan,
3944 Yellow,
3945 Grey,
3946
3947 Bright = 0x10,
3948
3949 BrightRed = Bright | Red,
3950 BrightGreen = Bright | Green,
3951 LightGrey = Bright | Grey,
3952 BrightWhite = Bright | White,
3953 BrightYellow = Bright | Yellow,
3954
3955 // By intention
3956 FileName = LightGrey,
3957 Warning = BrightYellow,
3958 ResultError = BrightRed,
3959 ResultSuccess = BrightGreen,
3960 ResultExpectedFailure = Warning,
3961
3962 Error = BrightRed,
3963 Success = Green,
3964
3965 OriginalExpression = Cyan,
3966 ReconstructedExpression = BrightYellow,
3967
3968 SecondaryText = LightGrey,
3969 Headers = White
3970 };
3971 };
3972
3973 class ColourImpl {
3974 protected:
3976 IStream* m_stream;
3977 public:
3978 ColourImpl( IStream* stream ): m_stream( stream ) {}
3979
3983 ColourImpl const* m_colourImpl;
3984 Colour::Code m_code;
3985 bool m_engaged = false;
3986
3987 public:
3989 ColourGuard( Colour::Code code,
3990 ColourImpl const* colour );
3991
3992 ColourGuard( ColourGuard const& rhs ) = delete;
3993 ColourGuard& operator=( ColourGuard const& rhs ) = delete;
3994
3995 ColourGuard( ColourGuard&& rhs ) noexcept;
3996 ColourGuard& operator=( ColourGuard&& rhs ) noexcept;
3997
3999 ~ColourGuard();
4000
4006 ColourGuard& engage( std::ostream& stream ) &;
4012 ColourGuard&& engage( std::ostream& stream ) &&;
4013
4014 private:
4016 friend std::ostream& operator<<( std::ostream& lhs,
4017 ColourGuard& guard ) {
4018 guard.engageImpl( lhs );
4019 return lhs;
4020 }
4022 friend std::ostream& operator<<( std::ostream& lhs,
4023 ColourGuard&& guard) {
4024 guard.engageImpl( lhs );
4025 return lhs;
4026 }
4027
4028 void engageImpl( std::ostream& stream );
4029
4030 };
4031
4032 virtual ~ColourImpl(); // = default
4039 ColourGuard guardColour( Colour::Code colourCode );
4040
4041 private:
4042 virtual void use( Colour::Code colourCode ) const = 0;
4043 };
4044
4046 Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
4047 IStream* stream );
4048
4050 bool isColourImplAvailable( ColourMode colourSelection );
4051
4052} // end namespace Catch
4053
4054#endif // CATCH_CONSOLE_COLOUR_HPP_INCLUDED
4055
4056#include <map>
4057#include <string>
4058#include <vector>
4059
4060namespace Catch {
4061
4062 enum class ColourMode : std::uint8_t;
4063
4064 namespace Detail {
4066 std::vector<std::string> splitReporterSpec( StringRef reporterSpec );
4067
4068 Optional<ColourMode> stringToColourMode( StringRef colourMode );
4069 }
4070
4079 class ReporterSpec {
4080 std::string m_name;
4081 Optional<std::string> m_outputFileName;
4082 Optional<ColourMode> m_colourMode;
4083 std::map<std::string, std::string> m_customOptions;
4084
4085 friend bool operator==( ReporterSpec const& lhs,
4086 ReporterSpec const& rhs );
4087 friend bool operator!=( ReporterSpec const& lhs,
4088 ReporterSpec const& rhs ) {
4089 return !( lhs == rhs );
4090 }
4091
4092 public:
4093 ReporterSpec(
4094 std::string name,
4095 Optional<std::string> outputFileName,
4096 Optional<ColourMode> colourMode,
4097 std::map<std::string, std::string> customOptions );
4098
4099 std::string const& name() const { return m_name; }
4100
4101 Optional<std::string> const& outputFile() const {
4102 return m_outputFileName;
4103 }
4104
4105 Optional<ColourMode> const& colourMode() const { return m_colourMode; }
4106
4107 std::map<std::string, std::string> const& customOptions() const {
4108 return m_customOptions;
4109 }
4110 };
4111
4122 Optional<ReporterSpec> parseReporterSpec( StringRef reporterSpec );
4123
4124}
4125
4126#endif // CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
4127
4128#include <chrono>
4129#include <map>
4130#include <string>
4131#include <vector>
4132
4133namespace Catch {
4134
4135 class IStream;
4136
4143 std::string name;
4144 std::string outputFilename;
4145 ColourMode colourMode;
4146 std::map<std::string, std::string> customOptions;
4147 friend bool operator==( ProcessedReporterSpec const& lhs,
4148 ProcessedReporterSpec const& rhs );
4149 friend bool operator!=( ProcessedReporterSpec const& lhs,
4150 ProcessedReporterSpec const& rhs ) {
4151 return !( lhs == rhs );
4152 }
4153 };
4154
4155 struct ConfigData {
4156
4157 bool listTests = false;
4158 bool listTags = false;
4159 bool listReporters = false;
4160 bool listListeners = false;
4161
4162 bool showSuccessfulTests = false;
4163 bool shouldDebugBreak = false;
4164 bool noThrow = false;
4165 bool showHelp = false;
4166 bool showInvisibles = false;
4167 bool filenamesAsTags = false;
4168 bool libIdentify = false;
4169 bool allowZeroTests = false;
4170
4171 int abortAfter = -1;
4172 uint32_t rngSeed = generateRandomSeed(GenerateFrom::Default);
4173
4174 unsigned int shardCount = 1;
4175 unsigned int shardIndex = 0;
4176
4177 bool skipBenchmarks = false;
4178 bool benchmarkNoAnalysis = false;
4179 unsigned int benchmarkSamples = 100;
4180 double benchmarkConfidenceInterval = 0.95;
4181 unsigned int benchmarkResamples = 100000;
4182 std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
4183
4184 Verbosity verbosity = Verbosity::Normal;
4185 WarnAbout::What warnings = WarnAbout::Nothing;
4186 ShowDurations showDurations = ShowDurations::DefaultForReporter;
4187 double minDuration = -1;
4188 TestRunOrder runOrder = TestRunOrder::Declared;
4189 ColourMode defaultColourMode = ColourMode::PlatformDefault;
4190 WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
4191
4192 std::string defaultOutputFilename;
4193 std::string name;
4194 std::string processName;
4195 std::vector<ReporterSpec> reporterSpecifications;
4196
4197 std::vector<std::string> testsOrTags;
4198 std::vector<std::string> sectionsToRun;
4199 };
4200
4201
4202 class Config : public IConfig {
4203 public:
4204
4205 Config() = default;
4206 Config( ConfigData const& data );
4207 ~Config() override; // = default in the cpp file
4208
4209 bool listTests() const;
4210 bool listTags() const;
4211 bool listReporters() const;
4212 bool listListeners() const;
4213
4214 std::vector<ReporterSpec> const& getReporterSpecs() const;
4215 std::vector<ProcessedReporterSpec> const&
4216 getProcessedReporterSpecs() const;
4217
4218 std::vector<std::string> const& getTestsOrTags() const override;
4219 std::vector<std::string> const& getSectionsToRun() const override;
4220
4221 TestSpec const& testSpec() const override;
4222 bool hasTestFilters() const override;
4223
4224 bool showHelp() const;
4225
4226 // IConfig interface
4227 bool allowThrows() const override;
4228 StringRef name() const override;
4229 bool includeSuccessfulResults() const override;
4230 bool warnAboutMissingAssertions() const override;
4231 bool warnAboutUnmatchedTestSpecs() const override;
4232 bool zeroTestsCountAsSuccess() const override;
4233 ShowDurations showDurations() const override;
4234 double minDuration() const override;
4235 TestRunOrder runOrder() const override;
4236 uint32_t rngSeed() const override;
4237 unsigned int shardCount() const override;
4238 unsigned int shardIndex() const override;
4239 ColourMode defaultColourMode() const override;
4240 bool shouldDebugBreak() const override;
4241 int abortAfter() const override;
4242 bool showInvisibles() const override;
4243 Verbosity verbosity() const override;
4244 bool skipBenchmarks() const override;
4245 bool benchmarkNoAnalysis() const override;
4246 unsigned int benchmarkSamples() const override;
4247 double benchmarkConfidenceInterval() const override;
4248 unsigned int benchmarkResamples() const override;
4249 std::chrono::milliseconds benchmarkWarmupTime() const override;
4250
4251 private:
4252 ConfigData m_data;
4253 std::vector<ProcessedReporterSpec> m_processedReporterSpecs;
4254 TestSpec m_testSpec;
4255 bool m_hasTestFilters = false;
4256 };
4257} // end namespace Catch
4258
4259#endif // CATCH_CONFIG_HPP_INCLUDED
4260
4261
4262#ifndef CATCH_MESSAGE_HPP_INCLUDED
4263#define CATCH_MESSAGE_HPP_INCLUDED
4264
4265
4266
4267#ifndef CATCH_STREAM_END_STOP_HPP_INCLUDED
4268#define CATCH_STREAM_END_STOP_HPP_INCLUDED
4269
4270
4271namespace Catch {
4272
4273 // Use this in variadic streaming macros to allow
4274 // << +StreamEndStop
4275 // as well as
4276 // << stuff +StreamEndStop
4277 struct StreamEndStop {
4278 StringRef operator+() const { return StringRef(); }
4279
4280 template <typename T>
4281 friend T const& operator+( T const& value, StreamEndStop ) {
4282 return value;
4283 }
4284 };
4285
4286} // namespace Catch
4287
4288#endif // CATCH_STREAM_END_STOP_HPP_INCLUDED
4289
4290#include <string>
4291#include <vector>
4292
4293namespace Catch {
4294
4295 struct SourceLineInfo;
4296
4298
4299 template<typename T>
4300 MessageStream& operator << ( T const& value ) {
4301 m_stream << value;
4302 return *this;
4303 }
4304
4305 ReusableStringStream m_stream;
4306 };
4307
4309 MessageBuilder( StringRef macroName,
4310 SourceLineInfo const& lineInfo,
4311 ResultWas::OfType type ):
4312 m_info(macroName, lineInfo, type) {}
4313
4314
4315 template<typename T>
4316 MessageBuilder& operator << ( T const& value ) {
4317 m_stream << value;
4318 return *this;
4319 }
4320
4321 MessageInfo m_info;
4322 };
4323
4325 public:
4326 explicit ScopedMessage( MessageBuilder const& builder );
4327 ScopedMessage( ScopedMessage& duplicate ) = delete;
4328 ScopedMessage( ScopedMessage&& old ) noexcept;
4330
4331 MessageInfo m_info;
4332 bool m_moved = false;
4333 };
4334
4335 class Capturer {
4336 std::vector<MessageInfo> m_messages;
4337 IResultCapture& m_resultCapture = getResultCapture();
4338 size_t m_captured = 0;
4339 public:
4340 Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
4341
4342 Capturer(Capturer const&) = delete;
4343 Capturer& operator=(Capturer const&) = delete;
4344
4345 ~Capturer();
4346
4347 void captureValue( size_t index, std::string const& value );
4348
4349 template<typename T>
4350 void captureValues( size_t index, T const& value ) {
4351 captureValue( index, Catch::Detail::stringify( value ) );
4352 }
4353
4354 template<typename T, typename... Ts>
4355 void captureValues( size_t index, T const& value, Ts const&... values ) {
4356 captureValue( index, Catch::Detail::stringify(value) );
4357 captureValues( index+1, values... );
4358 }
4359 };
4360
4361} // end namespace Catch
4362
4364#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
4365 do { \
4366 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
4367 catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
4368 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
4369 } while( false )
4370
4372#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
4373 Catch::Capturer varName( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
4374 varName.captureValues( 0, __VA_ARGS__ )
4375
4377#define INTERNAL_CATCH_INFO( macroName, log ) \
4378 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
4379
4381#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
4382 Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
4383
4384
4385#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
4386
4387 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
4388 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
4389 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
4390 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__ )
4391
4392#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
4393
4394 #define CATCH_INFO( msg ) (void)(0)
4395 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
4396 #define CATCH_WARN( msg ) (void)(0)
4397 #define CATCH_CAPTURE( ... ) (void)(0)
4398
4399#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
4400
4401 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
4402 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
4403 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
4404 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__ )
4405
4406#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
4407
4408 #define INFO( msg ) (void)(0)
4409 #define UNSCOPED_INFO( msg ) (void)(0)
4410 #define WARN( msg ) (void)(0)
4411 #define CAPTURE( ... ) (void)(0)
4412
4413#endif // end of user facing macro declarations
4414
4415
4416
4417
4418#endif // CATCH_MESSAGE_HPP_INCLUDED
4419
4420
4421#ifndef CATCH_SESSION_HPP_INCLUDED
4422#define CATCH_SESSION_HPP_INCLUDED
4423
4424
4425
4426#ifndef CATCH_COMMANDLINE_HPP_INCLUDED
4427#define CATCH_COMMANDLINE_HPP_INCLUDED
4428
4429
4430
4431#ifndef CATCH_CLARA_HPP_INCLUDED
4432#define CATCH_CLARA_HPP_INCLUDED
4433
4434#if defined( __clang__ )
4435# pragma clang diagnostic push
4436# pragma clang diagnostic ignored "-Wweak-vtables"
4437# pragma clang diagnostic ignored "-Wshadow"
4438# pragma clang diagnostic ignored "-Wdeprecated"
4439#endif
4440
4441#if defined( __GNUC__ )
4442# pragma GCC diagnostic push
4443# pragma GCC diagnostic ignored "-Wsign-conversion"
4444#endif
4445
4446#ifndef CLARA_CONFIG_OPTIONAL_TYPE
4447# ifdef __has_include
4448# if __has_include( <optional>) && __cplusplus >= 201703L
4449# include <optional>
4450# define CLARA_CONFIG_OPTIONAL_TYPE std::optional
4451# endif
4452# endif
4453#endif
4454
4455
4456#include <cassert>
4457#include <memory>
4458#include <ostream>
4459#include <sstream>
4460#include <string>
4461#include <type_traits>
4462#include <vector>
4463
4464namespace Catch {
4465 namespace Clara {
4466
4467 class Args;
4468 class Parser;
4469
4470 // enum of result types from a parse
4471 enum class ParseResultType {
4472 Matched,
4473 NoMatch,
4474 ShortCircuitAll,
4475 ShortCircuitSame
4476 };
4477
4478 struct accept_many_t {};
4479 constexpr accept_many_t accept_many {};
4480
4481 namespace Detail {
4482 struct fake_arg {
4483 template <typename T>
4484 operator T();
4485 };
4486
4487 template <typename F, typename = void>
4488 struct is_unary_function : std::false_type {};
4489
4490 template <typename F>
4492 F,
4493 Catch::Detail::void_t<decltype(
4494 std::declval<F>()( fake_arg() ) )
4495 >
4496 > : std::true_type {};
4497
4498 // Traits for extracting arg and return type of lambdas (for single
4499 // argument lambdas)
4500 template <typename L>
4502 : UnaryLambdaTraits<decltype( &L::operator() )> {};
4503
4504 template <typename ClassT, typename ReturnT, typename... Args>
4505 struct UnaryLambdaTraits<ReturnT ( ClassT::* )( Args... ) const> {
4506 static const bool isValid = false;
4507 };
4508
4509 template <typename ClassT, typename ReturnT, typename ArgT>
4510 struct UnaryLambdaTraits<ReturnT ( ClassT::* )( ArgT ) const> {
4511 static const bool isValid = true;
4512 using ArgType = std::remove_const_t<std::remove_reference_t<ArgT>>;
4513 using ReturnType = ReturnT;
4514 };
4515
4516 class TokenStream;
4517
4518 // Wraps a token coming from a token stream. These may not directly
4519 // correspond to strings as a single string may encode an option +
4520 // its argument if the : or = form is used
4521 enum class TokenType { Option, Argument };
4522 struct Token {
4523 TokenType type;
4524 std::string token;
4525 };
4526
4527 // Abstracts iterators into args as a stream of tokens, with option
4528 // arguments uniformly handled
4530 using Iterator = std::vector<std::string>::const_iterator;
4531 Iterator it;
4532 Iterator itEnd;
4533 std::vector<Token> m_tokenBuffer;
4534
4535 void loadBuffer();
4536
4537 public:
4538 explicit TokenStream( Args const& args );
4539 TokenStream( Iterator it, Iterator itEnd );
4540
4541 explicit operator bool() const {
4542 return !m_tokenBuffer.empty() || it != itEnd;
4543 }
4544
4545 size_t count() const {
4546 return m_tokenBuffer.size() + ( itEnd - it );
4547 }
4548
4549 Token operator*() const {
4550 assert( !m_tokenBuffer.empty() );
4551 return m_tokenBuffer.front();
4552 }
4553
4554 Token const* operator->() const {
4555 assert( !m_tokenBuffer.empty() );
4556 return &m_tokenBuffer.front();
4557 }
4558
4559 TokenStream& operator++();
4560 };
4561
4563 enum class ResultType {
4564 Ok,
4565 LogicError,
4568 };
4569
4571 protected:
4572 ResultBase( ResultType type ): m_type( type ) {}
4573 virtual ~ResultBase(); // = default;
4574
4575
4576 ResultBase(ResultBase const&) = default;
4577 ResultBase& operator=(ResultBase const&) = default;
4578 ResultBase(ResultBase&&) = default;
4579 ResultBase& operator=(ResultBase&&) = default;
4580
4581 virtual void enforceOk() const = 0;
4582
4583 ResultType m_type;
4584 };
4585
4586 template <typename T> class ResultValueBase : public ResultBase {
4587 public:
4588 auto value() const -> T const& {
4589 enforceOk();
4590 return m_value;
4591 }
4592
4593 protected:
4594 ResultValueBase( ResultType type ): ResultBase( type ) {}
4595
4596 ResultValueBase( ResultValueBase const& other ):
4597 ResultBase( other ) {
4598 if ( m_type == ResultType::Ok )
4599 new ( &m_value ) T( other.m_value );
4600 }
4601
4602 ResultValueBase( ResultType, T const& value ): ResultBase( ResultType::Ok ) {
4603 new ( &m_value ) T( value );
4604 }
4605
4606 auto operator=( ResultValueBase const& other )
4607 -> ResultValueBase& {
4608 if ( m_type == ResultType::Ok )
4609 m_value.~T();
4610 ResultBase::operator=( other );
4611 if ( m_type == ResultType::Ok )
4612 new ( &m_value ) T( other.m_value );
4613 return *this;
4614 }
4615
4616 ~ResultValueBase() override {
4617 if ( m_type == ResultType::Ok )
4618 m_value.~T();
4619 }
4620
4621 union {
4622 T m_value;
4623 };
4624 };
4625
4626 template <> class ResultValueBase<void> : public ResultBase {
4627 protected:
4628 using ResultBase::ResultBase;
4629 };
4630
4631 template <typename T = void>
4632 class BasicResult : public ResultValueBase<T> {
4633 public:
4634 template <typename U>
4635 explicit BasicResult( BasicResult<U> const& other ):
4636 ResultValueBase<T>( other.type() ),
4637 m_errorMessage( other.errorMessage() ) {
4638 assert( type() != ResultType::Ok );
4639 }
4640
4641 template <typename U>
4642 static auto ok( U const& value ) -> BasicResult {
4643 return { ResultType::Ok, value };
4644 }
4645 static auto ok() -> BasicResult { return { ResultType::Ok }; }
4646 static auto logicError( std::string&& message )
4647 -> BasicResult {
4648 return { ResultType::LogicError, CATCH_MOVE(message) };
4649 }
4650 static auto runtimeError( std::string&& message )
4651 -> BasicResult {
4652 return { ResultType::RuntimeError, CATCH_MOVE(message) };
4653 }
4654
4655 explicit operator bool() const {
4656 return m_type == ResultType::Ok;
4657 }
4658 auto type() const -> ResultType { return m_type; }
4659 auto errorMessage() const -> std::string const& {
4660 return m_errorMessage;
4661 }
4662
4663 protected:
4664 void enforceOk() const override {
4665
4666 // Errors shouldn't reach this point, but if they do
4667 // the actual error message will be in m_errorMessage
4668 assert( m_type != ResultType::LogicError );
4669 assert( m_type != ResultType::RuntimeError );
4670 if ( m_type != ResultType::Ok )
4671 std::abort();
4672 }
4673
4674 std::string
4675 m_errorMessage; // Only populated if resultType is an error
4676
4677 BasicResult( ResultType type,
4678 std::string&& message ):
4679 ResultValueBase<T>( type ), m_errorMessage( CATCH_MOVE(message) ) {
4680 assert( m_type != ResultType::Ok );
4681 }
4682
4683 using ResultValueBase<T>::ResultValueBase;
4684 using ResultBase::m_type;
4685 };
4686
4688 public:
4689 ParseState( ParseResultType type,
4690 TokenStream const& remainingTokens );
4691
4692 ParseResultType type() const { return m_type; }
4693 TokenStream const& remainingTokens() const {
4694 return m_remainingTokens;
4695 }
4696
4697 private:
4698 ParseResultType m_type;
4699 TokenStream m_remainingTokens;
4700 };
4701
4702 using Result = BasicResult<void>;
4705
4707 std::string left;
4708 std::string right;
4709 };
4710
4711 template <typename T>
4712 ParserResult convertInto( std::string const& source, T& target ) {
4713 std::stringstream ss( source );
4714 ss >> target;
4715 if ( ss.fail() ) {
4716 return ParserResult::runtimeError(
4717 "Unable to convert '" + source +
4718 "' to destination type" );
4719 } else {
4720 return ParserResult::ok( ParseResultType::Matched );
4721 }
4722 }
4723 ParserResult convertInto( std::string const& source,
4724 std::string& target );
4725 ParserResult convertInto( std::string const& source, bool& target );
4726
4727#ifdef CLARA_CONFIG_OPTIONAL_TYPE
4728 template <typename T>
4729 auto convertInto( std::string const& source,
4730 CLARA_CONFIG_OPTIONAL_TYPE<T>& target )
4731 -> ParserResult {
4732 T temp;
4733 auto result = convertInto( source, temp );
4734 if ( result )
4735 target = CATCH_MOVE( temp );
4736 return result;
4737 }
4738#endif // CLARA_CONFIG_OPTIONAL_TYPE
4739
4741 virtual ~BoundRef() = default;
4742 virtual bool isContainer() const;
4743 virtual bool isFlag() const;
4744 };
4746 virtual auto setValue( std::string const& arg )
4747 -> ParserResult = 0;
4748 };
4750 virtual auto setFlag( bool flag ) -> ParserResult = 0;
4751 bool isFlag() const override;
4752 };
4753
4754 template <typename T> struct BoundValueRef : BoundValueRefBase {
4755 T& m_ref;
4756
4757 explicit BoundValueRef( T& ref ): m_ref( ref ) {}
4758
4759 ParserResult setValue( std::string const& arg ) override {
4760 return convertInto( arg, m_ref );
4761 }
4762 };
4763
4764 template <typename T>
4765 struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
4766 std::vector<T>& m_ref;
4767
4768 explicit BoundValueRef( std::vector<T>& ref ): m_ref( ref ) {}
4769
4770 auto isContainer() const -> bool override { return true; }
4771
4772 auto setValue( std::string const& arg )
4773 -> ParserResult override {
4774 T temp;
4775 auto result = convertInto( arg, temp );
4776 if ( result )
4777 m_ref.push_back( temp );
4778 return result;
4779 }
4780 };
4781
4783 bool& m_ref;
4784
4785 explicit BoundFlagRef( bool& ref ): m_ref( ref ) {}
4786
4787 ParserResult setFlag( bool flag ) override;
4788 };
4789
4790 template <typename ReturnType> struct LambdaInvoker {
4791 static_assert(
4792 std::is_same<ReturnType, ParserResult>::value,
4793 "Lambda must return void or clara::ParserResult" );
4794
4795 template <typename L, typename ArgType>
4796 static auto invoke( L const& lambda, ArgType const& arg )
4797 -> ParserResult {
4798 return lambda( arg );
4799 }
4800 };
4801
4802 template <> struct LambdaInvoker<void> {
4803 template <typename L, typename ArgType>
4804 static auto invoke( L const& lambda, ArgType const& arg )
4805 -> ParserResult {
4806 lambda( arg );
4807 return ParserResult::ok( ParseResultType::Matched );
4808 }
4809 };
4810
4811 template <typename ArgType, typename L>
4812 auto invokeLambda( L const& lambda, std::string const& arg )
4813 -> ParserResult {
4814 ArgType temp{};
4815 auto result = convertInto( arg, temp );
4816 return !result ? result
4817 : LambdaInvoker<typename UnaryLambdaTraits<
4818 L>::ReturnType>::invoke( lambda, temp );
4819 }
4820
4821 template <typename L> struct BoundLambda : BoundValueRefBase {
4822 L m_lambda;
4823
4824 static_assert(
4826 "Supplied lambda must take exactly one argument" );
4827 explicit BoundLambda( L const& lambda ): m_lambda( lambda ) {}
4828
4829 auto setValue( std::string const& arg )
4830 -> ParserResult override {
4831 return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(
4832 m_lambda, arg );
4833 }
4834 };
4835
4836 template <typename L> struct BoundManyLambda : BoundLambda<L> {
4837 explicit BoundManyLambda( L const& lambda ): BoundLambda<L>( lambda ) {}
4838 bool isContainer() const override { return true; }
4839 };
4840
4841 template <typename L> struct BoundFlagLambda : BoundFlagRefBase {
4842 L m_lambda;
4843
4844 static_assert(
4846 "Supplied lambda must take exactly one argument" );
4847 static_assert(
4848 std::is_same<typename UnaryLambdaTraits<L>::ArgType,
4849 bool>::value,
4850 "flags must be boolean" );
4851
4852 explicit BoundFlagLambda( L const& lambda ):
4853 m_lambda( lambda ) {}
4854
4855 auto setFlag( bool flag ) -> ParserResult override {
4856 return LambdaInvoker<typename UnaryLambdaTraits<
4857 L>::ReturnType>::invoke( m_lambda, flag );
4858 }
4859 };
4860
4861 enum class Optionality { Optional, Required };
4862
4864 public:
4865 virtual ~ParserBase() = default;
4866 virtual auto validate() const -> Result { return Result::ok(); }
4867 virtual auto parse( std::string const& exeName,
4868 TokenStream const& tokens ) const
4869 -> InternalParseResult = 0;
4870 virtual size_t cardinality() const;
4871
4872 InternalParseResult parse( Args const& args ) const;
4873 };
4874
4875 template <typename DerivedT>
4877 public:
4878 template <typename T>
4879 auto operator|( T const& other ) const -> Parser;
4880 };
4881
4882 // Common code and state for Args and Opts
4883 template <typename DerivedT>
4884 class ParserRefImpl : public ComposableParserImpl<DerivedT> {
4885 protected:
4886 Optionality m_optionality = Optionality::Optional;
4887 std::shared_ptr<BoundRef> m_ref;
4888 std::string m_hint;
4889 std::string m_description;
4890
4891 explicit ParserRefImpl( std::shared_ptr<BoundRef> const& ref ):
4892 m_ref( ref ) {}
4893
4894 public:
4895 template <typename LambdaT>
4897 LambdaT const& ref,
4898 std::string const& hint ):
4899 m_ref( std::make_shared<BoundManyLambda<LambdaT>>( ref ) ),
4900 m_hint( hint ) {}
4901
4902 template <typename T,
4903 typename = typename std::enable_if_t<
4905 ParserRefImpl( T& ref, std::string const& hint ):
4906 m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
4907 m_hint( hint ) {}
4908
4909 template <typename LambdaT,
4910 typename = typename std::enable_if_t<
4912 ParserRefImpl( LambdaT const& ref, std::string const& hint ):
4913 m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
4914 m_hint( hint ) {}
4915
4916 auto operator()( std::string const& description ) -> DerivedT& {
4917 m_description = description;
4918 return static_cast<DerivedT&>( *this );
4919 }
4920
4921 auto optional() -> DerivedT& {
4922 m_optionality = Optionality::Optional;
4923 return static_cast<DerivedT&>( *this );
4924 }
4925
4926 auto required() -> DerivedT& {
4927 m_optionality = Optionality::Required;
4928 return static_cast<DerivedT&>( *this );
4929 }
4930
4931 auto isOptional() const -> bool {
4932 return m_optionality == Optionality::Optional;
4933 }
4934
4935 auto cardinality() const -> size_t override {
4936 if ( m_ref->isContainer() )
4937 return 0;
4938 else
4939 return 1;
4940 }
4941
4942 std::string const& hint() const { return m_hint; }
4943 };
4944
4945 } // namespace detail
4946
4947
4948 // A parser for arguments
4949 class Arg : public Detail::ParserRefImpl<Arg> {
4950 public:
4951 using ParserRefImpl::ParserRefImpl;
4952 using ParserBase::parse;
4953
4955 parse(std::string const&,
4956 Detail::TokenStream const& tokens) const override;
4957 };
4958
4959 // A parser for options
4960 class Opt : public Detail::ParserRefImpl<Opt> {
4961 protected:
4962 std::vector<std::string> m_optNames;
4963
4964 public:
4965 template <typename LambdaT>
4966 explicit Opt(LambdaT const& ref) :
4967 ParserRefImpl(
4968 std::make_shared<Detail::BoundFlagLambda<LambdaT>>(ref)) {}
4969
4970 explicit Opt(bool& ref);
4971
4972 template <typename LambdaT,
4973 typename = typename std::enable_if_t<
4975 Opt( LambdaT const& ref, std::string const& hint ):
4976 ParserRefImpl( ref, hint ) {}
4977
4978 template <typename LambdaT>
4979 Opt( accept_many_t, LambdaT const& ref, std::string const& hint ):
4980 ParserRefImpl( accept_many, ref, hint ) {}
4981
4982 template <typename T,
4983 typename = typename std::enable_if_t<
4985 Opt( T& ref, std::string const& hint ):
4986 ParserRefImpl( ref, hint ) {}
4987
4988 auto operator[](std::string const& optName) -> Opt& {
4989 m_optNames.push_back(optName);
4990 return *this;
4991 }
4992
4993 std::vector<Detail::HelpColumns> getHelpColumns() const;
4994
4995 bool isMatch(std::string const& optToken) const;
4996
4997 using ParserBase::parse;
4998
5000 parse(std::string const&,
5001 Detail::TokenStream const& tokens) const override;
5002
5003 Detail::Result validate() const override;
5004 };
5005
5006 // Specifies the name of the executable
5007 class ExeName : public Detail::ComposableParserImpl<ExeName> {
5008 std::shared_ptr<std::string> m_name;
5009 std::shared_ptr<Detail::BoundValueRefBase> m_ref;
5010
5011 public:
5012 ExeName();
5013 explicit ExeName(std::string& ref);
5014
5015 template <typename LambdaT>
5016 explicit ExeName(LambdaT const& lambda) : ExeName() {
5017 m_ref = std::make_shared<Detail::BoundLambda<LambdaT>>(lambda);
5018 }
5019
5020 // The exe name is not parsed out of the normal tokens, but is
5021 // handled specially
5023 parse(std::string const&,
5024 Detail::TokenStream const& tokens) const override;
5025
5026 std::string const& name() const { return *m_name; }
5027 Detail::ParserResult set(std::string const& newName);
5028 };
5029
5030
5031 // A Combined parser
5033 mutable ExeName m_exeName;
5034 std::vector<Opt> m_options;
5035 std::vector<Arg> m_args;
5036
5037 public:
5038
5039 auto operator|=(ExeName const& exeName) -> Parser& {
5040 m_exeName = exeName;
5041 return *this;
5042 }
5043
5044 auto operator|=(Arg const& arg) -> Parser& {
5045 m_args.push_back(arg);
5046 return *this;
5047 }
5048
5049 auto operator|=(Opt const& opt) -> Parser& {
5050 m_options.push_back(opt);
5051 return *this;
5052 }
5053
5054 Parser& operator|=(Parser const& other);
5055
5056 template <typename T>
5057 auto operator|(T const& other) const -> Parser {
5058 return Parser(*this) |= other;
5059 }
5060
5061 std::vector<Detail::HelpColumns> getHelpColumns() const;
5062
5063 void writeToStream(std::ostream& os) const;
5064
5065 friend auto operator<<(std::ostream& os, Parser const& parser)
5066 -> std::ostream& {
5067 parser.writeToStream(os);
5068 return os;
5069 }
5070
5071 Detail::Result validate() const override;
5072
5073 using ParserBase::parse;
5075 parse(std::string const& exeName,
5076 Detail::TokenStream const& tokens) const override;
5077 };
5078
5079 // Transport for raw args (copied from main args, or supplied via
5080 // init list for testing)
5081 class Args {
5082 friend Detail::TokenStream;
5083 std::string m_exeName;
5084 std::vector<std::string> m_args;
5085
5086 public:
5087 Args(int argc, char const* const* argv);
5088 Args(std::initializer_list<std::string> args);
5089
5090 std::string const& exeName() const { return m_exeName; }
5091 };
5092
5093
5094 // Convenience wrapper for option parser that specifies the help option
5095 struct Help : Opt {
5096 Help(bool& showHelpFlag);
5097 };
5098
5099 // Result type for parser operation
5101
5102 namespace Detail {
5103 template <typename DerivedT>
5104 template <typename T>
5105 Parser
5106 ComposableParserImpl<DerivedT>::operator|(T const& other) const {
5107 return Parser() | static_cast<DerivedT const&>(*this) | other;
5108 }
5109 }
5110
5111 } // namespace Clara
5112} // namespace Catch
5113
5114#if defined( __clang__ )
5115# pragma clang diagnostic pop
5116#endif
5117
5118#if defined( __GNUC__ )
5119# pragma GCC diagnostic pop
5120#endif
5121
5122#endif // CATCH_CLARA_HPP_INCLUDED
5123
5124namespace Catch {
5125
5126 struct ConfigData;
5127
5128 Clara::Parser makeCommandLineParser( ConfigData& config );
5129
5130} // end namespace Catch
5131
5132#endif // CATCH_COMMANDLINE_HPP_INCLUDED
5133
5134namespace Catch {
5135
5137 public:
5138
5139 Session();
5140 ~Session();
5141
5142 void showHelp() const;
5143 void libIdentify();
5144
5145 int applyCommandLine( int argc, char const * const * argv );
5146 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
5147 int applyCommandLine( int argc, wchar_t const * const * argv );
5148 #endif
5149
5150 void useConfigData( ConfigData const& configData );
5151
5152 template<typename CharT>
5153 int run(int argc, CharT const * const argv[]) {
5154 if (m_startupExceptions)
5155 return 1;
5156 int returnCode = applyCommandLine(argc, argv);
5157 if (returnCode == 0)
5158 returnCode = run();
5159 return returnCode;
5160 }
5161
5162 int run();
5163
5164 Clara::Parser const& cli() const;
5165 void cli( Clara::Parser const& newParser );
5166 ConfigData& configData();
5167 Config& config();
5168 private:
5169 int runInternal();
5170
5171 Clara::Parser m_cli;
5172 ConfigData m_configData;
5173 Detail::unique_ptr<Config> m_config;
5174 bool m_startupExceptions = false;
5175 };
5176
5177} // end namespace Catch
5178
5179#endif // CATCH_SESSION_HPP_INCLUDED
5180
5181
5182#ifndef CATCH_TAG_ALIAS_HPP_INCLUDED
5183#define CATCH_TAG_ALIAS_HPP_INCLUDED
5184
5185
5186#include <string>
5187
5188namespace Catch {
5189
5190 struct TagAlias {
5191 TagAlias(std::string const& _tag, SourceLineInfo _lineInfo):
5192 tag(_tag),
5193 lineInfo(_lineInfo)
5194 {}
5195
5196 std::string tag;
5197 SourceLineInfo lineInfo;
5198 };
5199
5200} // end namespace Catch
5201
5202#endif // CATCH_TAG_ALIAS_HPP_INCLUDED
5203
5204
5205#ifndef CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
5206#define CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
5207
5208
5209namespace Catch {
5210
5212 RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
5213 };
5214
5215} // end namespace Catch
5216
5217#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
5218 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5219 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5220 namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
5221 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5222
5223#endif // CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
5224
5225
5226#ifndef CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
5227#define CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
5228
5229// We need this suppression to leak, because it took until GCC 10
5230// for the front end to handle local suppression via _Pragma properly
5231// inside templates (so `TEMPLATE_TEST_CASE` and co).
5232// **THIS IS DIFFERENT FOR STANDARD TESTS, WHERE GCC 9 IS SUFFICIENT**
5233#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 10
5234#pragma GCC diagnostic ignored "-Wparentheses"
5235#endif
5236
5237
5238
5239
5240#ifndef CATCH_TEST_MACROS_HPP_INCLUDED
5241#define CATCH_TEST_MACROS_HPP_INCLUDED
5242
5243
5244
5245#ifndef CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5246#define CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5247
5248
5249
5250#ifndef CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5251#define CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5252
5253
5254
5255#ifndef CATCH_DECOMPOSER_HPP_INCLUDED
5256#define CATCH_DECOMPOSER_HPP_INCLUDED
5257
5258
5259#include <iosfwd>
5260
5261#ifdef _MSC_VER
5262#pragma warning(push)
5263#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
5264#pragma warning(disable:4018) // more "signed/unsigned mismatch"
5265#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
5266#pragma warning(disable:4180) // qualifier applied to function type has no meaning
5267#pragma warning(disable:4800) // Forcing result to true or false
5268#endif
5269
5270#ifdef __clang__
5271# pragma clang diagnostic push
5272# pragma clang diagnostic ignored "-Wsign-compare"
5273#elif defined __GNUC__
5274# pragma GCC diagnostic push
5275# pragma GCC diagnostic ignored "-Wsign-compare"
5276#endif
5277
5278namespace Catch {
5279
5281 bool m_isBinaryExpression;
5282 bool m_result;
5283
5284 public:
5285 auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
5286 auto getResult() const -> bool { return m_result; }
5287 virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
5288
5289 ITransientExpression( bool isBinaryExpression, bool result )
5290 : m_isBinaryExpression( isBinaryExpression ),
5291 m_result( result )
5292 {}
5293
5294 ITransientExpression() = default;
5296 ITransientExpression& operator=(ITransientExpression const&) = default;
5297
5298 // We don't actually need a virtual destructor, but many static analysers
5299 // complain if it's not here :-(
5300 virtual ~ITransientExpression(); // = default;
5301
5302 friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
5303 expr.streamReconstructedExpression(out);
5304 return out;
5305 }
5306 };
5307
5308 void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
5309
5310 template<typename LhsT, typename RhsT>
5312 LhsT m_lhs;
5313 StringRef m_op;
5314 RhsT m_rhs;
5315
5316 void streamReconstructedExpression( std::ostream &os ) const override {
5317 formatReconstructedExpression
5318 ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
5319 }
5320
5321 public:
5322 BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
5323 : ITransientExpression{ true, comparisonResult },
5324 m_lhs( lhs ),
5325 m_op( op ),
5326 m_rhs( rhs )
5327 {}
5328
5329 template<typename T>
5330 auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5331 static_assert(always_false<T>::value,
5332 "chained comparisons are not supported inside assertions, "
5333 "wrap the expression inside parentheses, or decompose it");
5334 }
5335
5336 template<typename T>
5337 auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5338 static_assert(always_false<T>::value,
5339 "chained comparisons are not supported inside assertions, "
5340 "wrap the expression inside parentheses, or decompose it");
5341 }
5342
5343 template<typename T>
5344 auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5345 static_assert(always_false<T>::value,
5346 "chained comparisons are not supported inside assertions, "
5347 "wrap the expression inside parentheses, or decompose it");
5348 }
5349
5350 template<typename T>
5351 auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5352 static_assert(always_false<T>::value,
5353 "chained comparisons are not supported inside assertions, "
5354 "wrap the expression inside parentheses, or decompose it");
5355 }
5356
5357 template<typename T>
5358 auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5359 static_assert(always_false<T>::value,
5360 "chained comparisons are not supported inside assertions, "
5361 "wrap the expression inside parentheses, or decompose it");
5362 }
5363
5364 template<typename T>
5365 auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5366 static_assert(always_false<T>::value,
5367 "chained comparisons are not supported inside assertions, "
5368 "wrap the expression inside parentheses, or decompose it");
5369 }
5370
5371 template<typename T>
5372 auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5373 static_assert(always_false<T>::value,
5374 "chained comparisons are not supported inside assertions, "
5375 "wrap the expression inside parentheses, or decompose it");
5376 }
5377
5378 template<typename T>
5379 auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5380 static_assert(always_false<T>::value,
5381 "chained comparisons are not supported inside assertions, "
5382 "wrap the expression inside parentheses, or decompose it");
5383 }
5384 };
5385
5386 template<typename LhsT>
5388 LhsT m_lhs;
5389
5390 void streamReconstructedExpression( std::ostream &os ) const override {
5391 os << Catch::Detail::stringify( m_lhs );
5392 }
5393
5394 public:
5395 explicit UnaryExpr( LhsT lhs )
5396 : ITransientExpression{ false, static_cast<bool>(lhs) },
5397 m_lhs( lhs )
5398 {}
5399 };
5400
5401
5402 // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
5403 template<typename LhsT, typename RhsT>
5404 auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
5405 template<typename T>
5406 auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
5407 template<typename T>
5408 auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
5409 template<typename T>
5410 auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
5411 template<typename T>
5412 auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
5413
5414 template<typename LhsT, typename RhsT>
5415 auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
5416 template<typename T>
5417 auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
5418 template<typename T>
5419 auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
5420 template<typename T>
5421 auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
5422 template<typename T>
5423 auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
5424
5425
5426 template<typename LhsT>
5427 class ExprLhs {
5428 LhsT m_lhs;
5429 public:
5430 explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
5431
5432 template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0>
5433 friend auto operator == ( ExprLhs && lhs, RhsT && rhs ) -> BinaryExpr<LhsT, RhsT const&> {
5434 return { compareEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "=="_sr, rhs };
5435 }
5436 template<typename RhsT, std::enable_if_t<std::is_arithmetic<RhsT>::value, int> = 0>
5437 friend auto operator == ( ExprLhs && lhs, RhsT rhs ) -> BinaryExpr<LhsT, RhsT> {
5438 return { compareEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "=="_sr, rhs };
5439 }
5440
5441 template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0>
5442 friend auto operator != ( ExprLhs && lhs, RhsT && rhs ) -> BinaryExpr<LhsT, RhsT const&> {
5443 return { compareNotEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "!="_sr, rhs };
5444 }
5445 template<typename RhsT, std::enable_if_t<std::is_arithmetic<RhsT>::value, int> = 0>
5446 friend auto operator != ( ExprLhs && lhs, RhsT rhs ) -> BinaryExpr<LhsT, RhsT> {
5447 return { compareNotEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "!="_sr, rhs };
5448 }
5449
5450 #define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(op) \
5451 template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0> \
5452 friend auto operator op ( ExprLhs && lhs, RhsT && rhs ) -> BinaryExpr<LhsT, RhsT const&> { \
5453 return { static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs }; \
5454 } \
5455 template<typename RhsT, std::enable_if_t<std::is_arithmetic<RhsT>::value, int> = 0> \
5456 friend auto operator op ( ExprLhs && lhs, RhsT rhs ) -> BinaryExpr<LhsT, RhsT> { \
5457 return { static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs }; \
5458 }
5459
5460 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(<)
5461 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(>)
5462 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(<=)
5463 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(>=)
5464 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(|)
5465 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(&)
5466 CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(^)
5467
5468 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR
5469
5470 template<typename RhsT>
5471 friend auto operator && ( ExprLhs &&, RhsT && ) -> BinaryExpr<LhsT, RhsT const&> {
5472 static_assert(always_false<RhsT>::value,
5473 "operator&& is not supported inside assertions, "
5474 "wrap the expression inside parentheses, or decompose it");
5475 }
5476
5477 template<typename RhsT>
5478 friend auto operator || ( ExprLhs &&, RhsT && ) -> BinaryExpr<LhsT, RhsT const&> {
5479 static_assert(always_false<RhsT>::value,
5480 "operator|| is not supported inside assertions, "
5481 "wrap the expression inside parentheses, or decompose it");
5482 }
5483
5484 auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
5485 return UnaryExpr<LhsT>{ m_lhs };
5486 }
5487 };
5488
5489 struct Decomposer {
5490 template<typename T, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<T>>::value, int> = 0>
5491 friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
5492 return ExprLhs<const T&>{ lhs };
5493 }
5494
5495 template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
5496 friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
5497 return ExprLhs<T>{ value };
5498 }
5499 };
5500
5501} // end namespace Catch
5502
5503#ifdef _MSC_VER
5504#pragma warning(pop)
5505#endif
5506#ifdef __clang__
5507# pragma clang diagnostic pop
5508#elif defined __GNUC__
5509# pragma GCC diagnostic pop
5510#endif
5511
5512#endif // CATCH_DECOMPOSER_HPP_INCLUDED
5513
5514#include <string>
5515
5516namespace Catch {
5517
5518 class IResultCapture;
5519
5521 bool shouldDebugBreak = false;
5522 bool shouldThrow = false;
5523 };
5524
5526 AssertionInfo m_assertionInfo;
5527 AssertionReaction m_reaction;
5528 bool m_completed = false;
5529 IResultCapture& m_resultCapture;
5530
5531 public:
5533 ( StringRef macroName,
5534 SourceLineInfo const& lineInfo,
5535 StringRef capturedExpression,
5536 ResultDisposition::Flags resultDisposition );
5538 if ( !m_completed ) {
5539 m_resultCapture.handleIncomplete( m_assertionInfo );
5540 }
5541 }
5542
5543
5544 template<typename T>
5545 void handleExpr( ExprLhs<T> const& expr ) {
5546 handleExpr( expr.makeUnaryExpr() );
5547 }
5548 void handleExpr( ITransientExpression const& expr );
5549
5550 void handleMessage(ResultWas::OfType resultType, StringRef message);
5551
5552 void handleExceptionThrownAsExpected();
5553 void handleUnexpectedExceptionNotThrown();
5554 void handleExceptionNotThrownAsExpected();
5555 void handleThrowingCallSkipped();
5556 void handleUnexpectedInflightException();
5557
5558 void complete();
5559 void setCompleted();
5560
5561 // query
5562 auto allowThrows() const -> bool;
5563 };
5564
5565 void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
5566
5567} // namespace Catch
5568
5569#endif // CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5570
5571// We need this suppression to leak, because it took until GCC 9
5572// for the front end to handle local suppression via _Pragma properly
5573#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 9
5574 #pragma GCC diagnostic ignored "-Wparentheses"
5575#endif
5576
5577#if !defined(CATCH_CONFIG_DISABLE)
5578
5579#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
5580 #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
5581#else
5582 #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
5583#endif
5584
5585#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
5586
5588// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
5589// macros.
5590#define INTERNAL_CATCH_TRY
5591#define INTERNAL_CATCH_CATCH( capturer )
5592
5593#else // CATCH_CONFIG_FAST_COMPILE
5594
5595#define INTERNAL_CATCH_TRY try
5596#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
5597
5598#endif
5599
5600#define INTERNAL_CATCH_REACT( handler ) handler.complete();
5601
5603#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
5604 do { /* NOLINT(bugprone-infinite-loop) */ \
5605 /* The expression should not be evaluated, but warnings should hopefully be checked */ \
5606 CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
5607 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
5608 INTERNAL_CATCH_TRY { \
5609 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5610 CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
5611 catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
5612 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5613 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
5614 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
5615 } while( (void)0, (false) && static_cast<const bool&>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
5616 // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
5617
5619#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
5620 INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
5621 if( Catch::getResultCapture().lastAssertionPassed() )
5622
5624#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
5625 INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
5626 if( !Catch::getResultCapture().lastAssertionPassed() )
5627
5629#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
5630 do { \
5631 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
5632 try { \
5633 static_cast<void>(__VA_ARGS__); \
5634 catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
5635 } \
5636 catch( ... ) { \
5637 catchAssertionHandler.handleUnexpectedInflightException(); \
5638 } \
5639 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
5640 } while( false )
5641
5643#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
5644 do { \
5645 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
5646 if( catchAssertionHandler.allowThrows() ) \
5647 try { \
5648 static_cast<void>(__VA_ARGS__); \
5649 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5650 } \
5651 catch( ... ) { \
5652 catchAssertionHandler.handleExceptionThrownAsExpected(); \
5653 } \
5654 else \
5655 catchAssertionHandler.handleThrowingCallSkipped(); \
5656 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
5657 } while( false )
5658
5660#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
5661 do { \
5662 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
5663 if( catchAssertionHandler.allowThrows() ) \
5664 try { \
5665 static_cast<void>(expr); \
5666 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5667 } \
5668 catch( exceptionType const& ) { \
5669 catchAssertionHandler.handleExceptionThrownAsExpected(); \
5670 } \
5671 catch( ... ) { \
5672 catchAssertionHandler.handleUnexpectedInflightException(); \
5673 } \
5674 else \
5675 catchAssertionHandler.handleThrowingCallSkipped(); \
5676 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
5677 } while( false )
5678
5679
5680
5682// Although this is matcher-based, it can be used with just a string
5683#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
5684 do { \
5685 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
5686 if( catchAssertionHandler.allowThrows() ) \
5687 try { \
5688 static_cast<void>(__VA_ARGS__); \
5689 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5690 } \
5691 catch( ... ) { \
5692 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
5693 } \
5694 else \
5695 catchAssertionHandler.handleThrowingCallSkipped(); \
5696 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
5697 } while( false )
5698
5699#endif // CATCH_CONFIG_DISABLE
5700
5701#endif // CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5702
5703
5704#ifndef CATCH_SECTION_HPP_INCLUDED
5705#define CATCH_SECTION_HPP_INCLUDED
5706
5707
5708
5709#ifndef CATCH_TIMER_HPP_INCLUDED
5710#define CATCH_TIMER_HPP_INCLUDED
5711
5712#include <cstdint>
5713
5714namespace Catch {
5715
5716 class Timer {
5717 uint64_t m_nanoseconds = 0;
5718 public:
5719 void start();
5720 auto getElapsedNanoseconds() const -> uint64_t;
5721 auto getElapsedMicroseconds() const -> uint64_t;
5722 auto getElapsedMilliseconds() const -> unsigned int;
5723 auto getElapsedSeconds() const -> double;
5724 };
5725
5726} // namespace Catch
5727
5728#endif // CATCH_TIMER_HPP_INCLUDED
5729
5730namespace Catch {
5731
5733 public:
5734 Section( SectionInfo&& info );
5735 ~Section();
5736
5737 // This indicates whether the section should be executed or not
5738 explicit operator bool() const;
5739
5740 private:
5741 SectionInfo m_info;
5742
5743 Counts m_assertions;
5744 bool m_sectionIncluded;
5745 Timer m_timer;
5746 };
5747
5748} // end namespace Catch
5749
5750#define INTERNAL_CATCH_SECTION( ... ) \
5751 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5752 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5753 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
5754 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5755
5756#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
5757 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5758 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5759 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
5760 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5761
5762#endif // CATCH_SECTION_HPP_INCLUDED
5763
5764
5765#ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
5766#define CATCH_TEST_REGISTRY_HPP_INCLUDED
5767
5768
5769
5770#ifndef CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
5771#define CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
5772
5773#include <vector>
5774
5775namespace Catch {
5776
5777 class TestSpec;
5778 struct TestCaseInfo;
5779
5780 class ITestInvoker {
5781 public:
5782 virtual void invoke () const = 0;
5783 virtual ~ITestInvoker(); // = default
5784 };
5785
5786 class TestCaseHandle;
5787 class IConfig;
5788
5789 class ITestCaseRegistry {
5790 public:
5791 virtual ~ITestCaseRegistry(); // = default
5792 // TODO: this exists only for adding filenames to test cases -- let's expose this in a saner way later
5793 virtual std::vector<TestCaseInfo* > const& getAllInfos() const = 0;
5794 virtual std::vector<TestCaseHandle> const& getAllTests() const = 0;
5795 virtual std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const = 0;
5796 };
5797
5798 bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
5799 bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config );
5800 std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
5801 std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );
5802
5803}
5804
5805#endif // CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
5806
5807
5808#ifndef CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5809#define CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5810
5811#define INTERNAL_CATCH_EXPAND1( param ) INTERNAL_CATCH_EXPAND2( param )
5812#define INTERNAL_CATCH_EXPAND2( ... ) INTERNAL_CATCH_NO##__VA_ARGS__
5813#define INTERNAL_CATCH_DEF( ... ) INTERNAL_CATCH_DEF __VA_ARGS__
5814#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
5815
5816#define INTERNAL_CATCH_REMOVE_PARENS( ... ) \
5817 INTERNAL_CATCH_EXPAND1( INTERNAL_CATCH_DEF __VA_ARGS__ )
5818
5819#endif // CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5820
5821// GCC 5 and older do not properly handle disabling unused-variable warning
5822// with a _Pragma. This means that we have to leak the suppression to the
5823// user code as well :-(
5824#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
5825#pragma GCC diagnostic ignored "-Wunused-variable"
5826#endif
5827
5828
5829
5830namespace Catch {
5831
5832template<typename C>
5833class TestInvokerAsMethod : public ITestInvoker {
5834 void (C::*m_testAsMethod)();
5835public:
5836 TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
5837
5838 void invoke() const override {
5839 C obj;
5840 (obj.*m_testAsMethod)();
5841 }
5842};
5843
5844Detail::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() );
5845
5846template<typename C>
5847Detail::unique_ptr<ITestInvoker> makeTestInvoker( void (C::*testAsMethod)() ) {
5848 return Detail::make_unique<TestInvokerAsMethod<C>>( testAsMethod );
5849}
5850
5852 constexpr NameAndTags( StringRef name_ = StringRef(),
5853 StringRef tags_ = StringRef() ) noexcept:
5854 name( name_ ), tags( tags_ ) {}
5855 StringRef name;
5856 StringRef tags;
5857};
5858
5860 AutoReg( Detail::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept;
5861};
5862
5863} // end namespace Catch
5864
5865#if defined(CATCH_CONFIG_DISABLE)
5866 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
5867 static inline void TestName()
5868 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
5869 namespace{ \
5870 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
5871 void test(); \
5872 }; \
5873 } \
5874 void TestName::test()
5875#endif
5876
5878 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
5879 static void TestName(); \
5880 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5881 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5882 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
5883 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5884 static void TestName()
5885 #define INTERNAL_CATCH_TESTCASE( ... ) \
5886 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
5887
5889 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
5890 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5891 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5892 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
5893 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5894
5896 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
5897 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5898 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5899 namespace{ \
5900 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
5901 void test(); \
5902 }; \
5903 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
5904 } \
5905 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5906 void TestName::test()
5907 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
5908 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
5909
5911 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
5912 do { \
5913 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5914 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5915 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
5916 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5917 } while(false)
5918
5919
5920#endif // CATCH_TEST_REGISTRY_HPP_INCLUDED
5921
5922
5923// All of our user-facing macros support configuration toggle, that
5924// forces them to be defined prefixed with CATCH_. We also like to
5925// support another toggle that can minimize (disable) their implementation.
5926// Given this, we have 4 different configuration options below
5927
5928#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
5929
5930 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
5931 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
5932
5933 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
5934 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
5935 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
5936
5937 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
5938 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
5939 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
5940 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
5941 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
5942
5943 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
5944 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
5945 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
5946
5947 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
5948 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
5949 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
5950 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
5951 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
5952 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
5953 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
5954 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
5955 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
5956
5957
5958 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
5959 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
5960 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
5961 #define CATCH_STATIC_CHECK( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
5962 #define CATCH_STATIC_CHECK_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
5963 #else
5964 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
5965 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
5966 #define CATCH_STATIC_CHECK( ... ) CATCH_CHECK( __VA_ARGS__ )
5967 #define CATCH_STATIC_CHECK_FALSE( ... ) CATCH_CHECK_FALSE( __VA_ARGS__ )
5968 #endif
5969
5970
5971 // "BDD-style" convenience wrappers
5972 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
5973 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
5974 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
5975 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
5976 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
5977 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
5978 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
5979 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
5980
5981#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) // ^^ prefixed, implemented | vv prefixed, disabled
5982
5983 #define CATCH_REQUIRE( ... ) (void)(0)
5984 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
5985
5986 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
5987 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
5988 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
5989
5990 #define CATCH_CHECK( ... ) (void)(0)
5991 #define CATCH_CHECK_FALSE( ... ) (void)(0)
5992 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
5993 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
5994 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
5995
5996 #define CATCH_CHECK_THROWS( ... ) (void)(0)
5997 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
5998 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
5999
6000 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6001 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6002 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
6003 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
6004 #define CATCH_SECTION( ... )
6005 #define CATCH_DYNAMIC_SECTION( ... )
6006 #define CATCH_FAIL( ... ) (void)(0)
6007 #define CATCH_FAIL_CHECK( ... ) (void)(0)
6008 #define CATCH_SUCCEED( ... ) (void)(0)
6009
6010 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
6011 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
6012 #define CATCH_STATIC_CHECK( ... ) (void)(0)
6013 #define CATCH_STATIC_CHECK_FALSE( ... ) (void)(0)
6014
6015 // "BDD-style" convenience wrappers
6016 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6017 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), className )
6018 #define CATCH_GIVEN( desc )
6019 #define CATCH_AND_GIVEN( desc )
6020 #define CATCH_WHEN( desc )
6021 #define CATCH_AND_WHEN( desc )
6022 #define CATCH_THEN( desc )
6023 #define CATCH_AND_THEN( desc )
6024
6025#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE) // ^^ prefixed, disabled | vv unprefixed, implemented
6026
6027 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6028 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
6029
6030 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6031 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
6032 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6033
6034 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6035 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
6036 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6037 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6038 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6039
6040 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6041 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
6042 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6043
6044 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
6045 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
6046 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
6047 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
6048 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
6049 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
6050 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
6051 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6052 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6053
6054
6055 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
6056 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
6057 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
6058 #define STATIC_CHECK( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
6059 #define STATIC_CHECK_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
6060 #else
6061 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
6062 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
6063 #define STATIC_CHECK( ... ) CHECK( __VA_ARGS__ )
6064 #define STATIC_CHECK_FALSE( ... ) CHECK_FALSE( __VA_ARGS__ )
6065 #endif
6066
6067 // "BDD-style" convenience wrappers
6068 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
6069 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
6070 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
6071 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
6072 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
6073 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
6074 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
6075 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
6076
6077#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) // ^^ unprefixed, implemented | vv unprefixed, disabled
6078
6079 #define REQUIRE( ... ) (void)(0)
6080 #define REQUIRE_FALSE( ... ) (void)(0)
6081
6082 #define REQUIRE_THROWS( ... ) (void)(0)
6083 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
6084 #define REQUIRE_NOTHROW( ... ) (void)(0)
6085
6086 #define CHECK( ... ) (void)(0)
6087 #define CHECK_FALSE( ... ) (void)(0)
6088 #define CHECKED_IF( ... ) if (__VA_ARGS__)
6089 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
6090 #define CHECK_NOFAIL( ... ) (void)(0)
6091
6092 #define CHECK_THROWS( ... ) (void)(0)
6093 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
6094 #define CHECK_NOTHROW( ... ) (void)(0)
6095
6096 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__)
6097 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6098 #define METHOD_AS_TEST_CASE( method, ... )
6099 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
6100 #define SECTION( ... )
6101 #define DYNAMIC_SECTION( ... )
6102 #define FAIL( ... ) (void)(0)
6103 #define FAIL_CHECK( ... ) (void)(0)
6104 #define SUCCEED( ... ) (void)(0)
6105
6106 #define STATIC_REQUIRE( ... ) (void)(0)
6107 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
6108 #define STATIC_CHECK( ... ) (void)(0)
6109 #define STATIC_CHECK_FALSE( ... ) (void)(0)
6110
6111 // "BDD-style" convenience wrappers
6112 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ) )
6113 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), className )
6114
6115 #define GIVEN( desc )
6116 #define AND_GIVEN( desc )
6117 #define WHEN( desc )
6118 #define AND_WHEN( desc )
6119 #define THEN( desc )
6120 #define AND_THEN( desc )
6121
6122#endif // ^^ unprefixed, disabled
6123
6124// end of user facing macros
6125
6126#endif // CATCH_TEST_MACROS_HPP_INCLUDED
6127
6128
6129#ifndef CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6130#define CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6131
6132
6133
6134#ifndef CATCH_PREPROCESSOR_HPP_INCLUDED
6135#define CATCH_PREPROCESSOR_HPP_INCLUDED
6136
6137
6138#if defined(__GNUC__)
6139// We need to silence "empty __VA_ARGS__ warning", and using just _Pragma does not work
6140#pragma GCC system_header
6141#endif
6142
6143
6144#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
6145#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
6146#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
6147#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
6148#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
6149#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
6150
6151#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6152#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
6153// MSVC needs more evaluations
6154#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
6155#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
6156#else
6157#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
6158#endif
6159
6160#define CATCH_REC_END(...)
6161#define CATCH_REC_OUT
6162
6163#define CATCH_EMPTY()
6164#define CATCH_DEFER(id) id CATCH_EMPTY()
6165
6166#define CATCH_REC_GET_END2() 0, CATCH_REC_END
6167#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
6168#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
6169#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
6170#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
6171#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
6172
6173#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
6174#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
6175#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
6176
6177#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
6178#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
6179#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
6180
6181// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
6182// and passes userdata as the first parameter to each invocation,
6183// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
6184#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
6185
6186#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
6187
6188#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
6189#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6190#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
6191#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
6192#else
6193// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
6194#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
6195#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
6196#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
6197#endif
6198
6199#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
6200#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
6201
6202#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6203#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
6204#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
6205#else
6206#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
6207#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
6208#endif
6209
6210#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
6211 CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
6212
6213#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
6214#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
6215#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
6216#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
6217#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
6218#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
6219#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
6220#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
6221#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
6222#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
6223#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
6224
6225#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
6226
6227#define INTERNAL_CATCH_TYPE_GEN\
6228 template<typename...> struct TypeList {};\
6229 template<typename...Ts>\
6230 constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
6231 template<template<typename...> class...> struct TemplateTypeList{};\
6232 template<template<typename...> class...Cs>\
6233 constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
6234 template<typename...>\
6235 struct append;\
6236 template<typename...>\
6237 struct rewrap;\
6238 template<template<typename...> class, typename...>\
6239 struct create;\
6240 template<template<typename...> class, typename>\
6241 struct convert;\
6242 \
6243 template<typename T> \
6244 struct append<T> { using type = T; };\
6245 template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
6246 struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
6247 template< template<typename...> class L1, typename...E1, typename...Rest>\
6248 struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
6249 \
6250 template< template<typename...> class Container, template<typename...> class List, typename...elems>\
6251 struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
6252 template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
6253 struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
6254 \
6255 template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
6256 struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
6257 template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
6258 struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
6259
6260#define INTERNAL_CATCH_NTTP_1(signature, ...)\
6261 template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
6262 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6263 constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
6264 template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
6265 template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
6266 constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
6267 \
6268 template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6269 struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
6270 template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
6271 struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
6272 template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
6273 struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
6274
6275#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
6276#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
6277 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6278 static void TestName()
6279#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
6280 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6281 static void TestName()
6282
6283#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
6284#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
6285 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6286 static void TestName()
6287#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
6288 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6289 static void TestName()
6290
6291#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
6292 template<typename Type>\
6293 void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
6294 {\
6295 Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
6296 }
6297
6298#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
6299 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6300 void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
6301 {\
6302 Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
6303 }
6304
6305#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
6306 template<typename Type>\
6307 void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
6308 {\
6309 Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
6310 }
6311
6312#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
6313 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6314 void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
6315 {\
6316 Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
6317 }
6318
6319#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
6320#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
6321 template<typename TestType> \
6322 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
6323 void test();\
6324 }
6325
6326#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
6327 template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6328 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
6329 void test();\
6330 }
6331
6332#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
6333#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
6334 template<typename TestType> \
6335 void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
6336#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
6337 template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6338 void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
6339
6340#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6341#define INTERNAL_CATCH_NTTP_0
6342#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
6343#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
6344#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
6345#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
6346#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
6347#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
6348#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
6349#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
6350#else
6351#define INTERNAL_CATCH_NTTP_0(signature)
6352#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
6353#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
6354#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
6355#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
6356#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
6357#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
6358#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
6359#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
6360#endif
6361
6362#endif // CATCH_PREPROCESSOR_HPP_INCLUDED
6363
6364
6365// GCC 5 and older do not properly handle disabling unused-variable warning
6366// with a _Pragma. This means that we have to leak the suppression to the
6367// user code as well :-(
6368#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
6369#pragma GCC diagnostic ignored "-Wunused-variable"
6370#endif
6371
6372#if defined(CATCH_CONFIG_DISABLE)
6373 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
6374 INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6375 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
6376 namespace{ \
6377 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6378 INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
6379 } \
6380 } \
6381 INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6382
6383 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6384 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
6385 INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, typename TestType, __VA_ARGS__ )
6386 #else
6387 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
6388 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
6389 #endif
6390
6391 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6392 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
6393 INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, Signature, __VA_ARGS__ )
6394 #else
6395 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
6396 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, Signature, __VA_ARGS__ ) )
6397 #endif
6398
6399 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6400 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
6401 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
6402 #else
6403 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
6404 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
6405 #endif
6406
6407 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6408 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
6409 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
6410 #else
6411 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
6412 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
6413 #endif
6414#endif
6415
6416
6418 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
6419 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6420 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6421 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6422 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6423 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6424 INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
6425 namespace {\
6426 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
6427 INTERNAL_CATCH_TYPE_GEN\
6428 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6429 INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6430 template<typename...Types> \
6431 struct TestName{\
6432 TestName(){\
6433 size_t index = 0; \
6434 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
6435 using expander = size_t[];\
6436 (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
6437 }\
6438 };\
6439 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6440 TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
6441 return 0;\
6442 }();\
6443 }\
6444 }\
6445 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6446 INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
6447
6448#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6449 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
6450 INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, typename TestType, __VA_ARGS__ )
6451#else
6452 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
6453 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
6454#endif
6455
6456#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6457 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6458 INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, Signature, __VA_ARGS__ )
6459#else
6460 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6461 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, Signature, __VA_ARGS__ ) )
6462#endif
6463
6464 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
6465 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6466 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6467 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6468 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6469 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6470 template<typename TestType> static void TestFuncName(); \
6471 namespace {\
6472 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6473 INTERNAL_CATCH_TYPE_GEN \
6474 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6475 template<typename... Types> \
6476 struct TestName { \
6477 void reg_tests() { \
6478 size_t index = 0; \
6479 using expander = size_t[]; \
6480 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
6481 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
6482 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
6483 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */\
6484 } \
6485 }; \
6486 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
6487 using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
6488 TestInit t; \
6489 t.reg_tests(); \
6490 return 0; \
6491 }(); \
6492 } \
6493 } \
6494 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6495 template<typename TestType> \
6496 static void TestFuncName()
6497
6498#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6499 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
6500 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, typename T,__VA_ARGS__)
6501#else
6502 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
6503 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, typename T, __VA_ARGS__ ) )
6504#endif
6505
6506#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6507 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
6508 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, Signature, __VA_ARGS__)
6509#else
6510 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
6511 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, Signature, __VA_ARGS__ ) )
6512#endif
6513
6514 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
6515 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6516 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6517 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6518 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6519 template<typename TestType> static void TestFunc(); \
6520 namespace {\
6521 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
6522 INTERNAL_CATCH_TYPE_GEN\
6523 template<typename... Types> \
6524 struct TestName { \
6525 void reg_tests() { \
6526 size_t index = 0; \
6527 using expander = size_t[]; \
6528 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
6529 } \
6530 };\
6531 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
6532 using TestInit = typename convert<TestName, TmplList>::type; \
6533 TestInit t; \
6534 t.reg_tests(); \
6535 return 0; \
6536 }(); \
6537 }}\
6538 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6539 template<typename TestType> \
6540 static void TestFunc()
6541
6542 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
6543 INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), Name, Tags, TmplList )
6544
6545
6546 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
6547 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6548 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6549 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6550 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6551 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6552 namespace {\
6553 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
6554 INTERNAL_CATCH_TYPE_GEN\
6555 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6556 INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
6557 INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6558 template<typename...Types> \
6559 struct TestNameClass{\
6560 TestNameClass(){\
6561 size_t index = 0; \
6562 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
6563 using expander = size_t[];\
6564 (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
6565 }\
6566 };\
6567 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6568 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
6569 return 0;\
6570 }();\
6571 }\
6572 }\
6573 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6574 INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6575
6576#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6577 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
6578 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
6579#else
6580 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
6581 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
6582#endif
6583
6584#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6585 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
6586 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
6587#else
6588 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
6589 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
6590#endif
6591
6592 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
6593 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6594 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6595 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6596 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6597 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6598 template<typename TestType> \
6599 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
6600 void test();\
6601 };\
6602 namespace {\
6603 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
6604 INTERNAL_CATCH_TYPE_GEN \
6605 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6606 template<typename...Types>\
6607 struct TestNameClass{\
6608 void reg_tests(){\
6609 std::size_t index = 0;\
6610 using expander = std::size_t[];\
6611 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
6612 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
6613 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
6614 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */ \
6615 }\
6616 };\
6617 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6618 using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
6619 TestInit t;\
6620 t.reg_tests();\
6621 return 0;\
6622 }(); \
6623 }\
6624 }\
6625 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6626 template<typename TestType> \
6627 void TestName<TestType>::test()
6628
6629#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6630 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
6631 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
6632#else
6633 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
6634 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
6635#endif
6636
6637#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6638 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
6639 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
6640#else
6641 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
6642 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
6643#endif
6644
6645 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
6646 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6647 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6648 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6649 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6650 template<typename TestType> \
6651 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
6652 void test();\
6653 };\
6654 namespace {\
6655 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
6656 INTERNAL_CATCH_TYPE_GEN\
6657 template<typename...Types>\
6658 struct TestNameClass{\
6659 void reg_tests(){\
6660 size_t index = 0;\
6661 using expander = size_t[];\
6662 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
6663 }\
6664 };\
6665 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6666 using TestInit = typename convert<TestNameClass, TmplList>::type;\
6667 TestInit t;\
6668 t.reg_tests();\
6669 return 0;\
6670 }(); \
6671 }}\
6672 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6673 template<typename TestType> \
6674 void TestName<TestType>::test()
6675
6676#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
6677 INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, TmplList )
6678
6679
6680#endif // CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6681
6682
6683#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
6684
6685 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6686 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
6687 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
6688 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6689 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
6690 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
6691 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
6692 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
6693 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
6694 #define CATCH_TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
6695 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
6696 #else
6697 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
6698 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
6699 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6700 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
6701 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
6702 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
6703 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6704 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
6705 #define CATCH_TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
6706 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6707 #endif
6708
6709#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
6710
6711 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6712 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
6713 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
6714 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
6715 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
6716 #else
6717 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
6718 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
6719 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
6720 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
6721 #endif
6722
6723 // When disabled, these can be shared between proper preprocessor and MSVC preprocessor
6724 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
6725 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
6726 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6727 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6728 #define CATCH_TEMPLATE_LIST_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
6729 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6730
6731#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
6732
6733 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6734 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
6735 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
6736 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6737 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
6738 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
6739 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
6740 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
6741 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
6742 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
6743 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
6744 #else
6745 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
6746 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
6747 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6748 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
6749 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
6750 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
6751 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6752 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
6753 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
6754 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6755 #endif
6756
6757#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
6758
6759 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6760 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
6761 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
6762 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
6763 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
6764 #else
6765 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
6766 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
6767 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
6768 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
6769 #endif
6770
6771 // When disabled, these can be shared between proper preprocessor and MSVC preprocessor
6772 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
6773 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
6774 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6775 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6776 #define TEMPLATE_LIST_TEST_CASE( ... ) TEMPLATE_TEST_CASE(__VA_ARGS__)
6777 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6778
6779#endif // end of user facing macro declarations
6780
6781
6782#endif // CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
6783
6784
6785#ifndef CATCH_TEST_CASE_INFO_HPP_INCLUDED
6786#define CATCH_TEST_CASE_INFO_HPP_INCLUDED
6787
6788
6789
6790#include <string>
6791#include <vector>
6792
6793#ifdef __clang__
6794#pragma clang diagnostic push
6795#pragma clang diagnostic ignored "-Wpadded"
6796#endif
6797
6798namespace Catch {
6799
6807 struct Tag {
6808 constexpr Tag(StringRef original_):
6809 original(original_)
6810 {}
6811 StringRef original;
6812
6813 friend bool operator< ( Tag const& lhs, Tag const& rhs );
6814 friend bool operator==( Tag const& lhs, Tag const& rhs );
6815 };
6816
6817 class ITestInvoker;
6818
6819 enum class TestCaseProperties : uint8_t {
6820 None = 0,
6821 IsHidden = 1 << 1,
6822 ShouldFail = 1 << 2,
6823 MayFail = 1 << 3,
6824 Throws = 1 << 4,
6825 NonPortable = 1 << 5,
6826 Benchmark = 1 << 6
6827 };
6828
6839
6840 TestCaseInfo(StringRef _className,
6841 NameAndTags const& _tags,
6842 SourceLineInfo const& _lineInfo);
6843
6844 bool isHidden() const;
6845 bool throws() const;
6846 bool okToFail() const;
6847 bool expectedToFail() const;
6848
6849 // Adds the tag(s) with test's filename (for the -# flag)
6850 void addFilenameTag();
6851
6853 friend bool operator<( TestCaseInfo const& lhs,
6854 TestCaseInfo const& rhs );
6855
6856
6857 std::string tagsAsString() const;
6858
6859 std::string name;
6860 StringRef className;
6861 private:
6862 std::string backingTags;
6863 // Internally we copy tags to the backing storage and then add
6864 // refs to this storage to the tags vector.
6865 void internalAppendTag(StringRef tagString);
6866 public:
6867 std::vector<Tag> tags;
6868 SourceLineInfo lineInfo;
6869 TestCaseProperties properties = TestCaseProperties::None;
6870 };
6871
6879 TestCaseInfo* m_info;
6880 ITestInvoker* m_invoker;
6881 public:
6882 TestCaseHandle(TestCaseInfo* info, ITestInvoker* invoker) :
6883 m_info(info), m_invoker(invoker) {}
6884
6885 void invoke() const {
6886 m_invoker->invoke();
6887 }
6888
6889 TestCaseInfo const& getTestCaseInfo() const;
6890 };
6891
6892 Detail::unique_ptr<TestCaseInfo>
6893 makeTestCaseInfo( StringRef className,
6894 NameAndTags const& nameAndTags,
6895 SourceLineInfo const& lineInfo );
6896}
6897
6898#ifdef __clang__
6899#pragma clang diagnostic pop
6900#endif
6901
6902#endif // CATCH_TEST_CASE_INFO_HPP_INCLUDED
6903
6904
6905#ifndef CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
6906#define CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
6907
6908
6909
6910#ifndef CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
6911#define CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
6912
6913
6914#include <string>
6915#include <vector>
6916
6917namespace Catch {
6918 using exceptionTranslateFunction = std::string(*)();
6919
6920 class IExceptionTranslator;
6921 using ExceptionTranslators = std::vector<Detail::unique_ptr<IExceptionTranslator const>>;
6922
6924 public:
6925 virtual ~IExceptionTranslator(); // = default
6926 virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
6927 };
6928
6930 public:
6931 virtual ~IExceptionTranslatorRegistry(); // = default
6932 virtual std::string translateActiveException() const = 0;
6933 };
6934
6935} // namespace Catch
6936
6937#endif // CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
6938
6939#include <exception>
6940
6941namespace Catch {
6942
6944 template<typename T>
6945 class ExceptionTranslator : public IExceptionTranslator {
6946 public:
6947
6948 ExceptionTranslator( std::string(*translateFunction)( T const& ) )
6949 : m_translateFunction( translateFunction )
6950 {}
6951
6952 std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
6953#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
6954 try {
6955 if( it == itEnd )
6956 std::rethrow_exception(std::current_exception());
6957 else
6958 return (*it)->translate( it+1, itEnd );
6959 }
6960 catch( T const& ex ) {
6961 return m_translateFunction( ex );
6962 }
6963#else
6964 return "You should never get here!";
6965#endif
6966 }
6967
6968 protected:
6969 std::string(*m_translateFunction)( T const& );
6970 };
6971
6972 public:
6973 template<typename T>
6974 ExceptionTranslatorRegistrar( std::string(*translateFunction)( T const& ) ) {
6975 getMutableRegistryHub().registerTranslator(
6976 Detail::make_unique<ExceptionTranslator<T>>(translateFunction)
6977 );
6978 }
6979 };
6980
6981} // namespace Catch
6982
6984#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
6985 static std::string translatorName( signature ); \
6986 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6987 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6988 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
6989 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6990 static std::string translatorName( signature )
6991
6992#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
6993
6994#if defined(CATCH_CONFIG_DISABLE)
6995 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
6996 static std::string translatorName( signature )
6997#endif
6998
6999
7000// This macro is always prefixed
7001#if !defined(CATCH_CONFIG_DISABLE)
7002#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
7003#else
7004#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
7005#endif
7006
7007
7008#endif // CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7009
7010
7011#ifndef CATCH_VERSION_HPP_INCLUDED
7012#define CATCH_VERSION_HPP_INCLUDED
7013
7014#include <iosfwd>
7015
7016namespace Catch {
7017
7018 // Versioning information
7019 struct Version {
7020 Version( Version const& ) = delete;
7021 Version& operator=( Version const& ) = delete;
7022 Version( unsigned int _majorVersion,
7023 unsigned int _minorVersion,
7024 unsigned int _patchNumber,
7025 char const * const _branchName,
7026 unsigned int _buildNumber );
7027
7028 unsigned int const majorVersion;
7029 unsigned int const minorVersion;
7030 unsigned int const patchNumber;
7031
7032 // buildNumber is only used if branchName is not null
7033 char const * const branchName;
7034 unsigned int const buildNumber;
7035
7036 friend std::ostream& operator << ( std::ostream& os, Version const& version );
7037 };
7038
7039 Version const& libraryVersion();
7040}
7041
7042#endif // CATCH_VERSION_HPP_INCLUDED
7043
7044
7045#ifndef CATCH_VERSION_MACROS_HPP_INCLUDED
7046#define CATCH_VERSION_MACROS_HPP_INCLUDED
7047
7048#define CATCH_VERSION_MAJOR 3
7049#define CATCH_VERSION_MINOR 0
7050#define CATCH_VERSION_PATCH 1
7051
7052#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
7053
7054
7068#ifndef CATCH_GENERATORS_ALL_HPP_INCLUDED
7069#define CATCH_GENERATORS_ALL_HPP_INCLUDED
7070
7071
7072
7073#ifndef CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7074#define CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7075
7076#include <exception>
7077
7078namespace Catch {
7079
7080 // Exception type to be thrown when a Generator runs into an error,
7081 // e.g. it cannot initialize the first return value based on
7082 // runtime information
7083 class GeneratorException : public std::exception {
7084 const char* const m_msg = "";
7085
7086 public:
7087 GeneratorException(const char* msg):
7088 m_msg(msg)
7089 {}
7090
7091 const char* what() const noexcept override final;
7092 };
7093
7094} // end namespace Catch
7095
7096#endif // CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7097
7098
7099#ifndef CATCH_GENERATORS_HPP_INCLUDED
7100#define CATCH_GENERATORS_HPP_INCLUDED
7101
7102
7103
7104#ifndef CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7105#define CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7106
7107
7108#include <string>
7109
7110namespace Catch {
7111
7112 namespace Generators {
7114 // Caches result from `toStringImpl`, assume that when it is an
7115 // empty string, the cache is invalidated.
7116 mutable std::string m_stringReprCache;
7117
7118 // Counts based on `next` returning true
7119 std::size_t m_currentElementIndex = 0;
7120
7127 virtual bool next() = 0;
7128
7130 virtual std::string stringifyImpl() const = 0;
7131
7132 public:
7133 GeneratorUntypedBase() = default;
7134 // Generation of copy ops is deprecated (and Clang will complain)
7135 // if there is a user destructor defined
7137 GeneratorUntypedBase& operator=(GeneratorUntypedBase const&) = default;
7138
7139 virtual ~GeneratorUntypedBase(); // = default;
7140
7151 bool countedNext();
7152
7153 std::size_t currentElementIndex() const { return m_currentElementIndex; }
7154
7169 };
7170 using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
7171
7172 } // namespace Generators
7173
7175 public:
7176 virtual ~IGeneratorTracker(); // = default;
7177 virtual auto hasGenerator() const -> bool = 0;
7178 virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
7179 virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
7180 };
7181
7182} // namespace Catch
7183
7184#endif // CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7185
7186#include <vector>
7187#include <tuple>
7188
7189namespace Catch {
7190
7191namespace Generators {
7192
7193namespace Detail {
7194
7196 [[noreturn]]
7197 void throw_generator_exception(char const * msg);
7198
7199} // end namespace detail
7200
7201 template<typename T>
7203 std::string stringifyImpl() const override {
7204 return ::Catch::Detail::stringify( get() );
7205 }
7206
7207 public:
7208 ~IGenerator() override = default;
7209 IGenerator() = default;
7210 IGenerator(IGenerator const&) = default;
7211 IGenerator& operator=(IGenerator const&) = default;
7212
7213
7214 // Returns the current element of the generator
7215 //
7216 // \Precondition The generator is either freshly constructed,
7217 // or the last call to `next()` returned true
7218 virtual T const& get() const = 0;
7219 using type = T;
7220 };
7221
7222 template <typename T>
7223 using GeneratorPtr = Catch::Detail::unique_ptr<IGenerator<T>>;
7224
7225 template <typename T>
7226 class GeneratorWrapper final {
7227 GeneratorPtr<T> m_generator;
7228 public:
7231 m_generator(generator) {}
7232 GeneratorWrapper(GeneratorPtr<T> generator):
7233 m_generator(CATCH_MOVE(generator)) {}
7234
7235 T const& get() const {
7236 return m_generator->get();
7237 }
7238 bool next() {
7239 return m_generator->countedNext();
7240 }
7241 };
7242
7243
7244 template<typename T>
7245 class SingleValueGenerator final : public IGenerator<T> {
7246 T m_value;
7247 public:
7248 SingleValueGenerator(T const& value) :
7249 m_value(value)
7250 {}
7251 SingleValueGenerator(T&& value):
7252 m_value(CATCH_MOVE(value))
7253 {}
7254
7255 T const& get() const override {
7256 return m_value;
7257 }
7258 bool next() override {
7259 return false;
7260 }
7261 };
7262
7263 template<typename T>
7264 class FixedValuesGenerator final : public IGenerator<T> {
7265 static_assert(!std::is_same<T, bool>::value,
7266 "FixedValuesGenerator does not support bools because of std::vector<bool>"
7267 "specialization, use SingleValue Generator instead.");
7268 std::vector<T> m_values;
7269 size_t m_idx = 0;
7270 public:
7271 FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
7272
7273 T const& get() const override {
7274 return m_values[m_idx];
7275 }
7276 bool next() override {
7277 ++m_idx;
7278 return m_idx < m_values.size();
7279 }
7280 };
7281
7282 template <typename T, typename DecayedT = std::decay_t<T>>
7283 GeneratorWrapper<DecayedT> value( T&& value ) {
7284 return GeneratorWrapper<DecayedT>(
7285 Catch::Detail::make_unique<SingleValueGenerator<DecayedT>>(
7286 CATCH_FORWARD( value ) ) );
7287 }
7288 template <typename T>
7289 GeneratorWrapper<T> values(std::initializer_list<T> values) {
7290 return GeneratorWrapper<T>(Catch::Detail::make_unique<FixedValuesGenerator<T>>(values));
7291 }
7292
7293 template<typename T>
7294 class Generators : public IGenerator<T> {
7295 std::vector<GeneratorWrapper<T>> m_generators;
7296 size_t m_current = 0;
7297
7298 void add_generator( GeneratorWrapper<T>&& generator ) {
7299 m_generators.emplace_back( CATCH_MOVE( generator ) );
7300 }
7301 void add_generator( T const& val ) {
7302 m_generators.emplace_back( value( val ) );
7303 }
7304 void add_generator( T&& val ) {
7305 m_generators.emplace_back( value( CATCH_MOVE( val ) ) );
7306 }
7307 template <typename U>
7308 std::enable_if_t<!std::is_same<std::decay_t<U>, T>::value>
7309 add_generator( U&& val ) {
7310 add_generator( T( CATCH_FORWARD( val ) ) );
7311 }
7312
7313 template <typename U> void add_generators( U&& valueOrGenerator ) {
7314 add_generator( CATCH_FORWARD( valueOrGenerator ) );
7315 }
7316
7317 template <typename U, typename... Gs>
7318 void add_generators( U&& valueOrGenerator, Gs&&... moreGenerators ) {
7319 add_generator( CATCH_FORWARD( valueOrGenerator ) );
7320 add_generators( CATCH_FORWARD( moreGenerators )... );
7321 }
7322
7323 public:
7324 template <typename... Gs>
7325 Generators(Gs &&... moreGenerators) {
7326 m_generators.reserve(sizeof...(Gs));
7327 add_generators(CATCH_FORWARD(moreGenerators)...);
7328 }
7329
7330 T const& get() const override {
7331 return m_generators[m_current].get();
7332 }
7333
7334 bool next() override {
7335 if (m_current >= m_generators.size()) {
7336 return false;
7337 }
7338 const bool current_status = m_generators[m_current].next();
7339 if (!current_status) {
7340 ++m_current;
7341 }
7342 return m_current < m_generators.size();
7343 }
7344 };
7345
7346
7347 template <typename... Ts>
7348 GeneratorWrapper<std::tuple<std::decay_t<Ts>...>>
7349 table( std::initializer_list<std::tuple<std::decay_t<Ts>...>> tuples ) {
7350 return values<std::tuple<Ts...>>( tuples );
7351 }
7352
7353 // Tag type to signal that a generator sequence should convert arguments to a specific type
7354 template <typename T>
7355 struct as {};
7356
7357 template<typename T, typename... Gs>
7358 auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
7359 return Generators<T>(CATCH_MOVE(generator), CATCH_FORWARD(moreGenerators)...);
7360 }
7361 template<typename T>
7362 auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
7363 return Generators<T>(CATCH_MOVE(generator));
7364 }
7365 template<typename T, typename... Gs>
7366 auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<std::decay_t<T>> {
7367 return makeGenerators( value( CATCH_FORWARD( val ) ), CATCH_FORWARD( moreGenerators )... );
7368 }
7369 template<typename T, typename U, typename... Gs>
7370 auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
7371 return makeGenerators( value( T( CATCH_FORWARD( val ) ) ), CATCH_FORWARD( moreGenerators )... );
7372 }
7373
7374 auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
7375
7376 template<typename L>
7377 // Note: The type after -> is weird, because VS2015 cannot parse
7378 // the expression used in the typedef inside, when it is in
7379 // return type. Yeah.
7380 auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
7381 using UnderlyingType = typename decltype(generatorExpression())::type;
7382
7383 IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
7384 if (!tracker.hasGenerator()) {
7385 tracker.setGenerator(Catch::Detail::make_unique<Generators<UnderlyingType>>(generatorExpression()));
7386 }
7387
7388 auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
7389 return generator.get();
7390 }
7391
7392} // namespace Generators
7393} // namespace Catch
7394
7395#define GENERATE( ... ) \
7396 Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7397 CATCH_INTERNAL_LINEINFO, \
7398 [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
7399#define GENERATE_COPY( ... ) \
7400 Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7401 CATCH_INTERNAL_LINEINFO, \
7402 [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
7403#define GENERATE_REF( ... ) \
7404 Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7405 CATCH_INTERNAL_LINEINFO, \
7406 [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
7407
7408#endif // CATCH_GENERATORS_HPP_INCLUDED
7409
7410
7411#ifndef CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7412#define CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7413
7414
7415#include <cassert>
7416
7417namespace Catch {
7418namespace Generators {
7419
7420 template <typename T>
7421 class TakeGenerator final : public IGenerator<T> {
7422 GeneratorWrapper<T> m_generator;
7423 size_t m_returned = 0;
7424 size_t m_target;
7425 public:
7426 TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
7427 m_generator(CATCH_MOVE(generator)),
7428 m_target(target)
7429 {
7430 assert(target != 0 && "Empty generators are not allowed");
7431 }
7432 T const& get() const override {
7433 return m_generator.get();
7434 }
7435 bool next() override {
7436 ++m_returned;
7437 if (m_returned >= m_target) {
7438 return false;
7439 }
7440
7441 const auto success = m_generator.next();
7442 // If the underlying generator does not contain enough values
7443 // then we cut short as well
7444 if (!success) {
7445 m_returned = m_target;
7446 }
7447 return success;
7448 }
7449 };
7450
7451 template <typename T>
7452 GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
7453 return GeneratorWrapper<T>(Catch::Detail::make_unique<TakeGenerator<T>>(target, CATCH_MOVE(generator)));
7454 }
7455
7456
7457 template <typename T, typename Predicate>
7458 class FilterGenerator final : public IGenerator<T> {
7459 GeneratorWrapper<T> m_generator;
7460 Predicate m_predicate;
7461 public:
7462 template <typename P = Predicate>
7463 FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
7464 m_generator(CATCH_MOVE(generator)),
7465 m_predicate(CATCH_FORWARD(pred))
7466 {
7467 if (!m_predicate(m_generator.get())) {
7468 // It might happen that there are no values that pass the
7469 // filter. In that case we throw an exception.
7470 auto has_initial_value = next();
7471 if (!has_initial_value) {
7472 Detail::throw_generator_exception("No valid value found in filtered generator");
7473 }
7474 }
7475 }
7476
7477 T const& get() const override {
7478 return m_generator.get();
7479 }
7480
7481 bool next() override {
7482 bool success = m_generator.next();
7483 if (!success) {
7484 return false;
7485 }
7486 while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
7487 return success;
7488 }
7489 };
7490
7491
7492 template <typename T, typename Predicate>
7493 GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
7494 return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, Predicate>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
7495 }
7496
7497 template <typename T>
7498 class RepeatGenerator final : public IGenerator<T> {
7499 static_assert(!std::is_same<T, bool>::value,
7500 "RepeatGenerator currently does not support bools"
7501 "because of std::vector<bool> specialization");
7502 GeneratorWrapper<T> m_generator;
7503 mutable std::vector<T> m_returned;
7504 size_t m_target_repeats;
7505 size_t m_current_repeat = 0;
7506 size_t m_repeat_index = 0;
7507 public:
7508 RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
7509 m_generator(CATCH_MOVE(generator)),
7510 m_target_repeats(repeats)
7511 {
7512 assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
7513 }
7514
7515 T const& get() const override {
7516 if (m_current_repeat == 0) {
7517 m_returned.push_back(m_generator.get());
7518 return m_returned.back();
7519 }
7520 return m_returned[m_repeat_index];
7521 }
7522
7523 bool next() override {
7524 // There are 2 basic cases:
7525 // 1) We are still reading the generator
7526 // 2) We are reading our own cache
7527
7528 // In the first case, we need to poke the underlying generator.
7529 // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
7530 if (m_current_repeat == 0) {
7531 const auto success = m_generator.next();
7532 if (!success) {
7533 ++m_current_repeat;
7534 }
7535 return m_current_repeat < m_target_repeats;
7536 }
7537
7538 // In the second case, we need to move indices forward and check that we haven't run up against the end
7539 ++m_repeat_index;
7540 if (m_repeat_index == m_returned.size()) {
7541 m_repeat_index = 0;
7542 ++m_current_repeat;
7543 }
7544 return m_current_repeat < m_target_repeats;
7545 }
7546 };
7547
7548 template <typename T>
7549 GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
7550 return GeneratorWrapper<T>(Catch::Detail::make_unique<RepeatGenerator<T>>(repeats, CATCH_MOVE(generator)));
7551 }
7552
7553 template <typename T, typename U, typename Func>
7554 class MapGenerator final : public IGenerator<T> {
7555 // TBD: provide static assert for mapping function, for friendly error message
7556 GeneratorWrapper<U> m_generator;
7557 Func m_function;
7558 // To avoid returning dangling reference, we have to save the values
7559 T m_cache;
7560 public:
7561 template <typename F2 = Func>
7562 MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
7563 m_generator(CATCH_MOVE(generator)),
7564 m_function(CATCH_FORWARD(function)),
7565 m_cache(m_function(m_generator.get()))
7566 {}
7567
7568 T const& get() const override {
7569 return m_cache;
7570 }
7571 bool next() override {
7572 const auto success = m_generator.next();
7573 if (success) {
7574 m_cache = m_function(m_generator.get());
7575 }
7576 return success;
7577 }
7578 };
7579
7580 template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
7581 GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
7582 return GeneratorWrapper<T>(
7583 Catch::Detail::make_unique<MapGenerator<T, U, Func>>(CATCH_FORWARD(function), CATCH_MOVE(generator))
7584 );
7585 }
7586
7587 template <typename T, typename U, typename Func>
7588 GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
7589 return GeneratorWrapper<T>(
7590 Catch::Detail::make_unique<MapGenerator<T, U, Func>>(CATCH_FORWARD(function), CATCH_MOVE(generator))
7591 );
7592 }
7593
7594 template <typename T>
7595 class ChunkGenerator final : public IGenerator<std::vector<T>> {
7596 std::vector<T> m_chunk;
7597 size_t m_chunk_size;
7598 GeneratorWrapper<T> m_generator;
7599 bool m_used_up = false;
7600 public:
7601 ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
7602 m_chunk_size(size), m_generator(CATCH_MOVE(generator))
7603 {
7604 m_chunk.reserve(m_chunk_size);
7605 if (m_chunk_size != 0) {
7606 m_chunk.push_back(m_generator.get());
7607 for (size_t i = 1; i < m_chunk_size; ++i) {
7608 if (!m_generator.next()) {
7609 Detail::throw_generator_exception("Not enough values to initialize the first chunk");
7610 }
7611 m_chunk.push_back(m_generator.get());
7612 }
7613 }
7614 }
7615 std::vector<T> const& get() const override {
7616 return m_chunk;
7617 }
7618 bool next() override {
7619 m_chunk.clear();
7620 for (size_t idx = 0; idx < m_chunk_size; ++idx) {
7621 if (!m_generator.next()) {
7622 return false;
7623 }
7624 m_chunk.push_back(m_generator.get());
7625 }
7626 return true;
7627 }
7628 };
7629
7630 template <typename T>
7631 GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
7632 return GeneratorWrapper<std::vector<T>>(
7633 Catch::Detail::make_unique<ChunkGenerator<T>>(size, CATCH_MOVE(generator))
7634 );
7635 }
7636
7637} // namespace Generators
7638} // namespace Catch
7639
7640
7641#endif // CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7642
7643
7644#ifndef CATCH_GENERATORS_RANDOM_HPP_INCLUDED
7645#define CATCH_GENERATORS_RANDOM_HPP_INCLUDED
7646
7647
7648
7649#ifndef CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
7650#define CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
7651
7652#include <cstdint>
7653
7654namespace Catch {
7655
7656 // This is a simple implementation of C++11 Uniform Random Number
7657 // Generator. It does not provide all operators, because Catch2
7658 // does not use it, but it should behave as expected inside stdlib's
7659 // distributions.
7660 // The implementation is based on the PCG family (http://pcg-random.org)
7662 using state_type = std::uint64_t;
7663 public:
7664 using result_type = std::uint32_t;
7665 static constexpr result_type (min)() {
7666 return 0;
7667 }
7668 static constexpr result_type (max)() {
7669 return static_cast<result_type>(-1);
7670 }
7671
7672 // Provide some default initial state for the default constructor
7673 SimplePcg32():SimplePcg32(0xed743cc4U) {}
7674
7675 explicit SimplePcg32(result_type seed_);
7676
7677 void seed(result_type seed_);
7678 void discard(uint64_t skip);
7679
7680 result_type operator()();
7681
7682 private:
7683 friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
7684 friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
7685
7686 // In theory we also need operator<< and operator>>
7687 // In practice we do not use them, so we will skip them for now
7688
7689
7690 std::uint64_t m_state;
7691 // This part of the state determines which "stream" of the numbers
7692 // is chosen -- we take it as a constant for Catch2, so we only
7693 // need to deal with seeding the main state.
7694 // Picked by reading 8 bytes from `/dev/random` :-)
7695 static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
7696 };
7697
7698} // end namespace Catch
7699
7700#endif // CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
7701
7702#include <random>
7703
7704namespace Catch {
7705namespace Generators {
7706namespace Detail {
7707 // Returns a suitable seed for a random floating generator based off
7708 // the primary internal rng. It does so by taking current value from
7709 // the rng and returning it as the seed.
7710 std::uint32_t getSeed();
7711}
7712
7713template <typename Float>
7714class RandomFloatingGenerator final : public IGenerator<Float> {
7715 Catch::SimplePcg32 m_rng;
7716 std::uniform_real_distribution<Float> m_dist;
7717 Float m_current_number;
7718public:
7719 RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ):
7720 m_rng(seed),
7721 m_dist(a, b) {
7722 static_cast<void>(next());
7723 }
7724
7725 Float const& get() const override {
7726 return m_current_number;
7727 }
7728 bool next() override {
7729 m_current_number = m_dist(m_rng);
7730 return true;
7731 }
7732};
7733
7734template <typename Integer>
7735class RandomIntegerGenerator final : public IGenerator<Integer> {
7736 Catch::SimplePcg32 m_rng;
7737 std::uniform_int_distribution<Integer> m_dist;
7738 Integer m_current_number;
7739public:
7740 RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
7741 m_rng(seed),
7742 m_dist(a, b) {
7743 static_cast<void>(next());
7744 }
7745
7746 Integer const& get() const override {
7747 return m_current_number;
7748 }
7749 bool next() override {
7750 m_current_number = m_dist(m_rng);
7751 return true;
7752 }
7753};
7754
7755// TODO: Ideally this would be also constrained against the various char types,
7756// but I don't expect users to run into that in practice.
7757template <typename T>
7758std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::value,
7759GeneratorWrapper<T>>
7760random(T a, T b) {
7761 return GeneratorWrapper<T>(
7762 Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
7763 );
7764}
7765
7766template <typename T>
7767std::enable_if_t<std::is_floating_point<T>::value,
7768GeneratorWrapper<T>>
7769random(T a, T b) {
7770 return GeneratorWrapper<T>(
7771 Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed())
7772 );
7773}
7774
7775
7776} // namespace Generators
7777} // namespace Catch
7778
7779
7780#endif // CATCH_GENERATORS_RANDOM_HPP_INCLUDED
7781
7782
7783#ifndef CATCH_GENERATORS_RANGE_HPP_INCLUDED
7784#define CATCH_GENERATORS_RANGE_HPP_INCLUDED
7785
7786
7787#include <iterator>
7788#include <type_traits>
7789
7790namespace Catch {
7791namespace Generators {
7792
7793
7794template <typename T>
7795class RangeGenerator final : public IGenerator<T> {
7796 T m_current;
7797 T m_end;
7798 T m_step;
7799 bool m_positive;
7800
7801public:
7802 RangeGenerator(T const& start, T const& end, T const& step):
7803 m_current(start),
7804 m_end(end),
7805 m_step(step),
7806 m_positive(m_step > T(0))
7807 {
7808 assert(m_current != m_end && "Range start and end cannot be equal");
7809 assert(m_step != T(0) && "Step size cannot be zero");
7810 assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
7811 }
7812
7813 RangeGenerator(T const& start, T const& end):
7814 RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
7815 {}
7816
7817 T const& get() const override {
7818 return m_current;
7819 }
7820
7821 bool next() override {
7822 m_current += m_step;
7823 return (m_positive) ? (m_current < m_end) : (m_current > m_end);
7824 }
7825};
7826
7827template <typename T>
7828GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
7829 static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
7830 return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end, step));
7831}
7832
7833template <typename T>
7834GeneratorWrapper<T> range(T const& start, T const& end) {
7835 static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
7836 return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end));
7837}
7838
7839
7840template <typename T>
7841class IteratorGenerator final : public IGenerator<T> {
7842 static_assert(!std::is_same<T, bool>::value,
7843 "IteratorGenerator currently does not support bools"
7844 "because of std::vector<bool> specialization");
7845
7846 std::vector<T> m_elems;
7847 size_t m_current = 0;
7848public:
7849 template <typename InputIterator, typename InputSentinel>
7850 IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
7851 if (m_elems.empty()) {
7852 Detail::throw_generator_exception("IteratorGenerator received no valid values");
7853 }
7854 }
7855
7856 T const& get() const override {
7857 return m_elems[m_current];
7858 }
7859
7860 bool next() override {
7861 ++m_current;
7862 return m_current != m_elems.size();
7863 }
7864};
7865
7866template <typename InputIterator,
7867 typename InputSentinel,
7868 typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
7869GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
7870 return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(from, to));
7871}
7872
7873template <typename Container,
7874 typename ResultType = typename Container::value_type>
7875GeneratorWrapper<ResultType> from_range(Container const& cnt) {
7876 return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
7877}
7878
7879
7880} // namespace Generators
7881} // namespace Catch
7882
7883
7884#endif // CATCH_GENERATORS_RANGE_HPP_INCLUDED
7885
7886#endif // CATCH_GENERATORS_ALL_HPP_INCLUDED
7887
7888
7903#ifndef CATCH_INTERFACES_ALL_HPP_INCLUDED
7904#define CATCH_INTERFACES_ALL_HPP_INCLUDED
7905
7906
7907
7908#ifndef CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
7909#define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
7910
7911
7912#include <string>
7913
7914namespace Catch {
7915
7916 struct ReporterConfig;
7917 class IConfig;
7918 class IEventListener;
7919 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
7920
7921
7923 public:
7924 virtual ~IReporterFactory(); // = default
7925
7926 virtual IEventListenerPtr
7927 create( ReporterConfig&& config ) const = 0;
7928 virtual std::string getDescription() const = 0;
7929 };
7930 using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
7931
7933 public:
7934 virtual ~EventListenerFactory(); // = default
7935 virtual IEventListenerPtr create( IConfig const* config ) const = 0;
7937 virtual StringRef getName() const = 0;
7939 virtual std::string getDescription() const = 0;
7940 };
7941} // namespace Catch
7942
7943#endif // CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
7944
7945
7946#ifndef CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED
7947#define CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED
7948
7949
7950
7951#ifndef CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
7952#define CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
7953
7954
7955namespace Catch {
7956 namespace Detail {
7959 bool operator()( StringRef lhs,
7960 StringRef rhs ) const;
7961 };
7962
7965 bool operator()( StringRef lhs,
7966 StringRef rhs ) const;
7967 };
7968
7969 } // namespace Detail
7970} // namespace Catch
7971
7972#endif // CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
7973
7974#include <string>
7975#include <vector>
7976#include <map>
7977
7978namespace Catch {
7979
7980 class IConfig;
7981
7982 class IEventListener;
7983 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
7984 class IReporterFactory;
7985 using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
7986 struct ReporterConfig;
7987 class EventListenerFactory;
7988
7990 public:
7991 using FactoryMap = std::map<std::string, IReporterFactoryPtr, Detail::CaseInsensitiveLess>;
7992 using Listeners = std::vector<Detail::unique_ptr<EventListenerFactory>>;
7993
7994 virtual ~IReporterRegistry(); // = default
7995 virtual IEventListenerPtr create( std::string const& name, ReporterConfig&& config ) const = 0;
7996 virtual FactoryMap const& getFactories() const = 0;
7997 virtual Listeners const& getListeners() const = 0;
7998 };
7999
8000} // end namespace Catch
8001
8002#endif // CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED
8003
8004
8005#ifndef CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8006#define CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8007
8008#include <string>
8009
8010namespace Catch {
8011
8012 struct TagAlias;
8013
8015 public:
8016 virtual ~ITagAliasRegistry(); // = default
8017 // Nullptr if not present
8018 virtual TagAlias const* find( std::string const& alias ) const = 0;
8019 virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
8020
8021 static ITagAliasRegistry const& get();
8022 };
8023
8024} // end namespace Catch
8025
8026#endif // CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8027
8028#endif // CATCH_INTERFACES_ALL_HPP_INCLUDED
8029
8030
8031
8040#ifndef CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
8041#define CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
8042
8043
8044#if defined(__ANDROID__)
8045# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
8046#endif
8047
8048
8049#if defined( CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE ) && \
8050 !defined( CATCH_CONFIG_NO_ANDROID_LOGWRITE ) && \
8051 !defined( CATCH_CONFIG_ANDROID_LOGWRITE )
8052# define CATCH_CONFIG_ANDROID_LOGWRITE
8053#endif
8054
8055#endif // CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
8056
8057
8058
8067#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
8068#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
8069
8070#if defined(_MSC_VER)
8071# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
8072# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
8073# endif
8074#endif
8075
8076
8077#include <exception>
8078
8079#if defined(__cpp_lib_uncaught_exceptions) \
8080 && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
8081
8082# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
8083#endif // __cpp_lib_uncaught_exceptions
8084
8085
8086#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
8087 && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
8088 && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
8089
8090# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
8091#endif
8092
8093
8094#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
8095
8096
8097#ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
8098#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
8099
8100#ifndef CATCH_CONFIG_CONSOLE_WIDTH
8101#define CATCH_CONFIG_CONSOLE_WIDTH 80
8102#endif
8103
8104#endif // CATCH_CONSOLE_WIDTH_HPP_INCLUDED
8105
8106
8107#ifndef CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
8108#define CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
8109
8110
8111#include <cstddef>
8112#include <initializer_list>
8113
8114// We want a simple polyfill over `std::empty`, `std::size` and so on
8115// for C++14 or C++ libraries with incomplete support.
8116// We also have to handle that MSVC std lib will happily provide these
8117// under older standards.
8118#if defined(CATCH_CPP17_OR_GREATER) || defined(_MSC_VER)
8119
8120// We are already using this header either way, so there shouldn't
8121// be much additional overhead in including it to get the feature
8122// test macros
8123#include <string>
8124
8125# if !defined(__cpp_lib_nonmember_container_access)
8126# define CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
8127# endif
8128
8129#else
8130#define CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
8131#endif
8132
8133
8134
8135namespace Catch {
8136namespace Detail {
8137
8138#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
8139 template <typename Container>
8140 constexpr auto empty(Container const& cont) -> decltype(cont.empty()) {
8141 return cont.empty();
8142 }
8143 template <typename T, std::size_t N>
8144 constexpr bool empty(const T (&)[N]) noexcept {
8145 // GCC < 7 does not support the const T(&)[] parameter syntax
8146 // so we have to ignore the length explicitly
8147 (void)N;
8148 return false;
8149 }
8150 template <typename T>
8151 constexpr bool empty(std::initializer_list<T> list) noexcept {
8152 return list.size() > 0;
8153 }
8154
8155
8156 template <typename Container>
8157 constexpr auto size(Container const& cont) -> decltype(cont.size()) {
8158 return cont.size();
8159 }
8160 template <typename T, std::size_t N>
8161 constexpr std::size_t size(const T(&)[N]) noexcept {
8162 return N;
8163 }
8164#endif // CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
8165
8166} // end namespace Detail
8167} // end namespace Catch
8168
8169
8170
8171#endif // CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
8172
8173
8174#ifndef CATCH_DEBUG_CONSOLE_HPP_INCLUDED
8175#define CATCH_DEBUG_CONSOLE_HPP_INCLUDED
8176
8177#include <string>
8178
8179namespace Catch {
8180 void writeToDebugConsole( std::string const& text );
8181}
8182
8183#endif // CATCH_DEBUG_CONSOLE_HPP_INCLUDED
8184
8185
8186#ifndef CATCH_DEBUGGER_HPP_INCLUDED
8187#define CATCH_DEBUGGER_HPP_INCLUDED
8188
8189
8190namespace Catch {
8191 bool isDebuggerActive();
8192}
8193
8194#ifdef CATCH_PLATFORM_MAC
8195
8196 #if defined(__i386__) || defined(__x86_64__)
8197 #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
8198 #elif defined(__aarch64__)
8199 #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
8200 #endif
8201
8202#elif defined(CATCH_PLATFORM_IPHONE)
8203
8204 // use inline assembler
8205 #if defined(__i386__) || defined(__x86_64__)
8206 #define CATCH_TRAP() __asm__("int $3")
8207 #elif defined(__aarch64__)
8208 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
8209 #elif defined(__arm__) && !defined(__thumb__)
8210 #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
8211 #elif defined(__arm__) && defined(__thumb__)
8212 #define CATCH_TRAP() __asm__(".inst 0xde01")
8213 #endif
8214
8215#elif defined(CATCH_PLATFORM_LINUX)
8216 // If we can use inline assembler, do it because this allows us to break
8217 // directly at the location of the failing check instead of breaking inside
8218 // raise() called from it, i.e. one stack frame below.
8219 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
8220 #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
8221 #else // Fall back to the generic way.
8222 #include <signal.h>
8223
8224 #define CATCH_TRAP() raise(SIGTRAP)
8225 #endif
8226#elif defined(_MSC_VER)
8227 #define CATCH_TRAP() __debugbreak()
8228#elif defined(__MINGW32__)
8229 extern "C" __declspec(dllimport) void __stdcall DebugBreak();
8230 #define CATCH_TRAP() DebugBreak()
8231#endif
8232
8233#ifndef CATCH_BREAK_INTO_DEBUGGER
8234 #ifdef CATCH_TRAP
8235 #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
8236 #else
8237 #define CATCH_BREAK_INTO_DEBUGGER() []{}()
8238 #endif
8239#endif
8240
8241#endif // CATCH_DEBUGGER_HPP_INCLUDED
8242
8243
8244#ifndef CATCH_ENFORCE_HPP_INCLUDED
8245#define CATCH_ENFORCE_HPP_INCLUDED
8246
8247
8248#include <exception>
8249
8250namespace Catch {
8251#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8252 template <typename Ex>
8253 [[noreturn]]
8254 void throw_exception(Ex const& e) {
8255 throw e;
8256 }
8257#else // ^^ Exceptions are enabled // Exceptions are disabled vv
8258 [[noreturn]]
8259 void throw_exception(std::exception const& e);
8260#endif
8261
8262 [[noreturn]]
8263 void throw_logic_error(std::string const& msg);
8264 [[noreturn]]
8265 void throw_domain_error(std::string const& msg);
8266 [[noreturn]]
8267 void throw_runtime_error(std::string const& msg);
8268
8269} // namespace Catch;
8270
8271#define CATCH_MAKE_MSG(...) \
8272 (Catch::ReusableStringStream() << __VA_ARGS__).str()
8273
8274#define CATCH_INTERNAL_ERROR(...) \
8275 Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
8276
8277#define CATCH_ERROR(...) \
8278 Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
8279
8280#define CATCH_RUNTIME_ERROR(...) \
8281 Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
8282
8283#define CATCH_ENFORCE( condition, ... ) \
8284 do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
8285
8286
8287#endif // CATCH_ENFORCE_HPP_INCLUDED
8288
8289
8290#ifndef CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
8291#define CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
8292
8293
8294#include <vector>
8295
8296namespace Catch {
8297
8298 namespace Detail {
8299
8300 Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
8301
8303
8304 std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
8305
8306 EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
8307 };
8308
8309 std::vector<StringRef> parseEnums( StringRef enums );
8310
8311 } // Detail
8312
8313} // Catch
8314
8315#endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
8316
8317
8318#ifndef CATCH_ERRNO_GUARD_HPP_INCLUDED
8319#define CATCH_ERRNO_GUARD_HPP_INCLUDED
8320
8321namespace Catch {
8322
8325 class ErrnoGuard {
8326 public:
8327 // Keep these outlined to avoid dragging in macros from <cerrno>
8328
8329 ErrnoGuard();
8330 ~ErrnoGuard();
8331 private:
8332 int m_oldErrno;
8333 };
8334
8335}
8336
8337#endif // CATCH_ERRNO_GUARD_HPP_INCLUDED
8338
8339
8340#ifndef CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
8341#define CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
8342
8343
8344#include <vector>
8345#include <string>
8346
8347namespace Catch {
8348
8349 class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
8350 public:
8351 ~ExceptionTranslatorRegistry() override;
8352 void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator );
8353 std::string translateActiveException() const override;
8354 std::string tryTranslators() const;
8355
8356 private:
8357 ExceptionTranslators m_translators;
8358 };
8359}
8360
8361#endif // CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
8362
8363
8364#ifndef CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
8365#define CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
8366
8367
8368#include <cassert>
8369
8370namespace Catch {
8371
8382 class FatalConditionHandler {
8383 bool m_started = false;
8384
8385 // Install/disengage implementation for specific platform.
8386 // Should be if-defed to work on current platform, can assume
8387 // engage-disengage 1:1 pairing.
8388 void engage_platform();
8389 void disengage_platform() noexcept;
8390 public:
8391 // Should also have platform-specific implementations as needed
8392 FatalConditionHandler();
8393 ~FatalConditionHandler();
8394
8395 void engage() {
8396 assert(!m_started && "Handler cannot be installed twice.");
8397 m_started = true;
8398 engage_platform();
8399 }
8400
8401 void disengage() noexcept {
8402 assert(m_started && "Handler cannot be uninstalled without being installed first");
8403 m_started = false;
8404 disengage_platform();
8405 }
8406 };
8407
8409 class FatalConditionHandlerGuard {
8410 FatalConditionHandler* m_handler;
8411 public:
8412 FatalConditionHandlerGuard(FatalConditionHandler* handler):
8413 m_handler(handler) {
8414 m_handler->engage();
8415 }
8416 ~FatalConditionHandlerGuard() {
8417 m_handler->disengage();
8418 }
8419 };
8420
8421} // end namespace Catch
8422
8423#endif // CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
8424
8425
8426#ifndef CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
8427#define CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
8428
8429
8430
8431#ifndef CATCH_POLYFILLS_HPP_INCLUDED
8432#define CATCH_POLYFILLS_HPP_INCLUDED
8433
8434namespace Catch {
8435 bool isnan(float f);
8436 bool isnan(double d);
8437}
8438
8439#endif // CATCH_POLYFILLS_HPP_INCLUDED
8440
8441#include <cassert>
8442#include <cmath>
8443#include <cstdint>
8444#include <utility>
8445#include <limits>
8446
8447namespace Catch {
8448 namespace Detail {
8449
8450 uint32_t convertToBits(float f);
8451 uint64_t convertToBits(double d);
8452
8453 } // end namespace Detail
8454
8455
8456
8457#if defined( __GNUC__ ) || defined( __clang__ )
8458# pragma GCC diagnostic push
8459 // We do a bunch of direct compensations of floating point numbers,
8460 // because we know what we are doing and actually do want the direct
8461 // comparison behaviour.
8462# pragma GCC diagnostic ignored "-Wfloat-equal"
8463#endif
8464
8482 template <typename FP>
8483 uint64_t ulpDistance( FP lhs, FP rhs ) {
8484 assert( std::numeric_limits<FP>::is_iec559 &&
8485 "ulpDistance assumes IEEE-754 format for floating point types" );
8486 assert( !Catch::isnan( lhs ) &&
8487 "Distance between NaN and number is not meaningful" );
8488 assert( !Catch::isnan( rhs ) &&
8489 "Distance between NaN and number is not meaningful" );
8490
8491 // We want X == Y to imply 0 ULP distance even if X and Y aren't
8492 // bit-equal (-0 and 0), or X - Y != 0 (same sign infinities).
8493 if ( lhs == rhs ) { return 0; }
8494
8495 // We need a properly typed positive zero for type inference.
8496 static constexpr FP positive_zero{};
8497
8498 // We want to ensure that +/- 0 is always represented as positive zero
8499 if ( lhs == positive_zero ) { lhs = positive_zero; }
8500 if ( rhs == positive_zero ) { rhs = positive_zero; }
8501
8502 // If arguments have different signs, we can handle them by summing
8503 // how far are they from 0 each.
8504 if ( std::signbit( lhs ) != std::signbit( rhs ) ) {
8505 return ulpDistance( std::abs( lhs ), positive_zero ) +
8506 ulpDistance( std::abs( rhs ), positive_zero );
8507 }
8508
8509 // When both lhs and rhs are of the same sign, we can just
8510 // read the numbers bitwise as integers, and then subtract them
8511 // (assuming IEEE).
8512 uint64_t lc = Detail::convertToBits( lhs );
8513 uint64_t rc = Detail::convertToBits( rhs );
8514
8515 // The ulp distance between two numbers is symmetric, so to avoid
8516 // dealing with overflows we want the bigger converted number on the lhs
8517 if ( lc < rc ) {
8518 std::swap( lc, rc );
8519 }
8520
8521 return lc - rc;
8522 }
8523
8524#if defined( __GNUC__ ) || defined( __clang__ )
8525# pragma GCC diagnostic pop
8526#endif
8527
8528
8529} // end namespace Catch
8530
8531#endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
8532
8533
8534#ifndef CATCH_ISTREAM_HPP_INCLUDED
8535#define CATCH_ISTREAM_HPP_INCLUDED
8536
8537
8538#include <iosfwd>
8539#include <cstddef>
8540#include <ostream>
8541#include <string>
8542
8543namespace Catch {
8544
8545 class IStream {
8546 public:
8547 virtual ~IStream(); // = default
8548 virtual std::ostream& stream() = 0;
8560 virtual bool isConsole() const { return false; }
8561 };
8562
8574 auto makeStream( std::string const& filename ) -> Detail::unique_ptr<IStream>;
8575
8576}
8577
8578#endif // CATCH_STREAM_HPP_INCLUDED
8579
8580
8581#ifndef CATCH_LEAK_DETECTOR_HPP_INCLUDED
8582#define CATCH_LEAK_DETECTOR_HPP_INCLUDED
8583
8584namespace Catch {
8585
8587 LeakDetector();
8588 ~LeakDetector();
8589 };
8590
8591}
8592#endif // CATCH_LEAK_DETECTOR_HPP_INCLUDED
8593
8594
8595#ifndef CATCH_LIST_HPP_INCLUDED
8596#define CATCH_LIST_HPP_INCLUDED
8597
8598
8599#include <set>
8600#include <string>
8601
8602
8603namespace Catch {
8604
8605 class IEventListener;
8606 class Config;
8607
8608
8610 std::string name, description;
8611 };
8613 StringRef name;
8614 std::string description;
8615 };
8616
8617 struct TagInfo {
8618 void add(StringRef spelling);
8619 std::string all() const;
8620
8621 std::set<StringRef> spellings;
8622 std::size_t count = 0;
8623 };
8624
8625 bool list( IEventListener& reporter, Config const& config );
8626
8627} // end namespace Catch
8628
8629#endif // CATCH_LIST_HPP_INCLUDED
8630
8631
8632#ifndef CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
8633#define CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
8634
8635
8636#include <cstdio>
8637#include <iosfwd>
8638#include <string>
8639
8640namespace Catch {
8641
8643 std::ostream& m_originalStream;
8644 std::ostream& m_redirectionStream;
8645 std::streambuf* m_prevBuf;
8646
8647 public:
8648 RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
8650 };
8651
8653 ReusableStringStream m_rss;
8654 RedirectedStream m_cout;
8655 public:
8657 auto str() const -> std::string;
8658 };
8659
8660 // StdErr has two constituent streams in C++, std::cerr and std::clog
8661 // This means that we need to redirect 2 streams into 1 to keep proper
8662 // order of writes
8664 ReusableStringStream m_rss;
8665 RedirectedStream m_cerr;
8666 RedirectedStream m_clog;
8667 public:
8669 auto str() const -> std::string;
8670 };
8671
8673 public:
8674 RedirectedStreams(RedirectedStreams const&) = delete;
8675 RedirectedStreams& operator=(RedirectedStreams const&) = delete;
8677 RedirectedStreams& operator=(RedirectedStreams&&) = delete;
8678
8679 RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
8681 private:
8682 std::string& m_redirectedCout;
8683 std::string& m_redirectedCerr;
8684 RedirectedStdOut m_redirectedStdOut;
8685 RedirectedStdErr m_redirectedStdErr;
8686 };
8687
8688#if defined(CATCH_CONFIG_NEW_CAPTURE)
8689
8690 // Windows's implementation of std::tmpfile is terrible (it tries
8691 // to create a file inside system folder, thus requiring elevated
8692 // privileges for the binary), so we have to use tmpnam(_s) and
8693 // create the file ourselves there.
8694 class TempFile {
8695 public:
8696 TempFile(TempFile const&) = delete;
8697 TempFile& operator=(TempFile const&) = delete;
8698 TempFile(TempFile&&) = delete;
8699 TempFile& operator=(TempFile&&) = delete;
8700
8701 TempFile();
8702 ~TempFile();
8703
8704 std::FILE* getFile();
8705 std::string getContents();
8706
8707 private:
8708 std::FILE* m_file = nullptr;
8709 #if defined(_MSC_VER)
8710 char m_buffer[L_tmpnam] = { 0 };
8711 #endif
8712 };
8713
8714
8715 class OutputRedirect {
8716 public:
8717 OutputRedirect(OutputRedirect const&) = delete;
8718 OutputRedirect& operator=(OutputRedirect const&) = delete;
8719 OutputRedirect(OutputRedirect&&) = delete;
8720 OutputRedirect& operator=(OutputRedirect&&) = delete;
8721
8722
8723 OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
8724 ~OutputRedirect();
8725
8726 private:
8727 int m_originalStdout = -1;
8728 int m_originalStderr = -1;
8729 TempFile m_stdoutFile;
8730 TempFile m_stderrFile;
8731 std::string& m_stdoutDest;
8732 std::string& m_stderrDest;
8733 };
8734
8735#endif
8736
8737} // end namespace Catch
8738
8739#endif // CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
8740
8741
8742#ifndef CATCH_REPORTER_REGISTRY_HPP_INCLUDED
8743#define CATCH_REPORTER_REGISTRY_HPP_INCLUDED
8744
8745
8746#include <map>
8747
8748namespace Catch {
8749
8750 class ReporterRegistry : public IReporterRegistry {
8751 public:
8752
8753 ReporterRegistry();
8754 ~ReporterRegistry() override; // = default, out of line to allow fwd decl
8755
8756 IEventListenerPtr create( std::string const& name, ReporterConfig&& config ) const override;
8757
8758 void registerReporter( std::string const& name, IReporterFactoryPtr factory );
8759 void registerListener( Detail::unique_ptr<EventListenerFactory> factory );
8760
8761 FactoryMap const& getFactories() const override;
8762 Listeners const& getListeners() const override;
8763
8764 private:
8765 FactoryMap m_factories;
8766 Listeners m_listeners;
8767 };
8768}
8769
8770#endif // CATCH_REPORTER_REGISTRY_HPP_INCLUDED
8771
8772
8773#ifndef CATCH_RUN_CONTEXT_HPP_INCLUDED
8774#define CATCH_RUN_CONTEXT_HPP_INCLUDED
8775
8776
8777
8778#ifndef CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
8779#define CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
8780
8781
8782#include <string>
8783#include <vector>
8784
8785namespace Catch {
8786namespace TestCaseTracking {
8787
8788 struct NameAndLocation {
8789 std::string name;
8790 SourceLineInfo location;
8791
8792 NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
8793 friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
8794 return lhs.name == rhs.name
8795 && lhs.location == rhs.location;
8796 }
8797 };
8798
8799 class ITracker;
8800
8801 using ITrackerPtr = Catch::Detail::unique_ptr<ITracker>;
8802
8803 class ITracker {
8804 NameAndLocation m_nameAndLocation;
8805
8806 using Children = std::vector<ITrackerPtr>;
8807
8808 protected:
8809 enum CycleState {
8810 NotStarted,
8811 Executing,
8812 ExecutingChildren,
8813 NeedsAnotherRun,
8814 CompletedSuccessfully,
8815 Failed
8816 };
8817
8818 ITracker* m_parent = nullptr;
8819 Children m_children;
8820 CycleState m_runState = NotStarted;
8821
8822 public:
8823 ITracker( NameAndLocation const& nameAndLoc, ITracker* parent ):
8824 m_nameAndLocation( nameAndLoc ),
8825 m_parent( parent )
8826 {}
8827
8828
8829 // static queries
8830 NameAndLocation const& nameAndLocation() const {
8831 return m_nameAndLocation;
8832 }
8833 ITracker* parent() const {
8834 return m_parent;
8835 }
8836
8837 virtual ~ITracker(); // = default
8838
8839
8840 // dynamic queries
8841
8843 virtual bool isComplete() const = 0;
8845 bool isSuccessfullyCompleted() const;
8847 bool isOpen() const;
8849 bool hasStarted() const;
8850
8851 // actions
8852 virtual void close() = 0; // Successfully complete
8853 virtual void fail() = 0;
8854 void markAsNeedingAnotherRun();
8855
8857 void addChild( ITrackerPtr&& child );
8863 ITracker* findChild( NameAndLocation const& nameAndLocation );
8865 bool hasChildren() const {
8866 return !m_children.empty();
8867 }
8868
8869
8871 void openChild();
8872
8879 virtual bool isSectionTracker() const;
8886 virtual bool isGeneratorTracker() const;
8887 };
8888
8889 class TrackerContext {
8890
8891 enum RunState {
8892 NotStarted,
8893 Executing,
8894 CompletedCycle
8895 };
8896
8897 ITrackerPtr m_rootTracker;
8898 ITracker* m_currentTracker = nullptr;
8899 RunState m_runState = NotStarted;
8900
8901 public:
8902
8903 ITracker& startRun();
8904 void endRun();
8905
8906 void startCycle();
8907 void completeCycle();
8908
8909 bool completedCycle() const;
8910 ITracker& currentTracker();
8911 void setCurrentTracker( ITracker* tracker );
8912 };
8913
8914 class TrackerBase : public ITracker {
8915 protected:
8916
8917 TrackerContext& m_ctx;
8918
8919 public:
8920 TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
8921
8922 bool isComplete() const override;
8923
8924 void open();
8925
8926 void close() override;
8927 void fail() override;
8928
8929 private:
8930 void moveToParent();
8931 void moveToThis();
8932 };
8933
8934 class SectionTracker : public TrackerBase {
8935 std::vector<StringRef> m_filters;
8936 std::string m_trimmed_name;
8937 public:
8938 SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
8939
8940 bool isSectionTracker() const override;
8941
8942 bool isComplete() const override;
8943
8944 static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
8945
8946 void tryOpen();
8947
8948 void addInitialFilters( std::vector<std::string> const& filters );
8949 void addNextFilters( std::vector<StringRef> const& filters );
8951 std::vector<StringRef> const& getFilters() const;
8953 StringRef trimmedName() const;
8954 };
8955
8956} // namespace TestCaseTracking
8957
8958using TestCaseTracking::ITracker;
8959using TestCaseTracking::TrackerContext;
8960using TestCaseTracking::SectionTracker;
8961
8962} // namespace Catch
8963
8964#endif // CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
8965
8966#include <string>
8967
8968namespace Catch {
8969
8970 class IMutableContext;
8971 class IGeneratorTracker;
8972 class IConfig;
8973
8975
8977
8978 public:
8979 RunContext( RunContext const& ) = delete;
8980 RunContext& operator =( RunContext const& ) = delete;
8981
8982 explicit RunContext( IConfig const* _config, IEventListenerPtr&& reporter );
8983
8984 ~RunContext() override;
8985
8986 Totals runTest(TestCaseHandle const& testCase);
8987
8988 public: // IResultCapture
8989
8990 // Assertion handlers
8991 void handleExpr
8992 ( AssertionInfo const& info,
8993 ITransientExpression const& expr,
8994 AssertionReaction& reaction ) override;
8995 void handleMessage
8996 ( AssertionInfo const& info,
8997 ResultWas::OfType resultType,
8998 StringRef message,
8999 AssertionReaction& reaction ) override;
9000 void handleUnexpectedExceptionNotThrown
9001 ( AssertionInfo const& info,
9002 AssertionReaction& reaction ) override;
9003 void handleUnexpectedInflightException
9004 ( AssertionInfo const& info,
9005 std::string const& message,
9006 AssertionReaction& reaction ) override;
9007 void handleIncomplete
9008 ( AssertionInfo const& info ) override;
9009 void handleNonExpr
9010 ( AssertionInfo const &info,
9011 ResultWas::OfType resultType,
9012 AssertionReaction &reaction ) override;
9013
9014 bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
9015
9016 void sectionEnded( SectionEndInfo const& endInfo ) override;
9017 void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
9018
9019 auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
9020
9021 void benchmarkPreparing( StringRef name ) override;
9022 void benchmarkStarting( BenchmarkInfo const& info ) override;
9023 void benchmarkEnded( BenchmarkStats<> const& stats ) override;
9024 void benchmarkFailed( StringRef error ) override;
9025
9026 void pushScopedMessage( MessageInfo const& message ) override;
9027 void popScopedMessage( MessageInfo const& message ) override;
9028
9029 void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
9030
9031 std::string getCurrentTestName() const override;
9032
9033 const AssertionResult* getLastResult() const override;
9034
9035 void exceptionEarlyReported() override;
9036
9037 void handleFatalErrorCondition( StringRef message ) override;
9038
9039 bool lastAssertionPassed() override;
9040
9041 void assertionPassed() override;
9042
9043 public:
9044 // !TBD We need to do this another way!
9045 bool aborting() const;
9046
9047 private:
9048
9049 void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
9050 void invokeActiveTestCase();
9051
9052 void resetAssertionInfo();
9053 bool testForMissingAssertions( Counts& assertions );
9054
9055 void assertionEnded( AssertionResult const& result );
9056 void reportExpr
9057 ( AssertionInfo const &info,
9058 ResultWas::OfType resultType,
9059 ITransientExpression const *expr,
9060 bool negated );
9061
9062 void populateReaction( AssertionReaction& reaction );
9063
9064 private:
9065
9066 void handleUnfinishedSections();
9067
9068 TestRunInfo m_runInfo;
9069 IMutableContext& m_context;
9070 TestCaseHandle const* m_activeTestCase = nullptr;
9071 ITracker* m_testCaseTracker = nullptr;
9072 Optional<AssertionResult> m_lastResult;
9073
9074 IConfig const* m_config;
9075 Totals m_totals;
9076 IEventListenerPtr m_reporter;
9077 std::vector<MessageInfo> m_messages;
9078 std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
9079 AssertionInfo m_lastAssertionInfo;
9080 std::vector<SectionEndInfo> m_unfinishedSections;
9081 std::vector<ITracker*> m_activeSections;
9082 TrackerContext m_trackerContext;
9083 FatalConditionHandler m_fatalConditionhandler;
9084 bool m_lastAssertionPassed = false;
9085 bool m_shouldReportUnexpected = true;
9086 bool m_includeSuccessfulResults;
9087 };
9088
9089 void seedRng(IConfig const& config);
9090 unsigned int rngSeed();
9091} // end namespace Catch
9092
9093#endif // CATCH_RUN_CONTEXT_HPP_INCLUDED
9094
9095
9096#ifndef CATCH_SHARDING_HPP_INCLUDED
9097#define CATCH_SHARDING_HPP_INCLUDED
9098
9099
9100#include <cmath>
9101
9102namespace Catch {
9103
9104 template<typename Container>
9105 Container createShard(Container const& container, std::size_t const shardCount, std::size_t const shardIndex) {
9106 assert(shardCount > shardIndex);
9107
9108 if (shardCount == 1) {
9109 return container;
9110 }
9111
9112 const std::size_t totalTestCount = container.size();
9113
9114 const std::size_t shardSize = totalTestCount / shardCount;
9115 const std::size_t leftoverTests = totalTestCount % shardCount;
9116
9117 const std::size_t startIndex = shardIndex * shardSize + (std::min)(shardIndex, leftoverTests);
9118 const std::size_t endIndex = (shardIndex + 1) * shardSize + (std::min)(shardIndex + 1, leftoverTests);
9119
9120 auto startIterator = std::next(container.begin(), static_cast<std::ptrdiff_t>(startIndex));
9121 auto endIterator = std::next(container.begin(), static_cast<std::ptrdiff_t>(endIndex));
9122
9123 return Container(startIterator, endIterator);
9124 }
9125
9126}
9127
9128#endif // CATCH_SHARDING_HPP_INCLUDED
9129
9130
9131#ifndef CATCH_SINGLETONS_HPP_INCLUDED
9132#define CATCH_SINGLETONS_HPP_INCLUDED
9133
9134namespace Catch {
9135
9136 struct ISingleton {
9137 virtual ~ISingleton(); // = default
9138 };
9139
9140
9141 void addSingleton( ISingleton* singleton );
9142 void cleanupSingletons();
9143
9144
9145 template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
9146 class Singleton : SingletonImplT, public ISingleton {
9147
9148 static auto getInternal() -> Singleton* {
9149 static Singleton* s_instance = nullptr;
9150 if( !s_instance ) {
9151 s_instance = new Singleton;
9152 addSingleton( s_instance );
9153 }
9154 return s_instance;
9155 }
9156
9157 public:
9158 static auto get() -> InterfaceT const& {
9159 return *getInternal();
9160 }
9161 static auto getMutable() -> MutableInterfaceT& {
9162 return *getInternal();
9163 }
9164 };
9165
9166} // namespace Catch
9167
9168#endif // CATCH_SINGLETONS_HPP_INCLUDED
9169
9170
9171#ifndef CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
9172#define CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
9173
9174
9175#include <vector>
9176#include <exception>
9177
9178namespace Catch {
9179
9181#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
9182 public:
9183 void add(std::exception_ptr const& exception) noexcept;
9184 std::vector<std::exception_ptr> const& getExceptions() const noexcept;
9185 private:
9186 std::vector<std::exception_ptr> m_exceptions;
9187#endif
9188 };
9189
9190} // end namespace Catch
9191
9192#endif // CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
9193
9194
9195
9196#ifndef CATCH_STDSTREAMS_HPP_INCLUDED
9197#define CATCH_STDSTREAMS_HPP_INCLUDED
9198
9199#include <iosfwd>
9200
9201namespace Catch {
9202
9203 std::ostream& cout();
9204 std::ostream& cerr();
9205 std::ostream& clog();
9206
9207} // namespace Catch
9208
9209#endif
9210
9211
9212#ifndef CATCH_STRING_MANIP_HPP_INCLUDED
9213#define CATCH_STRING_MANIP_HPP_INCLUDED
9214
9215
9216#include <string>
9217#include <iosfwd>
9218#include <vector>
9219
9220namespace Catch {
9221
9222 bool startsWith( std::string const& s, std::string const& prefix );
9223 bool startsWith( StringRef s, char prefix );
9224 bool endsWith( std::string const& s, std::string const& suffix );
9225 bool endsWith( std::string const& s, char suffix );
9226 bool contains( std::string const& s, std::string const& infix );
9227 void toLowerInPlace( std::string& s );
9228 std::string toLower( std::string const& s );
9229 char toLower( char c );
9231 std::string trim( std::string const& str );
9233 StringRef trim(StringRef ref);
9234
9235 // !!! Be aware, returns refs into original string - make sure original string outlives them
9236 std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
9237 bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
9238
9249 class pluralise {
9250 std::uint64_t m_count;
9251 StringRef m_label;
9252
9253 public:
9254 constexpr pluralise(std::uint64_t count, StringRef label):
9255 m_count(count),
9256 m_label(label)
9257 {}
9258
9259 friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
9260 };
9261}
9262
9263#endif // CATCH_STRING_MANIP_HPP_INCLUDED
9264
9265
9266#ifndef CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9267#define CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9268
9269
9270#include <map>
9271#include <string>
9272
9273namespace Catch {
9274 struct SourceLineInfo;
9275
9277 public:
9278 ~TagAliasRegistry() override;
9279 TagAlias const* find( std::string const& alias ) const override;
9280 std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
9281 void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
9282
9283 private:
9284 std::map<std::string, TagAlias> m_registry;
9285 };
9286
9287} // end namespace Catch
9288
9289#endif // CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9290
9291
9292#ifndef CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED
9293#define CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED
9294
9295#include <cstdint>
9296
9297namespace Catch {
9298
9299 struct TestCaseInfo;
9300
9301 class TestCaseInfoHasher {
9302 public:
9303 using hash_t = std::uint64_t;
9304 TestCaseInfoHasher( hash_t seed );
9305 uint32_t operator()( TestCaseInfo const& t ) const;
9306
9307 private:
9308 hash_t m_seed;
9309 };
9310
9311} // namespace Catch
9312
9313#endif /* CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED */
9314
9315
9316#ifndef CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
9317#define CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
9318
9319
9320#include <vector>
9321
9322namespace Catch {
9323
9324 class TestCaseHandle;
9325 class IConfig;
9326 class TestSpec;
9327
9328 std::vector<TestCaseHandle> sortTests( IConfig const& config, std::vector<TestCaseHandle> const& unsortedTestCases );
9329
9330 bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
9331 bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config );
9332
9333 void enforceNoDuplicateTestCases( std::vector<TestCaseHandle> const& functions );
9334
9335 std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
9336 std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );
9337
9338 class TestRegistry : public ITestCaseRegistry {
9339 public:
9340 ~TestRegistry() override = default;
9341
9342 void registerTest( Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker );
9343
9344 std::vector<TestCaseInfo*> const& getAllInfos() const override;
9345 std::vector<TestCaseHandle> const& getAllTests() const override;
9346 std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const override;
9347
9348 private:
9349 std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
9350 // Keeps a materialized vector for `getAllInfos`.
9351 // We should get rid of that eventually (see interface note)
9352 std::vector<TestCaseInfo*> m_viewed_test_infos;
9353
9354 std::vector<Detail::unique_ptr<ITestInvoker>> m_invokers;
9355 std::vector<TestCaseHandle> m_handles;
9356 mutable TestRunOrder m_currentSortOrder = TestRunOrder::Declared;
9357 mutable std::vector<TestCaseHandle> m_sortedFunctions;
9358 };
9359
9361
9362 class TestInvokerAsFunction final : public ITestInvoker {
9363 using TestType = void(*)();
9364 TestType m_testAsFunction;
9365 public:
9366 TestInvokerAsFunction(TestType testAsFunction) noexcept:
9367 m_testAsFunction(testAsFunction) {}
9368
9369 void invoke() const override;
9370 };
9371
9373
9374
9375} // end namespace Catch
9376
9377
9378#endif // CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
9379
9380
9381#ifndef CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
9382#define CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
9383
9384#ifdef __clang__
9385#pragma clang diagnostic push
9386#pragma clang diagnostic ignored "-Wpadded"
9387#endif
9388
9389
9390#include <vector>
9391#include <string>
9392
9393namespace Catch {
9394
9395 class ITagAliasRegistry;
9396
9398 enum Mode{ None, Name, QuotedName, Tag, EscapedName };
9399 Mode m_mode = None;
9400 Mode lastMode = None;
9401 bool m_exclusion = false;
9402 std::size_t m_pos = 0;
9403 std::size_t m_realPatternPos = 0;
9404 std::string m_arg;
9405 std::string m_substring;
9406 std::string m_patternName;
9407 std::vector<std::size_t> m_escapeChars;
9408 TestSpec::Filter m_currentFilter;
9409 TestSpec m_testSpec;
9410 ITagAliasRegistry const* m_tagAliases = nullptr;
9411
9412 public:
9413 TestSpecParser( ITagAliasRegistry const& tagAliases );
9414
9415 TestSpecParser& parse( std::string const& arg );
9416 TestSpec testSpec();
9417
9418 private:
9419 bool visitChar( char c );
9420 void startNewMode( Mode mode );
9421 bool processNoneChar( char c );
9422 void processNameChar( char c );
9423 bool processOtherChar( char c );
9424 void endMode();
9425 void escape();
9426 bool isControlChar( char c ) const;
9427 void saveLastMode();
9428 void revertBackToLastMode();
9429 void addFilter();
9430 bool separate();
9431
9432 // Handles common preprocessing of the pattern for name/tag patterns
9433 std::string preprocessPattern();
9434 // Adds the current pattern as a test name
9435 void addNamePattern();
9436 // Adds the current pattern as a tag
9437 void addTagPattern();
9438
9439 inline void addCharToPattern(char c) {
9440 m_substring += c;
9441 m_patternName += c;
9442 m_realPatternPos++;
9443 }
9444
9445 };
9446 TestSpec parseTestSpec( std::string const& arg );
9447
9448} // namespace Catch
9449
9450#ifdef __clang__
9451#pragma clang diagnostic pop
9452#endif
9453
9454#endif // CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
9455
9456
9457#ifndef CATCH_TEXTFLOW_HPP_INCLUDED
9458#define CATCH_TEXTFLOW_HPP_INCLUDED
9459
9460#include <cassert>
9461#include <string>
9462#include <vector>
9463
9464namespace Catch {
9465 namespace TextFlow {
9466
9467 class Columns;
9468
9476 class Column {
9477 // String to be written out
9478 std::string m_string;
9479 // Width of the column for linebreaking
9480 size_t m_width = CATCH_CONFIG_CONSOLE_WIDTH - 1;
9481 // Indentation of other lines (including first if initial indent is unset)
9482 size_t m_indent = 0;
9483 // Indentation of the first line
9484 size_t m_initialIndent = std::string::npos;
9485
9486 public:
9491 friend Column;
9492 struct EndTag {};
9493
9494 Column const& m_column;
9495 // Where does the current line start?
9496 size_t m_lineStart = 0;
9497 // How long should the current line be?
9498 size_t m_lineLength = 0;
9499 // How far have we checked the string to iterate?
9500 size_t m_parsedTo = 0;
9501 // Should a '-' be appended to the line?
9502 bool m_addHyphen = false;
9503
9504 const_iterator( Column const& column, EndTag ):
9505 m_column( column ), m_lineStart( m_column.m_string.size() ) {}
9506
9507 // Calculates the length of the current line
9508 void calcLength();
9509
9510 // Returns current indention width
9511 size_t indentSize() const;
9512
9513 // Creates an indented and (optionally) suffixed string from
9514 // current iterator position, indentation and length.
9515 std::string addIndentAndSuffix( size_t position,
9516 size_t length ) const;
9517
9518 public:
9519 using difference_type = std::ptrdiff_t;
9520 using value_type = std::string;
9521 using pointer = value_type*;
9522 using reference = value_type&;
9523 using iterator_category = std::forward_iterator_tag;
9524
9525 explicit const_iterator( Column const& column );
9526
9527 std::string operator*() const;
9528
9529 const_iterator& operator++();
9530 const_iterator operator++( int );
9531
9532 bool operator==( const_iterator const& other ) const {
9533 return m_lineStart == other.m_lineStart && &m_column == &other.m_column;
9534 }
9535 bool operator!=( const_iterator const& other ) const {
9536 return !operator==( other );
9537 }
9538 };
9539 using iterator = const_iterator;
9540
9541 explicit Column( std::string const& text ): m_string( text ) {}
9542
9543 Column& width( size_t newWidth ) {
9544 assert( newWidth > 0 );
9545 m_width = newWidth;
9546 return *this;
9547 }
9548 Column& indent( size_t newIndent ) {
9549 m_indent = newIndent;
9550 return *this;
9551 }
9552 Column& initialIndent( size_t newIndent ) {
9553 m_initialIndent = newIndent;
9554 return *this;
9555 }
9556
9557 size_t width() const { return m_width; }
9558 const_iterator begin() const { return const_iterator( *this ); }
9559 const_iterator end() const { return { *this, const_iterator::EndTag{} }; }
9560
9561 friend std::ostream& operator<<( std::ostream& os,
9562 Column const& col );
9563
9564 Columns operator+( Column const& other );
9565 };
9566
9568 Column Spacer( size_t spaceWidth );
9569
9570 class Columns {
9571 std::vector<Column> m_columns;
9572
9573 public:
9574 class iterator {
9575 friend Columns;
9576 struct EndTag {};
9577
9578 std::vector<Column> const& m_columns;
9579 std::vector<Column::const_iterator> m_iterators;
9580 size_t m_activeIterators;
9581
9582 iterator( Columns const& columns, EndTag );
9583
9584 public:
9585 using difference_type = std::ptrdiff_t;
9586 using value_type = std::string;
9587 using pointer = value_type*;
9588 using reference = value_type&;
9589 using iterator_category = std::forward_iterator_tag;
9590
9591 explicit iterator( Columns const& columns );
9592
9593 auto operator==( iterator const& other ) const -> bool {
9594 return m_iterators == other.m_iterators;
9595 }
9596 auto operator!=( iterator const& other ) const -> bool {
9597 return m_iterators != other.m_iterators;
9598 }
9599 std::string operator*() const;
9600 iterator& operator++();
9601 iterator operator++( int );
9602 };
9603 using const_iterator = iterator;
9604
9605 iterator begin() const { return iterator( *this ); }
9606 iterator end() const { return { *this, iterator::EndTag() }; }
9607
9608 Columns& operator+=( Column const& col );
9609 Columns operator+( Column const& col );
9610
9611 friend std::ostream& operator<<( std::ostream& os,
9612 Columns const& cols );
9613 };
9614
9615 } // namespace TextFlow
9616} // namespace Catch
9617#endif // CATCH_TEXTFLOW_HPP_INCLUDED
9618
9619
9620#ifndef CATCH_TO_STRING_HPP_INCLUDED
9621#define CATCH_TO_STRING_HPP_INCLUDED
9622
9623#include <string>
9624
9625
9626namespace Catch {
9627 template <typename T>
9628 std::string to_string(T const& t) {
9629#if defined(CATCH_CONFIG_CPP11_TO_STRING)
9630 return std::to_string(t);
9631#else
9632 ReusableStringStream rss;
9633 rss << t;
9634 return rss.str();
9635#endif
9636 }
9637} // end namespace Catch
9638
9639#endif // CATCH_TO_STRING_HPP_INCLUDED
9640
9641
9642#ifndef CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9643#define CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9644
9645namespace Catch {
9646 bool uncaught_exceptions();
9647} // end namespace Catch
9648
9649#endif // CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9650
9651
9652#ifndef CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
9653#define CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
9654
9655
9656#if defined(CATCH_PLATFORM_WINDOWS)
9657
9658// We might end up with the define made globally through the compiler,
9659// and we don't want to trigger warnings for this
9660#if !defined(NOMINMAX)
9661# define NOMINMAX
9662#endif
9663#if !defined(WIN32_LEAN_AND_MEAN)
9664# define WIN32_LEAN_AND_MEAN
9665#endif
9666
9667#ifdef __AFXDLL
9668#include <AfxWin.h>
9669#else
9670#include <windows.h>
9671#endif
9672
9673#endif // defined(CATCH_PLATFORM_WINDOWS)
9674
9675#endif // CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
9676
9677
9678#ifndef CATCH_XMLWRITER_HPP_INCLUDED
9679#define CATCH_XMLWRITER_HPP_INCLUDED
9680
9681
9682#include <iosfwd>
9683#include <vector>
9684
9685namespace Catch {
9686 enum class XmlFormatting {
9687 None = 0x00,
9688 Indent = 0x01,
9689 Newline = 0x02,
9690 };
9691
9692 XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
9693 XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
9694
9702 public:
9703 enum ForWhat { ForTextNodes, ForAttributes };
9704
9705 XmlEncode( StringRef str, ForWhat forWhat = ForTextNodes );
9706
9707 void encodeTo( std::ostream& os ) const;
9708
9709 friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
9710
9711 private:
9712 StringRef m_str;
9713 ForWhat m_forWhat;
9714 };
9715
9717 public:
9718
9720 public:
9721 ScopedElement( XmlWriter* writer, XmlFormatting fmt );
9722
9723 ScopedElement( ScopedElement&& other ) noexcept;
9724 ScopedElement& operator=( ScopedElement&& other ) noexcept;
9725
9727
9729 writeText( StringRef text,
9730 XmlFormatting fmt = XmlFormatting::Newline |
9731 XmlFormatting::Indent );
9732
9733 ScopedElement& writeAttribute( StringRef name,
9734 StringRef attribute );
9735 template <typename T,
9736 // Without this SFINAE, this overload is a better match
9737 // for `std::string`, `char const*`, `char const[N]` args.
9738 // While it would still work, it would cause code bloat
9739 // and multiple iteration over the strings
9740 typename = typename std::enable_if_t<
9741 !std::is_convertible<T, StringRef>::value>>
9742 ScopedElement& writeAttribute( StringRef name,
9743 T const& attribute ) {
9744 m_writer->writeAttribute( name, attribute );
9745 return *this;
9746 }
9747
9748 private:
9749 XmlWriter* m_writer = nullptr;
9750 XmlFormatting m_fmt;
9751 };
9752
9753 XmlWriter( std::ostream& os );
9754 ~XmlWriter();
9755
9756 XmlWriter( XmlWriter const& ) = delete;
9757 XmlWriter& operator=( XmlWriter const& ) = delete;
9758
9759 XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
9760
9761 ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
9762
9763 XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
9764
9766 XmlWriter& writeAttribute( StringRef name, StringRef attribute );
9767
9769 XmlWriter& writeAttribute( StringRef name, bool attribute );
9770
9772 XmlWriter& writeAttribute( StringRef name, char const* attribute );
9773
9776 template <typename T,
9777 // Without this SFINAE, this overload is a better match
9778 // for `std::string`, `char const*`, `char const[N]` args.
9779 // While it would still work, it would cause code bloat
9780 // and multiple iteration over the strings
9781 typename = typename std::enable_if_t<
9782 !std::is_convertible<T, StringRef>::value>>
9783 XmlWriter& writeAttribute( StringRef name, T const& attribute ) {
9784 ReusableStringStream rss;
9785 rss << attribute;
9786 return writeAttribute( name, rss.str() );
9787 }
9788
9791 XmlFormatting fmt = XmlFormatting::Newline |
9792 XmlFormatting::Indent );
9793
9796 XmlFormatting fmt = XmlFormatting::Newline |
9797 XmlFormatting::Indent );
9798
9799 void writeStylesheetRef( StringRef url );
9800
9801 void ensureTagClosed();
9802
9803 private:
9804
9805 void applyFormatting(XmlFormatting fmt);
9806
9807 void writeDeclaration();
9808
9809 void newlineIfNecessary();
9810
9811 bool m_tagIsOpen = false;
9812 bool m_needsNewline = false;
9813 std::vector<std::string> m_tags;
9814 std::string m_indent;
9815 std::ostream& m_os;
9816 };
9817
9818}
9819
9820#endif // CATCH_XMLWRITER_HPP_INCLUDED
9821
9822
9835#ifndef CATCH_MATCHERS_ALL_HPP_INCLUDED
9836#define CATCH_MATCHERS_ALL_HPP_INCLUDED
9837
9838
9839
9840#ifndef CATCH_MATCHERS_HPP_INCLUDED
9841#define CATCH_MATCHERS_HPP_INCLUDED
9842
9843
9844
9845#ifndef CATCH_MATCHERS_IMPL_HPP_INCLUDED
9846#define CATCH_MATCHERS_IMPL_HPP_INCLUDED
9847
9848
9849namespace Catch {
9850
9851 template<typename ArgT, typename MatcherT>
9852 class MatchExpr : public ITransientExpression {
9853 ArgT && m_arg;
9854 MatcherT const& m_matcher;
9855 StringRef m_matcherString;
9856 public:
9857 MatchExpr( ArgT && arg, MatcherT const& matcher, StringRef matcherString )
9858 : ITransientExpression{ true, matcher.match( arg ) }, // not forwarding arg here on purpose
9859 m_arg( CATCH_FORWARD(arg) ),
9860 m_matcher( matcher ),
9861 m_matcherString( matcherString )
9862 {}
9863
9864 void streamReconstructedExpression( std::ostream& os ) const override {
9865 os << Catch::Detail::stringify( m_arg )
9866 << ' '
9867 << m_matcher.toString();
9868 }
9869 };
9870
9871 namespace Matchers {
9872 template <typename ArgT>
9873 class MatcherBase;
9874 }
9875
9876 using StringMatcher = Matchers::MatcherBase<std::string>;
9877
9878 void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString );
9879
9880 template<typename ArgT, typename MatcherT>
9881 auto makeMatchExpr( ArgT && arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr<ArgT, MatcherT> {
9882 return MatchExpr<ArgT, MatcherT>( CATCH_FORWARD(arg), matcher, matcherString );
9883 }
9884
9885} // namespace Catch
9886
9887
9889#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
9890 do { \
9891 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
9892 INTERNAL_CATCH_TRY { \
9893 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
9894 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
9895 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
9896 } while( false )
9897
9898
9900#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
9901 do { \
9902 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
9903 if( catchAssertionHandler.allowThrows() ) \
9904 try { \
9905 static_cast<void>(__VA_ARGS__ ); \
9906 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
9907 } \
9908 catch( exceptionType const& ex ) { \
9909 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
9910 } \
9911 catch( ... ) { \
9912 catchAssertionHandler.handleUnexpectedInflightException(); \
9913 } \
9914 else \
9915 catchAssertionHandler.handleThrowingCallSkipped(); \
9916 INTERNAL_CATCH_REACT( catchAssertionHandler ) \
9917 } while( false )
9918
9919
9920#endif // CATCH_MATCHERS_IMPL_HPP_INCLUDED
9921
9922#include <string>
9923#include <vector>
9924
9925namespace Catch {
9926namespace Matchers {
9927
9929 public:
9930 MatcherUntypedBase() = default;
9931
9932 MatcherUntypedBase(MatcherUntypedBase const&) = default;
9934
9935 MatcherUntypedBase& operator = (MatcherUntypedBase const&) = delete;
9936 MatcherUntypedBase& operator = (MatcherUntypedBase&&) = delete;
9937
9938 std::string toString() const;
9939
9940 protected:
9941 virtual ~MatcherUntypedBase(); // = default;
9942 virtual std::string describe() const = 0;
9943 mutable std::string m_cachedToString;
9944 };
9945
9946
9947 template<typename T>
9949 public:
9950 virtual bool match( T const& arg ) const = 0;
9951 };
9952
9953 namespace Detail {
9954
9955 template<typename ArgT>
9956 class MatchAllOf final : public MatcherBase<ArgT> {
9957 std::vector<MatcherBase<ArgT> const*> m_matchers;
9958
9959 public:
9960 MatchAllOf() = default;
9961 MatchAllOf(MatchAllOf const&) = delete;
9962 MatchAllOf& operator=(MatchAllOf const&) = delete;
9963 MatchAllOf(MatchAllOf&&) = default;
9964 MatchAllOf& operator=(MatchAllOf&&) = default;
9965
9966
9967 bool match( ArgT const& arg ) const override {
9968 for( auto matcher : m_matchers ) {
9969 if (!matcher->match(arg))
9970 return false;
9971 }
9972 return true;
9973 }
9974 std::string describe() const override {
9975 std::string description;
9976 description.reserve( 4 + m_matchers.size()*32 );
9977 description += "( ";
9978 bool first = true;
9979 for( auto matcher : m_matchers ) {
9980 if( first )
9981 first = false;
9982 else
9983 description += " and ";
9984 description += matcher->toString();
9985 }
9986 description += " )";
9987 return description;
9988 }
9989
9990 friend MatchAllOf operator&& (MatchAllOf&& lhs, MatcherBase<ArgT> const& rhs) {
9991 lhs.m_matchers.push_back(&rhs);
9992 return CATCH_MOVE(lhs);
9993 }
9994 friend MatchAllOf operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf&& rhs) {
9995 rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
9996 return CATCH_MOVE(rhs);
9997 }
9998 };
9999
10002 template<typename ArgT>
10003 MatchAllOf<ArgT> operator&& (MatchAllOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
10006 template<typename ArgT>
10007 MatchAllOf<ArgT> operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf<ArgT> const& rhs) = delete;
10008
10009 template<typename ArgT>
10010 class MatchAnyOf final : public MatcherBase<ArgT> {
10011 std::vector<MatcherBase<ArgT> const*> m_matchers;
10012 public:
10013 MatchAnyOf() = default;
10014 MatchAnyOf(MatchAnyOf const&) = delete;
10015 MatchAnyOf& operator=(MatchAnyOf const&) = delete;
10016 MatchAnyOf(MatchAnyOf&&) = default;
10017 MatchAnyOf& operator=(MatchAnyOf&&) = default;
10018
10019 bool match( ArgT const& arg ) const override {
10020 for( auto matcher : m_matchers ) {
10021 if (matcher->match(arg))
10022 return true;
10023 }
10024 return false;
10025 }
10026 std::string describe() const override {
10027 std::string description;
10028 description.reserve( 4 + m_matchers.size()*32 );
10029 description += "( ";
10030 bool first = true;
10031 for( auto matcher : m_matchers ) {
10032 if( first )
10033 first = false;
10034 else
10035 description += " or ";
10036 description += matcher->toString();
10037 }
10038 description += " )";
10039 return description;
10040 }
10041
10042 friend MatchAnyOf operator|| (MatchAnyOf&& lhs, MatcherBase<ArgT> const& rhs) {
10043 lhs.m_matchers.push_back(&rhs);
10044 return CATCH_MOVE(lhs);
10045 }
10046 friend MatchAnyOf operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf&& rhs) {
10047 rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
10048 return CATCH_MOVE(rhs);
10049 }
10050 };
10051
10054 template<typename ArgT>
10055 MatchAnyOf<ArgT> operator|| (MatchAnyOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
10058 template<typename ArgT>
10059 MatchAnyOf<ArgT> operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf<ArgT> const& rhs) = delete;
10060
10061 template<typename ArgT>
10062 class MatchNotOf final : public MatcherBase<ArgT> {
10063 MatcherBase<ArgT> const& m_underlyingMatcher;
10064
10065 public:
10066 explicit MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ):
10067 m_underlyingMatcher( underlyingMatcher )
10068 {}
10069
10070 bool match( ArgT const& arg ) const override {
10071 return !m_underlyingMatcher.match( arg );
10072 }
10073
10074 std::string describe() const override {
10075 return "not " + m_underlyingMatcher.toString();
10076 }
10077 };
10078
10079 } // namespace Detail
10080
10081 template <typename T>
10082 Detail::MatchAllOf<T> operator&& (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
10083 return Detail::MatchAllOf<T>{} && lhs && rhs;
10084 }
10085 template <typename T>
10086 Detail::MatchAnyOf<T> operator|| (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
10087 return Detail::MatchAnyOf<T>{} || lhs || rhs;
10088 }
10089
10090 template <typename T>
10091 Detail::MatchNotOf<T> operator! (MatcherBase<T> const& matcher) {
10092 return Detail::MatchNotOf<T>{ matcher };
10093 }
10094
10095
10096} // namespace Matchers
10097} // namespace Catch
10098
10099
10100#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
10101 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
10102 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
10103
10104 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
10105 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
10106
10107 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
10108 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
10109
10110#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
10111
10112 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
10113 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
10114
10115 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
10116 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
10117
10118 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
10119 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
10120
10121#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
10122
10123 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
10124 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
10125
10126 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
10127 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
10128
10129 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
10130 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
10131
10132#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
10133
10134 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
10135 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
10136
10137 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
10138 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
10139
10140 #define CHECK_THAT( arg, matcher ) (void)(0)
10141 #define REQUIRE_THAT( arg, matcher ) (void)(0)
10142
10143#endif // end of user facing macro declarations
10144
10145#endif // CATCH_MATCHERS_HPP_INCLUDED
10146
10147
10148#ifndef CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
10149#define CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
10150
10151
10152
10153#ifndef CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
10154#define CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
10155
10156
10157#include <array>
10158#include <algorithm>
10159#include <string>
10160#include <type_traits>
10161
10162namespace Catch {
10163namespace Matchers {
10165 public:
10166 MatcherGenericBase() = default;
10167 ~MatcherGenericBase() override; // = default;
10168
10171
10172 MatcherGenericBase& operator=(MatcherGenericBase const&) = delete;
10173 MatcherGenericBase& operator=(MatcherGenericBase&&) = delete;
10174 };
10175
10176
10177 namespace Detail {
10178 template<std::size_t N, std::size_t M>
10179 std::array<void const*, N + M> array_cat(std::array<void const*, N> && lhs, std::array<void const*, M> && rhs) {
10180 std::array<void const*, N + M> arr{};
10181 std::copy_n(lhs.begin(), N, arr.begin());
10182 std::copy_n(rhs.begin(), M, arr.begin() + N);
10183 return arr;
10184 }
10185
10186 template<std::size_t N>
10187 std::array<void const*, N+1> array_cat(std::array<void const*, N> && lhs, void const* rhs) {
10188 std::array<void const*, N+1> arr{};
10189 std::copy_n(lhs.begin(), N, arr.begin());
10190 arr[N] = rhs;
10191 return arr;
10192 }
10193
10194 template<std::size_t N>
10195 std::array<void const*, N+1> array_cat(void const* lhs, std::array<void const*, N> && rhs) {
10196 std::array<void const*, N + 1> arr{ {lhs} };
10197 std::copy_n(rhs.begin(), N, arr.begin() + 1);
10198 return arr;
10199 }
10200
10201#if defined( __cpp_lib_logical_traits ) && __cpp_lib_logical_traits >= 201510
10202
10203 using std::conjunction;
10204
10205#else // __cpp_lib_logical_traits
10206
10207 template<typename... Cond>
10208 struct conjunction : std::true_type {};
10209
10210 template<typename Cond, typename... Rest>
10211 struct conjunction<Cond, Rest...> : std::integral_constant<bool, Cond::value && conjunction<Rest...>::value> {};
10212
10213#endif // __cpp_lib_logical_traits
10214
10215 template<typename T>
10216 using is_generic_matcher = std::is_base_of<
10218 std::remove_cv_t<std::remove_reference_t<T>>
10219 >;
10220
10221 template<typename... Ts>
10223
10224 template<typename T>
10225 using is_matcher = std::is_base_of<
10227 std::remove_cv_t<std::remove_reference_t<T>>
10228 >;
10229
10230
10231 template<std::size_t N, typename Arg>
10232 bool match_all_of(Arg&&, std::array<void const*, N> const&, std::index_sequence<>) {
10233 return true;
10234 }
10235
10236 template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
10237 bool match_all_of(Arg&& arg, std::array<void const*, N> const& matchers, std::index_sequence<Idx, Indices...>) {
10238 return static_cast<T const*>(matchers[Idx])->match(arg) && match_all_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
10239 }
10240
10241
10242 template<std::size_t N, typename Arg>
10243 bool match_any_of(Arg&&, std::array<void const*, N> const&, std::index_sequence<>) {
10244 return false;
10245 }
10246
10247 template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
10248 bool match_any_of(Arg&& arg, std::array<void const*, N> const& matchers, std::index_sequence<Idx, Indices...>) {
10249 return static_cast<T const*>(matchers[Idx])->match(arg) || match_any_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
10250 }
10251
10252 std::string describe_multi_matcher(StringRef combine, std::string const* descriptions_begin, std::string const* descriptions_end);
10253
10254 template<typename... MatcherTs, std::size_t... Idx>
10255 std::string describe_multi_matcher(StringRef combine, std::array<void const*, sizeof...(MatcherTs)> const& matchers, std::index_sequence<Idx...>) {
10256 std::array<std::string, sizeof...(MatcherTs)> descriptions {{
10257 static_cast<MatcherTs const*>(matchers[Idx])->toString()...
10258 }};
10259
10260 return describe_multi_matcher(combine, descriptions.data(), descriptions.data() + descriptions.size());
10261 }
10262
10263
10264 template<typename... MatcherTs>
10266 public:
10267 MatchAllOfGeneric(MatchAllOfGeneric const&) = delete;
10268 MatchAllOfGeneric& operator=(MatchAllOfGeneric const&) = delete;
10270 MatchAllOfGeneric& operator=(MatchAllOfGeneric&&) = default;
10271
10272 MatchAllOfGeneric(MatcherTs const&... matchers) : m_matchers{ {std::addressof(matchers)...} } {}
10273 explicit MatchAllOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
10274
10275 template<typename Arg>
10276 bool match(Arg&& arg) const {
10277 return match_all_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
10278 }
10279
10280 std::string describe() const override {
10281 return describe_multi_matcher<MatcherTs...>(" and "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
10282 }
10283
10284 // Has to be public to enable the concatenating operators
10285 // below, because they are not friend of the RHS, only LHS,
10286 // and thus cannot access private fields of RHS
10287 std::array<void const*, sizeof...( MatcherTs )> m_matchers;
10288
10289
10291 template<typename... MatchersRHS>
10292 friend
10293 MatchAllOfGeneric<MatcherTs..., MatchersRHS...> operator && (
10296 return MatchAllOfGeneric<MatcherTs..., MatchersRHS...>{array_cat(CATCH_MOVE(lhs.m_matchers), CATCH_MOVE(rhs.m_matchers))};
10297 }
10298
10300 template<typename MatcherRHS>
10301 friend std::enable_if_t<is_matcher<MatcherRHS>::value,
10302 MatchAllOfGeneric<MatcherTs..., MatcherRHS>> operator && (
10304 MatcherRHS const& rhs) {
10305 return MatchAllOfGeneric<MatcherTs..., MatcherRHS>{array_cat(CATCH_MOVE(lhs.m_matchers), static_cast<void const*>(&rhs))};
10306 }
10307
10309 template<typename MatcherLHS>
10310 friend std::enable_if_t<is_matcher<MatcherLHS>::value,
10311 MatchAllOfGeneric<MatcherLHS, MatcherTs...>> operator && (
10312 MatcherLHS const& lhs,
10314 return MatchAllOfGeneric<MatcherLHS, MatcherTs...>{array_cat(static_cast<void const*>(std::addressof(lhs)), CATCH_MOVE(rhs.m_matchers))};
10315 }
10316 };
10317
10318
10319 template<typename... MatcherTs>
10321 public:
10322 MatchAnyOfGeneric(MatchAnyOfGeneric const&) = delete;
10323 MatchAnyOfGeneric& operator=(MatchAnyOfGeneric const&) = delete;
10325 MatchAnyOfGeneric& operator=(MatchAnyOfGeneric&&) = default;
10326
10327 MatchAnyOfGeneric(MatcherTs const&... matchers) : m_matchers{ {std::addressof(matchers)...} } {}
10328 explicit MatchAnyOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
10329
10330 template<typename Arg>
10331 bool match(Arg&& arg) const {
10332 return match_any_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
10333 }
10334
10335 std::string describe() const override {
10336 return describe_multi_matcher<MatcherTs...>(" or "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
10337 }
10338
10339
10340 // Has to be public to enable the concatenating operators
10341 // below, because they are not friend of the RHS, only LHS,
10342 // and thus cannot access private fields of RHS
10343 std::array<void const*, sizeof...( MatcherTs )> m_matchers;
10344
10346 template<typename... MatchersRHS>
10347 friend MatchAnyOfGeneric<MatcherTs..., MatchersRHS...> operator || (
10350 return MatchAnyOfGeneric<MatcherTs..., MatchersRHS...>{array_cat(CATCH_MOVE(lhs.m_matchers), CATCH_MOVE(rhs.m_matchers))};
10351 }
10352
10354 template<typename MatcherRHS>
10355 friend std::enable_if_t<is_matcher<MatcherRHS>::value,
10356 MatchAnyOfGeneric<MatcherTs..., MatcherRHS>> operator || (
10358 MatcherRHS const& rhs) {
10359 return MatchAnyOfGeneric<MatcherTs..., MatcherRHS>{array_cat(CATCH_MOVE(lhs.m_matchers), static_cast<void const*>(std::addressof(rhs)))};
10360 }
10361
10363 template<typename MatcherLHS>
10364 friend std::enable_if_t<is_matcher<MatcherLHS>::value,
10365 MatchAnyOfGeneric<MatcherLHS, MatcherTs...>> operator || (
10366 MatcherLHS const& lhs,
10368 return MatchAnyOfGeneric<MatcherLHS, MatcherTs...>{array_cat(static_cast<void const*>(std::addressof(lhs)), CATCH_MOVE(rhs.m_matchers))};
10369 }
10370 };
10371
10372
10373 template<typename MatcherT>
10375 MatcherT const& m_matcher;
10376
10377 public:
10378 MatchNotOfGeneric(MatchNotOfGeneric const&) = delete;
10379 MatchNotOfGeneric& operator=(MatchNotOfGeneric const&) = delete;
10381 MatchNotOfGeneric& operator=(MatchNotOfGeneric&&) = default;
10382
10383 explicit MatchNotOfGeneric(MatcherT const& matcher) : m_matcher{matcher} {}
10384
10385 template<typename Arg>
10386 bool match(Arg&& arg) const {
10387 return !m_matcher.match(arg);
10388 }
10389
10390 std::string describe() const override {
10391 return "not " + m_matcher.toString();
10392 }
10393
10395 friend MatcherT const& operator ! (MatchNotOfGeneric<MatcherT> const& matcher) {
10396 return matcher.m_matcher;
10397 }
10398 };
10399 } // namespace Detail
10400
10401
10402 // compose only generic matchers
10403 template<typename MatcherLHS, typename MatcherRHS>
10404 std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>
10405 operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) {
10406 return { lhs, rhs };
10407 }
10408
10409 template<typename MatcherLHS, typename MatcherRHS>
10410 std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>
10411 operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) {
10412 return { lhs, rhs };
10413 }
10414
10416 template<typename MatcherT>
10417 std::enable_if_t<Detail::is_generic_matcher<MatcherT>::value, Detail::MatchNotOfGeneric<MatcherT>>
10418 operator ! (MatcherT const& matcher) {
10420 }
10421
10422
10423 // compose mixed generic and non-generic matchers
10424 template<typename MatcherLHS, typename ArgRHS>
10425 std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
10426 operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
10427 return { lhs, rhs };
10428 }
10429
10430 template<typename ArgLHS, typename MatcherRHS>
10431 std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
10432 operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
10433 return { lhs, rhs };
10434 }
10435
10436 template<typename MatcherLHS, typename ArgRHS>
10437 std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
10438 operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
10439 return { lhs, rhs };
10440 }
10441
10442 template<typename ArgLHS, typename MatcherRHS>
10443 std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
10444 operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
10445 return { lhs, rhs };
10446 }
10447
10448} // namespace Matchers
10449} // namespace Catch
10450
10451#endif // CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
10452
10453namespace Catch {
10454 namespace Matchers {
10455
10456 class IsEmptyMatcher final : public MatcherGenericBase {
10457 public:
10458 // todo: Use polyfills
10459 template <typename RangeLike>
10460 bool match(RangeLike&& rng) const {
10461#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
10462 using Catch::Detail::empty;
10463#else
10464 using std::empty;
10465#endif
10466 return empty(rng);
10467 }
10468
10469 std::string describe() const override;
10470 };
10471
10472 class HasSizeMatcher final : public MatcherGenericBase {
10473 std::size_t m_target_size;
10474 public:
10475 explicit HasSizeMatcher(std::size_t target_size):
10476 m_target_size(target_size)
10477 {}
10478
10479 template <typename RangeLike>
10480 bool match(RangeLike&& rng) const {
10481#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
10482 using Catch::Detail::size;
10483#else
10484 using std::size;
10485#endif
10486 return size(rng) == m_target_size;
10487 }
10488
10489 std::string describe() const override;
10490 };
10491
10492 template <typename Matcher>
10494 Matcher m_matcher;
10495 public:
10496 explicit SizeMatchesMatcher(Matcher m):
10497 m_matcher(CATCH_MOVE(m))
10498 {}
10499
10500 template <typename RangeLike>
10501 bool match(RangeLike&& rng) const {
10502#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
10503 using Catch::Detail::size;
10504#else
10505 using std::size;
10506#endif
10507 return m_matcher.match(size(rng));
10508 }
10509
10510 std::string describe() const override {
10511 return "size matches " + m_matcher.describe();
10512 }
10513 };
10514
10515
10519 HasSizeMatcher SizeIs(std::size_t sz);
10520 template <typename Matcher>
10521 std::enable_if_t<Detail::is_matcher<Matcher>::value,
10522 SizeMatchesMatcher<Matcher>> SizeIs(Matcher&& m) {
10524 }
10525
10526 } // end namespace Matchers
10527} // end namespace Catch
10528
10529#endif // CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
10530
10531
10532#ifndef CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
10533#define CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
10534
10535
10536#include <algorithm>
10537#include <functional>
10538
10539namespace Catch {
10540 namespace Matchers {
10542 template <typename T, typename Equality>
10544 T m_desired;
10545 Equality m_eq;
10546 public:
10547 template <typename T2, typename Equality2>
10548 ContainsElementMatcher(T2&& target, Equality2&& predicate):
10549 m_desired(CATCH_FORWARD(target)),
10550 m_eq(CATCH_FORWARD(predicate))
10551 {}
10552
10553 std::string describe() const override {
10554 return "contains element " + Catch::Detail::stringify(m_desired);
10555 }
10556
10557 template <typename RangeLike>
10558 bool match(RangeLike&& rng) const {
10559 using std::begin; using std::end;
10560
10561 return end(rng) != std::find_if(begin(rng), end(rng),
10562 [&](auto const& elem) {
10563 return m_eq(elem, m_desired);
10564 });
10565 }
10566 };
10567
10569 template <typename Matcher>
10571 Matcher m_matcher;
10572 public:
10573 // Note that we do a copy+move to avoid having to SFINAE this
10574 // constructor (and also avoid some perfect forwarding failure
10575 // cases)
10576 ContainsMatcherMatcher(Matcher matcher):
10577 m_matcher(CATCH_MOVE(matcher))
10578 {}
10579
10580 template <typename RangeLike>
10581 bool match(RangeLike&& rng) const {
10582 for (auto&& elem : rng) {
10583 if (m_matcher.match(elem)) {
10584 return true;
10585 }
10586 }
10587 return false;
10588 }
10589
10590 std::string describe() const override {
10591 return "contains element matching " + m_matcher.describe();
10592 }
10593 };
10594
10600 template <typename T>
10601 std::enable_if_t<!Detail::is_matcher<T>::value,
10603 return { CATCH_FORWARD(elem), std::equal_to<>{} };
10604 }
10605
10607 template <typename Matcher>
10608 std::enable_if_t<Detail::is_matcher<Matcher>::value,
10610 return { CATCH_FORWARD(matcher) };
10611 }
10612
10618 template <typename T, typename Equality>
10620 return { CATCH_FORWARD(elem), CATCH_FORWARD(eq) };
10621 }
10622
10623 }
10624}
10625
10626#endif // CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
10627
10628
10629#ifndef CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
10630#define CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
10631
10632
10633namespace Catch {
10634namespace Matchers {
10635
10636class ExceptionMessageMatcher final : public MatcherBase<std::exception> {
10637 std::string m_message;
10638public:
10639
10640 ExceptionMessageMatcher(std::string const& message):
10641 m_message(message)
10642 {}
10643
10644 bool match(std::exception const& ex) const override;
10645
10646 std::string describe() const override;
10647};
10648
10650ExceptionMessageMatcher Message(std::string const& message);
10651
10652} // namespace Matchers
10653} // namespace Catch
10654
10655#endif // CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
10656
10657
10658#ifndef CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
10659#define CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
10660
10661
10662namespace Catch {
10663namespace Matchers {
10664
10665 namespace Detail {
10666 enum class FloatingPointKind : uint8_t;
10667 }
10668
10669 class WithinAbsMatcher final : public MatcherBase<double> {
10670 public:
10671 WithinAbsMatcher(double target, double margin);
10672 bool match(double const& matchee) const override;
10673 std::string describe() const override;
10674 private:
10675 double m_target;
10676 double m_margin;
10677 };
10678
10679 class WithinUlpsMatcher final : public MatcherBase<double> {
10680 public:
10681 WithinUlpsMatcher( double target,
10682 uint64_t ulps,
10683 Detail::FloatingPointKind baseType );
10684 bool match(double const& matchee) const override;
10685 std::string describe() const override;
10686 private:
10687 double m_target;
10688 uint64_t m_ulps;
10689 Detail::FloatingPointKind m_type;
10690 };
10691
10692 // Given IEEE-754 format for floats and doubles, we can assume
10693 // that float -> double promotion is lossless. Given this, we can
10694 // assume that if we do the standard relative comparison of
10695 // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
10696 // the same result if we do this for floats, as if we do this for
10697 // doubles that were promoted from floats.
10698 class WithinRelMatcher final : public MatcherBase<double> {
10699 public:
10700 WithinRelMatcher( double target, double epsilon );
10701 bool match(double const& matchee) const override;
10702 std::string describe() const override;
10703 private:
10704 double m_target;
10705 double m_epsilon;
10706 };
10707
10709 WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
10711 WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
10713 WithinAbsMatcher WithinAbs(double target, double margin);
10714
10716 WithinRelMatcher WithinRel(double target, double eps);
10718 WithinRelMatcher WithinRel(double target);
10720 WithinRelMatcher WithinRel(float target, float eps);
10722 WithinRelMatcher WithinRel(float target);
10723
10724} // namespace Matchers
10725} // namespace Catch
10726
10727#endif // CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
10728
10729
10730#ifndef CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
10731#define CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
10732
10733
10734#include <string>
10735
10736namespace Catch {
10737namespace Matchers {
10738
10739namespace Detail {
10740 std::string finalizeDescription(const std::string& desc);
10741} // namespace Detail
10742
10743template <typename T, typename Predicate>
10744class PredicateMatcher final : public MatcherBase<T> {
10745 Predicate m_predicate;
10746 std::string m_description;
10747public:
10748
10749 PredicateMatcher(Predicate&& elem, std::string const& descr)
10750 :m_predicate(CATCH_FORWARD(elem)),
10751 m_description(Detail::finalizeDescription(descr))
10752 {}
10753
10754 bool match( T const& item ) const override {
10755 return m_predicate(item);
10756 }
10757
10758 std::string describe() const override {
10759 return m_description;
10760 }
10761};
10762
10768 template<typename T, typename Pred>
10769 PredicateMatcher<T, Pred> Predicate(Pred&& predicate, std::string const& description = "") {
10770 static_assert(is_callable<Pred(T)>::value, "Predicate not callable with argument T");
10771 static_assert(std::is_same<bool, FunctionReturnType<Pred, T>>::value, "Predicate does not return bool");
10772 return PredicateMatcher<T, Pred>(CATCH_FORWARD(predicate), description);
10773 }
10774
10775} // namespace Matchers
10776} // namespace Catch
10777
10778#endif // CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
10779
10780
10781#ifndef CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
10782#define CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
10783
10784
10785namespace Catch {
10786 namespace Matchers {
10787 // Matcher for checking that all elements in range matches a given matcher.
10788 template <typename Matcher>
10790 Matcher m_matcher;
10791 public:
10792 AllMatchMatcher(Matcher matcher):
10793 m_matcher(CATCH_MOVE(matcher))
10794 {}
10795
10796 std::string describe() const override {
10797 return "all match " + m_matcher.describe();
10798 }
10799
10800 template <typename RangeLike>
10801 bool match(RangeLike&& rng) const {
10802 for (auto&& elem : rng) {
10803 if (!m_matcher.match(elem)) {
10804 return false;
10805 }
10806 }
10807 return true;
10808 }
10809 };
10810
10811 // Matcher for checking that no element in range matches a given matcher.
10812 template <typename Matcher>
10814 Matcher m_matcher;
10815 public:
10816 NoneMatchMatcher(Matcher matcher):
10817 m_matcher(CATCH_MOVE(matcher))
10818 {}
10819
10820 std::string describe() const override {
10821 return "none match " + m_matcher.describe();
10822 }
10823
10824 template <typename RangeLike>
10825 bool match(RangeLike&& rng) const {
10826 for (auto&& elem : rng) {
10827 if (m_matcher.match(elem)) {
10828 return false;
10829 }
10830 }
10831 return true;
10832 }
10833 };
10834
10835 // Matcher for checking that at least one element in range matches a given matcher.
10836 template <typename Matcher>
10838 Matcher m_matcher;
10839 public:
10840 AnyMatchMatcher(Matcher matcher):
10841 m_matcher(CATCH_MOVE(matcher))
10842 {}
10843
10844 std::string describe() const override {
10845 return "any match " + m_matcher.describe();
10846 }
10847
10848 template <typename RangeLike>
10849 bool match(RangeLike&& rng) const {
10850 for (auto&& elem : rng) {
10851 if (m_matcher.match(elem)) {
10852 return true;
10853 }
10854 }
10855 return false;
10856 }
10857 };
10858
10859 // Creates a matcher that checks whether a range contains element matching a matcher
10860 template <typename Matcher>
10861 AllMatchMatcher<Matcher> AllMatch(Matcher&& matcher) {
10862 return { CATCH_FORWARD(matcher) };
10863 }
10864
10865 // Creates a matcher that checks whether no element in a range matches a matcher.
10866 template <typename Matcher>
10867 NoneMatchMatcher<Matcher> NoneMatch(Matcher&& matcher) {
10868 return { CATCH_FORWARD(matcher) };
10869 }
10870
10871 // Creates a matcher that checks whether any element in a range matches a matcher.
10872 template <typename Matcher>
10873 AnyMatchMatcher<Matcher> AnyMatch(Matcher&& matcher) {
10874 return { CATCH_FORWARD(matcher) };
10875 }
10876 }
10877}
10878
10879#endif // CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
10880
10881
10882#ifndef CATCH_MATCHERS_STRING_HPP_INCLUDED
10883#define CATCH_MATCHERS_STRING_HPP_INCLUDED
10884
10885
10886#include <string>
10887
10888namespace Catch {
10889namespace Matchers {
10890
10892 CasedString( std::string const& str, CaseSensitive caseSensitivity );
10893 std::string adjustString( std::string const& str ) const;
10894 StringRef caseSensitivitySuffix() const;
10895
10896 CaseSensitive m_caseSensitivity;
10897 std::string m_str;
10898 };
10899
10900 class StringMatcherBase : public MatcherBase<std::string> {
10901 protected:
10902 CasedString m_comparator;
10903 StringRef m_operation;
10904
10905 public:
10906 StringMatcherBase( StringRef operation,
10907 CasedString const& comparator );
10908 std::string describe() const override;
10909 };
10910
10912 public:
10913 StringEqualsMatcher( CasedString const& comparator );
10914 bool match( std::string const& source ) const override;
10915 };
10917 public:
10918 StringContainsMatcher( CasedString const& comparator );
10919 bool match( std::string const& source ) const override;
10920 };
10922 public:
10923 StartsWithMatcher( CasedString const& comparator );
10924 bool match( std::string const& source ) const override;
10925 };
10926 class EndsWithMatcher final : public StringMatcherBase {
10927 public:
10928 EndsWithMatcher( CasedString const& comparator );
10929 bool match( std::string const& source ) const override;
10930 };
10931
10932 class RegexMatcher final : public MatcherBase<std::string> {
10933 std::string m_regex;
10934 CaseSensitive m_caseSensitivity;
10935
10936 public:
10937 RegexMatcher( std::string regex, CaseSensitive caseSensitivity );
10938 bool match( std::string const& matchee ) const override;
10939 std::string describe() const override;
10940 };
10941
10943 StringEqualsMatcher Equals( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
10945 StringContainsMatcher ContainsSubstring( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
10947 EndsWithMatcher EndsWith( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
10949 StartsWithMatcher StartsWith( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
10951 RegexMatcher Matches( std::string const& regex, CaseSensitive caseSensitivity = CaseSensitive::Yes );
10952
10953} // namespace Matchers
10954} // namespace Catch
10955
10956#endif // CATCH_MATCHERS_STRING_HPP_INCLUDED
10957
10958
10959#ifndef CATCH_MATCHERS_VECTOR_HPP_INCLUDED
10960#define CATCH_MATCHERS_VECTOR_HPP_INCLUDED
10961
10962
10963#include <algorithm>
10964
10965namespace Catch {
10966namespace Matchers {
10967
10968 template<typename T, typename Alloc>
10969 class VectorContainsElementMatcher final : public MatcherBase<std::vector<T, Alloc>> {
10970 T const& m_comparator;
10971
10972 public:
10973 VectorContainsElementMatcher(T const& comparator):
10974 m_comparator(comparator)
10975 {}
10976
10977 bool match(std::vector<T, Alloc> const& v) const override {
10978 for (auto const& el : v) {
10979 if (el == m_comparator) {
10980 return true;
10981 }
10982 }
10983 return false;
10984 }
10985
10986 std::string describe() const override {
10987 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
10988 }
10989 };
10990
10991 template<typename T, typename AllocComp, typename AllocMatch>
10992 class ContainsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
10993 std::vector<T, AllocComp> const& m_comparator;
10994
10995 public:
10996 ContainsMatcher(std::vector<T, AllocComp> const& comparator):
10997 m_comparator( comparator )
10998 {}
10999
11000 bool match(std::vector<T, AllocMatch> const& v) const override {
11001 // !TBD: see note in EqualsMatcher
11002 if (m_comparator.size() > v.size())
11003 return false;
11004 for (auto const& comparator : m_comparator) {
11005 auto present = false;
11006 for (const auto& el : v) {
11007 if (el == comparator) {
11008 present = true;
11009 break;
11010 }
11011 }
11012 if (!present) {
11013 return false;
11014 }
11015 }
11016 return true;
11017 }
11018 std::string describe() const override {
11019 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
11020 }
11021 };
11022
11023 template<typename T, typename AllocComp, typename AllocMatch>
11024 class EqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
11025 std::vector<T, AllocComp> const& m_comparator;
11026
11027 public:
11028 EqualsMatcher(std::vector<T, AllocComp> const& comparator):
11029 m_comparator( comparator )
11030 {}
11031
11032 bool match(std::vector<T, AllocMatch> const& v) const override {
11033 // !TBD: This currently works if all elements can be compared using !=
11034 // - a more general approach would be via a compare template that defaults
11035 // to using !=. but could be specialised for, e.g. std::vector<T> etc
11036 // - then just call that directly
11037 if (m_comparator.size() != v.size())
11038 return false;
11039 for (std::size_t i = 0; i < v.size(); ++i)
11040 if (m_comparator[i] != v[i])
11041 return false;
11042 return true;
11043 }
11044 std::string describe() const override {
11045 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
11046 }
11047 };
11048
11049 template<typename T, typename AllocComp, typename AllocMatch>
11050 class ApproxMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
11051 std::vector<T, AllocComp> const& m_comparator;
11052 mutable Catch::Approx approx = Catch::Approx::custom();
11053
11054 public:
11055 ApproxMatcher(std::vector<T, AllocComp> const& comparator):
11056 m_comparator( comparator )
11057 {}
11058
11059 bool match(std::vector<T, AllocMatch> const& v) const override {
11060 if (m_comparator.size() != v.size())
11061 return false;
11062 for (std::size_t i = 0; i < v.size(); ++i)
11063 if (m_comparator[i] != approx(v[i]))
11064 return false;
11065 return true;
11066 }
11067 std::string describe() const override {
11068 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
11069 }
11070 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
11071 ApproxMatcher& epsilon( T const& newEpsilon ) {
11072 approx.epsilon(static_cast<double>(newEpsilon));
11073 return *this;
11074 }
11075 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
11076 ApproxMatcher& margin( T const& newMargin ) {
11077 approx.margin(static_cast<double>(newMargin));
11078 return *this;
11079 }
11080 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
11081 ApproxMatcher& scale( T const& newScale ) {
11082 approx.scale(static_cast<double>(newScale));
11083 return *this;
11084 }
11085 };
11086
11087 template<typename T, typename AllocComp, typename AllocMatch>
11088 class UnorderedEqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
11089 std::vector<T, AllocComp> const& m_target;
11090
11091 public:
11092 UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target):
11093 m_target(target)
11094 {}
11095 bool match(std::vector<T, AllocMatch> const& vec) const override {
11096 if (m_target.size() != vec.size()) {
11097 return false;
11098 }
11099 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
11100 }
11101
11102 std::string describe() const override {
11103 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
11104 }
11105 };
11106
11107
11108 // The following functions create the actual matcher objects.
11109 // This allows the types to be inferred
11110
11112 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
11113 ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
11115 }
11116
11118 template<typename T, typename Alloc = std::allocator<T>>
11120 return VectorContainsElementMatcher<T, Alloc>(comparator);
11121 }
11122
11124 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
11125 EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
11126 return EqualsMatcher<T, AllocComp, AllocMatch>(comparator);
11127 }
11128
11130 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
11131 ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
11132 return ApproxMatcher<T, AllocComp, AllocMatch>(comparator);
11133 }
11134
11136 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
11139 }
11140
11141} // namespace Matchers
11142} // namespace Catch
11143
11144#endif // CATCH_MATCHERS_VECTOR_HPP_INCLUDED
11145
11146#endif // CATCH_MATCHERS_ALL_HPP_INCLUDED
11147
11148
11162#ifndef CATCH_REPORTERS_ALL_HPP_INCLUDED
11163#define CATCH_REPORTERS_ALL_HPP_INCLUDED
11164
11165
11166
11167#ifndef CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
11168#define CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
11169
11170
11171
11172#ifndef CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
11173#define CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
11174
11175
11176
11177#ifndef CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
11178#define CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
11179
11180
11181#include <map>
11182#include <string>
11183
11184namespace Catch {
11185 class ColourImpl;
11186
11198 protected:
11200 Detail::unique_ptr<IStream> m_wrapped_stream;
11203 std::ostream& m_stream;
11205 Detail::unique_ptr<ColourImpl> m_colour;
11207 std::map<std::string, std::string> m_customOptions;
11208
11209 public:
11210 ReporterBase( ReporterConfig&& config );
11211 ~ReporterBase() override; // = default;
11212
11219 void listReporters(
11220 std::vector<ReporterDescription> const& descriptions ) override;
11227 void listListeners(
11228 std::vector<ListenerDescription> const& descriptions ) override;
11236 void listTests( std::vector<TestCaseHandle> const& tests ) override;
11243 void listTags( std::vector<TagInfo> const& tags ) override;
11244 };
11245} // namespace Catch
11246
11247#endif // CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
11248
11249#include <vector>
11250
11251namespace Catch {
11252
11254 public:
11255 using ReporterBase::ReporterBase;
11256 ~StreamingReporterBase() override;
11257
11258 void benchmarkPreparing( StringRef ) override {}
11259 void benchmarkStarting( BenchmarkInfo const& ) override {}
11260 void benchmarkEnded( BenchmarkStats<> const& ) override {}
11261 void benchmarkFailed( StringRef ) override {}
11262
11263 void fatalErrorEncountered( StringRef /*error*/ ) override {}
11264 void noMatchingTestCases( StringRef /*unmatchedSpec*/ ) override {}
11265 void reportInvalidTestSpec( StringRef /*invalidArgument*/ ) override {}
11266
11267 void testRunStarting( TestRunInfo const& _testRunInfo ) override;
11268
11269 void testCaseStarting(TestCaseInfo const& _testInfo) override {
11270 currentTestCaseInfo = &_testInfo;
11271 }
11272 void testCasePartialStarting( TestCaseInfo const&, uint64_t ) override {}
11273 void sectionStarting(SectionInfo const& _sectionInfo) override {
11274 m_sectionStack.push_back(_sectionInfo);
11275 }
11276
11277 void assertionStarting( AssertionInfo const& ) override {}
11278 void assertionEnded( AssertionStats const& ) override {}
11279
11280 void sectionEnded(SectionStats const& /* _sectionStats */) override {
11281 m_sectionStack.pop_back();
11282 }
11283 void testCasePartialEnded( TestCaseStats const&, uint64_t ) override {}
11284 void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
11285 currentTestCaseInfo = nullptr;
11286 }
11287 void testRunEnded( TestRunStats const& /* _testRunStats */ ) override;
11288
11289 void skipTest(TestCaseInfo const&) override {
11290 // Don't do anything with this by default.
11291 // It can optionally be overridden in the derived class.
11292 }
11293
11294 protected:
11295 TestRunInfo currentTestRunInfo{ "test run has not started yet"_sr };
11296 TestCaseInfo const* currentTestCaseInfo = nullptr;
11297
11299 std::vector<SectionInfo> m_sectionStack;
11300 };
11301
11302} // end namespace Catch
11303
11304#endif // CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
11305
11306#include <string>
11307
11308namespace Catch {
11309
11311 public:
11312 using StreamingReporterBase::StreamingReporterBase;
11313 ~AutomakeReporter() override;
11314
11315 static std::string getDescription() {
11316 using namespace std::string_literals;
11317 return "Reports test results in the format of Automake .trs files"s;
11318 }
11319
11320 void testCaseEnded(TestCaseStats const& _testCaseStats) override;
11321 void skipTest(TestCaseInfo const& testInfo) override;
11322 };
11323
11324} // end namespace Catch
11325
11326#endif // CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
11327
11328
11329#ifndef CATCH_REPORTER_COMPACT_HPP_INCLUDED
11330#define CATCH_REPORTER_COMPACT_HPP_INCLUDED
11331
11332
11333
11334
11335namespace Catch {
11336
11338 public:
11339 using StreamingReporterBase::StreamingReporterBase;
11340
11341 ~CompactReporter() override;
11342
11343 static std::string getDescription();
11344
11345 void noMatchingTestCases( StringRef unmatchedSpec ) override;
11346
11347 void testRunStarting( TestRunInfo const& _testInfo ) override;
11348
11349 void assertionEnded(AssertionStats const& _assertionStats) override;
11350
11351 void sectionEnded(SectionStats const& _sectionStats) override;
11352
11353 void testRunEnded(TestRunStats const& _testRunStats) override;
11354
11355 };
11356
11357} // end namespace Catch
11358
11359#endif // CATCH_REPORTER_COMPACT_HPP_INCLUDED
11360
11361
11362#ifndef CATCH_REPORTER_CONSOLE_HPP_INCLUDED
11363#define CATCH_REPORTER_CONSOLE_HPP_INCLUDED
11364
11365
11366namespace Catch {
11367 // Fwd decls
11368 struct SummaryColumn;
11369 class TablePrinter;
11370
11372 Detail::unique_ptr<TablePrinter> m_tablePrinter;
11373
11374 public:
11376 ~ConsoleReporter() override;
11377 static std::string getDescription();
11378
11379 void noMatchingTestCases( StringRef unmatchedSpec ) override;
11380 void reportInvalidTestSpec( StringRef arg ) override;
11381
11382 void assertionStarting(AssertionInfo const&) override;
11383
11384 void assertionEnded(AssertionStats const& _assertionStats) override;
11385
11386 void sectionStarting(SectionInfo const& _sectionInfo) override;
11387 void sectionEnded(SectionStats const& _sectionStats) override;
11388
11389 void benchmarkPreparing( StringRef name ) override;
11390 void benchmarkStarting(BenchmarkInfo const& info) override;
11391 void benchmarkEnded(BenchmarkStats<> const& stats) override;
11392 void benchmarkFailed( StringRef error ) override;
11393
11394 void testCaseEnded(TestCaseStats const& _testCaseStats) override;
11395 void testRunEnded(TestRunStats const& _testRunStats) override;
11396 void testRunStarting(TestRunInfo const& _testRunInfo) override;
11397
11398 private:
11399 void lazyPrint();
11400
11401 void lazyPrintWithoutClosingBenchmarkTable();
11402 void lazyPrintRunInfo();
11403 void printTestCaseAndSectionHeader();
11404
11405 void printClosedHeader(std::string const& _name);
11406 void printOpenHeader(std::string const& _name);
11407
11408 // if string has a : in first line will set indent to follow it on
11409 // subsequent lines
11410 void printHeaderString(std::string const& _string, std::size_t indent = 0);
11411
11412
11413 void printTotals(Totals const& totals);
11414 void printSummaryRow(StringRef label, std::vector<SummaryColumn> const& cols, std::size_t row);
11415
11416 void printTotalsDivider(Totals const& totals);
11417 void printSummaryDivider();
11418
11419 bool m_headerPrinted = false;
11420 bool m_testRunInfoPrinted = false;
11421 };
11422
11423} // end namespace Catch
11424
11425#endif // CATCH_REPORTER_CONSOLE_HPP_INCLUDED
11426
11427
11428#ifndef CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
11429#define CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
11430
11431
11432#include <string>
11433#include <vector>
11434
11435namespace Catch {
11436
11437 namespace Detail {
11438
11440 class AssertionOrBenchmarkResult {
11441 // This should really be a variant, but this is much faster
11442 // to write and the data layout here is already terrible
11443 // enough that we do not have to care about the object size.
11444 Optional<AssertionStats> m_assertion;
11445 Optional<BenchmarkStats<>> m_benchmark;
11446 public:
11447 AssertionOrBenchmarkResult(AssertionStats const& assertion);
11448 AssertionOrBenchmarkResult(BenchmarkStats<> const& benchmark);
11449
11450 bool isAssertion() const;
11451 bool isBenchmark() const;
11452
11453 AssertionStats const& asAssertion() const;
11454 BenchmarkStats<> const& asBenchmark() const;
11455 };
11456 }
11457
11478 class CumulativeReporterBase : public ReporterBase {
11479 public:
11480 template<typename T, typename ChildNodeT>
11481 struct Node {
11482 explicit Node( T const& _value ) : value( _value ) {}
11483
11484 using ChildNodes = std::vector<Detail::unique_ptr<ChildNodeT>>;
11485 T value;
11486 ChildNodes children;
11487 };
11489 explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
11490
11491 bool operator == (SectionNode const& other) const {
11492 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
11493 }
11494
11495 bool hasAnyAssertions() const;
11496
11497 SectionStats stats;
11498 std::vector<Detail::unique_ptr<SectionNode>> childSections;
11499 std::vector<Detail::AssertionOrBenchmarkResult> assertionsAndBenchmarks;
11500 std::string stdOut;
11501 std::string stdErr;
11502 };
11503
11504
11507
11508 using ReporterBase::ReporterBase;
11509 ~CumulativeReporterBase() override;
11510
11511 void benchmarkPreparing( StringRef ) override {}
11512 void benchmarkStarting( BenchmarkInfo const& ) override {}
11513 void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
11514 void benchmarkFailed( StringRef ) override {}
11515
11516 void noMatchingTestCases( StringRef ) override {}
11517 void reportInvalidTestSpec( StringRef ) override {}
11518 void fatalErrorEncountered( StringRef /*error*/ ) override {}
11519
11520 void testRunStarting( TestRunInfo const& ) override {}
11521
11522 void testCaseStarting( TestCaseInfo const& ) override {}
11523 void testCasePartialStarting( TestCaseInfo const&, uint64_t ) override {}
11524 void sectionStarting( SectionInfo const& sectionInfo ) override;
11525
11526 void assertionStarting( AssertionInfo const& ) override {}
11527
11528 void assertionEnded( AssertionStats const& assertionStats ) override;
11529 void sectionEnded( SectionStats const& sectionStats ) override;
11530 void testCasePartialEnded( TestCaseStats const&, uint64_t ) override {}
11531 void testCaseEnded( TestCaseStats const& testCaseStats ) override;
11532 void testRunEnded( TestRunStats const& testRunStats ) override;
11534 virtual void testRunEndedCumulative() = 0;
11535
11536 void skipTest(TestCaseInfo const&) override {}
11537
11538 protected:
11540 bool m_shouldStoreSuccesfulAssertions = true;
11542 bool m_shouldStoreFailedAssertions = true;
11543
11544 // We need lazy construction here. We should probably refactor it
11545 // later, after the events are redone.
11547 Detail::unique_ptr<TestRunNode> m_testRun;
11548
11549 private:
11550 // Note: We rely on pointer identity being stable, which is why
11551 // we store pointers to the nodes rather than the values.
11552 std::vector<Detail::unique_ptr<TestCaseNode>> m_testCases;
11553 // Root section of the _current_ test case
11554 Detail::unique_ptr<SectionNode> m_rootSection;
11555 // Deepest section of the _current_ test case
11556 SectionNode* m_deepestSection = nullptr;
11557 // Stack of _active_ sections in the _current_ test case
11558 std::vector<SectionNode*> m_sectionStack;
11559 };
11560
11561} // end namespace Catch
11562
11563#endif // CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
11564
11565
11566#ifndef CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
11567#define CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
11568
11569
11570namespace Catch {
11571
11580 public:
11581 using IEventListener::IEventListener;
11582
11583 void reportInvalidTestSpec( StringRef unmatchedSpec ) override;
11584 void fatalErrorEncountered( StringRef error ) override;
11585
11586 void benchmarkPreparing( StringRef name ) override;
11587 void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
11588 void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
11589 void benchmarkFailed( StringRef error ) override;
11590
11591 void assertionStarting( AssertionInfo const& assertionInfo ) override;
11592 void assertionEnded( AssertionStats const& assertionStats ) override;
11593
11594 void listReporters(
11595 std::vector<ReporterDescription> const& descriptions ) override;
11596 void listListeners(
11597 std::vector<ListenerDescription> const& descriptions ) override;
11598 void listTests( std::vector<TestCaseHandle> const& tests ) override;
11599 void listTags( std::vector<TagInfo> const& tagInfos ) override;
11600
11601 void noMatchingTestCases( StringRef unmatchedSpec ) override;
11602 void testRunStarting( TestRunInfo const& testRunInfo ) override;
11603 void testCaseStarting( TestCaseInfo const& testInfo ) override;
11604 void testCasePartialStarting( TestCaseInfo const& testInfo,
11605 uint64_t partNumber ) override;
11606 void sectionStarting( SectionInfo const& sectionInfo ) override;
11607 void sectionEnded( SectionStats const& sectionStats ) override;
11608 void testCasePartialEnded( TestCaseStats const& testCaseStats,
11609 uint64_t partNumber ) override;
11610 void testCaseEnded( TestCaseStats const& testCaseStats ) override;
11611 void testRunEnded( TestRunStats const& testRunStats ) override;
11612 void skipTest( TestCaseInfo const& testInfo ) override;
11613 };
11614
11615} // end namespace Catch
11616
11617#endif // CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
11618
11619
11620#ifndef CATCH_REPORTER_HELPERS_HPP_INCLUDED
11621#define CATCH_REPORTER_HELPERS_HPP_INCLUDED
11622
11623#include <iosfwd>
11624#include <string>
11625#include <vector>
11626
11627
11628namespace Catch {
11629
11630 class IConfig;
11631 class TestCaseHandle;
11632 class ColourImpl;
11633
11634 // Returns double formatted as %.3f (format expected on output)
11635 std::string getFormattedDuration( double duration );
11636
11638 bool shouldShowDuration( IConfig const& config, double duration );
11639
11640 std::string serializeFilters( std::vector<std::string> const& filters );
11641
11643 char c;
11644 constexpr lineOfChars( char c_ ): c( c_ ) {}
11645
11646 friend std::ostream& operator<<( std::ostream& out, lineOfChars value );
11647 };
11648
11657 void
11658 defaultListReporters( std::ostream& out,
11659 std::vector<ReporterDescription> const& descriptions,
11660 Verbosity verbosity );
11661
11666 void defaultListListeners( std::ostream& out,
11667 std::vector<ListenerDescription> const& descriptions );
11668
11676 void defaultListTags( std::ostream& out, std::vector<TagInfo> const& tags, bool isFiltered );
11677
11687 void defaultListTests( std::ostream& out,
11688 ColourImpl* streamColour,
11689 std::vector<TestCaseHandle> const& tests,
11690 bool isFiltered,
11691 Verbosity verbosity );
11692
11693} // end namespace Catch
11694
11695#endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED
11696
11697
11698#ifndef CATCH_REPORTER_JUNIT_HPP_INCLUDED
11699#define CATCH_REPORTER_JUNIT_HPP_INCLUDED
11700
11701
11702
11703namespace Catch {
11704
11705 class JunitReporter final : public CumulativeReporterBase {
11706 public:
11707 JunitReporter(ReporterConfig&& _config);
11708
11709 ~JunitReporter() override = default;
11710
11711 static std::string getDescription();
11712
11713 void testRunStarting(TestRunInfo const& runInfo) override;
11714
11715 void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
11716 void assertionEnded(AssertionStats const& assertionStats) override;
11717
11718 void testCaseEnded(TestCaseStats const& testCaseStats) override;
11719
11720 void testRunEndedCumulative() override;
11721
11722 private:
11723 void writeRun(TestRunNode const& testRunNode, double suiteTime);
11724
11725 void writeTestCase(TestCaseNode const& testCaseNode);
11726
11727 void writeSection( std::string const& className,
11728 std::string const& rootName,
11729 SectionNode const& sectionNode,
11730 bool testOkToFail );
11731
11732 void writeAssertions(SectionNode const& sectionNode);
11733 void writeAssertion(AssertionStats const& stats);
11734
11735 XmlWriter xml;
11736 Timer suiteTimer;
11737 std::string stdOutForSuite;
11738 std::string stdErrForSuite;
11739 unsigned int unexpectedExceptions = 0;
11740 bool m_okToFail = false;
11741 };
11742
11743} // end namespace Catch
11744
11745#endif // CATCH_REPORTER_JUNIT_HPP_INCLUDED
11746
11747
11748#ifndef CATCH_REPORTER_MULTI_HPP_INCLUDED
11749#define CATCH_REPORTER_MULTI_HPP_INCLUDED
11750
11751
11752namespace Catch {
11753
11754 class MultiReporter final : public IEventListener {
11755 /*
11756 * Stores all added reporters and listeners
11757 *
11758 * All Listeners are stored before all reporters, and individual
11759 * listeners/reporters are stored in order of insertion.
11760 */
11761 std::vector<IEventListenerPtr> m_reporterLikes;
11762 bool m_haveNoncapturingReporters = false;
11763
11764 // Keep track of how many listeners we have already inserted,
11765 // so that we can insert them into the main vector at the right place
11766 size_t m_insertedListeners = 0;
11767
11768 void updatePreferences(IEventListener const& reporterish);
11769
11770 public:
11771 using IEventListener::IEventListener;
11772
11773 void addListener( IEventListenerPtr&& listener );
11774 void addReporter( IEventListenerPtr&& reporter );
11775
11776 public: // IEventListener
11777
11778 void noMatchingTestCases( StringRef unmatchedSpec ) override;
11779 void fatalErrorEncountered( StringRef error ) override;
11780 void reportInvalidTestSpec( StringRef arg ) override;
11781
11782 void benchmarkPreparing( StringRef name ) override;
11783 void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
11784 void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
11785 void benchmarkFailed( StringRef error ) override;
11786
11787 void testRunStarting( TestRunInfo const& testRunInfo ) override;
11788 void testCaseStarting( TestCaseInfo const& testInfo ) override;
11789 void testCasePartialStarting(TestCaseInfo const& testInfo, uint64_t partNumber) override;
11790 void sectionStarting( SectionInfo const& sectionInfo ) override;
11791 void assertionStarting( AssertionInfo const& assertionInfo ) override;
11792
11793 void assertionEnded( AssertionStats const& assertionStats ) override;
11794 void sectionEnded( SectionStats const& sectionStats ) override;
11795 void testCasePartialEnded(TestCaseStats const& testInfo, uint64_t partNumber) override;
11796 void testCaseEnded( TestCaseStats const& testCaseStats ) override;
11797 void testRunEnded( TestRunStats const& testRunStats ) override;
11798
11799 void skipTest( TestCaseInfo const& testInfo ) override;
11800
11801 void listReporters(std::vector<ReporterDescription> const& descriptions) override;
11802 void listListeners(std::vector<ListenerDescription> const& descriptions) override;
11803 void listTests(std::vector<TestCaseHandle> const& tests) override;
11804 void listTags(std::vector<TagInfo> const& tags) override;
11805
11806
11807 };
11808
11809} // end namespace Catch
11810
11811#endif // CATCH_REPORTER_MULTI_HPP_INCLUDED
11812
11813
11814#ifndef CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
11815#define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
11816
11817
11818#include <type_traits>
11819
11820namespace Catch {
11821
11822 namespace Detail {
11823
11824 template <typename T, typename = void>
11825 struct has_description : std::false_type {};
11826
11827 template <typename T>
11829 T,
11830 void_t<decltype( T::getDescription() )>>
11831 : std::true_type {};
11832
11835 void registerReporterImpl( std::string const& name,
11836 IReporterFactoryPtr reporterPtr );
11837
11838 } // namespace Detail
11839
11840 class IEventListener;
11841 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
11842
11843 template <typename T>
11845
11846 IEventListenerPtr create( ReporterConfig&& config ) const override {
11847 return Detail::make_unique<T>( CATCH_MOVE(config) );
11848 }
11849
11850 std::string getDescription() const override {
11851 return T::getDescription();
11852 }
11853 };
11854
11855
11856 template<typename T>
11858 public:
11859 explicit ReporterRegistrar( std::string const& name ) {
11860 registerReporterImpl( name,
11861 Detail::make_unique<ReporterFactory<T>>() );
11862 }
11863 };
11864
11865 template<typename T>
11867
11868 class TypedListenerFactory : public EventListenerFactory {
11869 StringRef m_listenerName;
11870
11871 std::string getDescriptionImpl( std::true_type ) const {
11872 return T::getDescription();
11873 }
11874
11875 std::string getDescriptionImpl( std::false_type ) const {
11876 return "(No description provided)";
11877 }
11878
11879 public:
11880 TypedListenerFactory( StringRef listenerName ):
11881 m_listenerName( listenerName ) {}
11882
11883 IEventListenerPtr create( IConfig const* config ) const override {
11884 return Detail::make_unique<T>( config );
11885 }
11886
11887 StringRef getName() const override {
11888 return m_listenerName;
11889 }
11890
11891 std::string getDescription() const override {
11892 return getDescriptionImpl( Detail::has_description<T>{} );
11893 }
11894 };
11895
11896 public:
11897 ListenerRegistrar(StringRef listenerName) {
11898 getMutableRegistryHub().registerListener( Detail::make_unique<TypedListenerFactory>(listenerName) );
11899 }
11900 };
11901}
11902
11903#if !defined(CATCH_CONFIG_DISABLE)
11904
11905# define CATCH_REGISTER_REPORTER( name, reporterType ) \
11906 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
11907 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
11908 namespace { \
11909 Catch::ReporterRegistrar<reporterType> INTERNAL_CATCH_UNIQUE_NAME( \
11910 catch_internal_RegistrarFor )( name ); \
11911 } \
11912 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
11913
11914# define CATCH_REGISTER_LISTENER( listenerType ) \
11915 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
11916 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
11917 namespace { \
11918 Catch::ListenerRegistrar<listenerType> INTERNAL_CATCH_UNIQUE_NAME( \
11919 catch_internal_RegistrarFor )( #listenerType ); \
11920 } \
11921 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
11922
11923#else // CATCH_CONFIG_DISABLE
11924
11925#define CATCH_REGISTER_REPORTER(name, reporterType)
11926#define CATCH_REGISTER_LISTENER(listenerType)
11927
11928#endif // CATCH_CONFIG_DISABLE
11929
11930#endif // CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
11931
11932
11933#ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
11934#define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
11935
11936
11937
11938namespace Catch {
11939
11940 class SonarQubeReporter final : public CumulativeReporterBase {
11941 public:
11943 : CumulativeReporterBase(CATCH_MOVE(config))
11944 , xml(m_stream) {
11947 m_shouldStoreSuccesfulAssertions = false;
11948 }
11949
11950 ~SonarQubeReporter() override = default;
11951
11952 static std::string getDescription() {
11953 using namespace std::string_literals;
11954 return "Reports test results in the Generic Test Data SonarQube XML format"s;
11955 }
11956
11957 void testRunStarting( TestRunInfo const& testRunInfo ) override;
11958
11959 void testRunEndedCumulative() override {
11960 writeRun( *m_testRun );
11961 xml.endElement();
11962 }
11963
11964 void writeRun( TestRunNode const& groupNode );
11965
11966 void writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes);
11967
11968 void writeTestCase(TestCaseNode const& testCaseNode);
11969
11970 void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail);
11971
11972 void writeAssertions(SectionNode const& sectionNode, bool okToFail);
11973
11974 void writeAssertion(AssertionStats const& stats, bool okToFail);
11975
11976 private:
11977 XmlWriter xml;
11978 };
11979
11980
11981} // end namespace Catch
11982
11983#endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
11984
11985
11986#ifndef CATCH_REPORTER_TAP_HPP_INCLUDED
11987#define CATCH_REPORTER_TAP_HPP_INCLUDED
11988
11989
11990namespace Catch {
11991
11992 class TAPReporter final : public StreamingReporterBase {
11993 public:
11994 TAPReporter( ReporterConfig&& config ):
11995 StreamingReporterBase( CATCH_MOVE(config) ) {
11997 }
11998 ~TAPReporter() override = default;
11999
12000 static std::string getDescription() {
12001 using namespace std::string_literals;
12002 return "Reports test results in TAP format, suitable for test harnesses"s;
12003 }
12004
12005 void testRunStarting( TestRunInfo const& testInfo ) override;
12006
12007 void noMatchingTestCases( StringRef unmatchedSpec ) override;
12008
12009 void assertionEnded(AssertionStats const& _assertionStats) override;
12010
12011 void testRunEnded(TestRunStats const& _testRunStats) override;
12012
12013 private:
12014 std::size_t counter = 0;
12015 };
12016
12017} // end namespace Catch
12018
12019#endif // CATCH_REPORTER_TAP_HPP_INCLUDED
12020
12021
12022#ifndef CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
12023#define CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
12024
12025
12026#include <cstring>
12027
12028#ifdef __clang__
12029# pragma clang diagnostic push
12030# pragma clang diagnostic ignored "-Wpadded"
12031#endif
12032
12033namespace Catch {
12034
12035 class TeamCityReporter final : public StreamingReporterBase {
12036 public:
12037 TeamCityReporter( ReporterConfig&& _config )
12038 : StreamingReporterBase( CATCH_MOVE(_config) )
12039 {
12041 }
12042
12043 ~TeamCityReporter() override;
12044
12045 static std::string getDescription() {
12046 using namespace std::string_literals;
12047 return "Reports test results as TeamCity service messages"s;
12048 }
12049
12050 void testRunStarting( TestRunInfo const& groupInfo ) override;
12051 void testRunEnded( TestRunStats const& testGroupStats ) override;
12052
12053
12054 void assertionEnded(AssertionStats const& assertionStats) override;
12055
12056 void sectionStarting(SectionInfo const& sectionInfo) override {
12057 m_headerPrintedForThisSection = false;
12059 }
12060
12061 void testCaseStarting(TestCaseInfo const& testInfo) override;
12062
12063 void testCaseEnded(TestCaseStats const& testCaseStats) override;
12064
12065 private:
12066 void printSectionHeader(std::ostream& os);
12067
12068 bool m_headerPrintedForThisSection = false;
12069 Timer m_testTimer;
12070 };
12071
12072} // end namespace Catch
12073
12074#ifdef __clang__
12075# pragma clang diagnostic pop
12076#endif
12077
12078#endif // CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
12079
12080
12081#ifndef CATCH_REPORTER_XML_HPP_INCLUDED
12082#define CATCH_REPORTER_XML_HPP_INCLUDED
12083
12084
12085
12086
12087namespace Catch {
12088 class XmlReporter : public StreamingReporterBase {
12089 public:
12090 XmlReporter(ReporterConfig&& _config);
12091
12092 ~XmlReporter() override;
12093
12094 static std::string getDescription();
12095
12096 virtual std::string getStylesheetRef() const;
12097
12098 void writeSourceInfo(SourceLineInfo const& sourceInfo);
12099
12100 public: // StreamingReporterBase
12101
12102 void testRunStarting(TestRunInfo const& testInfo) override;
12103
12104 void testCaseStarting(TestCaseInfo const& testInfo) override;
12105
12106 void sectionStarting(SectionInfo const& sectionInfo) override;
12107
12108 void assertionStarting(AssertionInfo const&) override;
12109
12110 void assertionEnded(AssertionStats const& assertionStats) override;
12111
12112 void sectionEnded(SectionStats const& sectionStats) override;
12113
12114 void testCaseEnded(TestCaseStats const& testCaseStats) override;
12115
12116 void testRunEnded(TestRunStats const& testRunStats) override;
12117
12118 void benchmarkPreparing( StringRef name ) override;
12119 void benchmarkStarting(BenchmarkInfo const&) override;
12120 void benchmarkEnded(BenchmarkStats<> const&) override;
12121 void benchmarkFailed( StringRef error ) override;
12122
12123 void listReporters(std::vector<ReporterDescription> const& descriptions) override;
12124 void listListeners(std::vector<ListenerDescription> const& descriptions) override;
12125 void listTests(std::vector<TestCaseHandle> const& tests) override;
12126 void listTags(std::vector<TagInfo> const& tags) override;
12127
12128 private:
12129 Timer m_testCaseTimer;
12130 XmlWriter m_xml;
12131 int m_sectionDepth = 0;
12132 };
12133
12134} // end namespace Catch
12135
12136#endif // CATCH_REPORTER_XML_HPP_INCLUDED
12137
12138#endif // CATCH_REPORTERS_ALL_HPP_INCLUDED
12139
12140#endif // CATCH_ALL_HPP_INCLUDED
12141#endif // CATCH_AMALGAMATED_HPP_INCLUDED
WithinAbsMatcher WithinAbs(double target, double margin)
Creates a matcher that accepts numbers within certain range of target.
Definition catch_amalgamated.cpp:7366
Column Spacer(size_t spaceWidth)
Creates a column that serves as an empty space of specific width.
Definition catch_amalgamated.cpp:6698
void defaultListReporters(std::ostream &out, std::vector< ReporterDescription > const &descriptions, Verbosity verbosity)
Lists reporter descriptions to the provided stream in user-friendly format.
Definition catch_amalgamated.cpp:7784
StringContainsMatcher ContainsSubstring(std::string const &str, CaseSensitive caseSensitivity)
Creates matcher that accepts strings that contain str
Definition catch_amalgamated.cpp:7478
void defaultListListeners(std::ostream &out, std::vector< ListenerDescription > const &descriptions)
Lists listeners descriptions to the provided stream in user-friendly format.
Definition catch_amalgamated.cpp:7817
HasSizeMatcher SizeIs(std::size_t sz)
Creates a matcher that accepts ranges/containers with specific size.
Definition catch_amalgamated.cpp:7582
WithinRelMatcher WithinRel(double target, double eps)
Creates a matcher that accepts doubles within certain relative range of target.
Definition catch_amalgamated.cpp:7370
StringEqualsMatcher Equals(std::string const &str, CaseSensitive caseSensitivity)
Creates matcher that accepts strings that are exactly equal to str
Definition catch_amalgamated.cpp:7475
std::vector< std::string > splitReporterSpec(StringRef reporterSpec)
Splits the reporter spec into reporter name and kv-pair options.
Definition catch_amalgamated.cpp:4692
WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff)
Creates a matcher that accepts doubles within certain ULP range of target.
Definition catch_amalgamated.cpp:7358
StartsWithMatcher StartsWith(std::string const &str, CaseSensitive caseSensitivity)
Creates matcher that accepts strings that start with str
Definition catch_amalgamated.cpp:7484
void defaultListTags(std::ostream &out, std::vector< TagInfo > const &tags, bool isFiltered)
Lists tag information to the provided stream in user-friendly format.
Definition catch_amalgamated.cpp:7844
IsEmptyMatcher IsEmpty()
Creates a matcher that accepts empty ranges/containers.
Definition catch_amalgamated.cpp:7578
Optional< ReporterSpec > parseReporterSpec(StringRef reporterSpec)
Parses provided reporter spec string into.
Definition catch_amalgamated.cpp:4764
std::string trim(std::string const &str)
Returns a new string without whitespace at the start/end.
Definition catch_amalgamated.cpp:5674
RegexMatcher Matches(std::string const &regex, CaseSensitive caseSensitivity)
Creates matcher that accepts strings matching regex
Definition catch_amalgamated.cpp:7488
void defaultListTests(std::ostream &out, ColourImpl *streamColour, std::vector< TestCaseHandle > const &tests, bool isFiltered, Verbosity verbosity)
Lists test case information to the provided stream in user-friendly format.
Definition catch_amalgamated.cpp:7866
EndsWithMatcher EndsWith(std::string const &str, CaseSensitive caseSensitivity)
Creates matcher that accepts strings that end with str
Definition catch_amalgamated.cpp:7481
ExceptionMessageMatcher Message(std::string const &message)
Creates a matcher that checks whether a std derived exception has the provided message.
Definition catch_amalgamated.cpp:7644
std::enable_if_t<!Detail::is_matcher< T >::value, ContainsElementMatcher< T, std::equal_to<> > > Contains(T &&elem)
Creates a matcher that checks whether a range contains a specific element.
Definition catch_amalgamated.hpp:10602
uint64_t ulpDistance(FP lhs, FP rhs)
Calculates the ULP distance between two floating point numbers.
Definition catch_amalgamated.hpp:8483
UnorderedEqualsMatcher< T, AllocComp, AllocMatch > UnorderedEquals(std::vector< T, AllocComp > const &target)
Creates a matcher that matches vectors that is equal to target modulo permutation.
Definition catch_amalgamated.hpp:11137
ResultType
Denotes type of a parsing result.
Definition catch_amalgamated.hpp:4563
@ RuntimeError
Error in parsing inputs.
@ LogicError
Error in user-specified arguments for construction.
#define CATCH_MOVE(...)
Replacement for std::move with better compile time performance.
Definition catch_amalgamated.hpp:741
VectorContainsElementMatcher< T, Alloc > VectorContains(T const &comparator)
Creates a matcher that matches vectors that contain comparator as an element.
Definition catch_amalgamated.hpp:11119
ColourMode
Definition catch_amalgamated.hpp:231
@ None
Don't use any colour.
@ PlatformDefault
Let Catch2 pick implementation based on platform detection.
@ Win32
Use Win32 console colour API.
@ ANSI
Use ANSI colour code escapes.
#define CATCH_FORWARD(...)
Replacement for std::forward with better compile time performance.
Definition catch_amalgamated.hpp:744
Definition catch_amalgamated.hpp:3558
Definition catch_amalgamated.hpp:5525
Definition catch_amalgamated.hpp:971
Definition catch_amalgamated.hpp:11310
void skipTest(TestCaseInfo const &testInfo) override
Called with test cases that are skipped due to the test run aborting.
Definition catch_amalgamated.cpp:7673
void testCaseEnded(TestCaseStats const &_testCaseStats) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.cpp:7659
Definition catch_amalgamated.hpp:5311
Definition catch_amalgamated.hpp:4335
Definition catch_amalgamated.hpp:4949
Definition catch_amalgamated.hpp:5081
Definition catch_amalgamated.hpp:4632
Definition catch_amalgamated.hpp:4876
Definition catch_amalgamated.hpp:4687
Definition catch_amalgamated.hpp:4863
Definition catch_amalgamated.hpp:4884
Definition catch_amalgamated.hpp:4570
Definition catch_amalgamated.hpp:4586
Definition catch_amalgamated.hpp:4529
Definition catch_amalgamated.hpp:5007
Definition catch_amalgamated.hpp:4960
Definition catch_amalgamated.hpp:5032
RAII wrapper around writing specific colour of text using specific colour impl into a stream.
Definition catch_amalgamated.hpp:3982
friend std::ostream & operator<<(std::ostream &lhs, ColourGuard &&guard)
Engages the guard and starts using colour.
Definition catch_amalgamated.hpp:4022
ColourGuard & engage(std::ostream &stream) &
Explicitly engages colour for given stream.
Definition catch_amalgamated.cpp:3267
friend std::ostream & operator<<(std::ostream &lhs, ColourGuard &guard)
Engages the guard and starts using colour.
Definition catch_amalgamated.hpp:4016
~ColourGuard()
Removes colour if the guard was engaged.
Definition catch_amalgamated.cpp:3260
Definition catch_amalgamated.hpp:11337
void assertionEnded(AssertionStats const &_assertionStats) override
Called after assertion was fully evaluated.
Definition catch_amalgamated.cpp:8233
void testRunStarting(TestRunInfo const &_testInfo) override
Called once in a testing run before tests are started.
Definition catch_amalgamated.cpp:8223
void sectionEnded(SectionStats const &_sectionStats) override
Called after a SECTION has finished running.
Definition catch_amalgamated.cpp:8251
void testRunEnded(TestRunStats const &_testRunStats) override
Called once after all tests in a testing run are finished.
Definition catch_amalgamated.cpp:8258
void noMatchingTestCases(StringRef unmatchedSpec) override
Called when no test cases match provided test spec.
Definition catch_amalgamated.cpp:8219
Definition catch_amalgamated.hpp:4202
Definition catch_amalgamated.hpp:11371
void testCaseEnded(TestCaseStats const &_testCaseStats) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.cpp:8734
void sectionStarting(SectionInfo const &_sectionInfo) override
Called when a SECTION is being entered. Not called for skipped sections.
Definition catch_amalgamated.cpp:8660
void benchmarkFailed(StringRef error) override
Called if running the benchmarks fails for any reason.
Definition catch_amalgamated.cpp:8727
void testRunEnded(TestRunStats const &_testRunStats) override
Called once after all tests in a testing run are finished.
Definition catch_amalgamated.cpp:8739
void benchmarkStarting(BenchmarkInfo const &info) override
Called after probe but before the user-code is being benchmarked.
Definition catch_amalgamated.cpp:8704
void reportInvalidTestSpec(StringRef arg) override
Called for all invalid test specs from the cli.
Definition catch_amalgamated.cpp:8638
void sectionEnded(SectionStats const &_sectionStats) override
Called after a SECTION has finished running.
Definition catch_amalgamated.cpp:8665
void testRunStarting(TestRunInfo const &_testRunInfo) override
Called once in a testing run before tests are started.
Definition catch_amalgamated.cpp:8745
void assertionStarting(AssertionInfo const &) override
Called before assertion success/failure is evaluated.
Definition catch_amalgamated.cpp:8642
void noMatchingTestCases(StringRef unmatchedSpec) override
Called when no test cases match provided test spec.
Definition catch_amalgamated.cpp:8634
void benchmarkEnded(BenchmarkStats<> const &stats) override
Called with the benchmark results if benchmark successfully finishes.
Definition catch_amalgamated.cpp:8710
void benchmarkPreparing(StringRef name) override
Called when user-code is being probed before the actual benchmark runs.
Definition catch_amalgamated.cpp:8687
void assertionEnded(AssertionStats const &_assertionStats) override
Called after assertion was fully evaluated.
Definition catch_amalgamated.cpp:8644
Definition catch_amalgamated.hpp:8302
Definition catch_amalgamated.hpp:2948
Deriving classes become noncopyable and nonmovable.
Definition catch_amalgamated.hpp:74
Base class to simplify implementing listeners.
Definition catch_amalgamated.hpp:11579
void listReporters(std::vector< ReporterDescription > const &descriptions) override
Writes out information about provided reporters using reporter-specific format.
Definition catch_amalgamated.cpp:7922
void testRunEnded(TestRunStats const &testRunStats) override
Called once after all tests in a testing run are finished.
Definition catch_amalgamated.cpp:7937
void fatalErrorEncountered(StringRef error) override
Called if a fatal error (signal/structured exception) occured.
Definition catch_amalgamated.cpp:7912
void reportInvalidTestSpec(StringRef unmatchedSpec) override
Called for all invalid test specs from the cli.
Definition catch_amalgamated.cpp:7929
void sectionEnded(SectionStats const &sectionStats) override
Called after a SECTION has finished running.
Definition catch_amalgamated.cpp:7934
void testCaseEnded(TestCaseStats const &testCaseStats) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.cpp:7936
void listListeners(std::vector< ListenerDescription > const &descriptions) override
Writes out the provided listeners descriptions using reporter-specific format.
Definition catch_amalgamated.cpp:7924
void testRunStarting(TestRunInfo const &testRunInfo) override
Called once in a testing run before tests are started.
Definition catch_amalgamated.cpp:7930
void sectionStarting(SectionInfo const &sectionInfo) override
Called when a SECTION is being entered. Not called for skipped sections.
Definition catch_amalgamated.cpp:7933
void benchmarkFailed(StringRef error) override
Called if running the benchmarks fails for any reason.
Definition catch_amalgamated.cpp:7917
void listTags(std::vector< TagInfo > const &tagInfos) override
Writes out information about the provided tags using reporter-specific format.
Definition catch_amalgamated.cpp:7927
void noMatchingTestCases(StringRef unmatchedSpec) override
Called when no test cases match provided test spec.
Definition catch_amalgamated.cpp:7928
void skipTest(TestCaseInfo const &testInfo) override
Called with test cases that are skipped due to the test run aborting.
Definition catch_amalgamated.cpp:7938
void assertionEnded(AssertionStats const &assertionStats) override
Called after assertion was fully evaluated.
Definition catch_amalgamated.cpp:7921
void benchmarkStarting(BenchmarkInfo const &benchmarkInfo) override
Called after probe but before the user-code is being benchmarked.
Definition catch_amalgamated.cpp:7915
void testCasePartialStarting(TestCaseInfo const &testInfo, uint64_t partNumber) override
Called every time a TEST_CASE is entered, including repeats (due to sections)
Definition catch_amalgamated.cpp:7932
void listTests(std::vector< TestCaseHandle > const &tests) override
Writes out information about provided tests using reporter-specific format.
Definition catch_amalgamated.cpp:7926
void benchmarkPreparing(StringRef name) override
Called when user-code is being probed before the actual benchmark runs.
Definition catch_amalgamated.cpp:7914
void testCasePartialEnded(TestCaseStats const &testCaseStats, uint64_t partNumber) override
Called every time a TEST_CASE is entered, including repeats (due to sections)
Definition catch_amalgamated.cpp:7935
void assertionStarting(AssertionInfo const &assertionInfo) override
Called before assertion success/failure is evaluated.
Definition catch_amalgamated.cpp:7919
void testCaseStarting(TestCaseInfo const &testInfo) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.cpp:7931
void benchmarkEnded(BenchmarkStats<> const &benchmarkStats) override
Called with the benchmark results if benchmark successfully finishes.
Definition catch_amalgamated.cpp:7916
Definition catch_amalgamated.hpp:7932
virtual std::string getDescription() const =0
Return listener's description if available.
virtual StringRef getName() const =0
Return a meaningful name for the listener, e.g. its type name.
Definition catch_amalgamated.hpp:6943
Definition catch_amalgamated.hpp:5427
Definition catch_amalgamated.hpp:7083
Definition catch_amalgamated.hpp:7595
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7618
Definition catch_amalgamated.hpp:7458
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7481
Definition catch_amalgamated.hpp:7264
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7276
Definition catch_amalgamated.hpp:7113
bool countedNext()
Attempts to move the generator to the next element.
Definition catch_amalgamated.cpp:2028
StringRef currentElementAsString() const
Returns generator's current element as user-friendly string.
Definition catch_amalgamated.cpp:2037
Definition catch_amalgamated.hpp:7226
GeneratorWrapper(IGenerator< T > *generator)
Takes ownership of the passed pointer.
Definition catch_amalgamated.hpp:7230
Definition catch_amalgamated.hpp:7294
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7334
Definition catch_amalgamated.hpp:7202
Definition catch_amalgamated.hpp:7841
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7860
Definition catch_amalgamated.hpp:7554
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7571
Definition catch_amalgamated.hpp:7795
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7821
Definition catch_amalgamated.hpp:7498
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7523
Definition catch_amalgamated.hpp:7245
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7258
Definition catch_amalgamated.hpp:7421
bool next() override
Attempts to move the generator to the next element.
Definition catch_amalgamated.hpp:7435
Definition catch_amalgamated.hpp:251
Definition catch_amalgamated.hpp:682
The common base for all reporters and event listeners.
Definition catch_amalgamated.hpp:1440
virtual void sectionEnded(SectionStats const &sectionStats)=0
Called after a SECTION has finished running.
virtual void testCasePartialEnded(TestCaseStats const &testCaseStats, uint64_t partNumber)=0
Called every time a TEST_CASE is entered, including repeats (due to sections)
virtual void testCaseStarting(TestCaseInfo const &testInfo)=0
Called once for each TEST_CASE, no matter how many times it is entered.
IConfig const * m_config
The test run's config as filled in from CLI and defaults.
Definition catch_amalgamated.hpp:1445
virtual void skipTest(TestCaseInfo const &testInfo)=0
Called with test cases that are skipped due to the test run aborting.
virtual void testRunStarting(TestRunInfo const &testRunInfo)=0
Called once in a testing run before tests are started.
virtual void assertionEnded(AssertionStats const &assertionStats)=0
Called after assertion was fully evaluated.
virtual void listTags(std::vector< TagInfo > const &tags)=0
Writes out information about the provided tags using reporter-specific format.
virtual void listTests(std::vector< TestCaseHandle > const &tests)=0
Writes out information about provided tests using reporter-specific format.
virtual void benchmarkEnded(BenchmarkStats<> const &benchmarkStats)=0
Called with the benchmark results if benchmark successfully finishes.
virtual void assertionStarting(AssertionInfo const &assertionInfo)=0
Called before assertion success/failure is evaluated.
virtual void listReporters(std::vector< ReporterDescription > const &descriptions)=0
Writes out information about provided reporters using reporter-specific format.
virtual void benchmarkFailed(StringRef benchmarkName)=0
Called if running the benchmarks fails for any reason.
virtual void benchmarkStarting(BenchmarkInfo const &benchmarkInfo)=0
Called after probe but before the user-code is being benchmarked.
virtual void testRunEnded(TestRunStats const &testRunStats)=0
Called once after all tests in a testing run are finished.
virtual void testCasePartialStarting(TestCaseInfo const &testInfo, uint64_t partNumber)=0
Called every time a TEST_CASE is entered, including repeats (due to sections)
virtual void sectionStarting(SectionInfo const &sectionInfo)=0
Called when a SECTION is being entered. Not called for skipped sections.
virtual void testCaseEnded(TestCaseStats const &testCaseStats)=0
Called once for each TEST_CASE, no matter how many times it is entered.
virtual void benchmarkPreparing(StringRef benchmarkName)=0
Called when user-code is being probed before the actual benchmark runs.
virtual void listListeners(std::vector< ListenerDescription > const &descriptions)=0
Writes out the provided listeners descriptions using reporter-specific format.
virtual void reportInvalidTestSpec(StringRef invalidArgument)=0
Called for all invalid test specs from the cli.
virtual void noMatchingTestCases(StringRef unmatchedSpec)=0
Called when no test cases match provided test spec.
ReporterPreferences m_preferences
Derived classes can set up their preferences here.
Definition catch_amalgamated.hpp:1443
virtual void fatalErrorEncountered(StringRef error)=0
Called if a fatal error (signal/structured exception) occured.
Definition catch_amalgamated.hpp:6929
Definition catch_amalgamated.hpp:6923
Definition catch_amalgamated.hpp:7174
Definition catch_amalgamated.hpp:690
Definition catch_amalgamated.hpp:2889
Definition catch_amalgamated.hpp:1776
Definition catch_amalgamated.hpp:1763
Definition catch_amalgamated.hpp:7922
Definition catch_amalgamated.hpp:7989
Definition catch_amalgamated.hpp:1030
Definition catch_amalgamated.hpp:8545
virtual bool isConsole() const
Best guess on whether the instance is writing to a console (e.g.
Definition catch_amalgamated.hpp:8560
Definition catch_amalgamated.hpp:8014
Definition catch_amalgamated.hpp:5280
Definition catch_amalgamated.hpp:11705
void testCaseStarting(TestCaseInfo const &testCaseInfo) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.cpp:9195
void testRunStarting(TestRunInfo const &runInfo) override
Called once in a testing run before tests are started.
Definition catch_amalgamated.cpp:9186
void assertionEnded(AssertionStats const &assertionStats) override
Called after assertion was fully evaluated.
Definition catch_amalgamated.cpp:9199
void testCaseEnded(TestCaseStats const &testCaseStats) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.cpp:9205
Definition catch_amalgamated.hpp:928
Definition catch_amalgamated.hpp:11866
Definition catch_amalgamated.hpp:10789
Definition catch_amalgamated.hpp:10837
Definition catch_amalgamated.hpp:11050
Matcher for checking that an element in range is equal to specific element.
Definition catch_amalgamated.hpp:10543
Meta-matcher for checking that an element in a range matches a specific matcher.
Definition catch_amalgamated.hpp:10570
Definition catch_amalgamated.hpp:10992
Definition catch_amalgamated.hpp:10265
friend MatchAllOfGeneric< MatcherTs..., MatchersRHS... > operator&&(MatchAllOfGeneric< MatcherTs... > &&lhs, MatchAllOfGeneric< MatchersRHS... > &&rhs)
Avoids type nesting for GenericAllOf && GenericAllOf case.
Definition catch_amalgamated.hpp:10293
Definition catch_amalgamated.hpp:9956
Definition catch_amalgamated.hpp:10320
friend MatchAnyOfGeneric< MatcherTs..., MatchersRHS... > operator||(MatchAnyOfGeneric< MatcherTs... > &&lhs, MatchAnyOfGeneric< MatchersRHS... > &&rhs)
Avoids type nesting for GenericAnyOf || GenericAnyOf case.
Definition catch_amalgamated.hpp:10347
Definition catch_amalgamated.hpp:10010
Definition catch_amalgamated.hpp:10374
friend MatcherT const & operator!(MatchNotOfGeneric< MatcherT > const &matcher)
Negating negation can just unwrap and return underlying matcher.
Definition catch_amalgamated.hpp:10395
Definition catch_amalgamated.hpp:10062
Definition catch_amalgamated.hpp:10926
Definition catch_amalgamated.hpp:11024
Definition catch_amalgamated.hpp:10636
Definition catch_amalgamated.hpp:10472
Definition catch_amalgamated.hpp:10456
Definition catch_amalgamated.hpp:9948
Definition catch_amalgamated.hpp:10164
Definition catch_amalgamated.hpp:9928
Definition catch_amalgamated.hpp:10813
Definition catch_amalgamated.hpp:10932
Definition catch_amalgamated.hpp:10493
Definition catch_amalgamated.hpp:10921
Definition catch_amalgamated.hpp:10916
Definition catch_amalgamated.hpp:10911
Definition catch_amalgamated.hpp:10900
Definition catch_amalgamated.hpp:11088
Definition catch_amalgamated.hpp:10969
Definition catch_amalgamated.hpp:10669
Definition catch_amalgamated.hpp:10698
Definition catch_amalgamated.hpp:10679
Definition catch_amalgamated.hpp:3811
Definition catch_amalgamated.hpp:8663
Definition catch_amalgamated.hpp:8652
Definition catch_amalgamated.hpp:8642
Definition catch_amalgamated.hpp:8672
This is the base class for all reporters.
Definition catch_amalgamated.hpp:11197
void listTests(std::vector< TestCaseHandle > const &tests) override
Provides a simple default listing of tests.
Definition catch_amalgamated.cpp:7967
Detail::unique_ptr< IStream > m_wrapped_stream
The stream wrapper as passed to us by outside code.
Definition catch_amalgamated.hpp:11200
void listTags(std::vector< TagInfo > const &tags) override
Provides a simple default listing of tags.
Definition catch_amalgamated.cpp:7975
void listReporters(std::vector< ReporterDescription > const &descriptions) override
Provides a simple default listing of reporters.
Definition catch_amalgamated.cpp:7957
std::ostream & m_stream
Cached output stream from m_wrapped_stream to reduce number of indirect calls needed to write output.
Definition catch_amalgamated.hpp:11203
void listListeners(std::vector< ListenerDescription > const &descriptions) override
Provides a simple default listing of listeners.
Definition catch_amalgamated.cpp:7962
Detail::unique_ptr< ColourImpl > m_colour
Colour implementation this reporter was configured for.
Definition catch_amalgamated.hpp:11205
std::map< std::string, std::string > m_customOptions
The custom reporter options user passed down to the reporter.
Definition catch_amalgamated.hpp:11207
Definition catch_amalgamated.hpp:11844
Definition catch_amalgamated.hpp:11857
Definition catch_amalgamated.hpp:8976
Definition catch_amalgamated.hpp:4324
Definition catch_amalgamated.hpp:5732
Definition catch_amalgamated.hpp:5136
Definition catch_amalgamated.hpp:7661
Definition catch_amalgamated.hpp:11940
void testRunStarting(TestRunInfo const &testRunInfo) override
Called once in a testing run before tests are started.
Definition catch_amalgamated.cpp:9619
Definition catch_amalgamated.hpp:9180
Definition catch_amalgamated.hpp:11253
void benchmarkPreparing(StringRef) override
Called when user-code is being probed before the actual benchmark runs.
Definition catch_amalgamated.hpp:11258
void sectionStarting(SectionInfo const &_sectionInfo) override
Called when a SECTION is being entered. Not called for skipped sections.
Definition catch_amalgamated.hpp:11273
void benchmarkEnded(BenchmarkStats<> const &) override
Called with the benchmark results if benchmark successfully finishes.
Definition catch_amalgamated.hpp:11260
void testCaseStarting(TestCaseInfo const &_testInfo) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.hpp:11269
void testRunStarting(TestRunInfo const &_testRunInfo) override
Called once in a testing run before tests are started.
Definition catch_amalgamated.cpp:9755
void testCaseEnded(TestCaseStats const &) override
Called once for each TEST_CASE, no matter how many times it is entered.
Definition catch_amalgamated.hpp:11284
void assertionStarting(AssertionInfo const &) override
Called before assertion success/failure is evaluated.
Definition catch_amalgamated.hpp:11277
std::vector< SectionInfo > m_sectionStack
Stack of all active sections in the current test case.
Definition catch_amalgamated.hpp:11299
void sectionEnded(SectionStats const &) override
Called after a SECTION has finished running.
Definition catch_amalgamated.hpp:11280
void testCasePartialEnded(TestCaseStats const &, uint64_t) override
Called every time a TEST_CASE is entered, including repeats (due to sections)
Definition catch_amalgamated.hpp:11283
void assertionEnded(AssertionStats const &) override
Called after assertion was fully evaluated.
Definition catch_amalgamated.hpp:11278
void benchmarkFailed(StringRef) override
Called if running the benchmarks fails for any reason.
Definition catch_amalgamated.hpp:11261
void skipTest(TestCaseInfo const &) override
Called with test cases that are skipped due to the test run aborting.
Definition catch_amalgamated.hpp:11289
void benchmarkStarting(BenchmarkInfo const &) override
Called after probe but before the user-code is being benchmarked.
Definition catch_amalgamated.hpp:11259
void testRunEnded(TestRunStats const &) override
Called once after all tests in a testing run are finished.
Definition catch_amalgamated.cpp:9759
void fatalErrorEncountered(StringRef) override
Called if a fatal error (signal/structured exception) occured.
Definition catch_amalgamated.hpp:11263
void reportInvalidTestSpec(StringRef) override
Called for all invalid test specs from the cli.
Definition catch_amalgamated.hpp:11265
void noMatchingTestCases(StringRef) override
Called when no test cases match provided test spec.
Definition catch_amalgamated.hpp:11264
void testCasePartialStarting(TestCaseInfo const &, uint64_t) override
Called every time a TEST_CASE is entered, including repeats (due to sections)
Definition catch_amalgamated.hpp:11272
A non-owning string class (similar to the forthcoming std::string_view) Note that,...
Definition catch_amalgamated.hpp:103
int compare(StringRef rhs) const
Provides a three-way comparison with rhs.
Definition catch_amalgamated.cpp:5756
Definition catch_amalgamated.hpp:9276
Wrapper over the test case information and the test case invoker.
Definition catch_amalgamated.hpp:6878
Definition catch_amalgamated.hpp:5833
Definition catch_amalgamated.hpp:9397
Iterates "lines" in Column and return sthem.
Definition catch_amalgamated.hpp:9490
Definition catch_amalgamated.hpp:9574
Definition catch_amalgamated.hpp:5716
Definition catch_amalgamated.hpp:5387
Definition catch_amalgamated.hpp:3707
Helper for XML-encoding text (escaping angle brackets, quotes, etc)
Definition catch_amalgamated.hpp:9701
Definition catch_amalgamated.hpp:9719
Definition catch_amalgamated.hpp:9716
XmlWriter & writeText(StringRef text, XmlFormatting fmt=XmlFormatting::Newline|XmlFormatting::Indent)
Writes escaped text in a element.
Definition catch_amalgamated.cpp:7120
XmlWriter & writeAttribute(StringRef name, T const &attribute)
The attribute value must provide op<<(ostream&, T).
Definition catch_amalgamated.hpp:9783
XmlWriter & writeAttribute(StringRef name, StringRef attribute)
The attribute content is XML-encoded.
Definition catch_amalgamated.cpp:7102
XmlWriter & writeComment(StringRef text, XmlFormatting fmt=XmlFormatting::Newline|XmlFormatting::Indent)
Writes XML comment as "<!-- text -->".
Definition catch_amalgamated.cpp:7134
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
front< Pair > first
Retrieve the first element of the pair Pair.
Definition meta.hpp:2251
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition meta.hpp:1696
front< pop_front< Pair > > second
Retrieve the first element of the pair Pair.
Definition meta.hpp:2256
bool_< 0==size< L >::type::value > empty
An Boolean integral constant wrapper around true if L is an empty type list; false,...
Definition meta.hpp:2231
list< F, S > pair
A list with exactly two elements.
Definition meta.hpp:2246
_t< detail::count_< L, T > > count
Count the number of times a type T appears in the list L.
Definition meta.hpp:2725
_t< detail::is_callable_< T > > is_callable
An alias for std::true_type if T::invoke exists and names a class template or alias template; otherwi...
Definition meta.hpp:689
Point operator*(double s, const Point &a)
Multiply point by scalar.
Definition shapes.h:250
Definition catch_amalgamated.hpp:905
Definition catch_amalgamated.hpp:5520
Definition catch_amalgamated.hpp:958
Definition catch_amalgamated.hpp:1326
Definition catch_amalgamated.hpp:5859
Definition catch_amalgamated.hpp:1378
Definition catch_amalgamated.hpp:2570
Definition catch_amalgamated.hpp:1867
We need to reinvent std::function because every piece of code that might add overhead in a measuremen...
Definition catch_amalgamated.hpp:1961
Definition catch_amalgamated.hpp:1846
Definition catch_amalgamated.hpp:1856
Definition catch_amalgamated.hpp:1811
Definition catch_amalgamated.hpp:1803
Definition catch_amalgamated.hpp:2338
Definition catch_amalgamated.hpp:2048
Definition catch_amalgamated.hpp:1242
Definition catch_amalgamated.hpp:2173
Definition catch_amalgamated.hpp:1266
Definition catch_amalgamated.hpp:2474
Definition catch_amalgamated.hpp:2092
Definition catch_amalgamated.hpp:1597
Definition catch_amalgamated.hpp:4841
Definition catch_amalgamated.hpp:4749
Definition catch_amalgamated.hpp:4782
Definition catch_amalgamated.hpp:4821
Definition catch_amalgamated.hpp:4836
Definition catch_amalgamated.hpp:4740
Definition catch_amalgamated.hpp:4745
Definition catch_amalgamated.hpp:4754
Definition catch_amalgamated.hpp:4706
Definition catch_amalgamated.hpp:4790
Definition catch_amalgamated.hpp:4522
Definition catch_amalgamated.hpp:4502
Definition catch_amalgamated.hpp:4482
Definition catch_amalgamated.hpp:4488
Definition catch_amalgamated.hpp:5095
Definition catch_amalgamated.hpp:4478
Definition catch_amalgamated.hpp:4155
Definition catch_amalgamated.hpp:788
Definition catch_amalgamated.hpp:11481
Definition catch_amalgamated.hpp:11488
Definition catch_amalgamated.hpp:5489
Provides case-insensitive op== semantics when called.
Definition catch_amalgamated.hpp:7964
Provides case-insensitive op< semantics when called.
Definition catch_amalgamated.hpp:7958
Definition catch_amalgamated.hpp:2879
Definition catch_amalgamated.hpp:11825
Definition catch_amalgamated.hpp:3366
Definition catch_amalgamated.hpp:2858
Definition catch_amalgamated.hpp:7355
Definition catch_amalgamated.hpp:8586
Definition catch_amalgamated.hpp:8612
Definition catch_amalgamated.hpp:10891
Definition catch_amalgamated.hpp:10208
Definition catch_amalgamated.hpp:4308
Definition catch_amalgamated.hpp:1096
Definition catch_amalgamated.hpp:4297
Definition catch_amalgamated.hpp:5851
ReporterSpec but with the defaults filled in.
Definition catch_amalgamated.hpp:4142
Definition catch_amalgamated.hpp:5211
Definition catch_amalgamated.hpp:1299
Definition catch_amalgamated.hpp:8609
By setting up its preferences, a reporter can modify Catch2's behaviour in some regards,...
Definition catch_amalgamated.hpp:1419
bool shouldReportAllAssertions
Catch2 should call Reporter::assertionEnded even for passing assertions.
Definition catch_amalgamated.hpp:1425
bool shouldRedirectStdOut
Catch2 should redirect writes to stdout and pass them to the reporter.
Definition catch_amalgamated.hpp:1422
Definition catch_amalgamated.hpp:885
Definition catch_amalgamated.hpp:860
Definition catch_amalgamated.hpp:833
Definition catch_amalgamated.hpp:819
Definition catch_amalgamated.hpp:1341
Definition catch_amalgamated.hpp:3001
Definition catch_amalgamated.hpp:8617
A view of a tag string that provides case insensitive comparisons.
Definition catch_amalgamated.hpp:6807
Various metadata about the test case.
Definition catch_amalgamated.hpp:6838
friend bool operator<(TestCaseInfo const &lhs, TestCaseInfo const &rhs)
Orders by name, classname and tags.
Definition catch_amalgamated.cpp:1398
Definition catch_amalgamated.hpp:1353
Used to signal that an assertion macro failed.
Definition catch_amalgamated.hpp:1688
Definition catch_amalgamated.hpp:1321
Definition catch_amalgamated.hpp:1367
Definition catch_amalgamated.hpp:3776
Definition catch_amalgamated.hpp:801
Definition catch_amalgamated.hpp:7019
Definition catch_amalgamated.hpp:241
Definition catch_amalgamated.hpp:213
What
Definition catch_amalgamated.hpp:213
@ UnmatchedTestSpec
A command line test spec matched no test cases.
Definition catch_amalgamated.hpp:218
@ NoAssertions
A test case or leaf section did not run any assertions.
Definition catch_amalgamated.hpp:216
Definition catch_amalgamated.hpp:1702
Definition catch_amalgamated.hpp:1705
Definition catch_amalgamated.hpp:1713
Definition catch_amalgamated.hpp:3373
Definition catch_amalgamated.hpp:11642
Definition catch_amalgamated.hpp:3430
Definition catch_amalgamated.hpp:1704
Definition catch_amalgamated.hpp:2920