QtRocket
 
Loading...
Searching...
No Matches
catch_amalgamated.hpp
Go to the documentation of this file.
1
2// Copyright Catch2 Authors
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE.txt or copy at
5// https://www.boost.org/LICENSE_1_0.txt)
6
7// SPDX-License-Identifier: BSL-1.0
8
9// Catch v3.8.1
10// Generated: 2025-04-08 12:33:19.851017
11// ----------------------------------------------------------
12// This file is an amalgamation of multiple different files.
13// You probably shouldn't edit it directly.
14// ----------------------------------------------------------
15#ifndef CATCH_AMALGAMATED_HPP_INCLUDED
16#define CATCH_AMALGAMATED_HPP_INCLUDED
17
18
32
33#ifndef CATCH_ALL_HPP_INCLUDED
34#define CATCH_ALL_HPP_INCLUDED
35
36
37
50
51#ifndef CATCH_BENCHMARK_ALL_HPP_INCLUDED
52#define CATCH_BENCHMARK_ALL_HPP_INCLUDED
53
54
55
56// Adapted from donated nonius code.
57
58#ifndef CATCH_BENCHMARK_HPP_INCLUDED
59#define CATCH_BENCHMARK_HPP_INCLUDED
60
61
62
63#ifndef CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
64#define CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
65
66// Detect a number of compiler features - by compiler
67// The following features are defined:
68//
69// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
70// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
71// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
72// ****************
73// Note to maintainers: if new toggles are added please document them
74// in configuration.md, too
75// ****************
76
77// In general each macro has a _NO_<feature name> form
78// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
79// Many features, at point of detection, define an _INTERNAL_ macro, so they
80// can be combined, en-mass, with the _NO_ forms later.
81
82
83
84#ifndef CATCH_PLATFORM_HPP_INCLUDED
85#define CATCH_PLATFORM_HPP_INCLUDED
86
87// See e.g.:
88// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
89#ifdef __APPLE__
90# ifndef __has_extension
91# define __has_extension(x) 0
92# endif
93# include <TargetConditionals.h>
94# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
95 (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
96# define CATCH_PLATFORM_MAC
97# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
98# define CATCH_PLATFORM_IPHONE
99# endif
100
101#elif defined(linux) || defined(__linux) || defined(__linux__)
102# define CATCH_PLATFORM_LINUX
103
104#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
105# define CATCH_PLATFORM_WINDOWS
106
107# if defined( WINAPI_FAMILY ) && ( WINAPI_FAMILY == WINAPI_FAMILY_APP )
108# define CATCH_PLATFORM_WINDOWS_UWP
109# endif
110
111#elif defined(__ORBIS__) || defined(__PROSPERO__)
112# define CATCH_PLATFORM_PLAYSTATION
113
114#endif
115
116#endif // CATCH_PLATFORM_HPP_INCLUDED
117
118#ifdef __cplusplus
119
120# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
121# define CATCH_CPP17_OR_GREATER
122# endif
123
124# if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
125# define CATCH_CPP20_OR_GREATER
126# endif
127
128#endif
129
130// Only GCC compiler should be used in this block, so other compilers trying to
131// mask themselves as GCC should be ignored.
132#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) && !defined(__NVCOMPILER)
133# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
134# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
135
136// This only works on GCC 9+. so we have to also add a global suppression of Wparentheses
137// for older versions of GCC.
138# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
139 _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
140
141# define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
142 _Pragma( "GCC diagnostic ignored \"-Wunused-result\"" )
143
144# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
145 _Pragma( "GCC diagnostic ignored \"-Wunused-variable\"" )
146
147# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
148 _Pragma( "GCC diagnostic ignored \"-Wuseless-cast\"" )
149
150# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
151 _Pragma( "GCC diagnostic ignored \"-Wshadow\"" )
152
153# define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P
154
155#endif
156
157#if defined(__NVCOMPILER)
158# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "diag push" )
159# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "diag pop" )
160# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress declared_but_not_referenced" )
161#endif
162
163#if defined(__CUDACC__) && !defined(__clang__)
164# ifdef __NVCC_DIAG_PRAGMA_SUPPORT__
165// New pragmas introduced in CUDA 11.5+
166# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" )
167# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" )
168# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" )
169# else
170# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress 177" )
171# endif
172#endif
173
174// clang-cl defines _MSC_VER as well as __clang__, which could cause the
175// start/stop internal suppression macros to be double defined.
176#if defined(__clang__) && !defined(_MSC_VER)
177# define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P
178# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
179# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
180#endif // __clang__ && !_MSC_VER
181
182#if defined(__clang__)
183
184# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
185 _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
186 _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
187
188# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
189 _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
190
191# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
192 _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
193
194# if (__clang_major__ >= 20)
195# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
196 _Pragma( "clang diagnostic ignored \"-Wvariadic-macro-arguments-omitted\"" )
197# elif (__clang_major__ == 19)
198# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
199 _Pragma( "clang diagnostic ignored \"-Wc++20-extensions\"" )
200# else
201# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
202 _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
203# endif
204
205# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
206 _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
207
208# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
209 _Pragma( "clang diagnostic ignored \"-Wcomma\"" )
210
211# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
212 _Pragma( "clang diagnostic ignored \"-Wshadow\"" )
213
214#endif // __clang__
215
216// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
217// which results in calls to destructors being emitted for each temporary,
218// without a matching initialization. In practice, this can result in something
219// like `std::string::~string` being called on an uninitialized value.
220//
221// For example, this code will likely segfault under IBM XL:
222// ```
223// REQUIRE(std::string("12") + "34" == "1234")
224// ```
225//
226// Similarly, NVHPC's implementation of `__builtin_constant_p` has a bug which
227// results in calls to the immediately evaluated lambda expressions to be
228// reported as unevaluated lambdas.
229// https://developer.nvidia.com/nvidia_bug/3321845.
230//
231// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
232#if defined( __ibmxl__ ) || defined( __CUDACC__ ) || defined( __NVCOMPILER )
233# define CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P
234#endif
235
236
237
239// We know some environments not to support full POSIX signals
240#if defined( CATCH_PLATFORM_WINDOWS ) || \
241 defined( CATCH_PLATFORM_PLAYSTATION ) || \
242 defined( __CYGWIN__ ) || \
243 defined( __QNX__ ) || \
244 defined( __EMSCRIPTEN__ ) || \
245 defined( __DJGPP__ ) || \
246 defined( __OS400__ )
247# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
248#else
249# define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
250#endif
251
253// Assume that some platforms do not support getenv.
254#if defined( CATCH_PLATFORM_WINDOWS_UWP ) || \
255 defined( CATCH_PLATFORM_PLAYSTATION ) || \
256 defined( _GAMING_XBOX )
257# define CATCH_INTERNAL_CONFIG_NO_GETENV
258#else
259# define CATCH_INTERNAL_CONFIG_GETENV
260#endif
261
263// Android somehow still does not support std::to_string
264#if defined(__ANDROID__)
265# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
266#endif
267
269// Not all Windows environments support SEH properly
270#if defined(__MINGW32__)
271# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
272#endif
273
275// PS4
276#if defined(__ORBIS__)
277# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
278#endif
279
281// Cygwin
282#ifdef __CYGWIN__
283
284// Required for some versions of Cygwin to declare gettimeofday
285// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
286# define _BSD_SOURCE
287// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
288// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
289# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
290 && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
291
292# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
293
294# endif
295#endif // __CYGWIN__
296
298// Visual C++
299#if defined(_MSC_VER)
300
301// We want to defer to nvcc-specific warning suppression if we are compiled
302// with nvcc masquerading for MSVC.
303# if !defined( __CUDACC__ )
304# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
305 __pragma( warning( push ) )
306# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
307 __pragma( warning( pop ) )
308# endif
309
310// Universal Windows platform does not support SEH
311// Or console colours (or console at all...)
312# if defined(CATCH_PLATFORM_WINDOWS_UWP)
313# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
314# else
315# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
316# endif
317
318// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
319// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
320// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
321# if !defined(__clang__) // Handle Clang masquerading for msvc
322# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
323# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
324# endif // MSVC_TRADITIONAL
325# endif // __clang__
326
327#endif // _MSC_VER
328
329#if defined(_REENTRANT) || defined(_MSC_VER)
330// Enable async processing, as -pthread is specified or no additional linking is required
331# define CATCH_INTERNAL_CONFIG_USE_ASYNC
332#endif // _MSC_VER
333
335// Check if we are compiled with -fno-exceptions or equivalent
336#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
337# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
338#endif
339
340
342// Embarcadero C++Build
343#if defined(__BORLANDC__)
344 #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
345#endif
346
348
349// RTX is a special version of Windows that is real time.
350// This means that it is detected as Windows, but does not provide
351// the same set of capabilities as real Windows does.
352#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
353 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
354 #define CATCH_INTERNAL_CONFIG_NO_ASYNC
355 #define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32
356#endif
357
358#if !defined(_GLIBCXX_USE_C99_MATH_TR1)
359#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
360#endif
361
362// Various stdlib support checks that require __has_include
363#if defined(__has_include)
364 // Check if string_view is available and usable
365 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
366 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
367 #endif
368
369 // Check if optional is available and usable
370 # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
371 # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
372 # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
373
374 // Check if byte is available and usable
375 # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
376 # include <cstddef>
377 # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
378 # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
379 # endif
380 # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
381
382 // Check if variant is available and usable
383 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
384 # if defined(__clang__) && (__clang_major__ < 8)
385 // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
386 // fix should be in clang 8, workaround in libstdc++ 8.2
387 # include <ciso646>
388 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
389 # define CATCH_CONFIG_NO_CPP17_VARIANT
390 # else
391 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
392 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
393 # else
394 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
395 # endif // defined(__clang__) && (__clang_major__ < 8)
396 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
397#endif // defined(__has_include)
398
399
400#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)
401# define CATCH_CONFIG_WINDOWS_SEH
402#endif
403// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
404#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)
405# define CATCH_CONFIG_POSIX_SIGNALS
406#endif
407
408#if defined(CATCH_INTERNAL_CONFIG_GETENV) && !defined(CATCH_INTERNAL_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_GETENV)
409# define CATCH_CONFIG_GETENV
410#endif
411
412#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
413# define CATCH_CONFIG_CPP11_TO_STRING
414#endif
415
416#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
417# define CATCH_CONFIG_CPP17_OPTIONAL
418#endif
419
420#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
421# define CATCH_CONFIG_CPP17_STRING_VIEW
422#endif
423
424#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
425# define CATCH_CONFIG_CPP17_VARIANT
426#endif
427
428#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
429# define CATCH_CONFIG_CPP17_BYTE
430#endif
431
432
433#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
434# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
435#endif
436
437#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)
438# define CATCH_CONFIG_NEW_CAPTURE
439#endif
440
441#if !defined( CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED ) && \
442 !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS ) && \
443 !defined( CATCH_CONFIG_NO_DISABLE_EXCEPTIONS )
444# define CATCH_CONFIG_DISABLE_EXCEPTIONS
445#endif
446
447#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
448# define CATCH_CONFIG_POLYFILL_ISNAN
449#endif
450
451#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
452# define CATCH_CONFIG_USE_ASYNC
453#endif
454
455#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
456# define CATCH_CONFIG_GLOBAL_NEXTAFTER
457#endif
458
459
460// The goal of this macro is to avoid evaluation of the arguments, but
461// still have the compiler warn on problems inside...
462#if defined( CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P ) && \
463 !defined( CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P ) && !defined(CATCH_CONFIG_USE_BUILTIN_CONSTANT_P)
464#define CATCH_CONFIG_USE_BUILTIN_CONSTANT_P
465#endif
466
467#if defined( CATCH_CONFIG_USE_BUILTIN_CONSTANT_P ) && \
468 !defined( CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P )
469# define CATCH_INTERNAL_IGNORE_BUT_WARN( ... ) \
470 (void)__builtin_constant_p( __VA_ARGS__ ) /* NOLINT(cppcoreguidelines-pro-type-vararg, \
471 hicpp-vararg) */
472#else
473# define CATCH_INTERNAL_IGNORE_BUT_WARN( ... )
474#endif
475
476// Even if we do not think the compiler has that warning, we still have
477// to provide a macro that can be used by the code.
478#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
479# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
480#endif
481#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
482# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
483#endif
484#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
485# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
486#endif
487#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
488# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
489#endif
490#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT)
491# define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT
492#endif
493#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS)
494# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
495#endif
496#if !defined(CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS)
497# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS
498#endif
499#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
500# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
501#endif
502#if !defined( CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS )
503# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
504#endif
505#if !defined( CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS )
506# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS
507#endif
508#if !defined( CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS )
509# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS
510#endif
511
512#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
513# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
514#elif defined(__clang__) && (__clang_major__ < 5)
515# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
516#endif
517
518
519#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
520#define CATCH_TRY if ((true))
521#define CATCH_CATCH_ALL if ((false))
522#define CATCH_CATCH_ANON(type) if ((false))
523#else
524#define CATCH_TRY try
525#define CATCH_CATCH_ALL catch (...)
526#define CATCH_CATCH_ANON(type) catch (type)
527#endif
528
529#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
530#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
531#endif
532
533#if defined( CATCH_PLATFORM_WINDOWS ) && \
534 !defined( CATCH_CONFIG_COLOUR_WIN32 ) && \
535 !defined( CATCH_CONFIG_NO_COLOUR_WIN32 ) && \
536 !defined( CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 )
537# define CATCH_CONFIG_COLOUR_WIN32
538#endif
539
540#if defined( CATCH_CONFIG_SHARED_LIBRARY ) && defined( _MSC_VER ) && \
541 !defined( CATCH_CONFIG_STATIC )
542# ifdef Catch2_EXPORTS
543# define CATCH_EXPORT //__declspec( dllexport ) // not needed
544# else
545# define CATCH_EXPORT __declspec( dllimport )
546# endif
547#else
548# define CATCH_EXPORT
549#endif
550
551#endif // CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
552
553
554#ifndef CATCH_CONTEXT_HPP_INCLUDED
555#define CATCH_CONTEXT_HPP_INCLUDED
556
557
558namespace Catch {
559
560 class IResultCapture;
561 class IConfig;
562
563 class Context {
564 IConfig const* m_config = nullptr;
566
569 friend Context const& getCurrentContext();
570 static void createContext();
571 friend void cleanUpContext();
572
573 public:
574 constexpr IResultCapture* getResultCapture() const {
575 return m_resultCapture;
576 }
577 constexpr IConfig const* getConfig() const { return m_config; }
578 constexpr void setResultCapture( IResultCapture* resultCapture ) {
579 m_resultCapture = resultCapture;
580 }
581 constexpr void setConfig( IConfig const* config ) { m_config = config; }
582
583 };
584
585 Context& getCurrentMutableContext();
586
587 inline Context const& getCurrentContext() {
588 // We duplicate the logic from `getCurrentMutableContext` here,
589 // to avoid paying the call overhead in debug mode.
591 // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
593 }
594
595 void cleanUpContext();
596
597 class SimplePcg32;
599}
600
601#endif // CATCH_CONTEXT_HPP_INCLUDED
602
603
604#ifndef CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
605#define CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
606
607#include <type_traits>
608
610#define CATCH_MOVE(...) static_cast<std::remove_reference_t<decltype(__VA_ARGS__)>&&>(__VA_ARGS__)
611
613#define CATCH_FORWARD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
614
615#endif // CATCH_MOVE_AND_FORWARD_HPP_INCLUDED
616
617
618#ifndef CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
619#define CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
620
621namespace Catch {
622
627
633 [[noreturn]] void throw_test_failure_exception();
634
640 [[noreturn]] void throw_test_skip_exception();
641
642} // namespace Catch
643
644#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
645
646
647#ifndef CATCH_UNIQUE_NAME_HPP_INCLUDED
648#define CATCH_UNIQUE_NAME_HPP_INCLUDED
649
650
651
652
661
662#ifndef CATCH_CONFIG_COUNTER_HPP_INCLUDED
663#define CATCH_CONFIG_COUNTER_HPP_INCLUDED
664
665
666#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
667 #define CATCH_INTERNAL_CONFIG_COUNTER
668#endif
669
670#if defined( CATCH_INTERNAL_CONFIG_COUNTER ) && \
671 !defined( CATCH_CONFIG_NO_COUNTER ) && \
672 !defined( CATCH_CONFIG_COUNTER )
673# define CATCH_CONFIG_COUNTER
674#endif
675
676
677#endif // CATCH_CONFIG_COUNTER_HPP_INCLUDED
678#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
679#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
680#ifdef CATCH_CONFIG_COUNTER
681# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
682#else
683# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
684#endif
685
686#endif // CATCH_UNIQUE_NAME_HPP_INCLUDED
687
688
689#ifndef CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
690#define CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
691
692#include <string>
693
694
695
696#ifndef CATCH_STRINGREF_HPP_INCLUDED
697#define CATCH_STRINGREF_HPP_INCLUDED
698
699#include <cstddef>
700#include <string>
701#include <iosfwd>
702#include <cassert>
703
704#include <cstring>
705
706namespace Catch {
707
711 class StringRef {
712 public:
713 using size_type = std::size_t;
714 using const_iterator = const char*;
715
716 static constexpr size_type npos{ static_cast<size_type>( -1 ) };
717
718 private:
719 static constexpr char const* const s_empty = "";
720
721 char const* m_start = s_empty;
723
724 public: // construction
725 constexpr StringRef() noexcept = default;
726
727 StringRef( char const* rawChars ) noexcept;
728
729 constexpr StringRef( char const* rawChars, size_type size ) noexcept
730 : m_start( rawChars ),
731 m_size( size )
732 {}
733
734 StringRef( std::string const& stdString ) noexcept
735 : m_start( stdString.c_str() ),
736 m_size( stdString.size() )
737 {}
738
739 explicit operator std::string() const {
740 return std::string(m_start, m_size);
741 }
742
743 public: // operators
744 auto operator == ( StringRef other ) const noexcept -> bool {
745 return m_size == other.m_size
746 && (std::memcmp( m_start, other.m_start, m_size ) == 0);
747 }
748 auto operator != (StringRef other) const noexcept -> bool {
749 return !(*this == other);
750 }
751
752 constexpr auto operator[] ( size_type index ) const noexcept -> char {
753 assert(index < m_size);
754 return m_start[index];
755 }
756
757 bool operator<(StringRef rhs) const noexcept;
758
759 public: // named queries
760 constexpr auto empty() const noexcept -> bool {
761 return m_size == 0;
762 }
763 constexpr auto size() const noexcept -> size_type {
764 return m_size;
765 }
766
767 // Returns a substring of [start, start + length).
768 // If start + length > size(), then the substring is [start, size()).
769 // If start > size(), then the substring is empty.
770 constexpr StringRef substr(size_type start, size_type length) const noexcept {
771 if (start < m_size) {
772 const auto shortened_size = m_size - start;
773 return StringRef(m_start + start, (shortened_size < length) ? shortened_size : length);
774 } else {
775 return StringRef();
776 }
777 }
778
779 // Returns the current start pointer. May not be null-terminated.
780 constexpr char const* data() const noexcept {
781 return m_start;
782 }
783
784 constexpr const_iterator begin() const { return m_start; }
785 constexpr const_iterator end() const { return m_start + m_size; }
786
787
788 friend std::string& operator += (std::string& lhs, StringRef rhs);
789 friend std::ostream& operator << (std::ostream& os, StringRef str);
790 friend std::string operator+(StringRef lhs, StringRef rhs);
791
798 int compare( StringRef rhs ) const;
799 };
800
801
802 constexpr auto operator ""_sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
803 return StringRef( rawChars, size );
804 }
805} // namespace Catch
806
807constexpr auto operator ""_catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
808 return Catch::StringRef( rawChars, size );
809}
810
811#endif // CATCH_STRINGREF_HPP_INCLUDED
812
813
814#ifndef CATCH_RESULT_TYPE_HPP_INCLUDED
815#define CATCH_RESULT_TYPE_HPP_INCLUDED
816
817namespace Catch {
818
819 // ResultWas::OfType enum
820 struct ResultWas { enum OfType {
822 Ok = 0,
823 Info = 1,
825 // TODO: Should explicit skip be considered "not OK" (cf. isOk)? I.e., should it have the failure bit?
827
829
832
834
837
839
840 }; };
841
842 constexpr bool isOk( ResultWas::OfType resultType ) {
843 return ( resultType & ResultWas::FailureBit ) == 0;
844 }
845 constexpr bool isJustInfo( int flags ) { return flags == ResultWas::Info; }
846
847
848 // ResultDisposition::Flags enum
849 struct ResultDisposition { enum Flags {
850 Normal = 0x01,
851
852 ContinueOnFailure = 0x02, // Failures fail test, but execution continues
853 FalseTest = 0x04, // Prefix expression with !
854 SuppressFail = 0x08 // Failures are reported but do not fail the test
855 }; };
856
859 return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) |
860 static_cast<int>( rhs ) );
861 }
862
863 constexpr bool isFalseTest( int flags ) {
864 return ( flags & ResultDisposition::FalseTest ) != 0;
865 }
866 constexpr bool shouldSuppressFailure( int flags ) {
867 return ( flags & ResultDisposition::SuppressFail ) != 0;
868 }
869
870} // end namespace Catch
871
872#endif // CATCH_RESULT_TYPE_HPP_INCLUDED
873
874
875#ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED
876#define CATCH_UNIQUE_PTR_HPP_INCLUDED
877
878#include <cassert>
879#include <type_traits>
880
881
882namespace Catch {
883namespace Detail {
889 template <typename T>
892 public:
893 constexpr unique_ptr(std::nullptr_t = nullptr):
894 m_ptr{}
895 {}
896 explicit constexpr unique_ptr(T* ptr):
897 m_ptr(ptr)
898 {}
899
900 template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
902 m_ptr(from.release())
903 {}
904
905 template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>>
907 reset(from.release());
908
909 return *this;
910 }
911
912 unique_ptr(unique_ptr const&) = delete;
913 unique_ptr& operator=(unique_ptr const&) = delete;
914
915 unique_ptr(unique_ptr&& rhs) noexcept:
916 m_ptr(rhs.m_ptr) {
917 rhs.m_ptr = nullptr;
918 }
919 unique_ptr& operator=(unique_ptr&& rhs) noexcept {
920 reset(rhs.release());
921
922 return *this;
923 }
924
926 delete m_ptr;
927 }
928
930 assert(m_ptr);
931 return *m_ptr;
932 }
933 T const& operator*() const {
934 assert(m_ptr);
935 return *m_ptr;
936 }
937 T* operator->() noexcept {
938 assert(m_ptr);
939 return m_ptr;
940 }
941 T const* operator->() const noexcept {
942 assert(m_ptr);
943 return m_ptr;
944 }
945
946 T* get() { return m_ptr; }
947 T const* get() const { return m_ptr; }
948
949 void reset(T* ptr = nullptr) {
950 delete m_ptr;
951 m_ptr = ptr;
952 }
953
954 T* release() {
955 auto temp = m_ptr;
956 m_ptr = nullptr;
957 return temp;
958 }
959
960 explicit operator bool() const {
961 return m_ptr;
962 }
963
964 friend void swap(unique_ptr& lhs, unique_ptr& rhs) {
965 auto temp = lhs.m_ptr;
966 lhs.m_ptr = rhs.m_ptr;
967 rhs.m_ptr = temp;
968 }
969 };
970
972 template <typename T>
973 class unique_ptr<T[]>;
974
975 template <typename T, typename... Args>
976 unique_ptr<T> make_unique(Args&&... args) {
977 return unique_ptr<T>(new T(CATCH_FORWARD(args)...));
978 }
979
980
981} // end namespace Detail
982} // end namespace Catch
983
984#endif // CATCH_UNIQUE_PTR_HPP_INCLUDED
985
986
987#ifndef CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
988#define CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
989
990
991
992// Adapted from donated nonius code.
993
994#ifndef CATCH_CLOCK_HPP_INCLUDED
995#define CATCH_CLOCK_HPP_INCLUDED
996
997#include <chrono>
998
999namespace Catch {
1000 namespace Benchmark {
1001 using IDuration = std::chrono::nanoseconds;
1002 using FDuration = std::chrono::duration<double, std::nano>;
1003
1004 template <typename Clock>
1005 using TimePoint = typename Clock::time_point;
1006
1007 using default_clock = std::chrono::steady_clock;
1008 } // namespace Benchmark
1009} // namespace Catch
1010
1011#endif // CATCH_CLOCK_HPP_INCLUDED
1012
1013namespace Catch {
1014
1015 // We cannot forward declare the type with default template argument
1016 // multiple times, so it is split out into a separate header so that
1017 // we can prevent multiple declarations in dependees
1018 template <typename Duration = Benchmark::FDuration>
1019 struct BenchmarkStats;
1020
1021} // end namespace Catch
1022
1023#endif // CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
1024
1025namespace Catch {
1026
1027 class AssertionResult;
1028 struct AssertionInfo;
1029 struct SectionInfo;
1030 struct SectionEndInfo;
1031 struct MessageInfo;
1032 struct MessageBuilder;
1033 struct Counts;
1034 struct AssertionReaction;
1035 struct SourceLineInfo;
1036
1038 class IGeneratorTracker;
1039
1040 struct BenchmarkInfo;
1041
1042 namespace Generators {
1045 }
1046
1047
1049 public:
1051
1052 virtual void notifyAssertionStarted( AssertionInfo const& info ) = 0;
1053 virtual bool sectionStarted( StringRef sectionName,
1054 SourceLineInfo const& sectionLineInfo,
1055 Counts& assertions ) = 0;
1056 virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0;
1057 virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0;
1058
1059 virtual IGeneratorTracker*
1061 SourceLineInfo const& lineInfo ) = 0;
1062 virtual IGeneratorTracker*
1064 SourceLineInfo lineInfo,
1065 Generators::GeneratorBasePtr&& generator ) = 0;
1066
1067 virtual void benchmarkPreparing( StringRef name ) = 0;
1068 virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
1069 virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
1070 virtual void benchmarkFailed( StringRef error ) = 0;
1071
1072 virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1073 virtual void popScopedMessage( MessageInfo const& message ) = 0;
1074
1075 virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0;
1076
1077 virtual void handleFatalErrorCondition( StringRef message ) = 0;
1078
1079 virtual void handleExpr
1080 ( AssertionInfo const& info,
1081 ITransientExpression const& expr,
1082 AssertionReaction& reaction ) = 0;
1083 virtual void handleMessage
1084 ( AssertionInfo const& info,
1085 ResultWas::OfType resultType,
1086 std::string&& message,
1087 AssertionReaction& reaction ) = 0;
1089 ( AssertionInfo const& info,
1090 AssertionReaction& reaction ) = 0;
1092 ( AssertionInfo const& info,
1093 std::string&& message,
1094 AssertionReaction& reaction ) = 0;
1095 virtual void handleIncomplete
1096 ( AssertionInfo const& info ) = 0;
1097 virtual void handleNonExpr
1098 ( AssertionInfo const &info,
1099 ResultWas::OfType resultType,
1100 AssertionReaction &reaction ) = 0;
1101
1102
1103
1104 virtual bool lastAssertionPassed() = 0;
1105 virtual void assertionPassed() = 0;
1106
1107 // Deprecated, do not use:
1108 virtual std::string getCurrentTestName() const = 0;
1109 virtual const AssertionResult* getLastResult() const = 0;
1110 virtual void exceptionEarlyReported() = 0;
1111 };
1112
1114}
1115
1116#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
1117
1118
1119#ifndef CATCH_INTERFACES_CONFIG_HPP_INCLUDED
1120#define CATCH_INTERFACES_CONFIG_HPP_INCLUDED
1121
1122
1123
1124#ifndef CATCH_NONCOPYABLE_HPP_INCLUDED
1125#define CATCH_NONCOPYABLE_HPP_INCLUDED
1126
1127namespace Catch {
1128 namespace Detail {
1129
1132 NonCopyable( NonCopyable const& ) = delete;
1134 NonCopyable& operator=( NonCopyable const& ) = delete;
1136
1137 protected:
1138 NonCopyable() noexcept = default;
1139 };
1140
1141 } // namespace Detail
1142} // namespace Catch
1143
1144#endif // CATCH_NONCOPYABLE_HPP_INCLUDED
1145
1146#include <chrono>
1147#include <iosfwd>
1148#include <string>
1149#include <vector>
1150
1151namespace Catch {
1152
1153 enum class Verbosity {
1157 };
1158
1159 struct WarnAbout { enum What {
1160 Nothing = 0x00,
1165 }; };
1166
1177 enum class ColourMode : std::uint8_t {
1186 };
1193
1194 class TestSpec;
1195 class IStream;
1196
1198 public:
1199 virtual ~IConfig();
1200
1201 virtual bool allowThrows() const = 0;
1202 virtual StringRef name() const = 0;
1203 virtual bool includeSuccessfulResults() const = 0;
1204 virtual bool shouldDebugBreak() const = 0;
1205 virtual bool warnAboutMissingAssertions() const = 0;
1206 virtual bool warnAboutUnmatchedTestSpecs() const = 0;
1207 virtual bool zeroTestsCountAsSuccess() const = 0;
1208 virtual int abortAfter() const = 0;
1209 virtual bool showInvisibles() const = 0;
1210 virtual ShowDurations showDurations() const = 0;
1211 virtual double minDuration() const = 0;
1212 virtual TestSpec const& testSpec() const = 0;
1213 virtual bool hasTestFilters() const = 0;
1214 virtual std::vector<std::string> const& getTestsOrTags() const = 0;
1215 virtual TestRunOrder runOrder() const = 0;
1216 virtual uint32_t rngSeed() const = 0;
1217 virtual unsigned int shardCount() const = 0;
1218 virtual unsigned int shardIndex() const = 0;
1219 virtual ColourMode defaultColourMode() const = 0;
1220 virtual std::vector<std::string> const& getSectionsToRun() const = 0;
1221 virtual Verbosity verbosity() const = 0;
1222
1223 virtual bool skipBenchmarks() const = 0;
1224 virtual bool benchmarkNoAnalysis() const = 0;
1225 virtual unsigned int benchmarkSamples() const = 0;
1226 virtual double benchmarkConfidenceInterval() const = 0;
1227 virtual unsigned int benchmarkResamples() const = 0;
1228 virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
1229 };
1230}
1231
1232#endif // CATCH_INTERFACES_CONFIG_HPP_INCLUDED
1233
1234
1235#ifndef CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1236#define CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1237
1238
1239#include <string>
1240
1241namespace Catch {
1242
1243 class TestCaseHandle;
1244 struct TestCaseInfo;
1245 class ITestCaseRegistry;
1246 class IExceptionTranslatorRegistry;
1247 class IExceptionTranslator;
1248 class ReporterRegistry;
1249 class IReporterFactory;
1250 class ITagAliasRegistry;
1251 class ITestInvoker;
1252 class IMutableEnumValuesRegistry;
1253 struct SourceLineInfo;
1254
1255 class StartupExceptionRegistry;
1256 class EventListenerFactory;
1257
1259
1261 public:
1262 virtual ~IRegistryHub(); // = default
1263
1264 virtual ReporterRegistry const& getReporterRegistry() const = 0;
1265 virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
1266 virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
1268
1269
1270 virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
1271 };
1272
1274 public:
1275 virtual ~IMutableRegistryHub(); // = default
1276 virtual void registerReporter( std::string const& name, IReporterFactoryPtr factory ) = 0;
1280 virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
1281 virtual void registerStartupException() noexcept = 0;
1283 };
1284
1287 void cleanUp();
1288 std::string translateActiveException();
1289
1290}
1291
1292#endif // CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED
1293
1294
1295#ifndef CATCH_BENCHMARK_STATS_HPP_INCLUDED
1296#define CATCH_BENCHMARK_STATS_HPP_INCLUDED
1297
1298
1299
1300// Adapted from donated nonius code.
1301
1302#ifndef CATCH_ESTIMATE_HPP_INCLUDED
1303#define CATCH_ESTIMATE_HPP_INCLUDED
1304
1305namespace Catch {
1306 namespace Benchmark {
1307 template <typename Type>
1314 } // namespace Benchmark
1315} // namespace Catch
1316
1317#endif // CATCH_ESTIMATE_HPP_INCLUDED
1318
1319
1320// Adapted from donated nonius code.
1321
1322#ifndef CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED
1323#define CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED
1324
1325namespace Catch {
1326 namespace Benchmark {
1329 int low_severe = 0; // more than 3 times IQR below Q1
1330 int low_mild = 0; // 1.5 to 3 times IQR below Q1
1331 int high_mild = 0; // 1.5 to 3 times IQR above Q3
1332 int high_severe = 0; // more than 3 times IQR above Q3
1333
1334 constexpr int total() const {
1336 }
1337 };
1338 } // namespace Benchmark
1339} // namespace Catch
1340
1341#endif // CATCH_OUTLIERS_CLASSIFICATION_HPP_INCLUDED
1342// The fwd decl & default specialization needs to be seen by VS2017 before
1343// BenchmarkStats itself, or VS2017 will report compilation error.
1344
1345#include <string>
1346#include <vector>
1347
1348namespace Catch {
1349
1351 std::string name;
1354 unsigned int samples;
1355 unsigned int resamples;
1358 };
1359
1360 // We need to keep template parameter for backwards compatibility,
1361 // but we also do not want to use the template paraneter.
1362 template <class Dummy>
1372
1373
1374} // end namespace Catch
1375
1376#endif // CATCH_BENCHMARK_STATS_HPP_INCLUDED
1377
1378
1379// Adapted from donated nonius code.
1380
1381#ifndef CATCH_ENVIRONMENT_HPP_INCLUDED
1382#define CATCH_ENVIRONMENT_HPP_INCLUDED
1383
1384
1385namespace Catch {
1386 namespace Benchmark {
1395 } // namespace Benchmark
1396} // namespace Catch
1397
1398#endif // CATCH_ENVIRONMENT_HPP_INCLUDED
1399
1400
1401// Adapted from donated nonius code.
1402
1403#ifndef CATCH_EXECUTION_PLAN_HPP_INCLUDED
1404#define CATCH_EXECUTION_PLAN_HPP_INCLUDED
1405
1406
1407
1408// Adapted from donated nonius code.
1409
1410#ifndef CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1411#define CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1412
1413
1414
1415// Adapted from donated nonius code.
1416
1417#ifndef CATCH_CHRONOMETER_HPP_INCLUDED
1418#define CATCH_CHRONOMETER_HPP_INCLUDED
1419
1420
1421
1422// Adapted from donated nonius code.
1423
1424#ifndef CATCH_OPTIMIZER_HPP_INCLUDED
1425#define CATCH_OPTIMIZER_HPP_INCLUDED
1426
1427#if defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__)
1428# include <atomic> // atomic_thread_fence
1429#endif
1430
1431
1432#include <type_traits>
1433
1434namespace Catch {
1435 namespace Benchmark {
1436#if defined(__GNUC__) || defined(__clang__)
1437 template <typename T>
1438 inline void keep_memory(T* p) {
1439 asm volatile("" : : "g"(p) : "memory");
1440 }
1441 inline void keep_memory() {
1442 asm volatile("" : : : "memory");
1443 }
1444
1445 namespace Detail {
1446 inline void optimizer_barrier() { keep_memory(); }
1447 } // namespace Detail
1448#elif defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__)
1449
1450#if defined(_MSVC_VER)
1451#pragma optimize("", off)
1452#elif defined(__IAR_SYSTEMS_ICC__)
1453// For IAR the pragma only affects the following function
1454#pragma optimize=disable
1455#endif
1456 template <typename T>
1457 inline void keep_memory(T* p) {
1458 // thanks @milleniumbug
1459 *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
1460 }
1461 // TODO equivalent keep_memory()
1462#if defined(_MSVC_VER)
1463#pragma optimize("", on)
1464#endif
1465
1466 namespace Detail {
1467 inline void optimizer_barrier() {
1468 std::atomic_thread_fence(std::memory_order_seq_cst);
1469 }
1470 } // namespace Detail
1471
1472#endif
1473
1474 template <typename T>
1475 inline void deoptimize_value(T&& x) {
1476 keep_memory(&x);
1477 }
1478
1479 template <typename Fn, typename... Args>
1480 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<!std::is_same<void, decltype(fn(args...))>::value> {
1482 }
1483
1484 template <typename Fn, typename... Args>
1485 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<std::is_same<void, decltype(fn(args...))>::value> {
1486 CATCH_FORWARD((fn)) (CATCH_FORWARD(args)...);
1487 }
1488 } // namespace Benchmark
1489} // namespace Catch
1490
1491#endif // CATCH_OPTIMIZER_HPP_INCLUDED
1492
1493
1494#ifndef CATCH_META_HPP_INCLUDED
1495#define CATCH_META_HPP_INCLUDED
1496
1497#include <type_traits>
1498
1499namespace Catch {
1500 template <typename>
1501 struct true_given : std::true_type {};
1502
1504 template <typename Fun, typename... Args>
1505 static true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
1506 template <typename...>
1507 static std::false_type test(...);
1508 };
1509
1510 template <typename T>
1512
1513 template <typename Fun, typename... Args>
1514 struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
1515
1516
1517#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
1518 // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
1519 // replaced with std::invoke_result here.
1520 template <typename Func, typename... U>
1521 using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
1522#else
1523 template <typename Func, typename... U>
1524 using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::result_of_t<Func(U...)>>>;
1525#endif
1526
1527} // namespace Catch
1528
1529namespace mpl_{
1530 struct na;
1531}
1532
1533#endif // CATCH_META_HPP_INCLUDED
1534
1535namespace Catch {
1536 namespace Benchmark {
1537 namespace Detail {
1539 virtual void start() = 0;
1540 virtual void finish() = 0;
1541 virtual ~ChronometerConcept(); // = default;
1542
1546 };
1547 template <typename Clock>
1548 struct ChronometerModel final : public ChronometerConcept {
1549 void start() override { started = Clock::now(); }
1550 void finish() override { finished = Clock::now(); }
1551
1553 return std::chrono::duration_cast<std::chrono::nanoseconds>(
1554 finished - started );
1555 }
1556
1559 };
1560 } // namespace Detail
1561
1563 public:
1564 template <typename Fun>
1565 void measure(Fun&& fun) { measure(CATCH_FORWARD(fun), is_callable<Fun(int)>()); }
1566
1567 int runs() const { return repeats; }
1568
1570 : impl(&meter)
1571 , repeats(repeats_) {}
1572
1573 private:
1574 template <typename Fun>
1575 void measure(Fun&& fun, std::false_type) {
1576 measure([&fun](int) { return fun(); }, std::true_type());
1577 }
1578
1579 template <typename Fun>
1580 void measure(Fun&& fun, std::true_type) {
1581 Detail::optimizer_barrier();
1582 impl->start();
1583 for (int i = 0; i < repeats; ++i) invoke_deoptimized(fun, i);
1584 impl->finish();
1585 Detail::optimizer_barrier();
1586 }
1587
1590 };
1591 } // namespace Benchmark
1592} // namespace Catch
1593
1594#endif // CATCH_CHRONOMETER_HPP_INCLUDED
1595
1596#include <type_traits>
1597
1598namespace Catch {
1599 namespace Benchmark {
1600 namespace Detail {
1601 template <typename T, typename U>
1603 : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
1604
1613 private:
1614 struct callable {
1615 virtual void call(Chronometer meter) const = 0;
1616 virtual ~callable(); // = default;
1617
1618 callable() = default;
1619 callable(callable&&) = default;
1621 };
1622 template <typename Fun>
1623 struct model : public callable {
1624 model(Fun&& fun_) : fun(CATCH_MOVE(fun_)) {}
1625 model(Fun const& fun_) : fun(fun_) {}
1626
1627 void call(Chronometer meter) const override {
1628 call(meter, is_callable<Fun(Chronometer)>());
1629 }
1630 void call(Chronometer meter, std::true_type) const {
1631 fun(meter);
1632 }
1633 void call(Chronometer meter, std::false_type) const {
1634 meter.measure(fun);
1635 }
1636
1637 Fun fun;
1638 };
1639
1640 public:
1642
1643 template <typename Fun,
1644 std::enable_if_t<!is_related<Fun, BenchmarkFunction>::value, int> = 0>
1646 : f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {}
1647
1649 f( CATCH_MOVE( that.f ) ) {}
1650
1652 operator=( BenchmarkFunction&& that ) noexcept {
1653 f = CATCH_MOVE( that.f );
1654 return *this;
1655 }
1656
1657 void operator()(Chronometer meter) const { f->call(meter); }
1658
1659 private:
1661 };
1662 } // namespace Detail
1663 } // namespace Benchmark
1664} // namespace Catch
1665
1666#endif // CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
1667
1668
1669// Adapted from donated nonius code.
1670
1671#ifndef CATCH_REPEAT_HPP_INCLUDED
1672#define CATCH_REPEAT_HPP_INCLUDED
1673
1674#include <type_traits>
1675
1676namespace Catch {
1677 namespace Benchmark {
1678 namespace Detail {
1679 template <typename Fun>
1680 struct repeater {
1681 void operator()(int k) const {
1682 for (int i = 0; i < k; ++i) {
1683 fun();
1684 }
1685 }
1686 Fun fun;
1687 };
1688 template <typename Fun>
1690 return { CATCH_FORWARD(fun) };
1691 }
1692 } // namespace Detail
1693 } // namespace Benchmark
1694} // namespace Catch
1695
1696#endif // CATCH_REPEAT_HPP_INCLUDED
1697
1698
1699// Adapted from donated nonius code.
1700
1701#ifndef CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
1702#define CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
1703
1704
1705
1706// Adapted from donated nonius code.
1707
1708#ifndef CATCH_MEASURE_HPP_INCLUDED
1709#define CATCH_MEASURE_HPP_INCLUDED
1710
1711
1712
1713// Adapted from donated nonius code.
1714
1715#ifndef CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1716#define CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1717
1718
1719namespace Catch {
1720 namespace Benchmark {
1721 namespace Detail {
1722 template <typename T>
1723 struct CompleteType { using type = T; };
1724 template <>
1725 struct CompleteType<void> { struct type {}; };
1726
1727 template <typename T>
1729
1730 template <typename Result>
1732 template <typename Fun, typename... Args>
1733 static Result invoke(Fun&& fun, Args&&... args) {
1734 return CATCH_FORWARD(fun)(CATCH_FORWARD(args)...);
1735 }
1736 };
1737 template <>
1738 struct CompleteInvoker<void> {
1739 template <typename Fun, typename... Args>
1740 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
1741 CATCH_FORWARD(fun)(CATCH_FORWARD(args)...);
1742 return {};
1743 }
1744 };
1745
1746 // invoke and not return void :(
1747 template <typename Fun, typename... Args>
1748 CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
1749 return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...);
1750 }
1751
1752 } // namespace Detail
1753
1754 template <typename Fun>
1758 } // namespace Benchmark
1759} // namespace Catch
1760
1761#endif // CATCH_COMPLETE_INVOKE_HPP_INCLUDED
1762
1763
1764// Adapted from donated nonius code.
1765
1766#ifndef CATCH_TIMING_HPP_INCLUDED
1767#define CATCH_TIMING_HPP_INCLUDED
1768
1769
1770#include <type_traits>
1771
1772namespace Catch {
1773 namespace Benchmark {
1774 template <typename Result>
1780 template <typename Func, typename... Args>
1782 } // namespace Benchmark
1783} // namespace Catch
1784
1785#endif // CATCH_TIMING_HPP_INCLUDED
1786
1787namespace Catch {
1788 namespace Benchmark {
1789 namespace Detail {
1790 template <typename Clock, typename Fun, typename... Args>
1791 TimingOf<Fun, Args...> measure(Fun&& fun, Args&&... args) {
1792 auto start = Clock::now();
1793 auto&& r = Detail::complete_invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...);
1794 auto end = Clock::now();
1795 auto delta = end - start;
1796 return { delta, CATCH_FORWARD(r), 1 };
1797 }
1798 } // namespace Detail
1799 } // namespace Benchmark
1800} // namespace Catch
1801
1802#endif // CATCH_MEASURE_HPP_INCLUDED
1803
1804#include <type_traits>
1805
1806namespace Catch {
1807 namespace Benchmark {
1808 namespace Detail {
1809 template <typename Clock, typename Fun>
1810 TimingOf<Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
1811 return Detail::measure<Clock>(fun, iters);
1812 }
1813 template <typename Clock, typename Fun>
1814 TimingOf<Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
1816 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
1817
1818 return { meter.elapsed(), CATCH_MOVE(result), iters };
1819 }
1820
1821 template <typename Clock, typename Fun>
1822 using run_for_at_least_argument_t = std::conditional_t<is_callable<Fun(Chronometer)>::value, Chronometer, int>;
1823
1824
1825 [[noreturn]]
1827
1828 template <typename Clock, typename Fun>
1831 const int initial_iterations,
1832 Fun&& fun) {
1833 auto iters = initial_iterations;
1834 while (iters < (1 << 30)) {
1835 auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
1836
1837 if (Timing.elapsed >= how_long) {
1838 return { Timing.elapsed, CATCH_MOVE(Timing.result), iters };
1839 }
1840 iters *= 2;
1841 }
1843 }
1844 } // namespace Detail
1845 } // namespace Benchmark
1846} // namespace Catch
1847
1848#endif // CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
1849
1850#include <vector>
1851
1852namespace Catch {
1853 namespace Benchmark {
1860
1861 template <typename Clock>
1862 std::vector<FDuration> run(const IConfig &cfg, Environment env) const {
1863 // warmup a bit
1865 std::chrono::duration_cast<IDuration>( warmup_time ),
1867 Detail::repeat( []() { return Clock::now(); } )
1868 );
1869
1870 std::vector<FDuration> times;
1871 const auto num_samples = cfg.benchmarkSamples();
1872 times.reserve( num_samples );
1873 for ( size_t i = 0; i < num_samples; ++i ) {
1875 this->benchmark( Chronometer( model, iterations_per_sample ) );
1876 auto sample_time = model.elapsed() - env.clock_cost.mean;
1877 if ( sample_time < FDuration::zero() ) {
1878 sample_time = FDuration::zero();
1879 }
1880 times.push_back(sample_time / iterations_per_sample);
1881 }
1882 return times;
1883 }
1884 };
1885 } // namespace Benchmark
1886} // namespace Catch
1887
1888#endif // CATCH_EXECUTION_PLAN_HPP_INCLUDED
1889
1890
1891// Adapted from donated nonius code.
1892
1893#ifndef CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
1894#define CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
1895
1896
1897
1898// Adapted from donated nonius code.
1899
1900#ifndef CATCH_STATS_HPP_INCLUDED
1901#define CATCH_STATS_HPP_INCLUDED
1902
1903
1904#include <vector>
1905
1906namespace Catch {
1907 namespace Benchmark {
1908 namespace Detail {
1909 using sample = std::vector<double>;
1910
1911 double weighted_average_quantile( int k,
1912 int q,
1913 double* first,
1914 double* last );
1915
1917 classify_outliers( double const* first, double const* last );
1918
1919 double mean( double const* first, double const* last );
1920
1921 double normal_cdf( double x );
1922
1923 double erfc_inv(double x);
1924
1925 double normal_quantile(double p);
1926
1928 bootstrap( double confidence_level,
1929 double* first,
1930 double* last,
1931 sample const& resample,
1932 double ( *estimator )( double const*, double const* ) );
1933
1939
1940 bootstrap_analysis analyse_samples(double confidence_level,
1941 unsigned int n_resamples,
1942 double* first,
1943 double* last);
1944 } // namespace Detail
1945 } // namespace Benchmark
1946} // namespace Catch
1947
1948#endif // CATCH_STATS_HPP_INCLUDED
1949
1950#include <algorithm>
1951#include <vector>
1952#include <cmath>
1953
1954namespace Catch {
1955 namespace Benchmark {
1956 namespace Detail {
1957 template <typename Clock>
1958 std::vector<double> resolution(int k) {
1959 const size_t points = static_cast<size_t>( k + 1 );
1960 // To avoid overhead from the branch inside vector::push_back,
1961 // we allocate them all and then overwrite.
1962 std::vector<TimePoint<Clock>> times(points);
1963 for ( auto& time : times ) {
1964 time = Clock::now();
1965 }
1966
1967 std::vector<double> deltas;
1968 deltas.reserve(static_cast<size_t>(k));
1969 for ( size_t idx = 1; idx < points; ++idx ) {
1970 deltas.push_back( static_cast<double>(
1971 ( times[idx] - times[idx - 1] ).count() ) );
1972 }
1973
1974 return deltas;
1975 }
1976
1977 constexpr auto warmup_iterations = 10000;
1978 constexpr auto warmup_time = std::chrono::milliseconds(100);
1979 constexpr auto minimum_ticks = 1000;
1980 constexpr auto warmup_seed = 10000;
1981 constexpr auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
1982 constexpr auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
1983 constexpr auto clock_cost_estimation_tick_limit = 100000;
1984 constexpr auto clock_cost_estimation_time = std::chrono::milliseconds(10);
1985 constexpr auto clock_cost_estimation_iterations = 10000;
1986
1987 template <typename Clock>
1988 int warmup() {
1990 .iterations;
1991 }
1992 template <typename Clock>
1995 .result;
1996 return {
1997 FDuration(mean(r.data(), r.data() + r.size())),
1998 classify_outliers(r.data(), r.data() + r.size()),
1999 };
2000 }
2001 template <typename Clock>
2003 auto time_limit = (std::min)(
2006 auto time_clock = [](int k) {
2007 return Detail::measure<Clock>([k] {
2008 for (int i = 0; i < k; ++i) {
2009 volatile auto ignored = Clock::now();
2010 (void)ignored;
2011 }
2012 }).elapsed;
2013 };
2014 time_clock(1);
2016 auto&& r = run_for_at_least<Clock>(clock_cost_estimation_time, iters, time_clock);
2017 std::vector<double> times;
2018 int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
2019 times.reserve(static_cast<size_t>(nsamples));
2020 for ( int s = 0; s < nsamples; ++s ) {
2021 times.push_back( static_cast<double>(
2022 ( time_clock( r.iterations ) / r.iterations )
2023 .count() ) );
2024 }
2025 return {
2026 FDuration(mean(times.data(), times.data() + times.size())),
2027 classify_outliers(times.data(), times.data() + times.size()),
2028 };
2029 }
2030
2031 template <typename Clock>
2033#if defined(__clang__)
2034# pragma clang diagnostic push
2035# pragma clang diagnostic ignored "-Wexit-time-destructors"
2036#endif
2038#if defined(__clang__)
2039# pragma clang diagnostic pop
2040#endif
2041 if (env) {
2042 return *env;
2043 }
2044
2045 auto iters = Detail::warmup<Clock>();
2048
2050 return *env;
2051 }
2052 } // namespace Detail
2053 } // namespace Benchmark
2054} // namespace Catch
2055
2056#endif // CATCH_ESTIMATE_CLOCK_HPP_INCLUDED
2057
2058
2059// Adapted from donated nonius code.
2060
2061#ifndef CATCH_ANALYSE_HPP_INCLUDED
2062#define CATCH_ANALYSE_HPP_INCLUDED
2063
2064
2065
2066// Adapted from donated nonius code.
2067
2068#ifndef CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2069#define CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2070
2071
2072#include <vector>
2073
2074namespace Catch {
2075 namespace Benchmark {
2083 } // namespace Benchmark
2084} // namespace Catch
2085
2086#endif // CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED
2087
2088
2089namespace Catch {
2090 class IConfig;
2091
2092 namespace Benchmark {
2093 namespace Detail {
2094 SampleAnalysis analyse(const IConfig &cfg, FDuration* first, FDuration* last);
2095 } // namespace Detail
2096 } // namespace Benchmark
2097} // namespace Catch
2098
2099#endif // CATCH_ANALYSE_HPP_INCLUDED
2100
2101#include <algorithm>
2102#include <chrono>
2103#include <exception>
2104#include <string>
2105#include <cmath>
2106
2107namespace Catch {
2108 namespace Benchmark {
2109 struct Benchmark {
2110 Benchmark(std::string&& benchmarkName)
2111 : name(CATCH_MOVE(benchmarkName)) {}
2112
2113 template <class FUN>
2114 Benchmark(std::string&& benchmarkName , FUN &&func)
2115 : fun(CATCH_MOVE(func)), name(CATCH_MOVE(benchmarkName)) {}
2116
2117 template <typename Clock>
2119 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
2120 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
2121 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(run_time), 1, fun);
2122 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
2123 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), CATCH_MOVE(fun), std::chrono::duration_cast<FDuration>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
2124 }
2125
2126 template <typename Clock = default_clock>
2127 void run() {
2128 static_assert( Clock::is_steady,
2129 "Benchmarking clock should be steady" );
2130 auto const* cfg = getCurrentContext().getConfig();
2131
2133
2134 getResultCapture().benchmarkPreparing(name);
2135 CATCH_TRY{
2136 auto plan = user_code([&] {
2137 return prepare<Clock>(*cfg, env);
2138 });
2139
2140 BenchmarkInfo info {
2142 plan.estimated_duration.count(),
2143 plan.iterations_per_sample,
2144 cfg->benchmarkSamples(),
2145 cfg->benchmarkResamples(),
2146 env.clock_resolution.mean.count(),
2147 env.clock_cost.mean.count()
2148 };
2149
2150 getResultCapture().benchmarkStarting(info);
2151
2152 auto samples = user_code([&] {
2153 return plan.template run<Clock>(*cfg, env);
2154 });
2155
2156 auto analysis = Detail::analyse(*cfg, samples.data(), samples.data() + samples.size());
2157 BenchmarkStats<> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
2158 getResultCapture().benchmarkEnded(stats);
2160 getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr);
2162 getResultCapture().benchmarkFailed(translateActiveException());
2163 // We let the exception go further up so that the
2164 // test case is marked as failed.
2165 std::rethrow_exception(std::current_exception());
2166 }
2167 }
2168
2169 // sets lambda to be used in fun *and* executes benchmark!
2170 template <typename Fun, std::enable_if_t<!Detail::is_related<Fun, Benchmark>::value, int> = 0>
2171 Benchmark & operator=(Fun func) {
2172 auto const* cfg = getCurrentContext().getConfig();
2173 if (!cfg->skipBenchmarks()) {
2175 run();
2176 }
2177 return *this;
2178 }
2179
2180 explicit operator bool() {
2181 return true;
2182 }
2183
2184 private:
2186 std::string name;
2187 };
2188 }
2189} // namespace Catch
2190
2191#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
2192#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
2193
2194#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
2195 if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
2196 BenchmarkName = [&](int benchmarkIndex)
2197
2198#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
2199 if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
2200 BenchmarkName = [&]
2201
2202#if defined(CATCH_CONFIG_PREFIX_ALL)
2203
2204#define CATCH_BENCHMARK(...) \
2205 INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
2206#define CATCH_BENCHMARK_ADVANCED(name) \
2207 INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name)
2208
2209#else
2210
2211#define BENCHMARK(...) \
2212 INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
2213#define BENCHMARK_ADVANCED(name) \
2214 INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name)
2215
2216#endif
2217
2218#endif // CATCH_BENCHMARK_HPP_INCLUDED
2219
2220
2221// Adapted from donated nonius code.
2222
2223#ifndef CATCH_CONSTRUCTOR_HPP_INCLUDED
2224#define CATCH_CONSTRUCTOR_HPP_INCLUDED
2225
2226
2227#include <type_traits>
2228
2229namespace Catch {
2230 namespace Benchmark {
2231 namespace Detail {
2232 template <typename T, bool Destruct>
2234 {
2235 ObjectStorage() = default;
2236
2238 {
2239 new(&data) T(other.stored_object());
2240 }
2241
2243 {
2244 new(data) T(CATCH_MOVE(other.stored_object()));
2245 }
2246
2248
2249 template <typename... Args>
2250 void construct(Args&&... args)
2251 {
2252 new (data) T(CATCH_FORWARD(args)...);
2253 }
2254
2255 template <bool AllowManualDestruction = !Destruct>
2256 std::enable_if_t<AllowManualDestruction> destruct()
2257 {
2258 stored_object().~T();
2259 }
2260
2261 private:
2262 // If this is a constructor benchmark, destruct the underlying object
2263 template <typename U>
2264 void destruct_on_exit(std::enable_if_t<Destruct, U>* = nullptr) { destruct<true>(); }
2265 // Otherwise, don't
2266 template <typename U>
2267 void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
2268
2269#if defined( __GNUC__ ) && __GNUC__ <= 6
2270# pragma GCC diagnostic push
2271# pragma GCC diagnostic ignored "-Wstrict-aliasing"
2272#endif
2273 T& stored_object() { return *reinterpret_cast<T*>( data ); }
2274
2275 T const& stored_object() const {
2276 return *reinterpret_cast<T const*>( data );
2277 }
2278#if defined( __GNUC__ ) && __GNUC__ <= 6
2279# pragma GCC diagnostic pop
2280#endif
2281
2282 alignas( T ) unsigned char data[sizeof( T )]{};
2283 };
2284 } // namespace Detail
2285
2286 template <typename T>
2288
2289 template <typename T>
2291 } // namespace Benchmark
2292} // namespace Catch
2293
2294#endif // CATCH_CONSTRUCTOR_HPP_INCLUDED
2295
2296#endif // CATCH_BENCHMARK_ALL_HPP_INCLUDED
2297
2298
2299#ifndef CATCH_APPROX_HPP_INCLUDED
2300#define CATCH_APPROX_HPP_INCLUDED
2301
2302
2303
2304#ifndef CATCH_TOSTRING_HPP_INCLUDED
2305#define CATCH_TOSTRING_HPP_INCLUDED
2306
2307
2308#include <vector>
2309#include <cstddef>
2310#include <type_traits>
2311#include <string>
2312
2313
2314
2315
2323
2324#ifndef CATCH_CONFIG_WCHAR_HPP_INCLUDED
2325#define CATCH_CONFIG_WCHAR_HPP_INCLUDED
2326
2327
2328// We assume that WCHAR should be enabled by default, and only disabled
2329// for a shortlist (so far only DJGPP) of compilers.
2330
2331#if defined(__DJGPP__)
2332# define CATCH_INTERNAL_CONFIG_NO_WCHAR
2333#endif // __DJGPP__
2334
2335#if !defined( CATCH_INTERNAL_CONFIG_NO_WCHAR ) && \
2336 !defined( CATCH_CONFIG_NO_WCHAR ) && \
2337 !defined( CATCH_CONFIG_WCHAR )
2338# define CATCH_CONFIG_WCHAR
2339#endif
2340
2341#endif // CATCH_CONFIG_WCHAR_HPP_INCLUDED
2342
2343
2344#ifndef CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2345#define CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2346
2347
2348#include <iosfwd>
2349#include <cstddef>
2350#include <ostream>
2351#include <string>
2352
2353namespace Catch {
2354
2356 std::size_t m_index;
2357 std::ostream* m_oss;
2358 public:
2361
2363 std::string str() const;
2365 void str(std::string const& str);
2366
2367#if defined(__GNUC__) && !defined(__clang__)
2368#pragma GCC diagnostic push
2369// Old versions of GCC do not understand -Wnonnull-compare
2370#pragma GCC diagnostic ignored "-Wpragmas"
2371// Streaming a function pointer triggers Waddress and Wnonnull-compare
2372// on GCC, because it implicitly converts it to bool and then decides
2373// that the check it uses (a? true : false) is tautological and cannot
2374// be null...
2375#pragma GCC diagnostic ignored "-Waddress"
2376#pragma GCC diagnostic ignored "-Wnonnull-compare"
2377#endif
2378
2379 template<typename T>
2380 auto operator << ( T const& value ) -> ReusableStringStream& {
2381 *m_oss << value;
2382 return *this;
2383 }
2384
2385#if defined(__GNUC__) && !defined(__clang__)
2386#pragma GCC diagnostic pop
2387#endif
2388 auto get() -> std::ostream& { return *m_oss; }
2389 };
2390}
2391
2392#endif // CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED
2393
2394
2395#ifndef CATCH_VOID_TYPE_HPP_INCLUDED
2396#define CATCH_VOID_TYPE_HPP_INCLUDED
2397
2398
2399namespace Catch {
2400 namespace Detail {
2401
2402 template <typename...>
2403 struct make_void { using type = void; };
2404
2405 template <typename... Ts>
2406 using void_t = typename make_void<Ts...>::type;
2407
2408 } // namespace Detail
2409} // namespace Catch
2410
2411
2412#endif // CATCH_VOID_TYPE_HPP_INCLUDED
2413
2414
2415#ifndef CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2416#define CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2417
2418
2419#include <vector>
2420
2421namespace Catch {
2422
2423 namespace Detail {
2424 struct EnumInfo {
2426 std::vector<std::pair<int, StringRef>> m_values;
2427
2429
2430 StringRef lookup( int value ) const;
2431 };
2432 } // namespace Detail
2433
2435 public:
2436 virtual ~IMutableEnumValuesRegistry(); // = default;
2437
2438 virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
2439
2440 template<typename E>
2441 Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
2442 static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
2443 std::vector<int> intValues;
2444 intValues.reserve( values.size() );
2445 for( auto enumValue : values )
2446 intValues.push_back( static_cast<int>( enumValue ) );
2447 return registerEnum( enumName, allEnums, intValues );
2448 }
2449 };
2450
2451} // Catch
2452
2453#endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED
2454
2455#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2456#include <string_view>
2457#endif
2458
2459#ifdef _MSC_VER
2460#pragma warning(push)
2461#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
2462#endif
2463
2464// We need a dummy global operator<< so we can bring it into Catch namespace later
2466std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
2467
2468namespace Catch {
2469 // Bring in global namespace operator<< for ADL lookup in
2470 // `IsStreamInsertable` below.
2471 using ::operator<<;
2472
2473 namespace Detail {
2474
2475 inline std::size_t catch_strnlen(const char *str, std::size_t n) {
2476 auto ret = std::char_traits<char>::find(str, n, '\0');
2477 if (ret != nullptr) {
2478 return static_cast<std::size_t>(ret - str);
2479 }
2480 return n;
2481 }
2482
2483 constexpr StringRef unprintableString = "{?}"_sr;
2484
2486 std::string convertIntoString( StringRef string, bool escapeInvisibles );
2487
2490 std::string convertIntoString( StringRef string );
2491
2492 std::string rawMemoryToString( const void *object, std::size_t size );
2493
2494 template<typename T>
2495 std::string rawMemoryToString( const T& object ) {
2496 return rawMemoryToString( &object, sizeof(object) );
2497 }
2498
2499 template<typename T>
2501 template<typename Stream, typename U>
2502 static auto test(int)
2503 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
2504
2505 template<typename, typename>
2506 static auto test(...)->std::false_type;
2507
2508 public:
2509 static const bool value = decltype(test<std::ostream, const T&>(0))::value;
2510 };
2511
2512 template<typename E>
2513 std::string convertUnknownEnumToString( E e );
2514
2515 template<typename T>
2516 std::enable_if_t<
2517 !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
2518 std::string> convertUnstreamable( T const& ) {
2519 return std::string(Detail::unprintableString);
2520 }
2521 template<typename T>
2522 std::enable_if_t<
2523 !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
2524 std::string> convertUnstreamable(T const& ex) {
2525 return ex.what();
2526 }
2527
2528
2529 template<typename T>
2530 std::enable_if_t<
2531 std::is_enum<T>::value,
2532 std::string> convertUnstreamable( T const& value ) {
2533 return convertUnknownEnumToString( value );
2534 }
2535
2536#if defined(_MANAGED)
2538 template<typename T>
2539 std::string clrReferenceToString( T^ ref ) {
2540 if (ref == nullptr)
2541 return std::string("null");
2542 auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
2543 cli::pin_ptr<System::Byte> p = &bytes[0];
2544 return std::string(reinterpret_cast<char const *>(p), bytes->Length);
2545 }
2546#endif
2547
2548 } // namespace Detail
2549
2550
2551 template <typename T, typename = void>
2553 template <typename Fake = T>
2554 static
2555 std::enable_if_t<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>
2556 convert(const Fake& value) {
2558 // NB: call using the function-like syntax to avoid ambiguity with
2559 // user-defined templated operator<< under clang.
2560 rss.operator<<(value);
2561 return rss.str();
2562 }
2563
2564 template <typename Fake = T>
2565 static
2566 std::enable_if_t<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>
2567 convert( const Fake& value ) {
2568#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
2569 return Detail::convertUnstreamable(value);
2570#else
2571 return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
2572#endif
2573 }
2574 };
2575
2576 namespace Detail {
2577
2578 // This function dispatches all stringification requests inside of Catch.
2579 // Should be preferably called fully qualified, like ::Catch::Detail::stringify
2580 template <typename T>
2581 std::string stringify(const T& e) {
2582 return ::Catch::StringMaker<std::remove_cv_t<std::remove_reference_t<T>>>::convert(e);
2583 }
2584
2585 template<typename E>
2586 std::string convertUnknownEnumToString( E e ) {
2587 return ::Catch::Detail::stringify(static_cast<std::underlying_type_t<E>>(e));
2588 }
2589
2590#if defined(_MANAGED)
2591 template <typename T>
2592 std::string stringify( T^ e ) {
2593 return ::Catch::StringMaker<T^>::convert(e);
2594 }
2595#endif
2596
2597 } // namespace Detail
2598
2599 // Some predefined specializations
2600
2601 template<>
2602 struct StringMaker<std::string> {
2603 static std::string convert(const std::string& str);
2604 };
2605
2606#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2607 template<>
2608 struct StringMaker<std::string_view> {
2609 static std::string convert(std::string_view str);
2610 };
2611#endif
2612
2613 template<>
2614 struct StringMaker<char const *> {
2615 static std::string convert(char const * str);
2616 };
2617 template<>
2618 struct StringMaker<char *> {
2619 static std::string convert(char * str);
2620 };
2621
2622#if defined(CATCH_CONFIG_WCHAR)
2623 template<>
2624 struct StringMaker<std::wstring> {
2625 static std::string convert(const std::wstring& wstr);
2626 };
2627
2628# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
2629 template<>
2630 struct StringMaker<std::wstring_view> {
2631 static std::string convert(std::wstring_view str);
2632 };
2633# endif
2634
2635 template<>
2636 struct StringMaker<wchar_t const *> {
2637 static std::string convert(wchar_t const * str);
2638 };
2639 template<>
2640 struct StringMaker<wchar_t *> {
2641 static std::string convert(wchar_t * str);
2642 };
2643#endif // CATCH_CONFIG_WCHAR
2644
2645 template<size_t SZ>
2646 struct StringMaker<char[SZ]> {
2647 static std::string convert(char const* str) {
2649 StringRef( str, Detail::catch_strnlen( str, SZ ) ) );
2650 }
2651 };
2652 template<size_t SZ>
2653 struct StringMaker<signed char[SZ]> {
2654 static std::string convert(signed char const* str) {
2655 auto reinterpreted = reinterpret_cast<char const*>(str);
2657 StringRef(reinterpreted, Detail::catch_strnlen(reinterpreted, SZ)));
2658 }
2659 };
2660 template<size_t SZ>
2661 struct StringMaker<unsigned char[SZ]> {
2662 static std::string convert(unsigned char const* str) {
2663 auto reinterpreted = reinterpret_cast<char const*>(str);
2665 StringRef(reinterpreted, Detail::catch_strnlen(reinterpreted, SZ)));
2666 }
2667 };
2668
2669#if defined(CATCH_CONFIG_CPP17_BYTE)
2670 template<>
2671 struct StringMaker<std::byte> {
2672 static std::string convert(std::byte value);
2673 };
2674#endif // defined(CATCH_CONFIG_CPP17_BYTE)
2675 template<>
2676 struct StringMaker<int> {
2677 static std::string convert(int value);
2678 };
2679 template<>
2680 struct StringMaker<long> {
2681 static std::string convert(long value);
2682 };
2683 template<>
2684 struct StringMaker<long long> {
2685 static std::string convert(long long value);
2686 };
2687 template<>
2688 struct StringMaker<unsigned int> {
2689 static std::string convert(unsigned int value);
2690 };
2691 template<>
2692 struct StringMaker<unsigned long> {
2693 static std::string convert(unsigned long value);
2694 };
2695 template<>
2696 struct StringMaker<unsigned long long> {
2697 static std::string convert(unsigned long long value);
2698 };
2699
2700 template<>
2701 struct StringMaker<bool> {
2702 static std::string convert(bool b) {
2703 using namespace std::string_literals;
2704 return b ? "true"s : "false"s;
2705 }
2706 };
2707
2708 template<>
2709 struct StringMaker<char> {
2710 static std::string convert(char c);
2711 };
2712 template<>
2713 struct StringMaker<signed char> {
2714 static std::string convert(signed char value);
2715 };
2716 template<>
2717 struct StringMaker<unsigned char> {
2718 static std::string convert(unsigned char value);
2719 };
2720
2721 template<>
2722 struct StringMaker<std::nullptr_t> {
2723 static std::string convert(std::nullptr_t) {
2724 using namespace std::string_literals;
2725 return "nullptr"s;
2726 }
2727 };
2728
2729 template<>
2730 struct StringMaker<float> {
2731 static std::string convert(float value);
2733 };
2734
2735 template<>
2736 struct StringMaker<double> {
2737 static std::string convert(double value);
2739 };
2740
2741 template <typename T>
2742 struct StringMaker<T*> {
2743 template <typename U>
2744 static std::string convert(U* p) {
2745 if (p) {
2746 return ::Catch::Detail::rawMemoryToString(p);
2747 } else {
2748 return "nullptr";
2749 }
2750 }
2751 };
2752
2753 template <typename R, typename C>
2754 struct StringMaker<R C::*> {
2755 static std::string convert(R C::* p) {
2756 if (p) {
2757 return ::Catch::Detail::rawMemoryToString(p);
2758 } else {
2759 return "nullptr";
2760 }
2761 }
2762 };
2763
2764#if defined(_MANAGED)
2765 template <typename T>
2766 struct StringMaker<T^> {
2767 static std::string convert( T^ ref ) {
2768 return ::Catch::Detail::clrReferenceToString(ref);
2769 }
2770 };
2771#endif
2772
2773 namespace Detail {
2774 template<typename InputIterator, typename Sentinel = InputIterator>
2775 std::string rangeToString(InputIterator first, Sentinel last) {
2777 rss << "{ ";
2778 if (first != last) {
2779 rss << ::Catch::Detail::stringify(*first);
2780 for (++first; first != last; ++first)
2781 rss << ", " << ::Catch::Detail::stringify(*first);
2782 }
2783 rss << " }";
2784 return rss.str();
2785 }
2786 }
2787
2788} // namespace Catch
2789
2791// Separate std-lib types stringification, so it can be selectively enabled
2792// This means that we do not bring in their headers
2793
2794#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
2795# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2796# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2797# define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2798# define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2799#endif
2800
2801// Separate std::pair specialization
2802#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
2803#include <utility>
2804namespace Catch {
2805 template<typename T1, typename T2>
2806 struct StringMaker<std::pair<T1, T2> > {
2807 static std::string convert(const std::pair<T1, T2>& pair) {
2808 ReusableStringStream rss;
2809 rss << "{ "
2810 << ::Catch::Detail::stringify(pair.first)
2811 << ", "
2812 << ::Catch::Detail::stringify(pair.second)
2813 << " }";
2814 return rss.str();
2815 }
2816 };
2817}
2818#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
2819
2820#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
2821#include <optional>
2822namespace Catch {
2823 template<typename T>
2824 struct StringMaker<std::optional<T> > {
2825 static std::string convert(const std::optional<T>& optional) {
2826 if (optional.has_value()) {
2827 return ::Catch::Detail::stringify(*optional);
2828 } else {
2829 return "{ }";
2830 }
2831 }
2832 };
2833 template <>
2834 struct StringMaker<std::nullopt_t> {
2835 static std::string convert(const std::nullopt_t&) {
2836 return "{ }";
2837 }
2838 };
2839}
2840#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
2841
2842// Separate std::tuple specialization
2843#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
2844#include <tuple>
2845namespace Catch {
2846 namespace Detail {
2847 template<
2848 typename Tuple,
2849 std::size_t N = 0,
2850 bool = (N < std::tuple_size<Tuple>::value)
2851 >
2852 struct TupleElementPrinter {
2853 static void print(const Tuple& tuple, std::ostream& os) {
2854 os << (N ? ", " : " ")
2855 << ::Catch::Detail::stringify(std::get<N>(tuple));
2856 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
2857 }
2858 };
2859
2860 template<
2861 typename Tuple,
2862 std::size_t N
2863 >
2864 struct TupleElementPrinter<Tuple, N, false> {
2865 static void print(const Tuple&, std::ostream&) {}
2866 };
2867
2868 }
2869
2870
2871 template<typename ...Types>
2872 struct StringMaker<std::tuple<Types...>> {
2873 static std::string convert(const std::tuple<Types...>& tuple) {
2874 ReusableStringStream rss;
2875 rss << '{';
2876 Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
2877 rss << " }";
2878 return rss.str();
2879 }
2880 };
2881}
2882#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
2883
2884#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
2885#include <variant>
2886namespace Catch {
2887 template<>
2888 struct StringMaker<std::monostate> {
2889 static std::string convert(const std::monostate&) {
2890 return "{ }";
2891 }
2892 };
2893
2894 template<typename... Elements>
2895 struct StringMaker<std::variant<Elements...>> {
2896 static std::string convert(const std::variant<Elements...>& variant) {
2897 if (variant.valueless_by_exception()) {
2898 return "{valueless variant}";
2899 } else {
2900 return std::visit(
2901 [](const auto& value) {
2902 return ::Catch::Detail::stringify(value);
2903 },
2904 variant
2905 );
2906 }
2907 }
2908 };
2909}
2910#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
2911
2912namespace Catch {
2913 // Import begin/ end from std here
2914 using std::begin;
2915 using std::end;
2916
2917 namespace Detail {
2918 template <typename T, typename = void>
2919 struct is_range_impl : std::false_type {};
2920
2921 template <typename T>
2922 struct is_range_impl<T, void_t<decltype(begin(std::declval<T>()))>> : std::true_type {};
2923 } // namespace Detail
2924
2925 template <typename T>
2927
2928#if defined(_MANAGED) // Managed types are never ranges
2929 template <typename T>
2930 struct is_range<T^> {
2931 static const bool value = false;
2932 };
2933#endif
2934
2935 template<typename Range>
2936 std::string rangeToString( Range const& range ) {
2937 return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
2938 }
2939
2940 // Handle vector<bool> specially
2941 template<typename Allocator>
2942 std::string rangeToString( std::vector<bool, Allocator> const& v ) {
2944 rss << "{ ";
2945 bool first = true;
2946 for( bool b : v ) {
2947 if( first )
2948 first = false;
2949 else
2950 rss << ", ";
2951 rss << ::Catch::Detail::stringify( b );
2952 }
2953 rss << " }";
2954 return rss.str();
2955 }
2956
2957 template<typename R>
2958 struct StringMaker<R, std::enable_if_t<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>> {
2959 static std::string convert( R const& range ) {
2960 return rangeToString( range );
2961 }
2962 };
2963
2964 template <typename T, size_t SZ>
2965 struct StringMaker<T[SZ]> {
2966 static std::string convert(T const(&arr)[SZ]) {
2967 return rangeToString(arr);
2968 }
2969 };
2970
2971
2972} // namespace Catch
2973
2974// Separate std::chrono::duration specialization
2975#include <ctime>
2976#include <ratio>
2977#include <chrono>
2978
2979
2980namespace Catch {
2981
2982template <class Ratio>
2984 static std::string symbol() {
2986 rss << '[' << Ratio::num << '/'
2987 << Ratio::den << ']';
2988 return rss.str();
2989 }
2990};
2991
2992template <>
2993struct ratio_string<std::atto> {
2994 static char symbol() { return 'a'; }
2995};
2996template <>
2997struct ratio_string<std::femto> {
2998 static char symbol() { return 'f'; }
2999};
3000template <>
3001struct ratio_string<std::pico> {
3002 static char symbol() { return 'p'; }
3003};
3004template <>
3005struct ratio_string<std::nano> {
3006 static char symbol() { return 'n'; }
3007};
3008template <>
3009struct ratio_string<std::micro> {
3010 static char symbol() { return 'u'; }
3011};
3012template <>
3013struct ratio_string<std::milli> {
3014 static char symbol() { return 'm'; }
3015};
3016
3018 // std::chrono::duration specializations
3019 template<typename Value, typename Ratio>
3020 struct StringMaker<std::chrono::duration<Value, Ratio>> {
3021 static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
3023 rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
3024 return rss.str();
3025 }
3026 };
3027 template<typename Value>
3028 struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
3029 static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
3031 rss << duration.count() << " s";
3032 return rss.str();
3033 }
3034 };
3035 template<typename Value>
3036 struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
3037 static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
3039 rss << duration.count() << " m";
3040 return rss.str();
3041 }
3042 };
3043 template<typename Value>
3044 struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
3045 static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
3047 rss << duration.count() << " h";
3048 return rss.str();
3049 }
3050 };
3051
3053 // std::chrono::time_point specialization
3054 // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
3055 template<typename Clock, typename Duration>
3056 struct StringMaker<std::chrono::time_point<Clock, Duration>> {
3057 static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
3058 return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
3059 }
3060 };
3061 // std::chrono::time_point<system_clock> specialization
3062 template<typename Duration>
3063 struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
3064 static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
3065 auto converted = std::chrono::system_clock::to_time_t(time_point);
3066
3067#ifdef _MSC_VER
3068 std::tm timeInfo = {};
3069 const auto err = gmtime_s(&timeInfo, &converted);
3070 if ( err ) {
3071 return "gmtime from provided timepoint has failed. This "
3072 "happens e.g. with pre-1970 dates using Microsoft libc";
3073 }
3074#else
3075 std::tm* timeInfo = std::gmtime(&converted);
3076#endif
3077
3078 auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
3079 char timeStamp[timeStampSize];
3080 const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
3081
3082#ifdef _MSC_VER
3083 std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
3084#else
3085 std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
3086#endif
3087 return std::string(timeStamp, timeStampSize - 1);
3088 }
3089 };
3090}
3091
3092
3093#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
3094namespace Catch { \
3095 template<> struct StringMaker<enumName> { \
3096 static std::string convert( enumName value ) { \
3097 static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
3098 return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
3099 } \
3100 }; \
3101}
3102
3103#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
3104
3105#ifdef _MSC_VER
3106#pragma warning(pop)
3107#endif
3108
3109#endif // CATCH_TOSTRING_HPP_INCLUDED
3110
3111#include <type_traits>
3112
3113namespace Catch {
3114
3115 class Approx {
3116 private:
3117 bool equalityComparisonImpl(double other) const;
3118 // Sets and validates the new margin (margin >= 0)
3119 void setMargin(double margin);
3120 // Sets and validates the new epsilon (0 < epsilon < 1)
3121 void setEpsilon(double epsilon);
3122
3123 public:
3124 explicit Approx ( double value );
3125
3126 static Approx custom();
3127
3128 Approx operator-() const;
3129
3130 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3131 Approx operator()( T const& value ) const {
3132 Approx approx( static_cast<double>(value) );
3133 approx.m_epsilon = m_epsilon;
3134 approx.m_margin = m_margin;
3135 approx.m_scale = m_scale;
3136 return approx;
3137 }
3138
3139 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3140 explicit Approx( T const& value ): Approx(static_cast<double>(value))
3141 {}
3142
3143
3144 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3145 friend bool operator == ( const T& lhs, Approx const& rhs ) {
3146 auto lhs_v = static_cast<double>(lhs);
3147 return rhs.equalityComparisonImpl(lhs_v);
3148 }
3149
3150 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3151 friend bool operator == ( Approx const& lhs, const T& rhs ) {
3152 return operator==( rhs, lhs );
3153 }
3154
3155 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3156 friend bool operator != ( T const& lhs, Approx const& rhs ) {
3157 return !operator==( lhs, rhs );
3158 }
3159
3160 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3161 friend bool operator != ( Approx const& lhs, T const& rhs ) {
3162 return !operator==( rhs, lhs );
3163 }
3164
3165 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3166 friend bool operator <= ( T const& lhs, Approx const& rhs ) {
3167 return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
3168 }
3169
3170 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3171 friend bool operator <= ( Approx const& lhs, T const& rhs ) {
3172 return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
3173 }
3174
3175 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3176 friend bool operator >= ( T const& lhs, Approx const& rhs ) {
3177 return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
3178 }
3179
3180 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3181 friend bool operator >= ( Approx const& lhs, T const& rhs ) {
3182 return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
3183 }
3184
3185 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3186 Approx& epsilon( T const& newEpsilon ) {
3187 const auto epsilonAsDouble = static_cast<double>(newEpsilon);
3188 setEpsilon(epsilonAsDouble);
3189 return *this;
3190 }
3191
3192 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3193 Approx& margin( T const& newMargin ) {
3194 const auto marginAsDouble = static_cast<double>(newMargin);
3195 setMargin(marginAsDouble);
3196 return *this;
3197 }
3198
3199 template <typename T, typename = std::enable_if_t<std::is_constructible<double, T>::value>>
3200 Approx& scale( T const& newScale ) {
3201 m_scale = static_cast<double>(newScale);
3202 return *this;
3203 }
3204
3205 std::string toString() const;
3206
3207 private:
3209 double m_margin;
3210 double m_scale;
3211 double m_value;
3212 };
3213
3214namespace literals {
3215 Approx operator ""_a(long double val);
3216 Approx operator ""_a(unsigned long long val);
3217} // end namespace literals
3218
3219template<>
3221 static std::string convert(Catch::Approx const& value);
3222};
3223
3224} // end namespace Catch
3225
3226#endif // CATCH_APPROX_HPP_INCLUDED
3227
3228
3229#ifndef CATCH_ASSERTION_INFO_HPP_INCLUDED
3230#define CATCH_ASSERTION_INFO_HPP_INCLUDED
3231
3232
3233
3234#ifndef CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
3235#define CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
3236
3237#include <cstddef>
3238#include <iosfwd>
3239
3240namespace Catch {
3241
3243
3244 SourceLineInfo() = delete;
3245 constexpr SourceLineInfo( char const* _file, std::size_t _line ) noexcept:
3246 file( _file ),
3247 line( _line )
3248 {}
3249
3250 bool operator == ( SourceLineInfo const& other ) const noexcept;
3251 bool operator < ( SourceLineInfo const& other ) const noexcept;
3252
3253 char const* file;
3254 std::size_t line;
3255
3256 friend std::ostream& operator << (std::ostream& os, SourceLineInfo const& info);
3257 };
3258}
3259
3260#define CATCH_INTERNAL_LINEINFO \
3261 ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
3262
3263#endif // CATCH_SOURCE_LINE_INFO_HPP_INCLUDED
3264
3265namespace Catch {
3266
3275
3276} // end namespace Catch
3277
3278#endif // CATCH_ASSERTION_INFO_HPP_INCLUDED
3279
3280
3281#ifndef CATCH_ASSERTION_RESULT_HPP_INCLUDED
3282#define CATCH_ASSERTION_RESULT_HPP_INCLUDED
3283
3284
3285
3286#ifndef CATCH_LAZY_EXPR_HPP_INCLUDED
3287#define CATCH_LAZY_EXPR_HPP_INCLUDED
3288
3289#include <iosfwd>
3290
3291namespace Catch {
3292
3293 class ITransientExpression;
3294
3296 friend class AssertionHandler;
3297 friend struct AssertionStats;
3298 friend class RunContext;
3299
3302 public:
3303 constexpr LazyExpression( bool isNegated ):
3304 m_isNegated(isNegated)
3305 {}
3306 constexpr LazyExpression(LazyExpression const& other) = default;
3307 LazyExpression& operator = ( LazyExpression const& ) = delete;
3308
3309 constexpr explicit operator bool() const {
3310 return m_transientExpression != nullptr;
3311 }
3312
3313 friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
3314 };
3315
3316} // namespace Catch
3317
3318#endif // CATCH_LAZY_EXPR_HPP_INCLUDED
3319
3320#include <string>
3321
3322namespace Catch {
3323
3325 {
3327
3328 AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
3329
3330 std::string message;
3331 mutable std::string reconstructedExpression;
3334
3335 std::string reconstructExpression() const;
3336 };
3337
3339 public:
3341 AssertionResult( AssertionInfo const& info, AssertionResultData&& data );
3342
3343 bool isOk() const;
3344 bool succeeded() const;
3346 bool hasExpression() const;
3347 bool hasMessage() const;
3348 std::string getExpression() const;
3349 std::string getExpressionInMacro() const;
3350 bool hasExpandedExpression() const;
3351 std::string getExpandedExpression() const;
3352 StringRef getMessage() const;
3355
3356 //protected:
3359 };
3360
3361} // end namespace Catch
3362
3363#endif // CATCH_ASSERTION_RESULT_HPP_INCLUDED
3364
3365
3366#ifndef CATCH_CASE_SENSITIVE_HPP_INCLUDED
3367#define CATCH_CASE_SENSITIVE_HPP_INCLUDED
3368
3369namespace Catch {
3370
3371 enum class CaseSensitive { Yes, No };
3372
3373} // namespace Catch
3374
3375#endif // CATCH_CASE_SENSITIVE_HPP_INCLUDED
3376
3377
3378#ifndef CATCH_CONFIG_HPP_INCLUDED
3379#define CATCH_CONFIG_HPP_INCLUDED
3380
3381
3382
3383#ifndef CATCH_TEST_SPEC_HPP_INCLUDED
3384#define CATCH_TEST_SPEC_HPP_INCLUDED
3385
3386#ifdef __clang__
3387#pragma clang diagnostic push
3388#pragma clang diagnostic ignored "-Wpadded"
3389#endif
3390
3391
3392
3393#ifndef CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3394#define CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3395
3396
3397#include <string>
3398
3399namespace Catch
3400{
3408
3409 public:
3410
3411 WildcardPattern( std::string const& pattern, CaseSensitive caseSensitivity );
3412 bool matches( std::string const& str ) const;
3413
3414 private:
3415 std::string normaliseString( std::string const& str ) const;
3418 std::string m_pattern;
3419 };
3420}
3421
3422#endif // CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3423
3424#include <iosfwd>
3425#include <string>
3426#include <vector>
3427
3428namespace Catch {
3429
3430 class IConfig;
3431 struct TestCaseInfo;
3432 class TestCaseHandle;
3433
3434 class TestSpec {
3435
3436 class Pattern {
3437 public:
3438 explicit Pattern( std::string const& name );
3439 virtual ~Pattern();
3440 virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3441 std::string const& name() const;
3442 private:
3443 virtual void serializeTo( std::ostream& out ) const = 0;
3444 // Writes string that would be reparsed into the pattern
3445 friend std::ostream& operator<<(std::ostream& out,
3446 Pattern const& pattern) {
3447 pattern.serializeTo( out );
3448 return out;
3449 }
3450
3451 std::string const m_name;
3452 };
3453
3454 class NamePattern : public Pattern {
3455 public:
3456 explicit NamePattern( std::string const& name, std::string const& filterString );
3457 bool matches( TestCaseInfo const& testCase ) const override;
3458 private:
3459 void serializeTo( std::ostream& out ) const override;
3460
3462 };
3463
3464 class TagPattern : public Pattern {
3465 public:
3466 explicit TagPattern( std::string const& tag, std::string const& filterString );
3467 bool matches( TestCaseInfo const& testCase ) const override;
3468 private:
3469 void serializeTo( std::ostream& out ) const override;
3470
3471 std::string m_tag;
3472 };
3473
3474 struct Filter {
3475 std::vector<Detail::unique_ptr<Pattern>> m_required;
3476 std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
3477
3480 void serializeTo( std::ostream& out ) const;
3481 friend std::ostream& operator<<(std::ostream& out, Filter const& f) {
3482 f.serializeTo( out );
3483 return out;
3484 }
3485
3486 bool matches( TestCaseInfo const& testCase ) const;
3487 };
3488
3489 static std::string extractFilterName( Filter const& filter );
3490
3491 public:
3493 std::string name;
3494 std::vector<TestCaseHandle const*> tests;
3495 };
3496 using Matches = std::vector<FilterMatch>;
3497 using vectorStrings = std::vector<std::string>;
3498
3499 bool hasFilters() const;
3500 bool matches( TestCaseInfo const& testCase ) const;
3501 Matches matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const;
3502 const vectorStrings & getInvalidSpecs() const;
3503
3504 private:
3505 std::vector<Filter> m_filters;
3506 std::vector<std::string> m_invalidSpecs;
3507
3508 friend class TestSpecParser;
3511 void serializeTo( std::ostream& out ) const;
3512 friend std::ostream& operator<<(std::ostream& out,
3513 TestSpec const& spec) {
3514 spec.serializeTo( out );
3515 return out;
3516 }
3517 };
3518}
3519
3520#ifdef __clang__
3521#pragma clang diagnostic pop
3522#endif
3523
3524#endif // CATCH_TEST_SPEC_HPP_INCLUDED
3525
3526
3527#ifndef CATCH_OPTIONAL_HPP_INCLUDED
3528#define CATCH_OPTIONAL_HPP_INCLUDED
3529
3530
3531#include <cassert>
3532
3533namespace Catch {
3534
3535 // An optional type
3536 template<typename T>
3537 class Optional {
3538 public:
3539 Optional(): nullableValue( nullptr ) {}
3541
3542 Optional( T const& _value ):
3543 nullableValue( new ( storage ) T( _value ) ) {}
3544 Optional( T&& _value ):
3545 nullableValue( new ( storage ) T( CATCH_MOVE( _value ) ) ) {}
3546
3547 Optional& operator=( T const& _value ) {
3548 reset();
3549 nullableValue = new ( storage ) T( _value );
3550 return *this;
3551 }
3552 Optional& operator=( T&& _value ) {
3553 reset();
3554 nullableValue = new ( storage ) T( CATCH_MOVE( _value ) );
3555 return *this;
3556 }
3557
3558 Optional( Optional const& _other ):
3559 nullableValue( _other ? new ( storage ) T( *_other ) : nullptr ) {}
3560 Optional( Optional&& _other ):
3561 nullableValue( _other ? new ( storage ) T( CATCH_MOVE( *_other ) )
3562 : nullptr ) {}
3563
3564 Optional& operator=( Optional const& _other ) {
3565 if ( &_other != this ) {
3566 reset();
3567 if ( _other ) { nullableValue = new ( storage ) T( *_other ); }
3568 }
3569 return *this;
3570 }
3572 if ( &_other != this ) {
3573 reset();
3574 if ( _other ) {
3575 nullableValue = new ( storage ) T( CATCH_MOVE( *_other ) );
3576 }
3577 }
3578 return *this;
3579 }
3580
3581 void reset() {
3582 if ( nullableValue ) { nullableValue->~T(); }
3583 nullableValue = nullptr;
3584 }
3585
3587 assert(nullableValue);
3588 return *nullableValue;
3589 }
3590 T const& operator*() const {
3591 assert(nullableValue);
3592 return *nullableValue;
3593 }
3595 assert(nullableValue);
3596 return nullableValue;
3597 }
3598 const T* operator->() const {
3599 assert(nullableValue);
3600 return nullableValue;
3601 }
3602
3603 T valueOr( T const& defaultValue ) const {
3604 return nullableValue ? *nullableValue : defaultValue;
3605 }
3606
3607 bool some() const { return nullableValue != nullptr; }
3608 bool none() const { return nullableValue == nullptr; }
3609
3610 bool operator !() const { return nullableValue == nullptr; }
3611 explicit operator bool() const {
3612 return some();
3613 }
3614
3615 friend bool operator==(Optional const& a, Optional const& b) {
3616 if (a.none() && b.none()) {
3617 return true;
3618 } else if (a.some() && b.some()) {
3619 return *a == *b;
3620 } else {
3621 return false;
3622 }
3623 }
3624 friend bool operator!=(Optional const& a, Optional const& b) {
3625 return !( a == b );
3626 }
3627
3628 private:
3630 alignas(alignof(T)) char storage[sizeof(T)];
3631 };
3632
3633} // end namespace Catch
3634
3635#endif // CATCH_OPTIONAL_HPP_INCLUDED
3636
3637
3638#ifndef CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3639#define CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3640
3641#include <cstdint>
3642
3643namespace Catch {
3644
3651
3652 std::uint32_t generateRandomSeed(GenerateFrom from);
3653
3654} // end namespace Catch
3655
3656#endif // CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
3657
3658
3659#ifndef CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3660#define CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3661
3662
3663#include <map>
3664#include <string>
3665#include <vector>
3666
3667namespace Catch {
3668
3669 enum class ColourMode : std::uint8_t;
3670
3671 namespace Detail {
3673 std::vector<std::string> splitReporterSpec( StringRef reporterSpec );
3674
3675 Optional<ColourMode> stringToColourMode( StringRef colourMode );
3676 }
3677
3687 std::string m_name;
3690 std::map<std::string, std::string> m_customOptions;
3691
3692 friend bool operator==( ReporterSpec const& lhs,
3693 ReporterSpec const& rhs );
3694 friend bool operator!=( ReporterSpec const& lhs,
3695 ReporterSpec const& rhs ) {
3696 return !( lhs == rhs );
3697 }
3698
3699 public:
3701 std::string name,
3702 Optional<std::string> outputFileName,
3703 Optional<ColourMode> colourMode,
3704 std::map<std::string, std::string> customOptions );
3705
3706 std::string const& name() const { return m_name; }
3707
3709 return m_outputFileName;
3710 }
3711
3713
3714 std::map<std::string, std::string> const& customOptions() const {
3715 return m_customOptions;
3716 }
3717 };
3718
3729 Optional<ReporterSpec> parseReporterSpec( StringRef reporterSpec );
3730
3731}
3732
3733#endif // CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
3734
3735#include <chrono>
3736#include <map>
3737#include <string>
3738#include <vector>
3739
3740namespace Catch {
3741
3742 class IStream;
3743
3750 std::string name;
3751 std::string outputFilename;
3753 std::map<std::string, std::string> customOptions;
3754 friend bool operator==( ProcessedReporterSpec const& lhs,
3755 ProcessedReporterSpec const& rhs );
3756 friend bool operator!=( ProcessedReporterSpec const& lhs,
3757 ProcessedReporterSpec const& rhs ) {
3758 return !( lhs == rhs );
3759 }
3760 };
3761
3762 struct ConfigData {
3763
3764 bool listTests = false;
3765 bool listTags = false;
3766 bool listReporters = false;
3767 bool listListeners = false;
3768
3770 bool shouldDebugBreak = false;
3771 bool noThrow = false;
3772 bool showHelp = false;
3773 bool showInvisibles = false;
3774 bool filenamesAsTags = false;
3775 bool libIdentify = false;
3776 bool allowZeroTests = false;
3777
3778 int abortAfter = -1;
3780
3781 unsigned int shardCount = 1;
3782 unsigned int shardIndex = 0;
3783
3784 bool skipBenchmarks = false;
3786 unsigned int benchmarkSamples = 100;
3788 unsigned int benchmarkResamples = 100'000;
3789 std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
3790
3794 double minDuration = -1;
3798
3800 std::string name;
3801 std::string processName;
3802 std::vector<ReporterSpec> reporterSpecifications;
3803
3804 std::vector<std::string> testsOrTags;
3805 std::vector<std::string> sectionsToRun;
3806 };
3807
3808
3809 class Config : public IConfig {
3810 public:
3811
3812 Config() = default;
3813 Config( ConfigData const& data );
3814 ~Config() override; // = default in the cpp file
3815
3816 bool listTests() const;
3817 bool listTags() const;
3818 bool listReporters() const;
3819 bool listListeners() const;
3820
3821 std::vector<ReporterSpec> const& getReporterSpecs() const;
3822 std::vector<ProcessedReporterSpec> const&
3824
3825 std::vector<std::string> const& getTestsOrTags() const override;
3826 std::vector<std::string> const& getSectionsToRun() const override;
3827
3828 TestSpec const& testSpec() const override;
3829 bool hasTestFilters() const override;
3830
3831 bool showHelp() const;
3832
3833 // IConfig interface
3834 bool allowThrows() const override;
3835 StringRef name() const override;
3836 bool includeSuccessfulResults() const override;
3837 bool warnAboutMissingAssertions() const override;
3838 bool warnAboutUnmatchedTestSpecs() const override;
3839 bool zeroTestsCountAsSuccess() const override;
3840 ShowDurations showDurations() const override;
3841 double minDuration() const override;
3842 TestRunOrder runOrder() const override;
3843 uint32_t rngSeed() const override;
3844 unsigned int shardCount() const override;
3845 unsigned int shardIndex() const override;
3846 ColourMode defaultColourMode() const override;
3847 bool shouldDebugBreak() const override;
3848 int abortAfter() const override;
3849 bool showInvisibles() const override;
3850 Verbosity verbosity() const override;
3851 bool skipBenchmarks() const override;
3852 bool benchmarkNoAnalysis() const override;
3853 unsigned int benchmarkSamples() const override;
3854 double benchmarkConfidenceInterval() const override;
3855 unsigned int benchmarkResamples() const override;
3856 std::chrono::milliseconds benchmarkWarmupTime() const override;
3857
3858 private:
3859 // Reads Bazel env vars and applies them to the config
3860 void readBazelEnvVars();
3861
3863 std::vector<ProcessedReporterSpec> m_processedReporterSpecs;
3865 bool m_hasTestFilters = false;
3866 };
3867} // end namespace Catch
3868
3869#endif // CATCH_CONFIG_HPP_INCLUDED
3870
3871
3872#ifndef CATCH_GET_RANDOM_SEED_HPP_INCLUDED
3873#define CATCH_GET_RANDOM_SEED_HPP_INCLUDED
3874
3875#include <cstdint>
3876
3877namespace Catch {
3879 std::uint32_t getSeed();
3880}
3881
3882#endif // CATCH_GET_RANDOM_SEED_HPP_INCLUDED
3883
3884
3885#ifndef CATCH_MESSAGE_HPP_INCLUDED
3886#define CATCH_MESSAGE_HPP_INCLUDED
3887
3888
3889
3890
3901
3902#ifndef CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED
3903#define CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED
3904
3905
3906#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_PREFIX_MESSAGES)
3907 #define CATCH_CONFIG_PREFIX_MESSAGES
3908#endif
3909
3910#endif // CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED
3911
3912
3913#ifndef CATCH_STREAM_END_STOP_HPP_INCLUDED
3914#define CATCH_STREAM_END_STOP_HPP_INCLUDED
3915
3916
3917namespace Catch {
3918
3919 // Use this in variadic streaming macros to allow
3920 // << +StreamEndStop
3921 // as well as
3922 // << stuff +StreamEndStop
3924 constexpr StringRef operator+() const { return StringRef(); }
3925
3926 template <typename T>
3927 constexpr friend T const& operator+( T const& value, StreamEndStop ) {
3928 return value;
3929 }
3930 };
3931
3932} // namespace Catch
3933
3934#endif // CATCH_STREAM_END_STOP_HPP_INCLUDED
3935
3936
3937#ifndef CATCH_MESSAGE_INFO_HPP_INCLUDED
3938#define CATCH_MESSAGE_INFO_HPP_INCLUDED
3939
3940
3941#include <string>
3942
3943namespace Catch {
3944
3946 MessageInfo( StringRef _macroName,
3947 SourceLineInfo const& _lineInfo,
3948 ResultWas::OfType _type );
3949
3951 std::string message;
3954 unsigned int sequence;
3955
3956 bool operator == (MessageInfo const& other) const {
3957 return sequence == other.sequence;
3958 }
3959 bool operator < (MessageInfo const& other) const {
3960 return sequence < other.sequence;
3961 }
3962 private:
3963 static unsigned int globalCount;
3964 };
3965
3966} // end namespace Catch
3967
3968#endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
3969
3970#include <string>
3971#include <vector>
3972
3973namespace Catch {
3974
3975 struct SourceLineInfo;
3976 class IResultCapture;
3977
3979
3980 template<typename T>
3981 MessageStream& operator << ( T const& value ) {
3982 m_stream << value;
3983 return *this;
3984 }
3985
3987 };
3988
3991 SourceLineInfo const& lineInfo,
3992 ResultWas::OfType type ):
3993 m_info(macroName, lineInfo, type) {}
3994
3995 template<typename T>
3996 MessageBuilder&& operator << ( T const& value ) && {
3997 m_stream << value;
3998 return CATCH_MOVE(*this);
3999 }
4000
4002 };
4003
4005 public:
4006 explicit ScopedMessage( MessageBuilder&& builder );
4007 ScopedMessage( ScopedMessage& duplicate ) = delete;
4008 ScopedMessage( ScopedMessage&& old ) noexcept;
4010
4012 bool m_moved = false;
4013 };
4014
4015 class Capturer {
4016 std::vector<MessageInfo> m_messages;
4018 size_t m_captured = 0;
4019 public:
4020 Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
4021
4022 Capturer(Capturer const&) = delete;
4023 Capturer& operator=(Capturer const&) = delete;
4024
4025 ~Capturer();
4026
4027 void captureValue( size_t index, std::string const& value );
4028
4029 template<typename T>
4030 void captureValues( size_t index, T const& value ) {
4031 captureValue( index, Catch::Detail::stringify( value ) );
4032 }
4033
4034 template<typename T, typename... Ts>
4035 void captureValues( size_t index, T const& value, Ts const&... values ) {
4036 captureValue( index, Catch::Detail::stringify(value) );
4037 captureValues( index+1, values... );
4038 }
4039 };
4040
4041} // end namespace Catch
4042
4044#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
4045 do { \
4046 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
4047 catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
4048 catchAssertionHandler.complete(); \
4049 } while( false )
4050
4052#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
4053 Catch::Capturer varName( macroName##_catch_sr, \
4054 CATCH_INTERNAL_LINEINFO, \
4055 Catch::ResultWas::Info, \
4056 #__VA_ARGS__##_catch_sr ); \
4057 varName.captureValues( 0, __VA_ARGS__ )
4058
4060#define INTERNAL_CATCH_INFO( macroName, log ) \
4061 const Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
4062
4064#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
4065 Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
4066
4067
4068#if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
4069
4070 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
4071 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
4072 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
4073 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__ )
4074
4075#elif defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
4076
4077 #define CATCH_INFO( msg ) (void)(0)
4078 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
4079 #define CATCH_WARN( msg ) (void)(0)
4080 #define CATCH_CAPTURE( ... ) (void)(0)
4081
4082#elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
4083
4084 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
4085 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
4086 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
4087 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__ )
4088
4089#elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
4090
4091 #define INFO( msg ) (void)(0)
4092 #define UNSCOPED_INFO( msg ) (void)(0)
4093 #define WARN( msg ) (void)(0)
4094 #define CAPTURE( ... ) (void)(0)
4095
4096#endif // end of user facing macro declarations
4097
4098
4099
4100
4101#endif // CATCH_MESSAGE_HPP_INCLUDED
4102
4103
4104#ifndef CATCH_SECTION_INFO_HPP_INCLUDED
4105#define CATCH_SECTION_INFO_HPP_INCLUDED
4106
4107
4108
4109#ifndef CATCH_TOTALS_HPP_INCLUDED
4110#define CATCH_TOTALS_HPP_INCLUDED
4111
4112#include <cstdint>
4113
4114namespace Catch {
4115
4116 struct Counts {
4117 Counts operator - ( Counts const& other ) const;
4118 Counts& operator += ( Counts const& other );
4119
4120 std::uint64_t total() const;
4121 bool allPassed() const;
4122 bool allOk() const;
4123
4124 std::uint64_t passed = 0;
4125 std::uint64_t failed = 0;
4126 std::uint64_t failedButOk = 0;
4127 std::uint64_t skipped = 0;
4128 };
4129
4130 struct Totals {
4131
4132 Totals operator - ( Totals const& other ) const;
4133 Totals& operator += ( Totals const& other );
4134
4135 Totals delta( Totals const& prevTotals ) const;
4136
4139 };
4140}
4141
4142#endif // CATCH_TOTALS_HPP_INCLUDED
4143
4144#include <string>
4145
4146namespace Catch {
4147
4149 // The last argument is ignored, so that people can write
4150 // SECTION("ShortName", "Proper description that is long") and
4151 // still use the `-c` flag comfortably.
4152 SectionInfo( SourceLineInfo const& _lineInfo, std::string _name,
4153 const char* const = nullptr ):
4154 name(CATCH_MOVE(_name)),
4155 lineInfo(_lineInfo)
4156 {}
4157
4158 std::string name;
4160 };
4161
4167
4168} // end namespace Catch
4169
4170#endif // CATCH_SECTION_INFO_HPP_INCLUDED
4171
4172
4173#ifndef CATCH_SESSION_HPP_INCLUDED
4174#define CATCH_SESSION_HPP_INCLUDED
4175
4176
4177
4178#ifndef CATCH_COMMANDLINE_HPP_INCLUDED
4179#define CATCH_COMMANDLINE_HPP_INCLUDED
4180
4181
4182
4183#ifndef CATCH_CLARA_HPP_INCLUDED
4184#define CATCH_CLARA_HPP_INCLUDED
4185
4186#if defined( __clang__ )
4187# pragma clang diagnostic push
4188# pragma clang diagnostic ignored "-Wweak-vtables"
4189# pragma clang diagnostic ignored "-Wshadow"
4190# pragma clang diagnostic ignored "-Wdeprecated"
4191#endif
4192
4193#if defined( __GNUC__ )
4194# pragma GCC diagnostic push
4195# pragma GCC diagnostic ignored "-Wsign-conversion"
4196#endif
4197
4198#ifndef CLARA_CONFIG_OPTIONAL_TYPE
4199# ifdef __has_include
4200# if __has_include( <optional>) && __cplusplus >= 201703L
4201# include <optional>
4202# define CLARA_CONFIG_OPTIONAL_TYPE std::optional
4203# endif
4204# endif
4205#endif
4206
4207
4208#include <cassert>
4209#include <memory>
4210#include <ostream>
4211#include <sstream>
4212#include <string>
4213#include <type_traits>
4214#include <vector>
4215
4216namespace Catch {
4217 namespace Clara {
4218
4219 class Args;
4220 class Parser;
4221
4222 // enum of result types from a parse
4229
4230 struct accept_many_t {};
4232
4233 namespace Detail {
4234 struct fake_arg {
4235 template <typename T>
4236 operator T();
4237 };
4238
4239 template <typename F, typename = void>
4240 struct is_unary_function : std::false_type {};
4241
4242 template <typename F>
4244 F,
4245 Catch::Detail::void_t<decltype(
4246 std::declval<F>()( fake_arg() ) )
4247 >
4248 > : std::true_type {};
4249
4250 // Traits for extracting arg and return type of lambdas (for single
4251 // argument lambdas)
4252 template <typename L>
4254 : UnaryLambdaTraits<decltype( &L::operator() )> {};
4255
4256 template <typename ClassT, typename ReturnT, typename... Args>
4257 struct UnaryLambdaTraits<ReturnT ( ClassT::* )( Args... ) const> {
4258 static const bool isValid = false;
4259 };
4260
4261 template <typename ClassT, typename ReturnT, typename ArgT>
4262 struct UnaryLambdaTraits<ReturnT ( ClassT::* )( ArgT ) const> {
4263 static const bool isValid = true;
4264 using ArgType = std::remove_const_t<std::remove_reference_t<ArgT>>;
4265 using ReturnType = ReturnT;
4266 };
4267
4268 class TokenStream;
4269
4270 // Wraps a token coming from a token stream. These may not directly
4271 // correspond to strings as a single string may encode an option +
4272 // its argument if the : or = form is used
4273 enum class TokenType { Option, Argument };
4278
4279 // Abstracts iterators into args as a stream of tokens, with option
4280 // arguments uniformly handled
4282 using Iterator = std::vector<StringRef>::const_iterator;
4285 std::vector<Token> m_tokenBuffer;
4286 void loadBuffer();
4287
4288 public:
4289 explicit TokenStream( Args const& args );
4291
4292 explicit operator bool() const {
4293 return !m_tokenBuffer.empty() || it != itEnd;
4294 }
4295
4296 size_t count() const {
4297 return m_tokenBuffer.size() + ( itEnd - it );
4298 }
4299
4301 assert( !m_tokenBuffer.empty() );
4302 return m_tokenBuffer.front();
4303 }
4304
4305 Token const* operator->() const {
4306 assert( !m_tokenBuffer.empty() );
4307 return &m_tokenBuffer.front();
4308 }
4309
4310 TokenStream& operator++();
4311 };
4312
4320
4322 protected:
4323 ResultBase( ResultType type ): m_type( type ) {}
4324 virtual ~ResultBase(); // = default;
4325
4326
4327 ResultBase(ResultBase const&) = default;
4328 ResultBase& operator=(ResultBase const&) = default;
4331
4332 virtual void enforceOk() const = 0;
4333
4335 };
4336
4337 template <typename T>
4339 public:
4340 T const& value() const& {
4341 enforceOk();
4342 return m_value;
4343 }
4344 T&& value() && {
4345 enforceOk();
4346 return CATCH_MOVE( m_value );
4347 }
4348
4349 protected:
4351
4353 ResultBase( other ) {
4354 if ( m_type == ResultType::Ok )
4355 new ( &m_value ) T( other.m_value );
4356 }
4358 ResultBase( other ) {
4359 if ( m_type == ResultType::Ok )
4360 new ( &m_value ) T( CATCH_MOVE(other.m_value) );
4361 }
4362
4363
4366 new ( &m_value ) T( value );
4367 }
4370 new ( &m_value ) T( CATCH_MOVE(value) );
4371 }
4372
4374 if ( m_type == ResultType::Ok )
4375 m_value.~T();
4376 ResultBase::operator=( other );
4377 if ( m_type == ResultType::Ok )
4378 new ( &m_value ) T( other.m_value );
4379 return *this;
4380 }
4382 if ( m_type == ResultType::Ok ) m_value.~T();
4383 ResultBase::operator=( other );
4384 if ( m_type == ResultType::Ok )
4385 new ( &m_value ) T( CATCH_MOVE(other.m_value) );
4386 return *this;
4387 }
4388
4389
4390 ~ResultValueBase() override {
4391 if ( m_type == ResultType::Ok )
4392 m_value.~T();
4393 }
4394
4395 union {
4397 };
4398 };
4399
4400 template <> class ResultValueBase<void> : public ResultBase {
4401 protected:
4403 };
4404
4405 template <typename T = void>
4406 class BasicResult : public ResultValueBase<T> {
4407 public:
4408 template <typename U>
4409 explicit BasicResult( BasicResult<U> const& other ):
4410 ResultValueBase<T>( other.type() ),
4411 m_errorMessage( other.errorMessage() ) {
4412 assert( type() != ResultType::Ok );
4413 }
4414
4415 template <typename U>
4416 static auto ok( U&& value ) -> BasicResult {
4417 return { ResultType::Ok, CATCH_FORWARD(value) };
4418 }
4419 static auto ok() -> BasicResult { return { ResultType::Ok }; }
4420 static auto logicError( std::string&& message )
4421 -> BasicResult {
4422 return { ResultType::LogicError, CATCH_MOVE(message) };
4423 }
4424 static auto runtimeError( std::string&& message )
4425 -> BasicResult {
4426 return { ResultType::RuntimeError, CATCH_MOVE(message) };
4427 }
4428
4429 explicit operator bool() const {
4430 return m_type == ResultType::Ok;
4431 }
4432 auto type() const -> ResultType { return m_type; }
4433 auto errorMessage() const -> std::string const& {
4434 return m_errorMessage;
4435 }
4436
4437 protected:
4438 void enforceOk() const override {
4439
4440 // Errors shouldn't reach this point, but if they do
4441 // the actual error message will be in m_errorMessage
4442 assert( m_type != ResultType::LogicError );
4443 assert( m_type != ResultType::RuntimeError );
4444 if ( m_type != ResultType::Ok )
4445 std::abort();
4446 }
4447
4448 std::string
4449 m_errorMessage; // Only populated if resultType is an error
4450
4452 std::string&& message ):
4453 ResultValueBase<T>( type ), m_errorMessage( CATCH_MOVE(message) ) {
4454 assert( m_type != ResultType::Ok );
4455 }
4456
4459 };
4460
4462 public:
4465
4466 ParseResultType type() const { return m_type; }
4468 return m_remainingTokens;
4469 }
4473
4474 private:
4477 };
4478
4482
4484 std::string left;
4486 };
4487
4488 template <typename T>
4489 ParserResult convertInto( std::string const& source, T& target ) {
4490 std::stringstream ss( source );
4491 ss >> target;
4492 if ( ss.fail() ) {
4494 "Unable to convert '" + source +
4495 "' to destination type" );
4496 } else {
4498 }
4499 }
4500 ParserResult convertInto( std::string const& source,
4501 std::string& target );
4502 ParserResult convertInto( std::string const& source, bool& target );
4503
4504#ifdef CLARA_CONFIG_OPTIONAL_TYPE
4505 template <typename T>
4506 auto convertInto( std::string const& source,
4507 CLARA_CONFIG_OPTIONAL_TYPE<T>& target )
4508 -> ParserResult {
4509 T temp;
4510 auto result = convertInto( source, temp );
4511 if ( result )
4512 target = CATCH_MOVE( temp );
4513 return result;
4514 }
4515#endif // CLARA_CONFIG_OPTIONAL_TYPE
4516
4518 virtual ~BoundRef() = default;
4519 virtual bool isContainer() const;
4520 virtual bool isFlag() const;
4521 };
4523 virtual auto setValue( std::string const& arg )
4524 -> ParserResult = 0;
4525 };
4527 virtual auto setFlag( bool flag ) -> ParserResult = 0;
4528 bool isFlag() const override;
4529 };
4530
4531 template <typename T> struct BoundValueRef : BoundValueRefBase {
4533
4534 explicit BoundValueRef( T& ref ): m_ref( ref ) {}
4535
4536 ParserResult setValue( std::string const& arg ) override {
4537 return convertInto( arg, m_ref );
4538 }
4539 };
4540
4541 template <typename T>
4542 struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
4543 std::vector<T>& m_ref;
4544
4545 explicit BoundValueRef( std::vector<T>& ref ): m_ref( ref ) {}
4546
4547 auto isContainer() const -> bool override { return true; }
4548
4549 auto setValue( std::string const& arg )
4550 -> ParserResult override {
4551 T temp;
4552 auto result = convertInto( arg, temp );
4553 if ( result )
4554 m_ref.push_back( temp );
4555 return result;
4556 }
4557 };
4558
4560 bool& m_ref;
4561
4562 explicit BoundFlagRef( bool& ref ): m_ref( ref ) {}
4563
4564 ParserResult setFlag( bool flag ) override;
4565 };
4566
4567 template <typename ReturnType> struct LambdaInvoker {
4568 static_assert(
4569 std::is_same<ReturnType, ParserResult>::value,
4570 "Lambda must return void or clara::ParserResult" );
4571
4572 template <typename L, typename ArgType>
4573 static auto invoke( L const& lambda, ArgType const& arg )
4574 -> ParserResult {
4575 return lambda( arg );
4576 }
4577 };
4578
4579 template <> struct LambdaInvoker<void> {
4580 template <typename L, typename ArgType>
4581 static auto invoke( L const& lambda, ArgType const& arg )
4582 -> ParserResult {
4583 lambda( arg );
4585 }
4586 };
4587
4588 template <typename ArgType, typename L>
4589 auto invokeLambda( L const& lambda, std::string const& arg )
4590 -> ParserResult {
4591 ArgType temp{};
4592 auto result = convertInto( arg, temp );
4593 return !result ? result
4595 L>::ReturnType>::invoke( lambda, temp );
4596 }
4597
4598 template <typename L> struct BoundLambda : BoundValueRefBase {
4600
4601 static_assert(
4603 "Supplied lambda must take exactly one argument" );
4604 explicit BoundLambda( L const& lambda ): m_lambda( lambda ) {}
4605
4606 auto setValue( std::string const& arg )
4607 -> ParserResult override {
4609 m_lambda, arg );
4610 }
4611 };
4612
4613 template <typename L> struct BoundManyLambda : BoundLambda<L> {
4614 explicit BoundManyLambda( L const& lambda ): BoundLambda<L>( lambda ) {}
4615 bool isContainer() const override { return true; }
4616 };
4617
4618 template <typename L> struct BoundFlagLambda : BoundFlagRefBase {
4620
4621 static_assert(
4623 "Supplied lambda must take exactly one argument" );
4624 static_assert(
4625 std::is_same<typename UnaryLambdaTraits<L>::ArgType,
4626 bool>::value,
4627 "flags must be boolean" );
4628
4629 explicit BoundFlagLambda( L const& lambda ):
4630 m_lambda( lambda ) {}
4631
4632 auto setFlag( bool flag ) -> ParserResult override {
4633 return LambdaInvoker<typename UnaryLambdaTraits<
4634 L>::ReturnType>::invoke( m_lambda, flag );
4635 }
4636 };
4637
4639
4641 public:
4642 virtual ~ParserBase() = default;
4643 virtual auto validate() const -> Result { return Result::ok(); }
4644 virtual auto parse( std::string const& exeName,
4645 TokenStream tokens ) const
4646 -> InternalParseResult = 0;
4647 virtual size_t cardinality() const;
4648
4649 InternalParseResult parse( Args const& args ) const;
4650 };
4651
4652 template <typename DerivedT>
4654 public:
4655 template <typename T>
4656 auto operator|( T const& other ) const -> Parser;
4657 };
4658
4659 // Common code and state for Args and Opts
4660 template <typename DerivedT>
4661 class ParserRefImpl : public ComposableParserImpl<DerivedT> {
4662 protected:
4664 std::shared_ptr<BoundRef> m_ref;
4667
4668 explicit ParserRefImpl( std::shared_ptr<BoundRef> const& ref ):
4669 m_ref( ref ) {}
4670
4671 public:
4672 template <typename LambdaT>
4674 LambdaT const& ref,
4675 StringRef hint ):
4676 m_ref( std::make_shared<BoundManyLambda<LambdaT>>( ref ) ),
4677 m_hint( hint ) {}
4678
4679 template <typename T,
4680 typename = typename std::enable_if_t<
4683 m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
4684 m_hint( hint ) {}
4685
4686 template <typename LambdaT,
4687 typename = typename std::enable_if_t<
4689 ParserRefImpl( LambdaT const& ref, StringRef hint ):
4690 m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
4691 m_hint( hint ) {}
4692
4693 DerivedT& operator()( StringRef description ) & {
4694 m_description = description;
4695 return static_cast<DerivedT&>( *this );
4696 }
4697 DerivedT&& operator()( StringRef description ) && {
4698 m_description = description;
4699 return static_cast<DerivedT&&>( *this );
4700 }
4701
4702 auto optional() -> DerivedT& {
4704 return static_cast<DerivedT&>( *this );
4705 }
4706
4707 auto required() -> DerivedT& {
4709 return static_cast<DerivedT&>( *this );
4710 }
4711
4712 auto isOptional() const -> bool {
4714 }
4715
4716 auto cardinality() const -> size_t override {
4717 if ( m_ref->isContainer() )
4718 return 0;
4719 else
4720 return 1;
4721 }
4722
4723 StringRef hint() const { return m_hint; }
4724 };
4725
4726 } // namespace detail
4727
4728
4729 // A parser for arguments
4730 class Arg : public Detail::ParserRefImpl<Arg> {
4731 public:
4732 using ParserRefImpl::ParserRefImpl;
4733 using ParserBase::parse;
4734
4736 parse(std::string const&,
4737 Detail::TokenStream tokens) const override;
4738 };
4739
4740 // A parser for options
4741 class Opt : public Detail::ParserRefImpl<Opt> {
4742 protected:
4743 std::vector<StringRef> m_optNames;
4744
4745 public:
4746 template <typename LambdaT>
4747 explicit Opt(LambdaT const& ref) :
4749 std::make_shared<Detail::BoundFlagLambda<LambdaT>>(ref)) {}
4750
4751 explicit Opt(bool& ref);
4752
4753 template <typename LambdaT,
4754 typename = typename std::enable_if_t<
4756 Opt( LambdaT const& ref, StringRef hint ):
4757 ParserRefImpl( ref, hint ) {}
4758
4759 template <typename LambdaT>
4760 Opt( accept_many_t, LambdaT const& ref, StringRef hint ):
4761 ParserRefImpl( accept_many, ref, hint ) {}
4762
4763 template <typename T,
4764 typename = typename std::enable_if_t<
4766 Opt( T& ref, StringRef hint ):
4767 ParserRefImpl( ref, hint ) {}
4768
4769 Opt& operator[]( StringRef optName ) & {
4770 m_optNames.push_back(optName);
4771 return *this;
4772 }
4773 Opt&& operator[]( StringRef optName ) && {
4774 m_optNames.push_back( optName );
4775 return CATCH_MOVE(*this);
4776 }
4777
4778 Detail::HelpColumns getHelpColumns() const;
4779
4780 bool isMatch(StringRef optToken) const;
4781
4782 using ParserBase::parse;
4783
4785 parse(std::string const&,
4786 Detail::TokenStream tokens) const override;
4787
4788 Detail::Result validate() const override;
4789 };
4790
4791 // Specifies the name of the executable
4792 class ExeName : public Detail::ComposableParserImpl<ExeName> {
4793 std::shared_ptr<std::string> m_name;
4794 std::shared_ptr<Detail::BoundValueRefBase> m_ref;
4795
4796 public:
4797 ExeName();
4798 explicit ExeName(std::string& ref);
4799
4800 template <typename LambdaT>
4801 explicit ExeName(LambdaT const& lambda) : ExeName() {
4802 m_ref = std::make_shared<Detail::BoundLambda<LambdaT>>(lambda);
4803 }
4804
4805 // The exe name is not parsed out of the normal tokens, but is
4806 // handled specially
4808 parse(std::string const&,
4809 Detail::TokenStream tokens) const override;
4810
4811 std::string const& name() const { return *m_name; }
4812 Detail::ParserResult set(std::string const& newName);
4813 };
4814
4815
4816 // A Combined parser
4819 std::vector<Opt> m_options;
4820 std::vector<Arg> m_args;
4821
4822 public:
4823
4824 auto operator|=(ExeName const& exeName) -> Parser& {
4825 m_exeName = exeName;
4826 return *this;
4827 }
4828
4829 auto operator|=(Arg const& arg) -> Parser& {
4830 m_args.push_back(arg);
4831 return *this;
4832 }
4833
4834 friend Parser& operator|=( Parser& p, Opt const& opt ) {
4835 p.m_options.push_back( opt );
4836 return p;
4837 }
4838 friend Parser& operator|=( Parser& p, Opt&& opt ) {
4839 p.m_options.push_back( CATCH_MOVE(opt) );
4840 return p;
4841 }
4842
4843 Parser& operator|=(Parser const& other);
4844
4845 template <typename T>
4846 friend Parser operator|( Parser const& p, T&& rhs ) {
4847 Parser temp( p );
4848 temp |= rhs;
4849 return temp;
4850 }
4851
4852 template <typename T>
4853 friend Parser operator|( Parser&& p, T&& rhs ) {
4854 p |= CATCH_FORWARD(rhs);
4855 return CATCH_MOVE(p);
4856 }
4857
4858 std::vector<Detail::HelpColumns> getHelpColumns() const;
4859
4860 void writeToStream(std::ostream& os) const;
4861
4862 friend auto operator<<(std::ostream& os, Parser const& parser)
4863 -> std::ostream& {
4864 parser.writeToStream(os);
4865 return os;
4866 }
4867
4868 Detail::Result validate() const override;
4869
4870 using ParserBase::parse;
4872 parse(std::string const& exeName,
4873 Detail::TokenStream tokens) const override;
4874 };
4875
4879 class Args {
4880 friend Detail::TokenStream;
4882 std::vector<StringRef> m_args;
4883
4884 public:
4885 Args(int argc, char const* const* argv);
4886 // Helper constructor for testing
4887 Args(std::initializer_list<StringRef> args);
4888
4889 StringRef exeName() const { return m_exeName; }
4890 };
4891
4892
4893 // Convenience wrapper for option parser that specifies the help option
4894 struct Help : Opt {
4895 Help(bool& showHelpFlag);
4896 };
4897
4898 // Result type for parser operation
4900
4901 namespace Detail {
4902 template <typename DerivedT>
4903 template <typename T>
4904 Parser
4906 return Parser() | static_cast<DerivedT const&>(*this) | other;
4907 }
4908 }
4909
4910 } // namespace Clara
4911} // namespace Catch
4912
4913#if defined( __clang__ )
4914# pragma clang diagnostic pop
4915#endif
4916
4917#if defined( __GNUC__ )
4918# pragma GCC diagnostic pop
4919#endif
4920
4921#endif // CATCH_CLARA_HPP_INCLUDED
4922
4923namespace Catch {
4924
4925 struct ConfigData;
4926
4927 Clara::Parser makeCommandLineParser( ConfigData& config );
4928
4929} // end namespace Catch
4930
4931#endif // CATCH_COMMANDLINE_HPP_INCLUDED
4932
4933namespace Catch {
4934
4936 public:
4937
4938 Session();
4939 ~Session();
4940
4941 void showHelp() const;
4942 void libIdentify();
4943
4944 int applyCommandLine( int argc, char const * const * argv );
4945 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
4946 int applyCommandLine( int argc, wchar_t const * const * argv );
4947 #endif
4948
4949 void useConfigData( ConfigData const& configData );
4950
4951 template<typename CharT>
4952 int run(int argc, CharT const * const argv[]) {
4954 return 1;
4955 int returnCode = applyCommandLine(argc, argv);
4956 if (returnCode == 0)
4957 returnCode = run();
4958 return returnCode;
4959 }
4960
4961 int run();
4962
4963 Clara::Parser const& cli() const;
4964 void cli( Clara::Parser const& newParser );
4965 ConfigData& configData();
4966 Config& config();
4967 private:
4968 int runInternal();
4969
4974 };
4975
4976} // end namespace Catch
4977
4978#endif // CATCH_SESSION_HPP_INCLUDED
4979
4980
4981#ifndef CATCH_TAG_ALIAS_HPP_INCLUDED
4982#define CATCH_TAG_ALIAS_HPP_INCLUDED
4983
4984
4985#include <string>
4986
4987namespace Catch {
4988
4989 struct TagAlias {
4990 TagAlias(std::string const& _tag, SourceLineInfo _lineInfo):
4991 tag(_tag),
4992 lineInfo(_lineInfo)
4993 {}
4994
4995 std::string tag;
4997 };
4998
4999} // end namespace Catch
5000
5001#endif // CATCH_TAG_ALIAS_HPP_INCLUDED
5002
5003
5004#ifndef CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
5005#define CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
5006
5007
5008namespace Catch {
5009
5011 RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
5012 };
5013
5014} // end namespace Catch
5015
5016#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
5017 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5018 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5019 namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
5020 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5021
5022#endif // CATCH_TAG_ALIAS_AUTOREGISTRAR_HPP_INCLUDED
5023
5024
5025#ifndef CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
5026#define CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
5027
5028// We need this suppression to leak, because it took until GCC 10
5029// for the front end to handle local suppression via _Pragma properly
5030// inside templates (so `TEMPLATE_TEST_CASE` and co).
5031// **THIS IS DIFFERENT FOR STANDARD TESTS, WHERE GCC 9 IS SUFFICIENT**
5032#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 10
5033#pragma GCC diagnostic ignored "-Wparentheses"
5034#endif
5035
5036
5037
5038
5039#ifndef CATCH_TEST_MACROS_HPP_INCLUDED
5040#define CATCH_TEST_MACROS_HPP_INCLUDED
5041
5042
5043
5044#ifndef CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5045#define CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5046
5047
5048
5049#ifndef CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5050#define CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5051
5052
5053
5054#ifndef CATCH_DECOMPOSER_HPP_INCLUDED
5055#define CATCH_DECOMPOSER_HPP_INCLUDED
5056
5057
5058
5059#ifndef CATCH_COMPARE_TRAITS_HPP_INCLUDED
5060#define CATCH_COMPARE_TRAITS_HPP_INCLUDED
5061
5062
5063#include <type_traits>
5064
5065namespace Catch {
5066 namespace Detail {
5067
5068#if defined( __GNUC__ ) && !defined( __clang__ )
5069# pragma GCC diagnostic push
5070 // GCC likes to complain about comparing bool with 0, in the decltype()
5071 // that defines the comparable traits below.
5072# pragma GCC diagnostic ignored "-Wbool-compare"
5073 // "ordered comparison of pointer with integer zero" same as above,
5074 // but it does not have a separate warning flag to suppress
5075# pragma GCC diagnostic ignored "-Wextra"
5076 // Did you know that comparing floats with `0` directly
5077 // is super-duper dangerous in unevaluated context?
5078# pragma GCC diagnostic ignored "-Wfloat-equal"
5079#endif
5080
5081#if defined( __clang__ )
5082# pragma clang diagnostic push
5083 // Did you know that comparing floats with `0` directly
5084 // is super-duper dangerous in unevaluated context?
5085# pragma clang diagnostic ignored "-Wfloat-equal"
5086#endif
5087
5088#define CATCH_DEFINE_COMPARABLE_TRAIT( id, op ) \
5089 template <typename, typename, typename = void> \
5090 struct is_##id##_comparable : std::false_type {}; \
5091 template <typename T, typename U> \
5092 struct is_##id##_comparable< \
5093 T, \
5094 U, \
5095 void_t<decltype( std::declval<T>() op std::declval<U>() )>> \
5096 : std::true_type {}; \
5097 template <typename, typename = void> \
5098 struct is_##id##_0_comparable : std::false_type {}; \
5099 template <typename T> \
5100 struct is_##id##_0_comparable<T, \
5101 void_t<decltype( std::declval<T>() op 0 )>> \
5102 : std::true_type {};
5103
5104 // We need all 6 pre-spaceship comparison ops: <, <=, >, >=, ==, !=
5111
5112#undef CATCH_DEFINE_COMPARABLE_TRAIT
5113
5114#if defined( __GNUC__ ) && !defined( __clang__ )
5115# pragma GCC diagnostic pop
5116#endif
5117#if defined( __clang__ )
5118# pragma clang diagnostic pop
5119#endif
5120
5121
5122 } // namespace Detail
5123} // namespace Catch
5124
5125#endif // CATCH_COMPARE_TRAITS_HPP_INCLUDED
5126
5127
5128#ifndef CATCH_LOGICAL_TRAITS_HPP_INCLUDED
5129#define CATCH_LOGICAL_TRAITS_HPP_INCLUDED
5130
5131#include <type_traits>
5132
5133namespace Catch {
5134namespace Detail {
5135
5136#if defined( __cpp_lib_logical_traits ) && __cpp_lib_logical_traits >= 201510
5137
5138 using std::conjunction;
5139 using std::disjunction;
5140 using std::negation;
5141
5142#else
5143
5144 template <class...> struct conjunction : std::true_type {};
5145 template <class B1> struct conjunction<B1> : B1 {};
5146 template <class B1, class... Bn>
5147 struct conjunction<B1, Bn...>
5148 : std::conditional_t<bool( B1::value ), conjunction<Bn...>, B1> {};
5149
5150 template <class...> struct disjunction : std::false_type {};
5151 template <class B1> struct disjunction<B1> : B1 {};
5152 template <class B1, class... Bn>
5153 struct disjunction<B1, Bn...>
5154 : std::conditional_t<bool( B1::value ), B1, disjunction<Bn...>> {};
5155
5156 template <class B>
5157 struct negation : std::integral_constant<bool, !bool(B::value)> {};
5158
5159#endif
5160
5161} // namespace Detail
5162} // namespace Catch
5163
5164#endif // CATCH_LOGICAL_TRAITS_HPP_INCLUDED
5165
5166#include <type_traits>
5167#include <iosfwd>
5168
5248
5249#ifdef _MSC_VER
5250#pragma warning(push)
5251#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
5252#pragma warning(disable:4018) // more "signed/unsigned mismatch"
5253#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
5254#pragma warning(disable:4180) // qualifier applied to function type has no meaning
5255#pragma warning(disable:4800) // Forcing result to true or false
5256#endif
5257
5258#ifdef __clang__
5259# pragma clang diagnostic push
5260# pragma clang diagnostic ignored "-Wsign-compare"
5261# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
5262#elif defined __GNUC__
5263# pragma GCC diagnostic push
5264# pragma GCC diagnostic ignored "-Wsign-compare"
5265# pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
5266#endif
5267
5268#if defined(CATCH_CPP20_OR_GREATER) && __has_include(<compare>)
5269# include <compare>
5270# if defined( __cpp_lib_three_way_comparison ) && \
5271 __cpp_lib_three_way_comparison >= 201907L
5272# define CATCH_CONFIG_CPP20_COMPARE_OVERLOADS
5273# endif
5274#endif
5275
5276namespace Catch {
5277
5278 namespace Detail {
5279 // This was added in C++20, but we require only C++14 for now.
5280 template <typename T>
5281 using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>;
5282 }
5283
5284 // Note: There is nothing that stops us from extending this,
5285 // e.g. to `std::is_scalar`, but the more encompassing
5286 // traits are usually also more expensive. For now we
5287 // keep this as it used to be and it can be changed later.
5288 template <typename T>
5290 : std::integral_constant<bool, std::is_arithmetic<T>{}> {};
5291
5292#if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS )
5293 template <>
5294 struct capture_by_value<std::strong_ordering> : std::true_type {};
5295 template <>
5296 struct capture_by_value<std::weak_ordering> : std::true_type {};
5297 template <>
5298 struct capture_by_value<std::partial_ordering> : std::true_type {};
5299#endif
5300
5301 template <typename T>
5302 struct always_false : std::false_type {};
5303
5307
5308 protected:
5310
5311 public:
5312 constexpr auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
5313 constexpr auto getResult() const -> bool { return m_result; }
5315 virtual void streamReconstructedExpression( std::ostream& os ) const;
5316
5317 constexpr ITransientExpression( bool isBinaryExpression, bool result )
5319 m_result( result )
5320 {}
5321
5322 constexpr ITransientExpression( ITransientExpression const& ) = default;
5324
5325 friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
5327 return out;
5328 }
5329 };
5330
5331 void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
5332
5333 template<typename LhsT, typename RhsT>
5335 LhsT m_lhs;
5337 RhsT m_rhs;
5338
5339 void streamReconstructedExpression( std::ostream &os ) const override {
5342 }
5343
5344 public:
5345 constexpr BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
5346 : ITransientExpression{ true, comparisonResult },
5347 m_lhs( lhs ),
5348 m_op( op ),
5349 m_rhs( rhs )
5350 {}
5351
5352 template<typename T>
5353 auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5354 static_assert(always_false<T>::value,
5355 "chained comparisons are not supported inside assertions, "
5356 "wrap the expression inside parentheses, or decompose it");
5357 }
5358
5359 template<typename T>
5360 auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5361 static_assert(always_false<T>::value,
5362 "chained comparisons are not supported inside assertions, "
5363 "wrap the expression inside parentheses, or decompose it");
5364 }
5365
5366 template<typename T>
5367 auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5368 static_assert(always_false<T>::value,
5369 "chained comparisons are not supported inside assertions, "
5370 "wrap the expression inside parentheses, or decompose it");
5371 }
5372
5373 template<typename T>
5374 auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5375 static_assert(always_false<T>::value,
5376 "chained comparisons are not supported inside assertions, "
5377 "wrap the expression inside parentheses, or decompose it");
5378 }
5379
5380 template<typename T>
5381 auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5382 static_assert(always_false<T>::value,
5383 "chained comparisons are not supported inside assertions, "
5384 "wrap the expression inside parentheses, or decompose it");
5385 }
5386
5387 template<typename T>
5388 auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5389 static_assert(always_false<T>::value,
5390 "chained comparisons are not supported inside assertions, "
5391 "wrap the expression inside parentheses, or decompose it");
5392 }
5393
5394 template<typename T>
5395 auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5396 static_assert(always_false<T>::value,
5397 "chained comparisons are not supported inside assertions, "
5398 "wrap the expression inside parentheses, or decompose it");
5399 }
5400
5401 template<typename T>
5402 auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
5403 static_assert(always_false<T>::value,
5404 "chained comparisons are not supported inside assertions, "
5405 "wrap the expression inside parentheses, or decompose it");
5406 }
5407 };
5408
5409 template<typename LhsT>
5411 LhsT m_lhs;
5412
5413 void streamReconstructedExpression( std::ostream &os ) const override {
5415 }
5416
5417 public:
5418 explicit constexpr UnaryExpr( LhsT lhs )
5419 : ITransientExpression{ false, static_cast<bool>(lhs) },
5420 m_lhs( lhs )
5421 {}
5422 };
5423
5424
5425 template<typename LhsT>
5426 class ExprLhs {
5427 LhsT m_lhs;
5428 public:
5429 explicit constexpr ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
5430
5431#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
5432 template <typename RhsT> \
5433 constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
5434 -> std::enable_if_t< \
5435 Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5436 Detail::negation<capture_by_value< \
5437 Detail::RemoveCVRef_t<RhsT>>>>::value, \
5438 BinaryExpr<LhsT, RhsT const&>> { \
5439 return { \
5440 static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5441 } \
5442 template <typename RhsT> \
5443 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5444 -> std::enable_if_t< \
5445 Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5446 capture_by_value<RhsT>>::value, \
5447 BinaryExpr<LhsT, RhsT>> { \
5448 return { \
5449 static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5450 } \
5451 template <typename RhsT> \
5452 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5453 -> std::enable_if_t< \
5454 Detail::conjunction< \
5455 Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5456 Detail::is_eq_0_comparable<LhsT>, \
5457 /* We allow long because we want `ptr op NULL` to be accepted */ \
5458 Detail::disjunction<std::is_same<RhsT, int>, \
5459 std::is_same<RhsT, long>>>::value, \
5460 BinaryExpr<LhsT, RhsT>> { \
5461 if ( rhs != 0 ) { throw_test_failure_exception(); } \
5462 return { \
5463 static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
5464 } \
5465 template <typename RhsT> \
5466 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5467 -> std::enable_if_t< \
5468 Detail::conjunction< \
5469 Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5470 Detail::is_eq_0_comparable<RhsT>, \
5471 /* We allow long because we want `ptr op NULL` to be accepted */ \
5472 Detail::disjunction<std::is_same<LhsT, int>, \
5473 std::is_same<LhsT, long>>>::value, \
5474 BinaryExpr<LhsT, RhsT>> { \
5475 if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
5476 return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5477 }
5478
5481
5482 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
5483
5484
5485#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
5486 template <typename RhsT> \
5487 constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
5488 -> std::enable_if_t< \
5489 Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5490 Detail::negation<capture_by_value< \
5491 Detail::RemoveCVRef_t<RhsT>>>>::value, \
5492 BinaryExpr<LhsT, RhsT const&>> { \
5493 return { \
5494 static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5495 } \
5496 template <typename RhsT> \
5497 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5498 -> std::enable_if_t< \
5499 Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
5500 capture_by_value<RhsT>>::value, \
5501 BinaryExpr<LhsT, RhsT>> { \
5502 return { \
5503 static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5504 } \
5505 template <typename RhsT> \
5506 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5507 -> std::enable_if_t< \
5508 Detail::conjunction< \
5509 Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5510 Detail::is_##id##_0_comparable<LhsT>, \
5511 std::is_same<RhsT, int>>::value, \
5512 BinaryExpr<LhsT, RhsT>> { \
5513 if ( rhs != 0 ) { throw_test_failure_exception(); } \
5514 return { \
5515 static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
5516 } \
5517 template <typename RhsT> \
5518 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5519 -> std::enable_if_t< \
5520 Detail::conjunction< \
5521 Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
5522 Detail::is_##id##_0_comparable<RhsT>, \
5523 std::is_same<LhsT, int>>::value, \
5524 BinaryExpr<LhsT, RhsT>> { \
5525 if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
5526 return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5527 }
5528
5533
5534 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR
5535
5536
5537#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
5538 template <typename RhsT> \
5539 constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
5540 -> std::enable_if_t< \
5541 !capture_by_value<Detail::RemoveCVRef_t<RhsT>>::value, \
5542 BinaryExpr<LhsT, RhsT const&>> { \
5543 return { \
5544 static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5545 } \
5546 template <typename RhsT> \
5547 constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
5548 -> std::enable_if_t<capture_by_value<RhsT>::value, \
5549 BinaryExpr<LhsT, RhsT>> { \
5550 return { \
5551 static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
5552 }
5553
5557
5558 #undef CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR
5559
5560 template<typename RhsT>
5561 friend auto operator && ( ExprLhs &&, RhsT && ) -> BinaryExpr<LhsT, RhsT const&> {
5562 static_assert(always_false<RhsT>::value,
5563 "operator&& is not supported inside assertions, "
5564 "wrap the expression inside parentheses, or decompose it");
5565 }
5566
5567 template<typename RhsT>
5568 friend auto operator || ( ExprLhs &&, RhsT && ) -> BinaryExpr<LhsT, RhsT const&> {
5569 static_assert(always_false<RhsT>::value,
5570 "operator|| is not supported inside assertions, "
5571 "wrap the expression inside parentheses, or decompose it");
5572 }
5573
5574 constexpr auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
5575 return UnaryExpr<LhsT>{ m_lhs };
5576 }
5577 };
5578
5579 struct Decomposer {
5580 template <typename T,
5581 std::enable_if_t<!capture_by_value<Detail::RemoveCVRef_t<T>>::value,
5582 int> = 0>
5583 constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
5584 return ExprLhs<const T&>{ lhs };
5585 }
5586
5587 template <typename T,
5588 std::enable_if_t<capture_by_value<T>::value, int> = 0>
5589 constexpr friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
5590 return ExprLhs<T>{ value };
5591 }
5592 };
5593
5594} // end namespace Catch
5595
5596#ifdef _MSC_VER
5597#pragma warning(pop)
5598#endif
5599#ifdef __clang__
5600# pragma clang diagnostic pop
5601#elif defined __GNUC__
5602# pragma GCC diagnostic pop
5603#endif
5604
5605#endif // CATCH_DECOMPOSER_HPP_INCLUDED
5606
5607#include <string>
5608
5609namespace Catch {
5610
5612 bool shouldDebugBreak = false;
5613 bool shouldThrow = false;
5614 bool shouldSkip = false;
5615 };
5616
5620 bool m_completed = false;
5622
5623 public:
5625 ( StringRef macroName,
5626 SourceLineInfo const& lineInfo,
5627 StringRef capturedExpression,
5628 ResultDisposition::Flags resultDisposition );
5630 if ( !m_completed ) {
5631 m_resultCapture.handleIncomplete( m_assertionInfo );
5632 }
5633 }
5634
5635
5636 template<typename T>
5637 constexpr void handleExpr( ExprLhs<T> const& expr ) {
5638 handleExpr( expr.makeUnaryExpr() );
5639 }
5640 void handleExpr( ITransientExpression const& expr );
5641
5642 void handleMessage(ResultWas::OfType resultType, std::string&& message);
5643
5644 void handleExceptionThrownAsExpected();
5645 void handleUnexpectedExceptionNotThrown();
5646 void handleExceptionNotThrownAsExpected();
5647 void handleThrowingCallSkipped();
5648 void handleUnexpectedInflightException();
5649
5650 void complete();
5651
5652 // query
5653 auto allowThrows() const -> bool;
5654 };
5655
5656 void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str );
5657
5658} // namespace Catch
5659
5660#endif // CATCH_ASSERTION_HANDLER_HPP_INCLUDED
5661
5662
5663#ifndef CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
5664#define CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
5665
5666
5667#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
5668 #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__##_catch_sr
5669#else
5670 #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"_catch_sr
5671#endif
5672
5673#endif // CATCH_PREPROCESSOR_INTERNAL_STRINGIFY_HPP_INCLUDED
5674
5675// We need this suppression to leak, because it took until GCC 10
5676// for the front end to handle local suppression via _Pragma properly
5677#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ <= 9
5678 #pragma GCC diagnostic ignored "-Wparentheses"
5679#endif
5680
5681#if !defined(CATCH_CONFIG_DISABLE)
5682
5683#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
5684
5686// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
5687// macros.
5688#define INTERNAL_CATCH_TRY
5689#define INTERNAL_CATCH_CATCH( capturer )
5690
5691#else // CATCH_CONFIG_FAST_COMPILE
5692
5693#define INTERNAL_CATCH_TRY try
5694#define INTERNAL_CATCH_CATCH( handler ) catch(...) { (handler).handleUnexpectedInflightException(); }
5695
5696#endif
5697
5699#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
5700 do { /* NOLINT(bugprone-infinite-loop) */ \
5701 /* The expression should not be evaluated, but warnings should hopefully be checked */ \
5702 CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
5703 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
5704 INTERNAL_CATCH_TRY { \
5705 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5706 CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
5707 catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); /* NOLINT(bugprone-chained-comparison) */ \
5708 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5709 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
5710 catchAssertionHandler.complete(); \
5711 } 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
5712 // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
5713
5715#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
5716 INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
5717 if( Catch::getResultCapture().lastAssertionPassed() )
5718
5720#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
5721 INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
5722 if( !Catch::getResultCapture().lastAssertionPassed() )
5723
5725#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
5726 do { \
5727 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
5728 try { \
5729 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5730 CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5731 static_cast<void>(__VA_ARGS__); \
5732 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5733 catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
5734 } \
5735 catch( ... ) { \
5736 catchAssertionHandler.handleUnexpectedInflightException(); \
5737 } \
5738 catchAssertionHandler.complete(); \
5739 } while( false )
5740
5742#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
5743 do { \
5744 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
5745 if( catchAssertionHandler.allowThrows() ) \
5746 try { \
5747 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5748 CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
5749 CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5750 static_cast<void>(__VA_ARGS__); \
5751 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5752 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5753 } \
5754 catch( ... ) { \
5755 catchAssertionHandler.handleExceptionThrownAsExpected(); \
5756 } \
5757 else \
5758 catchAssertionHandler.handleThrowingCallSkipped(); \
5759 catchAssertionHandler.complete(); \
5760 } while( false )
5761
5763#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
5764 do { \
5765 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
5766 if( catchAssertionHandler.allowThrows() ) \
5767 try { \
5768 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5769 CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
5770 CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5771 static_cast<void>(expr); \
5772 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5773 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5774 } \
5775 catch( exceptionType const& ) { \
5776 catchAssertionHandler.handleExceptionThrownAsExpected(); \
5777 } \
5778 catch( ... ) { \
5779 catchAssertionHandler.handleUnexpectedInflightException(); \
5780 } \
5781 else \
5782 catchAssertionHandler.handleThrowingCallSkipped(); \
5783 catchAssertionHandler.complete(); \
5784 } while( false )
5785
5786
5787
5789// Although this is matcher-based, it can be used with just a string
5790#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
5791 do { \
5792 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
5793 if( catchAssertionHandler.allowThrows() ) \
5794 try { \
5795 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5796 CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
5797 CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
5798 static_cast<void>(__VA_ARGS__); \
5799 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
5800 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
5801 } \
5802 catch( ... ) { \
5803 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher ); \
5804 } \
5805 else \
5806 catchAssertionHandler.handleThrowingCallSkipped(); \
5807 catchAssertionHandler.complete(); \
5808 } while( false )
5809
5810#endif // CATCH_CONFIG_DISABLE
5811
5812#endif // CATCH_TEST_MACRO_IMPL_HPP_INCLUDED
5813
5814
5815#ifndef CATCH_SECTION_HPP_INCLUDED
5816#define CATCH_SECTION_HPP_INCLUDED
5817
5818
5819
5820
5829
5830#ifndef CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
5831#define CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
5832
5833
5834#if defined(__clang_analyzer__) || defined(__COVERITY__)
5835 #define CATCH_INTERNAL_CONFIG_STATIC_ANALYSIS_SUPPORT
5836#endif
5837
5838#if defined( CATCH_INTERNAL_CONFIG_STATIC_ANALYSIS_SUPPORT ) && \
5839 !defined( CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT ) && \
5840 !defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )
5841# define CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
5842#endif
5843
5844
5845#endif // CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
5846
5847
5848#ifndef CATCH_TIMER_HPP_INCLUDED
5849#define CATCH_TIMER_HPP_INCLUDED
5850
5851#include <cstdint>
5852
5853namespace Catch {
5854
5855 class Timer {
5856 uint64_t m_nanoseconds = 0;
5857 public:
5858 void start();
5859 auto getElapsedNanoseconds() const -> uint64_t;
5860 auto getElapsedMicroseconds() const -> uint64_t;
5861 auto getElapsedMilliseconds() const -> unsigned int;
5862 auto getElapsedSeconds() const -> double;
5863 };
5864
5865} // namespace Catch
5866
5867#endif // CATCH_TIMER_HPP_INCLUDED
5868
5869namespace Catch {
5870
5872 public:
5873 Section( SectionInfo&& info );
5874 Section( SourceLineInfo const& _lineInfo,
5875 StringRef _name,
5876 const char* const = nullptr );
5877 ~Section();
5878
5879 // This indicates whether the section should be executed or not
5880 explicit operator bool() const;
5881
5882 private:
5884
5888 };
5889
5890} // end namespace Catch
5891
5892#if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
5893# define INTERNAL_CATCH_SECTION( ... ) \
5894 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5895 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5896 if ( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( \
5897 catch_internal_Section ) = \
5898 Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
5899 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5900
5901# define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
5902 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5903 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5904 if ( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( \
5905 catch_internal_Section ) = \
5906 Catch::SectionInfo( \
5907 CATCH_INTERNAL_LINEINFO, \
5908 ( Catch::ReusableStringStream() << __VA_ARGS__ ) \
5909 .str() ) ) \
5910 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5911
5912#else
5913
5914// These section definitions imply that at most one section at one level
5915// will be intered (because only one section's __LINE__ can be equal to
5916// the dummy `catchInternalSectionHint` variable from `TEST_CASE`).
5917
5918namespace Catch {
5919 namespace Detail {
5920 // Intentionally without linkage, as it should only be used as a dummy
5921 // symbol for static analysis.
5922 // The arguments are used as a dummy for checking warnings in the passed
5923 // expressions.
5924 int GetNewSectionHint( StringRef, const char* const = nullptr );
5925 } // namespace Detail
5926} // namespace Catch
5927
5928
5929# define INTERNAL_CATCH_SECTION( ... ) \
5930 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5931 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5932 CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
5933 if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \
5934 catchInternalSectionHint, \
5935 catchInternalSectionHint = \
5936 Catch::Detail::GetNewSectionHint(__VA_ARGS__); \
5937 catchInternalPreviousSectionHint == __LINE__ ) \
5938 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5939
5940# define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
5941 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
5942 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
5943 CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
5944 if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \
5945 catchInternalSectionHint, \
5946 catchInternalSectionHint = Catch::Detail::GetNewSectionHint( \
5947 ( Catch::ReusableStringStream() << __VA_ARGS__ ).str()); \
5948 catchInternalPreviousSectionHint == __LINE__ ) \
5949 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
5950
5951#endif
5952
5953
5954#endif // CATCH_SECTION_HPP_INCLUDED
5955
5956
5957#ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
5958#define CATCH_TEST_REGISTRY_HPP_INCLUDED
5959
5960
5961
5962#ifndef CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED
5963#define CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED
5964
5965namespace Catch {
5966
5968 public:
5969 virtual void prepareTestCase();
5970 virtual void tearDownTestCase();
5971 virtual void invoke() const = 0;
5972 virtual ~ITestInvoker(); // = default
5973 };
5974
5975} // namespace Catch
5976
5977#endif // CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED
5978
5979
5980#ifndef CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5981#define CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5982
5983#define INTERNAL_CATCH_EXPAND1( param ) INTERNAL_CATCH_EXPAND2( param )
5984#define INTERNAL_CATCH_EXPAND2( ... ) INTERNAL_CATCH_NO##__VA_ARGS__
5985#define INTERNAL_CATCH_DEF( ... ) INTERNAL_CATCH_DEF __VA_ARGS__
5986#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
5987
5988#define INTERNAL_CATCH_REMOVE_PARENS( ... ) \
5989 INTERNAL_CATCH_EXPAND1( INTERNAL_CATCH_DEF __VA_ARGS__ )
5990
5991#endif // CATCH_PREPROCESSOR_REMOVE_PARENS_HPP_INCLUDED
5992
5993// GCC 5 and older do not properly handle disabling unused-variable warning
5994// with a _Pragma. This means that we have to leak the suppression to the
5995// user code as well :-(
5996#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
5997#pragma GCC diagnostic ignored "-Wunused-variable"
5998#endif
5999
6000
6001
6002namespace Catch {
6003
6004template<typename C>
6006 void (C::*m_testAsMethod)();
6007public:
6008 constexpr TestInvokerAsMethod( void ( C::*testAsMethod )() ) noexcept:
6009 m_testAsMethod( testAsMethod ) {}
6010
6011 void invoke() const override {
6012 C obj;
6013 (obj.*m_testAsMethod)();
6014 }
6015};
6016
6017Detail::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() );
6018
6019template<typename C>
6021 return Detail::make_unique<TestInvokerAsMethod<C>>( testAsMethod );
6022}
6023
6024template <typename C>
6026 void ( C::*m_testAsMethod )() const;
6028
6029public:
6030 constexpr TestInvokerFixture( void ( C::*testAsMethod )() const ) noexcept:
6031 m_testAsMethod( testAsMethod ) {}
6032
6033 void prepareTestCase() override {
6035 }
6036
6037 void tearDownTestCase() override {
6038 m_fixture.reset();
6039 }
6040
6041 void invoke() const override {
6042 auto* f = m_fixture.get();
6043 ( f->*m_testAsMethod )();
6044 }
6045};
6046
6047template<typename C>
6048Detail::unique_ptr<ITestInvoker> makeTestInvokerFixture( void ( C::*testAsMethod )() const ) {
6049 return Detail::make_unique<TestInvokerFixture<C>>( testAsMethod );
6050}
6051
6053 constexpr NameAndTags( StringRef name_ = StringRef(),
6054 StringRef tags_ = StringRef() ) noexcept:
6055 name( name_ ), tags( tags_ ) {}
6058};
6059
6061 AutoReg( Detail::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept;
6062};
6063
6064} // end namespace Catch
6065
6066#if defined(CATCH_CONFIG_DISABLE)
6067 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
6068 static inline void TestName()
6069 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
6070 namespace{ \
6071 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
6072 void test(); \
6073 }; \
6074 } \
6075 void TestName::test()
6076#endif
6077
6078
6079#if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
6080
6082 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
6083 static void TestName(); \
6084 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6085 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6086 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6087 namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
6088 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6089 static void TestName()
6090 #define INTERNAL_CATCH_TESTCASE( ... ) \
6091 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
6092
6093#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
6094
6095
6096// Dummy registrator for the dumy test case macros
6097namespace Catch {
6098 namespace Detail {
6099 struct DummyUse {
6100 DummyUse( void ( * )( int ), Catch::NameAndTags const& );
6101 };
6102 } // namespace Detail
6103} // namespace Catch
6104
6105// Note that both the presence of the argument and its exact name are
6106// necessary for the section support.
6107
6108// We provide a shadowed variable so that a `SECTION` inside non-`TEST_CASE`
6109// tests can compile. The redefined `TEST_CASE` shadows this with param.
6110static int catchInternalSectionHint = 0;
6111
6112# define INTERNAL_CATCH_TESTCASE2( fname, ... ) \
6113 static void fname( int ); \
6114 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6115 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6116 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6117 static const Catch::Detail::DummyUse INTERNAL_CATCH_UNIQUE_NAME( \
6118 dummyUser )( &(fname), Catch::NameAndTags{ __VA_ARGS__ } ); \
6119 CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
6120 static void fname( [[maybe_unused]] int catchInternalSectionHint ) \
6121 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6122# define INTERNAL_CATCH_TESTCASE( ... ) \
6123 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( dummyFunction ), __VA_ARGS__ )
6124
6125
6126#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
6127
6129 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
6130 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6131 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6132 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6133 namespace{ \
6134 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
6135 void test(); \
6136 }; \
6137 const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
6138 Catch::makeTestInvoker( &TestName::test ), \
6139 CATCH_INTERNAL_LINEINFO, \
6140 #ClassName##_catch_sr, \
6141 Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
6142 } \
6143 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6144 void TestName::test()
6145 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
6146 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
6147
6149 #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2( TestName, ClassName, ... ) \
6150 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6151 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6152 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6153 namespace { \
6154 struct TestName : INTERNAL_CATCH_REMOVE_PARENS( ClassName ) { \
6155 void test() const; \
6156 }; \
6157 const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
6158 Catch::makeTestInvokerFixture( &TestName::test ), \
6159 CATCH_INTERNAL_LINEINFO, \
6160 #ClassName##_catch_sr, \
6161 Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
6162 } \
6163 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6164 void TestName::test() const
6165 #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( ClassName, ... ) \
6166 INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
6167
6168
6170 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
6171 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6172 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6173 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6174 namespace { \
6175 const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
6176 Catch::makeTestInvoker( &QualifiedMethod ), \
6177 CATCH_INTERNAL_LINEINFO, \
6178 "&" #QualifiedMethod##_catch_sr, \
6179 Catch::NameAndTags{ __VA_ARGS__ } ); \
6180 } /* NOLINT */ \
6181 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
6182
6183
6185 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
6186 do { \
6187 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6188 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6189 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6190 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
6191 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6192 } while(false)
6193
6194
6195#endif // CATCH_TEST_REGISTRY_HPP_INCLUDED
6196
6197
6198// All of our user-facing macros support configuration toggle, that
6199// forces them to be defined prefixed with CATCH_. We also like to
6200// support another toggle that can minimize (disable) their implementation.
6201// Given this, we have 4 different configuration options below
6202
6203#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
6204
6205 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6206 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
6207
6208 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6209 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
6210 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6211
6212 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6213 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
6214 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6215 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6216 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6217
6218 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6219 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
6220 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6221
6222 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
6223 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
6224 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
6225 #define CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, __VA_ARGS__ )
6226 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
6227 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
6228 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
6229 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
6230 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6231 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6232 #define CATCH_SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
6233
6234
6235 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
6236 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
6237 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
6238 #define CATCH_STATIC_CHECK( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
6239 #define CATCH_STATIC_CHECK_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
6240 #else
6241 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
6242 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
6243 #define CATCH_STATIC_CHECK( ... ) CATCH_CHECK( __VA_ARGS__ )
6244 #define CATCH_STATIC_CHECK_FALSE( ... ) CATCH_CHECK_FALSE( __VA_ARGS__ )
6245 #endif
6246
6247
6248 // "BDD-style" convenience wrappers
6249 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
6250 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
6251 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
6252 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
6253 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
6254 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
6255 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
6256 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
6257
6258#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) // ^^ prefixed, implemented | vv prefixed, disabled
6259
6260 #define CATCH_REQUIRE( ... ) (void)(0)
6261 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
6262
6263 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
6264 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
6265 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
6266
6267 #define CATCH_CHECK( ... ) (void)(0)
6268 #define CATCH_CHECK_FALSE( ... ) (void)(0)
6269 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
6270 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
6271 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
6272
6273 #define CATCH_CHECK_THROWS( ... ) (void)(0)
6274 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
6275 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
6276
6277 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6278 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6279 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
6280 #define CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6281 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
6282 #define CATCH_SECTION( ... )
6283 #define CATCH_DYNAMIC_SECTION( ... )
6284 #define CATCH_FAIL( ... ) (void)(0)
6285 #define CATCH_FAIL_CHECK( ... ) (void)(0)
6286 #define CATCH_SUCCEED( ... ) (void)(0)
6287 #define CATCH_SKIP( ... ) (void)(0)
6288
6289 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
6290 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
6291 #define CATCH_STATIC_CHECK( ... ) (void)(0)
6292 #define CATCH_STATIC_CHECK_FALSE( ... ) (void)(0)
6293
6294 // "BDD-style" convenience wrappers
6295 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6296 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), className )
6297 #define CATCH_GIVEN( desc )
6298 #define CATCH_AND_GIVEN( desc )
6299 #define CATCH_WHEN( desc )
6300 #define CATCH_AND_WHEN( desc )
6301 #define CATCH_THEN( desc )
6302 #define CATCH_AND_THEN( desc )
6303
6304#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE) // ^^ prefixed, disabled | vv unprefixed, implemented
6305
6306 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6307 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
6308
6309 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6310 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
6311 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
6312
6313 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6314 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
6315 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6316 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6317 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
6318
6319 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6320 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
6321 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6322
6323 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
6324 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
6325 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
6326 #define TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, __VA_ARGS__ )
6327 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
6328 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
6329 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
6330 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
6331 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6332 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
6333 #define SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
6334
6335
6336 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
6337 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
6338 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
6339 #define STATIC_CHECK( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
6340 #define STATIC_CHECK_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
6341 #else
6342 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
6343 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
6344 #define STATIC_CHECK( ... ) CHECK( __VA_ARGS__ )
6345 #define STATIC_CHECK_FALSE( ... ) CHECK_FALSE( __VA_ARGS__ )
6346 #endif
6347
6348 // "BDD-style" convenience wrappers
6349 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
6350 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
6351 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
6352 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
6353 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
6354 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
6355 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
6356 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
6357
6358#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) // ^^ unprefixed, implemented | vv unprefixed, disabled
6359
6360 #define REQUIRE( ... ) (void)(0)
6361 #define REQUIRE_FALSE( ... ) (void)(0)
6362
6363 #define REQUIRE_THROWS( ... ) (void)(0)
6364 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
6365 #define REQUIRE_NOTHROW( ... ) (void)(0)
6366
6367 #define CHECK( ... ) (void)(0)
6368 #define CHECK_FALSE( ... ) (void)(0)
6369 #define CHECKED_IF( ... ) if (__VA_ARGS__)
6370 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
6371 #define CHECK_NOFAIL( ... ) (void)(0)
6372
6373 #define CHECK_THROWS( ... ) (void)(0)
6374 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
6375 #define CHECK_NOTHROW( ... ) (void)(0)
6376
6377 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__)
6378 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
6379 #define METHOD_AS_TEST_CASE( method, ... )
6380 #define TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__)
6381 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
6382 #define SECTION( ... )
6383 #define DYNAMIC_SECTION( ... )
6384 #define FAIL( ... ) (void)(0)
6385 #define FAIL_CHECK( ... ) (void)(0)
6386 #define SUCCEED( ... ) (void)(0)
6387 #define SKIP( ... ) (void)(0)
6388
6389 #define STATIC_REQUIRE( ... ) (void)(0)
6390 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
6391 #define STATIC_CHECK( ... ) (void)(0)
6392 #define STATIC_CHECK_FALSE( ... ) (void)(0)
6393
6394 // "BDD-style" convenience wrappers
6395 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ) )
6396 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), className )
6397
6398 #define GIVEN( desc )
6399 #define AND_GIVEN( desc )
6400 #define WHEN( desc )
6401 #define AND_WHEN( desc )
6402 #define THEN( desc )
6403 #define AND_THEN( desc )
6404
6405#endif // ^^ unprefixed, disabled
6406
6407// end of user facing macros
6408
6409#endif // CATCH_TEST_MACROS_HPP_INCLUDED
6410
6411
6412#ifndef CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6413#define CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6414
6415
6416
6417#ifndef CATCH_PREPROCESSOR_HPP_INCLUDED
6418#define CATCH_PREPROCESSOR_HPP_INCLUDED
6419
6420
6421#if defined(__GNUC__)
6422// We need to silence "empty __VA_ARGS__ warning", and using just _Pragma does not work
6423#pragma GCC system_header
6424#endif
6425
6426
6427#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
6428#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
6429#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
6430#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
6431#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
6432#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
6433
6434#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6435#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
6436// MSVC needs more evaluations
6437#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
6438#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
6439#else
6440#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
6441#endif
6442
6443#define CATCH_REC_END(...)
6444#define CATCH_REC_OUT
6445
6446#define CATCH_EMPTY()
6447#define CATCH_DEFER(id) id CATCH_EMPTY()
6448
6449#define CATCH_REC_GET_END2() 0, CATCH_REC_END
6450#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
6451#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
6452#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
6453#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
6454#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
6455
6456#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
6457#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
6458#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
6459
6460#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__ )
6461#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__ )
6462#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__ )
6463
6464// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
6465// and passes userdata as the first parameter to each invocation,
6466// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
6467#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
6468
6469#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
6470
6471#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
6472#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6473#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
6474#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
6475#else
6476// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
6477#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
6478#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
6479#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
6480#endif
6481
6482#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
6483#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
6484
6485#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6486#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
6487#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
6488#else
6489#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
6490#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
6491#endif
6492
6493#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
6494 CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
6495
6496#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
6497#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
6498#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
6499#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)
6500#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)
6501#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)
6502#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)
6503#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)
6504#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)
6505#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)
6506#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)
6507
6508#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
6509
6510#define INTERNAL_CATCH_TYPE_GEN\
6511 template<typename...> struct TypeList {};\
6512 template<typename...Ts>\
6513 constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
6514 template<template<typename...> class...> struct TemplateTypeList{};\
6515 template<template<typename...> class...Cs>\
6516 constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
6517 template<typename...>\
6518 struct append;\
6519 template<typename...>\
6520 struct rewrap;\
6521 template<template<typename...> class, typename...>\
6522 struct create;\
6523 template<template<typename...> class, typename>\
6524 struct convert;\
6525 \
6526 template<typename T> \
6527 struct append<T> { using type = T; };\
6528 template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
6529 struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
6530 template< template<typename...> class L1, typename...E1, typename...Rest>\
6531 struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
6532 \
6533 template< template<typename...> class Container, template<typename...> class List, typename...elems>\
6534 struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
6535 template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
6536 struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
6537 \
6538 template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
6539 struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
6540 template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
6541 struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
6542
6543#define INTERNAL_CATCH_NTTP_1(signature, ...)\
6544 template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
6545 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6546 constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
6547 template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
6548 template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
6549 constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
6550 \
6551 template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6552 struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
6553 template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
6554 struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
6555 template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
6556 struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
6557
6558#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
6559#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
6560 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6561 static void TestName()
6562#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
6563 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6564 static void TestName()
6565
6566#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
6567#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
6568 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6569 static void TestName()
6570#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
6571 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6572 static void TestName()
6573
6574#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
6575 template<typename Type>\
6576 void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
6577 {\
6578 Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
6579 }
6580
6581#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
6582 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6583 void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
6584 {\
6585 Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
6586 }
6587
6588#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
6589 template<typename Type>\
6590 void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
6591 {\
6592 Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
6593 }
6594
6595#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
6596 template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
6597 void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
6598 {\
6599 Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
6600 }
6601
6602#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
6603#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
6604 template<typename TestType> \
6605 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
6606 void test();\
6607 }
6608
6609#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
6610 template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6611 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
6612 void test();\
6613 }
6614
6615#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
6616#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
6617 template<typename TestType> \
6618 void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
6619#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
6620 template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
6621 void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
6622
6623#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6624#define INTERNAL_CATCH_NTTP_0
6625#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)
6626#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__)
6627#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__)
6628#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__)
6629#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__)
6630#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__)
6631#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__)
6632#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__)
6633#else
6634#define INTERNAL_CATCH_NTTP_0(signature)
6635#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__))
6636#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__))
6637#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__))
6638#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__))
6639#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__))
6640#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__))
6641#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__))
6642#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__))
6643#endif
6644
6645#endif // CATCH_PREPROCESSOR_HPP_INCLUDED
6646
6647
6648// GCC 5 and older do not properly handle disabling unused-variable warning
6649// with a _Pragma. This means that we have to leak the suppression to the
6650// user code as well :-(
6651#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
6652#pragma GCC diagnostic ignored "-Wunused-variable"
6653#endif
6654
6655#if defined(CATCH_CONFIG_DISABLE)
6656 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
6657 INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6658 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
6659 namespace{ \
6660 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6661 INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
6662 } \
6663 } \
6664 INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6665
6666 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6667 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
6668 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__ )
6669 #else
6670 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
6671 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__ ) )
6672 #endif
6673
6674 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6675 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
6676 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__ )
6677 #else
6678 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
6679 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__ ) )
6680 #endif
6681
6682 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6683 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
6684 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__ )
6685 #else
6686 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
6687 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__ ) )
6688 #endif
6689
6690 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6691 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
6692 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__ )
6693 #else
6694 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
6695 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__ ) )
6696 #endif
6697#endif
6698
6699
6701 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
6702 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6703 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6704 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6705 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6706 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6707 CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6708 INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
6709 namespace {\
6710 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
6711 INTERNAL_CATCH_TYPE_GEN\
6712 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6713 INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6714 template<typename...Types> \
6715 struct TestName{\
6716 TestName(){\
6717 size_t index = 0; \
6718 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */\
6719 using expander = size_t[]; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */\
6720 (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
6721 }\
6722 };\
6723 static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6724 TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
6725 return 0;\
6726 }();\
6727 }\
6728 }\
6729 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6730 INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
6731
6732#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6733 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
6734 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__ )
6735#else
6736 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
6737 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__ ) )
6738#endif
6739
6740#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6741 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6742 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__ )
6743#else
6744 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
6745 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__ ) )
6746#endif
6747
6748 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
6749 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6750 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6751 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6752 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6753 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6754 CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6755 template<typename TestType> static void TestFuncName(); \
6756 namespace {\
6757 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
6758 INTERNAL_CATCH_TYPE_GEN \
6759 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
6760 template<typename... Types> \
6761 struct TestName { \
6762 void reg_tests() { \
6763 size_t index = 0; \
6764 using expander = size_t[]; \
6765 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
6766 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
6767 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
6768 (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 */\
6769 } \
6770 }; \
6771 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
6772 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; \
6773 TestInit t; \
6774 t.reg_tests(); \
6775 return 0; \
6776 }(); \
6777 } \
6778 } \
6779 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6780 template<typename TestType> \
6781 static void TestFuncName()
6782
6783#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6784 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
6785 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__)
6786#else
6787 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
6788 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__ ) )
6789#endif
6790
6791#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6792 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
6793 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__)
6794#else
6795 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
6796 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__ ) )
6797#endif
6798
6799 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
6800 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6801 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6802 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6803 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6804 CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6805 template<typename TestType> static void TestFunc(); \
6806 namespace {\
6807 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
6808 INTERNAL_CATCH_TYPE_GEN\
6809 template<typename... Types> \
6810 struct TestName { \
6811 void reg_tests() { \
6812 size_t index = 0; \
6813 using expander = size_t[]; \
6814 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
6815 } \
6816 };\
6817 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
6818 using TestInit = typename convert<TestName, TmplList>::type; \
6819 TestInit t; \
6820 t.reg_tests(); \
6821 return 0; \
6822 }(); \
6823 }}\
6824 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6825 template<typename TestType> \
6826 static void TestFunc()
6827
6828 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
6829 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 )
6830
6831
6832 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
6833 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6834 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6835 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6836 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6837 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6838 namespace {\
6839 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
6840 INTERNAL_CATCH_TYPE_GEN\
6841 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6842 INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
6843 INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6844 template<typename...Types> \
6845 struct TestNameClass{\
6846 TestNameClass(){\
6847 size_t index = 0; \
6848 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
6849 using expander = size_t[];\
6850 (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
6851 }\
6852 };\
6853 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6854 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
6855 return 0;\
6856 }();\
6857 }\
6858 }\
6859 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6860 INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
6861
6862#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6863 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
6864 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__ )
6865#else
6866 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
6867 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__ ) )
6868#endif
6869
6870#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6871 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
6872 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__ )
6873#else
6874 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
6875 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__ ) )
6876#endif
6877
6878 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
6879 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6880 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6881 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
6882 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6883 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6884 template<typename TestType> \
6885 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
6886 void test();\
6887 };\
6888 namespace {\
6889 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
6890 INTERNAL_CATCH_TYPE_GEN \
6891 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
6892 template<typename...Types>\
6893 struct TestNameClass{\
6894 void reg_tests(){\
6895 std::size_t index = 0;\
6896 using expander = std::size_t[];\
6897 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
6898 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
6899 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
6900 (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 */ \
6901 }\
6902 };\
6903 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6904 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;\
6905 TestInit t;\
6906 t.reg_tests();\
6907 return 0;\
6908 }(); \
6909 }\
6910 }\
6911 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6912 template<typename TestType> \
6913 void TestName<TestType>::test()
6914
6915#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6916 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
6917 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__ )
6918#else
6919 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
6920 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__ ) )
6921#endif
6922
6923#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6924 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
6925 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__ )
6926#else
6927 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
6928 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__ ) )
6929#endif
6930
6931 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
6932 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
6933 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
6934 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
6935 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
6936 CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
6937 template<typename TestType> \
6938 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
6939 void test();\
6940 };\
6941 namespace {\
6942 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
6943 INTERNAL_CATCH_TYPE_GEN\
6944 template<typename...Types>\
6945 struct TestNameClass{\
6946 void reg_tests(){\
6947 size_t index = 0;\
6948 using expander = size_t[];\
6949 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
6950 }\
6951 };\
6952 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
6953 using TestInit = typename convert<TestNameClass, TmplList>::type;\
6954 TestInit t;\
6955 t.reg_tests();\
6956 return 0;\
6957 }(); \
6958 }}\
6959 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
6960 template<typename TestType> \
6961 void TestName<TestType>::test()
6962
6963#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
6964 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 )
6965
6966
6967#endif // CATCH_TEMPLATE_TEST_REGISTRY_HPP_INCLUDED
6968
6969
6970#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
6971
6972 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6973 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
6974 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
6975 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
6976 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
6977 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
6978 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
6979 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
6980 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
6981 #define CATCH_TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
6982 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
6983 #else
6984 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
6985 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
6986 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6987 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
6988 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
6989 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
6990 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6991 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
6992 #define CATCH_TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
6993 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
6994 #endif
6995
6996#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
6997
6998 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
6999 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
7000 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
7001 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
7002 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
7003 #else
7004 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
7005 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
7006 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
7007 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
7008 #endif
7009
7010 // When disabled, these can be shared between proper preprocessor and MSVC preprocessor
7011 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
7012 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
7013 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7014 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7015 #define CATCH_TEMPLATE_LIST_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
7016 #define CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7017
7018#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
7019
7020 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
7021 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
7022 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
7023 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7024 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
7025 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
7026 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
7027 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
7028 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
7029 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
7030 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
7031 #else
7032 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
7033 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
7034 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
7035 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
7036 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
7037 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
7038 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
7039 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
7040 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
7041 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
7042 #endif
7043
7044#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
7045
7046 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
7047 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
7048 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
7049 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
7050 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
7051 #else
7052 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
7053 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
7054 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
7055 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
7056 #endif
7057
7058 // When disabled, these can be shared between proper preprocessor and MSVC preprocessor
7059 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
7060 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
7061 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7062 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7063 #define TEMPLATE_LIST_TEST_CASE( ... ) TEMPLATE_TEST_CASE(__VA_ARGS__)
7064 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
7065
7066#endif // end of user facing macro declarations
7067
7068
7069#endif // CATCH_TEMPLATE_TEST_MACROS_HPP_INCLUDED
7070
7071
7072#ifndef CATCH_TEST_CASE_INFO_HPP_INCLUDED
7073#define CATCH_TEST_CASE_INFO_HPP_INCLUDED
7074
7075
7076
7077#include <cstdint>
7078#include <string>
7079#include <vector>
7080
7081#ifdef __clang__
7082#pragma clang diagnostic push
7083#pragma clang diagnostic ignored "-Wpadded"
7084#endif
7085
7086namespace Catch {
7087
7095 struct Tag {
7096 constexpr Tag(StringRef original_):
7097 original(original_)
7098 {}
7100
7101 friend bool operator< ( Tag const& lhs, Tag const& rhs );
7102 friend bool operator==( Tag const& lhs, Tag const& rhs );
7103 };
7104
7105 class ITestInvoker;
7106 struct NameAndTags;
7107
7108 enum class TestCaseProperties : uint8_t {
7109 None = 0,
7110 IsHidden = 1 << 1,
7111 ShouldFail = 1 << 2,
7112 MayFail = 1 << 3,
7113 Throws = 1 << 4,
7114 NonPortable = 1 << 5,
7115 Benchmark = 1 << 6
7116 };
7117
7128
7129 TestCaseInfo(StringRef _className,
7130 NameAndTags const& _nameAndTags,
7131 SourceLineInfo const& _lineInfo);
7132
7133 bool isHidden() const;
7134 bool throws() const;
7135 bool okToFail() const;
7136 bool expectedToFail() const;
7137
7138 // Adds the tag(s) with test's filename (for the -# flag)
7139 void addFilenameTag();
7140
7142 friend bool operator<( TestCaseInfo const& lhs,
7143 TestCaseInfo const& rhs );
7144
7145
7146 std::string tagsAsString() const;
7147
7148 std::string name;
7150 private:
7151 std::string backingTags;
7152 // Internally we copy tags to the backing storage and then add
7153 // refs to this storage to the tags vector.
7154 void internalAppendTag(StringRef tagString);
7155 public:
7156 std::vector<Tag> tags;
7159 };
7160
7170 public:
7171 constexpr TestCaseHandle(TestCaseInfo* info, ITestInvoker* invoker) :
7172 m_info(info), m_invoker(invoker) {}
7173
7174 void prepareTestCase() const {
7175 m_invoker->prepareTestCase();
7176 }
7177
7178 void tearDownTestCase() const {
7179 m_invoker->tearDownTestCase();
7180 }
7181
7182 void invoke() const {
7183 m_invoker->invoke();
7184 }
7185
7186 constexpr TestCaseInfo const& getTestCaseInfo() const {
7187 return *m_info;
7188 }
7189 };
7190
7191 Detail::unique_ptr<TestCaseInfo>
7192 makeTestCaseInfo( StringRef className,
7193 NameAndTags const& nameAndTags,
7194 SourceLineInfo const& lineInfo );
7195}
7196
7197#ifdef __clang__
7198#pragma clang diagnostic pop
7199#endif
7200
7201#endif // CATCH_TEST_CASE_INFO_HPP_INCLUDED
7202
7203
7204#ifndef CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7205#define CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7206
7207
7208
7209#ifndef CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
7210#define CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
7211
7212
7213#include <string>
7214#include <vector>
7215
7216namespace Catch {
7217 using exceptionTranslateFunction = std::string(*)();
7218
7220 using ExceptionTranslators = std::vector<Detail::unique_ptr<IExceptionTranslator const>>;
7221
7223 public:
7224 virtual ~IExceptionTranslator(); // = default
7225 virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
7226 };
7227
7229 public:
7230 virtual ~IExceptionTranslatorRegistry(); // = default
7231 virtual std::string translateActiveException() const = 0;
7232 };
7233
7234} // namespace Catch
7235
7236#endif // CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
7237
7238#include <exception>
7239
7240namespace Catch {
7241 namespace Detail {
7242 void registerTranslatorImpl(
7243 Detail::unique_ptr<IExceptionTranslator>&& translator );
7244 }
7245
7247 template<typename T>
7249 public:
7250
7251 constexpr ExceptionTranslator( std::string(*translateFunction)( T const& ) )
7252 : m_translateFunction( translateFunction )
7253 {}
7254
7255 std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
7256#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
7257 try {
7258 if( it == itEnd )
7259 std::rethrow_exception(std::current_exception());
7260 else
7261 return (*it)->translate( it+1, itEnd );
7262 }
7263 catch( T const& ex ) {
7264 return m_translateFunction( ex );
7265 }
7266#else
7267 return "You should never get here!";
7268#endif
7269 }
7270
7271 protected:
7272 std::string(*m_translateFunction)( T const& );
7273 };
7274
7275 public:
7276 template<typename T>
7277 ExceptionTranslatorRegistrar( std::string(*translateFunction)( T const& ) ) {
7280 translateFunction ) );
7281 }
7282 };
7283
7284} // namespace Catch
7285
7287#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
7288 static std::string translatorName( signature ); \
7289 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
7290 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
7291 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
7292 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
7293 static std::string translatorName( signature )
7294
7295#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
7296
7297#if defined(CATCH_CONFIG_DISABLE)
7298 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
7299 static std::string translatorName( signature )
7300#endif
7301
7302
7303// This macro is always prefixed
7304#if !defined(CATCH_CONFIG_DISABLE)
7305#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
7306#else
7307#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
7308#endif
7309
7310
7311#endif // CATCH_TRANSLATE_EXCEPTION_HPP_INCLUDED
7312
7313
7314#ifndef CATCH_VERSION_HPP_INCLUDED
7315#define CATCH_VERSION_HPP_INCLUDED
7316
7317#include <iosfwd>
7318
7319namespace Catch {
7320
7321 // Versioning information
7322 struct Version {
7323 Version( Version const& ) = delete;
7324 Version& operator=( Version const& ) = delete;
7325 Version( unsigned int _majorVersion,
7326 unsigned int _minorVersion,
7327 unsigned int _patchNumber,
7328 char const * const _branchName,
7329 unsigned int _buildNumber );
7330
7331 unsigned int const majorVersion;
7332 unsigned int const minorVersion;
7333 unsigned int const patchNumber;
7334
7335 // buildNumber is only used if branchName is not null
7336 char const * const branchName;
7337 unsigned int const buildNumber;
7338
7339 friend std::ostream& operator << ( std::ostream& os, Version const& version );
7340 };
7341
7342 Version const& libraryVersion();
7343}
7344
7345#endif // CATCH_VERSION_HPP_INCLUDED
7346
7347
7348#ifndef CATCH_VERSION_MACROS_HPP_INCLUDED
7349#define CATCH_VERSION_MACROS_HPP_INCLUDED
7350
7351#define CATCH_VERSION_MAJOR 3
7352#define CATCH_VERSION_MINOR 8
7353#define CATCH_VERSION_PATCH 1
7354
7355#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
7356
7357
7370
7371#ifndef CATCH_GENERATORS_ALL_HPP_INCLUDED
7372#define CATCH_GENERATORS_ALL_HPP_INCLUDED
7373
7374
7375
7376#ifndef CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7377#define CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7378
7379#include <exception>
7380
7381namespace Catch {
7382
7383 // Exception type to be thrown when a Generator runs into an error,
7384 // e.g. it cannot initialize the first return value based on
7385 // runtime information
7386 class GeneratorException : public std::exception {
7387 const char* const m_msg = "";
7388
7389 public:
7390 GeneratorException(const char* msg):
7391 m_msg(msg)
7392 {}
7393
7394 const char* what() const noexcept override final;
7395 };
7396
7397} // end namespace Catch
7398
7399#endif // CATCH_GENERATOR_EXCEPTION_HPP_INCLUDED
7400
7401
7402#ifndef CATCH_GENERATORS_HPP_INCLUDED
7403#define CATCH_GENERATORS_HPP_INCLUDED
7404
7405
7406
7407#ifndef CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7408#define CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7409
7410
7411#include <string>
7412
7413namespace Catch {
7414
7415 namespace Generators {
7417 // Caches result from `toStringImpl`, assume that when it is an
7418 // empty string, the cache is invalidated.
7419 mutable std::string m_stringReprCache;
7420
7421 // Counts based on `next` returning true
7422 std::size_t m_currentElementIndex = 0;
7423
7430 virtual bool next() = 0;
7431
7433 virtual std::string stringifyImpl() const = 0;
7434
7435 public:
7437 // Generation of copy ops is deprecated (and Clang will complain)
7438 // if there is a user destructor defined
7441
7442 virtual ~GeneratorUntypedBase(); // = default;
7443
7454 bool countedNext();
7455
7456 std::size_t currentElementIndex() const { return m_currentElementIndex; }
7457
7471 StringRef currentElementAsString() const;
7472 };
7473 using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
7474
7475 } // namespace Generators
7476
7478 public:
7479 virtual ~IGeneratorTracker(); // = default;
7480 virtual auto hasGenerator() const -> bool = 0;
7481 virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
7482 virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
7483 };
7484
7485} // namespace Catch
7486
7487#endif // CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED
7488
7489#include <vector>
7490#include <tuple>
7491
7492namespace Catch {
7493
7494namespace Generators {
7495
7496namespace Detail {
7497
7499 [[noreturn]]
7500 void throw_generator_exception(char const * msg);
7501
7502} // end namespace detail
7503
7504 template<typename T>
7506 std::string stringifyImpl() const override {
7507 return ::Catch::Detail::stringify( get() );
7508 }
7509
7510 public:
7511 // Returns the current element of the generator
7512 //
7513 // \Precondition The generator is either freshly constructed,
7514 // or the last call to `next()` returned true
7515 virtual T const& get() const = 0;
7516 using type = T;
7517 };
7518
7519 template <typename T>
7521
7522 template <typename T>
7523 class GeneratorWrapper final {
7525 public:
7528 m_generator(generator) {}
7531
7532 T const& get() const {
7533 return m_generator->get();
7534 }
7535 bool next() {
7536 return m_generator->countedNext();
7537 }
7538 };
7539
7540
7541 template<typename T>
7542 class SingleValueGenerator final : public IGenerator<T> {
7544 public:
7546 m_value(value)
7547 {}
7551
7552 T const& get() const override {
7553 return m_value;
7554 }
7555 bool next() override {
7556 return false;
7557 }
7558 };
7559
7560 template<typename T>
7561 class FixedValuesGenerator final : public IGenerator<T> {
7562 static_assert(!std::is_same<T, bool>::value,
7563 "FixedValuesGenerator does not support bools because of std::vector<bool>"
7564 "specialization, use SingleValue Generator instead.");
7565 std::vector<T> m_values;
7566 size_t m_idx = 0;
7567 public:
7568 FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
7569
7570 T const& get() const override {
7571 return m_values[m_idx];
7572 }
7573 bool next() override {
7574 ++m_idx;
7575 return m_idx < m_values.size();
7576 }
7577 };
7578
7579 template <typename T, typename DecayedT = std::decay_t<T>>
7585 template <typename T>
7589
7590 template<typename T>
7591 class Generators : public IGenerator<T> {
7592 std::vector<GeneratorWrapper<T>> m_generators;
7593 size_t m_current = 0;
7594
7596 m_generators.emplace_back( CATCH_MOVE( generator ) );
7597 }
7598 void add_generator( T const& val ) {
7599 m_generators.emplace_back( value( val ) );
7600 }
7601 void add_generator( T&& val ) {
7602 m_generators.emplace_back( value( CATCH_MOVE( val ) ) );
7603 }
7604 template <typename U>
7605 std::enable_if_t<!std::is_same<std::decay_t<U>, T>::value>
7606 add_generator( U&& val ) {
7607 add_generator( T( CATCH_FORWARD( val ) ) );
7608 }
7609
7610 template <typename U> void add_generators( U&& valueOrGenerator ) {
7611 add_generator( CATCH_FORWARD( valueOrGenerator ) );
7612 }
7613
7614 template <typename U, typename... Gs>
7615 void add_generators( U&& valueOrGenerator, Gs&&... moreGenerators ) {
7616 add_generator( CATCH_FORWARD( valueOrGenerator ) );
7617 add_generators( CATCH_FORWARD( moreGenerators )... );
7618 }
7619
7620 public:
7621 template <typename... Gs>
7622 Generators(Gs &&... moreGenerators) {
7623 m_generators.reserve(sizeof...(Gs));
7624 add_generators(CATCH_FORWARD(moreGenerators)...);
7625 }
7626
7627 T const& get() const override {
7628 return m_generators[m_current].get();
7629 }
7630
7631 bool next() override {
7632 if (m_current >= m_generators.size()) {
7633 return false;
7634 }
7635 const bool current_status = m_generators[m_current].next();
7636 if (!current_status) {
7637 ++m_current;
7638 }
7639 return m_current < m_generators.size();
7640 }
7641 };
7642
7643
7644 template <typename... Ts>
7645 GeneratorWrapper<std::tuple<std::decay_t<Ts>...>>
7646 table( std::initializer_list<std::tuple<std::decay_t<Ts>...>> tuples ) {
7647 return values<std::tuple<Ts...>>( tuples );
7648 }
7649
7650 // Tag type to signal that a generator sequence should convert arguments to a specific type
7651 template <typename T>
7652 struct as {};
7653
7654 template<typename T, typename... Gs>
7655 auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
7656 return Generators<T>(CATCH_MOVE(generator), CATCH_FORWARD(moreGenerators)...);
7657 }
7658 template<typename T>
7660 return Generators<T>(CATCH_MOVE(generator));
7661 }
7662 template<typename T, typename... Gs>
7663 auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<std::decay_t<T>> {
7664 return makeGenerators( value( CATCH_FORWARD( val ) ), CATCH_FORWARD( moreGenerators )... );
7665 }
7666 template<typename T, typename U, typename... Gs>
7667 auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
7668 return makeGenerators( value( T( CATCH_FORWARD( val ) ) ), CATCH_FORWARD( moreGenerators )... );
7669 }
7670
7671 IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName,
7672 SourceLineInfo const& lineInfo );
7673 IGeneratorTracker* createGeneratorTracker( StringRef generatorName,
7674 SourceLineInfo lineInfo,
7675 GeneratorBasePtr&& generator );
7676
7677 template<typename L>
7678 auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> typename decltype(generatorExpression())::type {
7679 using UnderlyingType = typename decltype(generatorExpression())::type;
7680
7681 IGeneratorTracker* tracker = acquireGeneratorTracker( generatorName, lineInfo );
7682 // Creation of tracker is delayed after generator creation, so
7683 // that constructing generator can fail without breaking everything.
7684 if (!tracker) {
7685 tracker = createGeneratorTracker(
7686 generatorName,
7687 lineInfo,
7689 generatorExpression() ) );
7690 }
7691
7692 auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker->getGenerator() );
7693 return generator.get();
7694 }
7695
7696} // namespace Generators
7697} // namespace Catch
7698
7699#define CATCH_INTERNAL_GENERATOR_STRINGIZE_IMPL( ... ) #__VA_ARGS__##_catch_sr
7700#define CATCH_INTERNAL_GENERATOR_STRINGIZE(...) CATCH_INTERNAL_GENERATOR_STRINGIZE_IMPL(__VA_ARGS__)
7701
7702#define GENERATE( ... ) \
7703 Catch::Generators::generate( CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7704 CATCH_INTERNAL_LINEINFO, \
7705 [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
7706#define GENERATE_COPY( ... ) \
7707 Catch::Generators::generate( CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7708 CATCH_INTERNAL_LINEINFO, \
7709 [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
7710#define GENERATE_REF( ... ) \
7711 Catch::Generators::generate( CATCH_INTERNAL_GENERATOR_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
7712 CATCH_INTERNAL_LINEINFO, \
7713 [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
7714
7715#endif // CATCH_GENERATORS_HPP_INCLUDED
7716
7717
7718#ifndef CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7719#define CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7720
7721
7722#include <cassert>
7723
7724namespace Catch {
7725namespace Generators {
7726
7727 template <typename T>
7728 class TakeGenerator final : public IGenerator<T> {
7730 size_t m_returned = 0;
7731 size_t m_target;
7732 public:
7733 TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
7734 m_generator(CATCH_MOVE(generator)),
7735 m_target(target)
7736 {
7737 assert(target != 0 && "Empty generators are not allowed");
7738 }
7739 T const& get() const override {
7740 return m_generator.get();
7741 }
7742 bool next() override {
7743 ++m_returned;
7744 if (m_returned >= m_target) {
7745 return false;
7746 }
7747
7748 const auto success = m_generator.next();
7749 // If the underlying generator does not contain enough values
7750 // then we cut short as well
7751 if (!success) {
7753 }
7754 return success;
7755 }
7756 };
7757
7758 template <typename T>
7759 GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
7761 }
7762
7763
7764 template <typename T, typename Predicate>
7765 class FilterGenerator final : public IGenerator<T> {
7767 Predicate m_predicate;
7768 public:
7769 template <typename P = Predicate>
7770 FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
7771 m_generator(CATCH_MOVE(generator)),
7773 {
7774 if (!m_predicate(m_generator.get())) {
7775 // It might happen that there are no values that pass the
7776 // filter. In that case we throw an exception.
7777 auto has_initial_value = next();
7778 if (!has_initial_value) {
7779 Detail::throw_generator_exception("No valid value found in filtered generator");
7780 }
7781 }
7782 }
7783
7784 T const& get() const override {
7785 return m_generator.get();
7786 }
7787
7788 bool next() override {
7789 bool success = m_generator.next();
7790 if (!success) {
7791 return false;
7792 }
7793 while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
7794 return success;
7795 }
7796 };
7797
7798
7799 template <typename T, typename Predicate>
7803
7804 template <typename T>
7805 class RepeatGenerator final : public IGenerator<T> {
7806 static_assert(!std::is_same<T, bool>::value,
7807 "RepeatGenerator currently does not support bools"
7808 "because of std::vector<bool> specialization");
7810 mutable std::vector<T> m_returned;
7813 size_t m_repeat_index = 0;
7814 public:
7815 RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
7816 m_generator(CATCH_MOVE(generator)),
7817 m_target_repeats(repeats)
7818 {
7819 assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
7820 }
7821
7822 T const& get() const override {
7823 if (m_current_repeat == 0) {
7824 m_returned.push_back(m_generator.get());
7825 return m_returned.back();
7826 }
7827 return m_returned[m_repeat_index];
7828 }
7829
7830 bool next() override {
7831 // There are 2 basic cases:
7832 // 1) We are still reading the generator
7833 // 2) We are reading our own cache
7834
7835 // In the first case, we need to poke the underlying generator.
7836 // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
7837 if (m_current_repeat == 0) {
7838 const auto success = m_generator.next();
7839 if (!success) {
7841 }
7843 }
7844
7845 // In the second case, we need to move indices forward and check that we haven't run up against the end
7847 if (m_repeat_index == m_returned.size()) {
7848 m_repeat_index = 0;
7850 }
7852 }
7853 };
7854
7855 template <typename T>
7856 GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
7858 }
7859
7860 template <typename T, typename U, typename Func>
7861 class MapGenerator final : public IGenerator<T> {
7862 // TBD: provide static assert for mapping function, for friendly error message
7865 // To avoid returning dangling reference, we have to save the values
7867 public:
7868 template <typename F2 = Func>
7869 MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
7870 m_generator(CATCH_MOVE(generator)),
7871 m_function(CATCH_FORWARD(function)),
7873 {}
7874
7875 T const& get() const override {
7876 return m_cache;
7877 }
7878 bool next() override {
7879 const auto success = m_generator.next();
7880 if (success) {
7882 }
7883 return success;
7884 }
7885 };
7886
7887 template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
7888 GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
7889 return GeneratorWrapper<T>(
7891 );
7892 }
7893
7894 template <typename T, typename U, typename Func>
7895 GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
7896 return GeneratorWrapper<T>(
7897 Catch::Detail::make_unique<MapGenerator<T, U, Func>>(CATCH_FORWARD(function), CATCH_MOVE(generator))
7898 );
7899 }
7900
7901 template <typename T>
7902 class ChunkGenerator final : public IGenerator<std::vector<T>> {
7903 std::vector<T> m_chunk;
7906 bool m_used_up = false;
7907 public:
7908 ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
7909 m_chunk_size(size), m_generator(CATCH_MOVE(generator))
7910 {
7911 m_chunk.reserve(m_chunk_size);
7912 if (m_chunk_size != 0) {
7913 m_chunk.push_back(m_generator.get());
7914 for (size_t i = 1; i < m_chunk_size; ++i) {
7915 if (!m_generator.next()) {
7916 Detail::throw_generator_exception("Not enough values to initialize the first chunk");
7917 }
7918 m_chunk.push_back(m_generator.get());
7919 }
7920 }
7921 }
7922 std::vector<T> const& get() const override {
7923 return m_chunk;
7924 }
7925 bool next() override {
7926 m_chunk.clear();
7927 for (size_t idx = 0; idx < m_chunk_size; ++idx) {
7928 if (!m_generator.next()) {
7929 return false;
7930 }
7931 m_chunk.push_back(m_generator.get());
7932 }
7933 return true;
7934 }
7935 };
7936
7937 template <typename T>
7943
7944} // namespace Generators
7945} // namespace Catch
7946
7947
7948#endif // CATCH_GENERATORS_ADAPTERS_HPP_INCLUDED
7949
7950
7951#ifndef CATCH_GENERATORS_RANDOM_HPP_INCLUDED
7952#define CATCH_GENERATORS_RANDOM_HPP_INCLUDED
7953
7954
7955
7956#ifndef CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
7957#define CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
7958
7959#include <cstdint>
7960
7961namespace Catch {
7962
7963 // This is a simple implementation of C++11 Uniform Random Number
7964 // Generator. It does not provide all operators, because Catch2
7965 // does not use it, but it should behave as expected inside stdlib's
7966 // distributions.
7967 // The implementation is based on the PCG family (http://pcg-random.org)
7969 using state_type = std::uint64_t;
7970 public:
7971 using result_type = std::uint32_t;
7972 static constexpr result_type (min)() {
7973 return 0;
7974 }
7975 static constexpr result_type (max)() {
7976 return static_cast<result_type>(-1);
7977 }
7978
7979 // Provide some default initial state for the default constructor
7980 SimplePcg32():SimplePcg32(0xed743cc4U) {}
7981
7982 explicit SimplePcg32(result_type seed_);
7983
7984 void seed(result_type seed_);
7985 void discard(uint64_t skip);
7986
7987 result_type operator()();
7988
7989 private:
7990 friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
7991 friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
7992
7993 // In theory we also need operator<< and operator>>
7994 // In practice we do not use them, so we will skip them for now
7995
7996
7997 std::uint64_t m_state;
7998 // This part of the state determines which "stream" of the numbers
7999 // is chosen -- we take it as a constant for Catch2, so we only
8000 // need to deal with seeding the main state.
8001 // Picked by reading 8 bytes from `/dev/random` :-)
8002 static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
8003 };
8004
8005} // end namespace Catch
8006
8007#endif // CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED
8008
8009
8010
8011#ifndef CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
8012#define CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
8013
8014
8015
8016
8017#ifndef CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED
8018#define CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED
8019
8020#include <climits>
8021#include <cstddef>
8022#include <cstdint>
8023#include <type_traits>
8024
8025// Note: We use the usual enable-disable-autodetect dance here even though
8026// we do not support these in CMake configuration options (yet?).
8027// It is highly unlikely that we will need to make these actually
8028// user-configurable, but this will make it simpler if weend up needing
8029// it, and it provides an escape hatch to the users who need it.
8030#if defined( __SIZEOF_INT128__ )
8031# define CATCH_CONFIG_INTERNAL_UINT128
8032// Unlike GCC, MSVC does not polyfill umul as mulh + mul pair on ARM machines.
8033// Currently we do not bother doing this ourselves, but we could if it became
8034// important for perf.
8035#elif defined( _MSC_VER ) && defined( _M_X64 )
8036# define CATCH_CONFIG_INTERNAL_MSVC_UMUL128
8037#endif
8038
8039#if defined( CATCH_CONFIG_INTERNAL_UINT128 ) && \
8040 !defined( CATCH_CONFIG_NO_UINT128 ) && \
8041 !defined( CATCH_CONFIG_UINT128 )
8042#define CATCH_CONFIG_UINT128
8043#endif
8044
8045#if defined( CATCH_CONFIG_INTERNAL_MSVC_UMUL128 ) && \
8046 !defined( CATCH_CONFIG_NO_MSVC_UMUL128 ) && \
8047 !defined( CATCH_CONFIG_MSVC_UMUL128 )
8048# define CATCH_CONFIG_MSVC_UMUL128
8049# include <intrin.h>
8050#endif
8051
8052
8053namespace Catch {
8054 namespace Detail {
8055
8056 template <std::size_t>
8057 struct SizedUnsignedType;
8058#define SizedUnsignedTypeHelper( TYPE ) \
8059 template <> \
8060 struct SizedUnsignedType<sizeof( TYPE )> { \
8061 using type = TYPE; \
8062 }
8063
8064 SizedUnsignedTypeHelper( std::uint8_t );
8065 SizedUnsignedTypeHelper( std::uint16_t );
8066 SizedUnsignedTypeHelper( std::uint32_t );
8067 SizedUnsignedTypeHelper( std::uint64_t );
8068#undef SizedUnsignedTypeHelper
8069
8070 template <std::size_t sz>
8071 using SizedUnsignedType_t = typename SizedUnsignedType<sz>::type;
8072
8073 template <typename T>
8074 using DoubleWidthUnsignedType_t = SizedUnsignedType_t<2 * sizeof( T )>;
8075
8076 template <typename T>
8077 struct ExtendedMultResult {
8078 T upper;
8079 T lower;
8080 constexpr bool operator==( ExtendedMultResult const& rhs ) const {
8081 return upper == rhs.upper && lower == rhs.lower;
8082 }
8083 };
8084
8091 constexpr ExtendedMultResult<std::uint64_t>
8092 extendedMultPortable(std::uint64_t lhs, std::uint64_t rhs) {
8093#define CarryBits( x ) ( x >> 32 )
8094#define Digits( x ) ( x & 0xFF'FF'FF'FF )
8095 std::uint64_t lhs_low = Digits( lhs );
8096 std::uint64_t rhs_low = Digits( rhs );
8097 std::uint64_t low_low = ( lhs_low * rhs_low );
8098 std::uint64_t high_high = CarryBits( lhs ) * CarryBits( rhs );
8099
8100 // We add in carry bits from low-low already
8101 std::uint64_t high_low =
8102 ( CarryBits( lhs ) * rhs_low ) + CarryBits( low_low );
8103 // Note that we can add only low bits from high_low, to avoid
8104 // overflow with large inputs
8105 std::uint64_t low_high =
8106 ( lhs_low * CarryBits( rhs ) ) + Digits( high_low );
8107
8108 return { high_high + CarryBits( high_low ) + CarryBits( low_high ),
8109 ( low_high << 32 ) | Digits( low_low ) };
8110#undef CarryBits
8111#undef Digits
8112 }
8113
8115 inline ExtendedMultResult<std::uint64_t>
8116 extendedMult( std::uint64_t lhs, std::uint64_t rhs ) {
8117#if defined( CATCH_CONFIG_UINT128 )
8118 auto result = __uint128_t( lhs ) * __uint128_t( rhs );
8119 return { static_cast<std::uint64_t>( result >> 64 ),
8120 static_cast<std::uint64_t>( result ) };
8121#elif defined( CATCH_CONFIG_MSVC_UMUL128 )
8122 std::uint64_t high;
8123 std::uint64_t low = _umul128( lhs, rhs, &high );
8124 return { high, low };
8125#else
8126 return extendedMultPortable( lhs, rhs );
8127#endif
8128 }
8129
8130
8131 template <typename UInt>
8132 constexpr ExtendedMultResult<UInt> extendedMult( UInt lhs, UInt rhs ) {
8133 static_assert( std::is_unsigned<UInt>::value,
8134 "extendedMult can only handle unsigned integers" );
8135 static_assert( sizeof( UInt ) < sizeof( std::uint64_t ),
8136 "Generic extendedMult can only handle types smaller "
8137 "than uint64_t" );
8138 using WideType = DoubleWidthUnsignedType_t<UInt>;
8139
8140 auto result = WideType( lhs ) * WideType( rhs );
8141 return {
8142 static_cast<UInt>( result >> ( CHAR_BIT * sizeof( UInt ) ) ),
8143 static_cast<UInt>( result & UInt( -1 ) ) };
8144 }
8145
8146
8147 template <typename TargetType,
8148 typename Generator>
8149 std::enable_if_t<sizeof(typename Generator::result_type) >= sizeof(TargetType),
8150 TargetType> fillBitsFrom(Generator& gen) {
8151 using gresult_type = typename Generator::result_type;
8152 static_assert( std::is_unsigned<TargetType>::value, "Only unsigned integers are supported" );
8153 static_assert( Generator::min() == 0 &&
8154 Generator::max() == static_cast<gresult_type>( -1 ),
8155 "Generator must be able to output all numbers in its result type (effectively it must be a random bit generator)" );
8156
8157 // We want to return the top bits from a generator, as they are
8158 // usually considered higher quality.
8159 constexpr auto generated_bits = sizeof( gresult_type ) * CHAR_BIT;
8160 constexpr auto return_bits = sizeof( TargetType ) * CHAR_BIT;
8161
8162 return static_cast<TargetType>( gen() >>
8163 ( generated_bits - return_bits) );
8164 }
8165
8166 template <typename TargetType,
8167 typename Generator>
8168 std::enable_if_t<sizeof(typename Generator::result_type) < sizeof(TargetType),
8169 TargetType> fillBitsFrom(Generator& gen) {
8170 using gresult_type = typename Generator::result_type;
8171 static_assert( std::is_unsigned<TargetType>::value,
8172 "Only unsigned integers are supported" );
8173 static_assert( Generator::min() == 0 &&
8174 Generator::max() == static_cast<gresult_type>( -1 ),
8175 "Generator must be able to output all numbers in its result type (effectively it must be a random bit generator)" );
8176
8177 constexpr auto generated_bits = sizeof( gresult_type ) * CHAR_BIT;
8178 constexpr auto return_bits = sizeof( TargetType ) * CHAR_BIT;
8179 std::size_t filled_bits = 0;
8180 TargetType ret = 0;
8181 do {
8182 ret <<= generated_bits;
8183 ret |= gen();
8184 filled_bits += generated_bits;
8185 } while ( filled_bits < return_bits );
8186
8187 return ret;
8188 }
8189
8190 /*
8191 * Transposes numbers into unsigned type while keeping their ordering
8192 *
8193 * This means that signed types are changed so that the ordering is
8194 * [INT_MIN, ..., -1, 0, ..., INT_MAX], rather than order we would
8195 * get by simple casting ([0, ..., INT_MAX, INT_MIN, ..., -1])
8196 */
8197 template <typename OriginalType, typename UnsignedType>
8198 constexpr
8199 std::enable_if_t<std::is_signed<OriginalType>::value, UnsignedType>
8200 transposeToNaturalOrder( UnsignedType in ) {
8201 static_assert(
8202 sizeof( OriginalType ) == sizeof( UnsignedType ),
8203 "reordering requires the same sized types on both sides" );
8204 static_assert( std::is_unsigned<UnsignedType>::value,
8205 "Input type must be unsigned" );
8206 // Assuming 2s complement (standardized in current C++), the
8207 // positive and negative numbers are already internally ordered,
8208 // and their difference is in the top bit. Swapping it orders
8209 // them the desired way.
8210 constexpr auto highest_bit =
8211 UnsignedType( 1 ) << ( sizeof( UnsignedType ) * CHAR_BIT - 1 );
8212 return static_cast<UnsignedType>( in ^ highest_bit );
8213 }
8214
8215
8216
8217 template <typename OriginalType,
8218 typename UnsignedType>
8219 constexpr
8220 std::enable_if_t<std::is_unsigned<OriginalType>::value, UnsignedType>
8221 transposeToNaturalOrder(UnsignedType in) {
8222 static_assert(
8223 sizeof( OriginalType ) == sizeof( UnsignedType ),
8224 "reordering requires the same sized types on both sides" );
8225 static_assert( std::is_unsigned<UnsignedType>::value, "Input type must be unsigned" );
8226 // No reordering is needed for unsigned -> unsigned
8227 return in;
8228 }
8229 } // namespace Detail
8230} // namespace Catch
8231
8232#endif // CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED
8233
8234namespace Catch {
8235
8247template <typename IntegerType>
8248class uniform_integer_distribution {
8249 static_assert(std::is_integral<IntegerType>::value, "...");
8250
8251 using UnsignedIntegerType = Detail::SizedUnsignedType_t<sizeof(IntegerType)>;
8252
8253 // Only the left bound is stored, and we store it converted to its
8254 // unsigned image. This avoids having to do the conversions inside
8255 // the operator(), at the cost of having to do the conversion in
8256 // the a() getter. The right bound is only needed in the b() getter,
8257 // so we recompute it there from other stored data.
8258 UnsignedIntegerType m_a;
8259
8260 // How many different values are there in [a, b]. a == b => 1, can be 0 for distribution over all values in the type.
8261 UnsignedIntegerType m_ab_distance;
8262
8263 // We hoisted this out of the main generation function. Technically,
8264 // this means that using this distribution will be slower than Lemire's
8265 // algorithm if this distribution instance will be used only few times,
8266 // but it will be faster if it is used many times. Since Catch2 uses
8267 // distributions only to implement random generators, we assume that each
8268 // distribution will be reused many times and this is an optimization.
8269 UnsignedIntegerType m_rejection_threshold = 0;
8270
8271 static constexpr UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) {
8272 // This overflows and returns 0 if a == 0 and b == TYPE_MAX.
8273 // We handle that later when generating the number.
8274 return transposeTo(b) - transposeTo(a) + 1;
8275 }
8276
8277 static constexpr UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) {
8278 // distance == 0 means that we will return all possible values from
8279 // the type's range, and that we shouldn't reject anything.
8280 if ( ab_distance == 0 ) { return 0; }
8281 return ( ~ab_distance + 1 ) % ab_distance;
8282 }
8283
8284 static constexpr UnsignedIntegerType transposeTo(IntegerType in) {
8285 return Detail::transposeToNaturalOrder<IntegerType>(
8286 static_cast<UnsignedIntegerType>( in ) );
8287 }
8288 static constexpr IntegerType transposeBack(UnsignedIntegerType in) {
8289 return static_cast<IntegerType>(
8290 Detail::transposeToNaturalOrder<IntegerType>(in) );
8291 }
8292
8293public:
8294 using result_type = IntegerType;
8295
8296 constexpr uniform_integer_distribution( IntegerType a, IntegerType b ):
8297 m_a( transposeTo(a) ),
8298 m_ab_distance( computeDistance(a, b) ),
8299 m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) {
8300 assert( a <= b );
8301 }
8302
8303 template <typename Generator>
8304 constexpr result_type operator()( Generator& g ) {
8305 // All possible values of result_type are valid.
8306 if ( m_ab_distance == 0 ) {
8307 return transposeBack( Detail::fillBitsFrom<UnsignedIntegerType>( g ) );
8308 }
8309
8310 auto random_number = Detail::fillBitsFrom<UnsignedIntegerType>( g );
8311 auto emul = Detail::extendedMult( random_number, m_ab_distance );
8312 // Unlike Lemire's algorithm we skip the ab_distance check, since
8313 // we precomputed the rejection threshold, which is always tighter.
8314 while (emul.lower < m_rejection_threshold) {
8315 random_number = Detail::fillBitsFrom<UnsignedIntegerType>( g );
8316 emul = Detail::extendedMult( random_number, m_ab_distance );
8317 }
8318
8319 return transposeBack(m_a + emul.upper);
8320 }
8321
8322 constexpr result_type a() const { return transposeBack(m_a); }
8323 constexpr result_type b() const { return transposeBack(m_ab_distance + m_a - 1); }
8324};
8325
8326} // end namespace Catch
8327
8328#endif // CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
8329
8330
8331
8332#ifndef CATCH_UNIFORM_FLOATING_POINT_DISTRIBUTION_HPP_INCLUDED
8333#define CATCH_UNIFORM_FLOATING_POINT_DISTRIBUTION_HPP_INCLUDED
8334
8335
8336
8337
8338#ifndef CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
8339#define CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
8340
8341
8342
8343#ifndef CATCH_POLYFILLS_HPP_INCLUDED
8344#define CATCH_POLYFILLS_HPP_INCLUDED
8345
8346namespace Catch {
8347
8348 bool isnan(float f);
8349 bool isnan(double d);
8350
8351 float nextafter(float x, float y);
8352 double nextafter(double x, double y);
8353
8354}
8355
8356#endif // CATCH_POLYFILLS_HPP_INCLUDED
8357
8358#include <cassert>
8359#include <cmath>
8360#include <cstdint>
8361#include <limits>
8362#include <type_traits>
8363
8364namespace Catch {
8365
8366 namespace Detail {
8372 template <typename FloatType>
8373 FloatType gamma(FloatType a, FloatType b) {
8374 static_assert( std::is_floating_point<FloatType>::value,
8375 "gamma returns the largest ULP magnitude within "
8376 "floating point range [a, b]. This only makes sense "
8377 "for floating point types" );
8378 assert( a <= b );
8379
8380 const auto gamma_up = Catch::nextafter( a, std::numeric_limits<FloatType>::infinity() ) - a;
8381 const auto gamma_down = b - Catch::nextafter( b, -std::numeric_limits<FloatType>::infinity() );
8382
8383 return gamma_up < gamma_down ? gamma_down : gamma_up;
8384 }
8385
8386 template <typename FloatingPoint>
8387 struct DistanceTypePicker;
8388 template <>
8389 struct DistanceTypePicker<float> {
8390 using type = std::uint32_t;
8391 };
8392 template <>
8393 struct DistanceTypePicker<double> {
8394 using type = std::uint64_t;
8395 };
8396
8397 template <typename T>
8398 using DistanceType = typename DistanceTypePicker<T>::type;
8399
8400#if defined( __GNUC__ ) || defined( __clang__ )
8401# pragma GCC diagnostic push
8402# pragma GCC diagnostic ignored "-Wfloat-equal"
8403#endif
8413 template <typename FloatType>
8414 DistanceType<FloatType>
8415 count_equidistant_floats( FloatType a, FloatType b, FloatType distance ) {
8416 assert( a <= b );
8417 // We get distance as gamma for our uniform float distribution,
8418 // so this will round perfectly.
8419 const auto ag = a / distance;
8420 const auto bg = b / distance;
8421
8422 const auto s = bg - ag;
8423 const auto err = ( std::fabs( a ) <= std::fabs( b ) )
8424 ? -ag - ( s - bg )
8425 : bg - ( s + ag );
8426 const auto ceil_s = static_cast<DistanceType<FloatType>>( std::ceil( s ) );
8427
8428 return ( ceil_s != s ) ? ceil_s : ceil_s + ( err > 0 );
8429 }
8430#if defined( __GNUC__ ) || defined( __clang__ )
8431# pragma GCC diagnostic pop
8432#endif
8433
8434 }
8435
8436} // end namespace Catch
8437
8438#endif // CATCH_RANDOM_FLOATING_POINT_HELPERS_HPP_INCLUDED
8439
8440#include <cmath>
8441#include <type_traits>
8442
8443namespace Catch {
8444
8445 namespace Detail {
8446#if defined( __GNUC__ ) || defined( __clang__ )
8447# pragma GCC diagnostic push
8448# pragma GCC diagnostic ignored "-Wfloat-equal"
8449#endif
8450 // The issue with overflow only happens with maximal ULP and HUGE
8451 // distance, e.g. when generating numbers in [-inf, inf] for given
8452 // type. So we only check for the largest possible ULP in the
8453 // type, and return something that does not overflow to inf in 1 mult.
8454 constexpr std::uint64_t calculate_max_steps_in_one_go(double gamma) {
8455 if ( gamma == 1.99584030953472e+292 ) { return 9007199254740991; }
8456 return static_cast<std::uint64_t>( -1 );
8457 }
8458 constexpr std::uint32_t calculate_max_steps_in_one_go(float gamma) {
8459 if ( gamma == 2.028241e+31f ) { return 16777215; }
8460 return static_cast<std::uint32_t>( -1 );
8461 }
8462#if defined( __GNUC__ ) || defined( __clang__ )
8463# pragma GCC diagnostic pop
8464#endif
8465 }
8466
8493template <typename FloatType>
8494class uniform_floating_point_distribution {
8495 static_assert(std::is_floating_point<FloatType>::value, "...");
8496 static_assert(!std::is_same<FloatType, long double>::value,
8497 "We do not support long double due to inconsistent behaviour between platforms");
8498
8499 using WidthType = Detail::DistanceType<FloatType>;
8500
8501 FloatType m_a, m_b;
8502 FloatType m_ulp_magnitude;
8503 WidthType m_floats_in_range;
8504 uniform_integer_distribution<WidthType> m_int_dist;
8505
8506 // In specific cases, we can overflow into `inf` when computing the
8507 // `steps * g` offset. To avoid this, we don't offset by more than this
8508 // in one multiply + addition.
8509 WidthType m_max_steps_in_one_go;
8510 // We don't want to do the magnitude check every call to `operator()`
8511 bool m_a_has_leq_magnitude;
8512
8513public:
8514 using result_type = FloatType;
8515
8516 uniform_floating_point_distribution( FloatType a, FloatType b ):
8517 m_a( a ),
8518 m_b( b ),
8519 m_ulp_magnitude( Detail::gamma( m_a, m_b ) ),
8520 m_floats_in_range( Detail::count_equidistant_floats( m_a, m_b, m_ulp_magnitude ) ),
8521 m_int_dist(0, m_floats_in_range),
8522 m_max_steps_in_one_go( Detail::calculate_max_steps_in_one_go(m_ulp_magnitude)),
8523 m_a_has_leq_magnitude(std::fabs(m_a) <= std::fabs(m_b))
8524 {
8525 assert( a <= b );
8526 }
8527
8528 template <typename Generator>
8529 result_type operator()( Generator& g ) {
8530 WidthType steps = m_int_dist( g );
8531 if ( m_a_has_leq_magnitude ) {
8532 if ( steps == m_floats_in_range ) { return m_a; }
8533 auto b = m_b;
8534 while (steps > m_max_steps_in_one_go) {
8535 b -= m_max_steps_in_one_go * m_ulp_magnitude;
8536 steps -= m_max_steps_in_one_go;
8537 }
8538 return b - steps * m_ulp_magnitude;
8539 } else {
8540 if ( steps == m_floats_in_range ) { return m_b; }
8541 auto a = m_a;
8542 while (steps > m_max_steps_in_one_go) {
8543 a += m_max_steps_in_one_go * m_ulp_magnitude;
8544 steps -= m_max_steps_in_one_go;
8545 }
8546 return a + steps * m_ulp_magnitude;
8547 }
8548 }
8549
8550 result_type a() const { return m_a; }
8551 result_type b() const { return m_b; }
8552};
8553
8554} // end namespace Catch
8555
8556#endif // CATCH_UNIFORM_FLOATING_POINT_DISTRIBUTION_HPP_INCLUDED
8557
8558namespace Catch {
8559namespace Generators {
8560namespace Detail {
8561 // Returns a suitable seed for a random floating generator based off
8562 // the primary internal rng. It does so by taking current value from
8563 // the rng and returning it as the seed.
8564 std::uint32_t getSeed();
8565}
8566
8567template <typename Float>
8568class RandomFloatingGenerator final : public IGenerator<Float> {
8569 Catch::SimplePcg32 m_rng;
8570 Catch::uniform_floating_point_distribution<Float> m_dist;
8571 Float m_current_number;
8572public:
8573 RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ):
8574 m_rng(seed),
8575 m_dist(a, b) {
8576 static_cast<void>(next());
8577 }
8578
8579 Float const& get() const override {
8580 return m_current_number;
8581 }
8582 bool next() override {
8583 m_current_number = m_dist(m_rng);
8584 return true;
8585 }
8586};
8587
8588template <>
8589class RandomFloatingGenerator<long double> final : public IGenerator<long double> {
8590 // We still rely on <random> for this specialization, but we don't
8591 // want to drag it into the header.
8592 struct PImpl;
8593 Catch::Detail::unique_ptr<PImpl> m_pimpl;
8594 long double m_current_number;
8595
8596public:
8597 RandomFloatingGenerator( long double a, long double b, std::uint32_t seed );
8598
8599 long double const& get() const override { return m_current_number; }
8600 bool next() override;
8601
8602 ~RandomFloatingGenerator() override; // = default
8603};
8604
8605template <typename Integer>
8606class RandomIntegerGenerator final : public IGenerator<Integer> {
8607 Catch::SimplePcg32 m_rng;
8608 Catch::uniform_integer_distribution<Integer> m_dist;
8609 Integer m_current_number;
8610public:
8611 RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
8612 m_rng(seed),
8613 m_dist(a, b) {
8614 static_cast<void>(next());
8615 }
8616
8617 Integer const& get() const override {
8618 return m_current_number;
8619 }
8620 bool next() override {
8621 m_current_number = m_dist(m_rng);
8622 return true;
8623 }
8624};
8625
8626template <typename T>
8627std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
8628random(T a, T b) {
8629 return GeneratorWrapper<T>(
8630 Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
8631 );
8632}
8633
8634template <typename T>
8635std::enable_if_t<std::is_floating_point<T>::value,
8636GeneratorWrapper<T>>
8637random(T a, T b) {
8638 return GeneratorWrapper<T>(
8639 Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed())
8640 );
8641}
8642
8643
8644} // namespace Generators
8645} // namespace Catch
8646
8647
8648#endif // CATCH_GENERATORS_RANDOM_HPP_INCLUDED
8649
8650
8651#ifndef CATCH_GENERATORS_RANGE_HPP_INCLUDED
8652#define CATCH_GENERATORS_RANGE_HPP_INCLUDED
8653
8654
8655#include <iterator>
8656#include <type_traits>
8657
8658namespace Catch {
8659namespace Generators {
8660
8661
8662template <typename T>
8663class RangeGenerator final : public IGenerator<T> {
8664 T m_current;
8665 T m_end;
8666 T m_step;
8667 bool m_positive;
8668
8669public:
8670 RangeGenerator(T const& start, T const& end, T const& step):
8671 m_current(start),
8672 m_end(end),
8673 m_step(step),
8674 m_positive(m_step > T(0))
8675 {
8676 assert(m_current != m_end && "Range start and end cannot be equal");
8677 assert(m_step != T(0) && "Step size cannot be zero");
8678 assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
8679 }
8680
8681 RangeGenerator(T const& start, T const& end):
8682 RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
8683 {}
8684
8685 T const& get() const override {
8686 return m_current;
8687 }
8688
8689 bool next() override {
8690 m_current += m_step;
8691 return (m_positive) ? (m_current < m_end) : (m_current > m_end);
8692 }
8693};
8694
8695template <typename T>
8696GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
8697 static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
8698 return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end, step));
8699}
8700
8701template <typename T>
8702GeneratorWrapper<T> range(T const& start, T const& end) {
8703 static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
8704 return GeneratorWrapper<T>(Catch::Detail::make_unique<RangeGenerator<T>>(start, end));
8705}
8706
8707
8708template <typename T>
8709class IteratorGenerator final : public IGenerator<T> {
8710 static_assert(!std::is_same<T, bool>::value,
8711 "IteratorGenerator currently does not support bools"
8712 "because of std::vector<bool> specialization");
8713
8714 std::vector<T> m_elems;
8715 size_t m_current = 0;
8716public:
8717 template <typename InputIterator, typename InputSentinel>
8718 IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
8719 if (m_elems.empty()) {
8720 Detail::throw_generator_exception("IteratorGenerator received no valid values");
8721 }
8722 }
8723
8724 T const& get() const override {
8725 return m_elems[m_current];
8726 }
8727
8728 bool next() override {
8729 ++m_current;
8730 return m_current != m_elems.size();
8731 }
8732};
8733
8734template <typename InputIterator,
8735 typename InputSentinel,
8736 typename ResultType = std::remove_const_t<typename std::iterator_traits<InputIterator>::value_type>>
8737GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
8738 return GeneratorWrapper<ResultType>(Catch::Detail::make_unique<IteratorGenerator<ResultType>>(from, to));
8739}
8740
8741template <typename Container>
8742auto from_range(Container const& cnt) {
8743 using std::begin;
8744 using std::end;
8745 return from_range( begin( cnt ), end( cnt ) );
8746}
8747
8748
8749} // namespace Generators
8750} // namespace Catch
8751
8752
8753#endif // CATCH_GENERATORS_RANGE_HPP_INCLUDED
8754
8755#endif // CATCH_GENERATORS_ALL_HPP_INCLUDED
8756
8757
8770
8771
8772#ifndef CATCH_INTERFACES_ALL_HPP_INCLUDED
8773#define CATCH_INTERFACES_ALL_HPP_INCLUDED
8774
8775
8776
8777#ifndef CATCH_INTERFACES_REPORTER_HPP_INCLUDED
8778#define CATCH_INTERFACES_REPORTER_HPP_INCLUDED
8779
8780
8781
8782#ifndef CATCH_TEST_RUN_INFO_HPP_INCLUDED
8783#define CATCH_TEST_RUN_INFO_HPP_INCLUDED
8784
8785
8786namespace Catch {
8787
8788 struct TestRunInfo {
8789 constexpr TestRunInfo(StringRef _name) : name(_name) {}
8790 StringRef name;
8791 };
8792
8793} // end namespace Catch
8794
8795#endif // CATCH_TEST_RUN_INFO_HPP_INCLUDED
8796
8797#include <map>
8798#include <string>
8799#include <vector>
8800#include <iosfwd>
8801
8802namespace Catch {
8803
8804 struct ReporterDescription;
8805 struct ListenerDescription;
8806 struct TagInfo;
8807 struct TestCaseInfo;
8808 class TestCaseHandle;
8809 class IConfig;
8810 class IStream;
8811 enum class ColourMode : std::uint8_t;
8812
8813 struct ReporterConfig {
8814 ReporterConfig( IConfig const* _fullConfig,
8815 Detail::unique_ptr<IStream> _stream,
8816 ColourMode colourMode,
8817 std::map<std::string, std::string> customOptions );
8818
8819 ReporterConfig( ReporterConfig&& ) = default;
8820 ReporterConfig& operator=( ReporterConfig&& ) = default;
8821 ~ReporterConfig(); // = default
8822
8823 Detail::unique_ptr<IStream> takeStream() &&;
8824 IConfig const* fullConfig() const;
8825 ColourMode colourMode() const;
8826 std::map<std::string, std::string> const& customOptions() const;
8827
8828 private:
8829 Detail::unique_ptr<IStream> m_stream;
8830 IConfig const* m_fullConfig;
8831 ColourMode m_colourMode;
8832 std::map<std::string, std::string> m_customOptions;
8833 };
8834
8835 struct AssertionStats {
8836 AssertionStats( AssertionResult const& _assertionResult,
8837 std::vector<MessageInfo> const& _infoMessages,
8838 Totals const& _totals );
8839
8840 AssertionStats( AssertionStats const& ) = default;
8841 AssertionStats( AssertionStats && ) = default;
8842 AssertionStats& operator = ( AssertionStats const& ) = delete;
8843 AssertionStats& operator = ( AssertionStats && ) = delete;
8844
8845 AssertionResult assertionResult;
8846 std::vector<MessageInfo> infoMessages;
8847 Totals totals;
8848 };
8849
8850 struct SectionStats {
8851 SectionStats( SectionInfo&& _sectionInfo,
8852 Counts const& _assertions,
8853 double _durationInSeconds,
8854 bool _missingAssertions );
8855
8856 SectionInfo sectionInfo;
8857 Counts assertions;
8858 double durationInSeconds;
8859 bool missingAssertions;
8860 };
8861
8862 struct TestCaseStats {
8863 TestCaseStats( TestCaseInfo const& _testInfo,
8864 Totals const& _totals,
8865 std::string&& _stdOut,
8866 std::string&& _stdErr,
8867 bool _aborting );
8868
8869 TestCaseInfo const * testInfo;
8870 Totals totals;
8871 std::string stdOut;
8872 std::string stdErr;
8873 bool aborting;
8874 };
8875
8876 struct TestRunStats {
8877 TestRunStats( TestRunInfo const& _runInfo,
8878 Totals const& _totals,
8879 bool _aborting );
8880
8881 TestRunInfo runInfo;
8882 Totals totals;
8883 bool aborting;
8884 };
8885
8889 struct ReporterPreferences {
8892 bool shouldRedirectStdOut = false;
8895 bool shouldReportAllAssertions = false;
8896 };
8897
8910 class IEventListener {
8911 protected:
8913 ReporterPreferences m_preferences;
8915 IConfig const* m_config;
8916
8917 public:
8918 IEventListener( IConfig const* config ): m_config( config ) {}
8919
8920 virtual ~IEventListener(); // = default;
8921
8922 // Implementing class must also provide the following static methods:
8923 // static std::string getDescription();
8924
8925 ReporterPreferences const& getPreferences() const {
8926 return m_preferences;
8927 }
8928
8930 virtual void noMatchingTestCases( StringRef unmatchedSpec ) = 0;
8932 virtual void reportInvalidTestSpec( StringRef invalidArgument ) = 0;
8933
8939 virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
8940
8942 virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
8944 virtual void testCasePartialStarting( TestCaseInfo const& testInfo, uint64_t partNumber ) = 0;
8946 virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
8947
8949 virtual void benchmarkPreparing( StringRef benchmarkName ) = 0;
8951 virtual void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) = 0;
8953 virtual void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) = 0;
8955 virtual void benchmarkFailed( StringRef benchmarkName ) = 0;
8956
8958 virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
8959
8961 virtual void assertionEnded( AssertionStats const& assertionStats ) = 0;
8962
8964 virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
8966 virtual void testCasePartialEnded(TestCaseStats const& testCaseStats, uint64_t partNumber ) = 0;
8968 virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
8974 virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
8975
8982 virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
8983
8985 virtual void fatalErrorEncountered( StringRef error ) = 0;
8986
8988 virtual void listReporters(std::vector<ReporterDescription> const& descriptions) = 0;
8990 virtual void listListeners(std::vector<ListenerDescription> const& descriptions) = 0;
8992 virtual void listTests(std::vector<TestCaseHandle> const& tests) = 0;
8994 virtual void listTags(std::vector<TagInfo> const& tags) = 0;
8995 };
8996 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
8997
8998} // end namespace Catch
8999
9000#endif // CATCH_INTERFACES_REPORTER_HPP_INCLUDED
9001
9002
9003#ifndef CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
9004#define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
9005
9006
9007#include <string>
9008
9009namespace Catch {
9010
9011 struct ReporterConfig;
9012 class IConfig;
9013 class IEventListener;
9014 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
9015
9016
9017 class IReporterFactory {
9018 public:
9019 virtual ~IReporterFactory(); // = default
9020
9021 virtual IEventListenerPtr
9022 create( ReporterConfig&& config ) const = 0;
9023 virtual std::string getDescription() const = 0;
9024 };
9025 using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
9026
9027 class EventListenerFactory {
9028 public:
9029 virtual ~EventListenerFactory(); // = default
9030 virtual IEventListenerPtr create( IConfig const* config ) const = 0;
9032 virtual StringRef getName() const = 0;
9034 virtual std::string getDescription() const = 0;
9035 };
9036} // namespace Catch
9037
9038#endif // CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
9039
9040
9041#ifndef CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9042#define CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9043
9044#include <string>
9045
9046namespace Catch {
9047
9048 struct TagAlias;
9049
9050 class ITagAliasRegistry {
9051 public:
9052 virtual ~ITagAliasRegistry(); // = default
9053 // Nullptr if not present
9054 virtual TagAlias const* find( std::string const& alias ) const = 0;
9055 virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
9056
9057 static ITagAliasRegistry const& get();
9058 };
9059
9060} // end namespace Catch
9061
9062#endif // CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9063
9064
9065#ifndef CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
9066#define CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
9067
9068#include <vector>
9069
9070namespace Catch {
9071
9072 struct TestCaseInfo;
9073 class TestCaseHandle;
9074 class IConfig;
9075
9076 class ITestCaseRegistry {
9077 public:
9078 virtual ~ITestCaseRegistry(); // = default
9079 // TODO: this exists only for adding filenames to test cases -- let's expose this in a saner way later
9080 virtual std::vector<TestCaseInfo* > const& getAllInfos() const = 0;
9081 virtual std::vector<TestCaseHandle> const& getAllTests() const = 0;
9082 virtual std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const = 0;
9083 };
9084
9085}
9086
9087#endif // CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
9088
9089#endif // CATCH_INTERFACES_ALL_HPP_INCLUDED
9090
9091
9092#ifndef CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
9093#define CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
9094
9095
9096namespace Catch {
9097 namespace Detail {
9099 struct CaseInsensitiveLess {
9100 bool operator()( StringRef lhs,
9101 StringRef rhs ) const;
9102 };
9103
9105 struct CaseInsensitiveEqualTo {
9106 bool operator()( StringRef lhs,
9107 StringRef rhs ) const;
9108 };
9109
9110 } // namespace Detail
9111} // namespace Catch
9112
9113#endif // CATCH_CASE_INSENSITIVE_COMPARISONS_HPP_INCLUDED
9114
9115
9116
9124
9125#ifndef CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
9126#define CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
9127
9128
9129#if defined(__ANDROID__)
9130# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
9131#endif
9132
9133
9134#if defined( CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE ) && \
9135 !defined( CATCH_CONFIG_NO_ANDROID_LOGWRITE ) && \
9136 !defined( CATCH_CONFIG_ANDROID_LOGWRITE )
9137# define CATCH_CONFIG_ANDROID_LOGWRITE
9138#endif
9139
9140#endif // CATCH_CONFIG_ANDROID_LOGWRITE_HPP_INCLUDED
9141
9142
9143
9151
9152#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9153#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9154
9155
9156#if defined(_MSC_VER)
9157# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
9158# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
9159# endif
9160#endif
9161
9162
9163#include <exception>
9164
9165#if defined(__cpp_lib_uncaught_exceptions) \
9166 && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
9167
9168# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
9169#endif // __cpp_lib_uncaught_exceptions
9170
9171
9172#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
9173 && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
9174 && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
9175
9176# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
9177#endif
9178
9179
9180#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
9181
9182
9183#ifndef CATCH_CONSOLE_COLOUR_HPP_INCLUDED
9184#define CATCH_CONSOLE_COLOUR_HPP_INCLUDED
9185
9186
9187#include <iosfwd>
9188#include <cstdint>
9189
9190namespace Catch {
9191
9192 enum class ColourMode : std::uint8_t;
9193 class IStream;
9194
9195 struct Colour {
9196 enum Code {
9197 None = 0,
9198
9199 White,
9200 Red,
9201 Green,
9202 Blue,
9203 Cyan,
9204 Yellow,
9205 Grey,
9206
9207 Bright = 0x10,
9208
9209 BrightRed = Bright | Red,
9210 BrightGreen = Bright | Green,
9211 LightGrey = Bright | Grey,
9212 BrightWhite = Bright | White,
9213 BrightYellow = Bright | Yellow,
9214
9215 // By intention
9216 FileName = LightGrey,
9217 Warning = BrightYellow,
9218 ResultError = BrightRed,
9219 ResultSuccess = BrightGreen,
9220 ResultExpectedFailure = Warning,
9221
9222 Error = BrightRed,
9223 Success = Green,
9224 Skip = LightGrey,
9225
9226 OriginalExpression = Cyan,
9227 ReconstructedExpression = BrightYellow,
9228
9229 SecondaryText = LightGrey,
9230 Headers = White
9231 };
9232 };
9233
9234 class ColourImpl {
9235 protected:
9237 IStream* m_stream;
9238 public:
9239 ColourImpl( IStream* stream ): m_stream( stream ) {}
9240
9243 class ColourGuard {
9244 ColourImpl const* m_colourImpl;
9245 Colour::Code m_code;
9246 bool m_engaged = false;
9247
9248 public:
9250 ColourGuard( Colour::Code code,
9251 ColourImpl const* colour );
9252
9253 ColourGuard( ColourGuard const& rhs ) = delete;
9254 ColourGuard& operator=( ColourGuard const& rhs ) = delete;
9255
9256 ColourGuard( ColourGuard&& rhs ) noexcept;
9257 ColourGuard& operator=( ColourGuard&& rhs ) noexcept;
9258
9260 ~ColourGuard();
9261
9267 ColourGuard& engage( std::ostream& stream ) &;
9273 ColourGuard&& engage( std::ostream& stream ) &&;
9274
9275 private:
9277 friend std::ostream& operator<<( std::ostream& lhs,
9278 ColourGuard& guard ) {
9279 guard.engageImpl( lhs );
9280 return lhs;
9281 }
9283 friend std::ostream& operator<<( std::ostream& lhs,
9284 ColourGuard&& guard) {
9285 guard.engageImpl( lhs );
9286 return lhs;
9287 }
9288
9289 void engageImpl( std::ostream& stream );
9290
9291 };
9292
9293 virtual ~ColourImpl(); // = default
9300 ColourGuard guardColour( Colour::Code colourCode );
9301
9302 private:
9303 virtual void use( Colour::Code colourCode ) const = 0;
9304 };
9305
9307 Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
9308 IStream* stream );
9309
9311 bool isColourImplAvailable( ColourMode colourSelection );
9312
9313} // end namespace Catch
9314
9315#endif // CATCH_CONSOLE_COLOUR_HPP_INCLUDED
9316
9317
9318#ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
9319#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
9320
9321// This include must be kept so that user's configured value for CONSOLE_WIDTH
9322// is used before we attempt to provide a default value
9323
9324#ifndef CATCH_CONFIG_CONSOLE_WIDTH
9325#define CATCH_CONFIG_CONSOLE_WIDTH 80
9326#endif
9327
9328#endif // CATCH_CONSOLE_WIDTH_HPP_INCLUDED
9329
9330
9331#ifndef CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
9332#define CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
9333
9334
9335#include <cstddef>
9336#include <initializer_list>
9337
9338// We want a simple polyfill over `std::empty`, `std::size` and so on
9339// for C++14 or C++ libraries with incomplete support.
9340// We also have to handle that MSVC std lib will happily provide these
9341// under older standards.
9342#if defined(CATCH_CPP17_OR_GREATER) || defined(_MSC_VER)
9343
9344// We are already using this header either way, so there shouldn't
9345// be much additional overhead in including it to get the feature
9346// test macros
9347#include <string>
9348
9349# if !defined(__cpp_lib_nonmember_container_access)
9350# define CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
9351# endif
9352
9353#else
9354#define CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
9355#endif
9356
9357
9358
9359namespace Catch {
9360namespace Detail {
9361
9362#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
9363 template <typename Container>
9364 constexpr auto empty(Container const& cont) -> decltype(cont.empty()) {
9365 return cont.empty();
9366 }
9367 template <typename T, std::size_t N>
9368 constexpr bool empty(const T (&)[N]) noexcept {
9369 // GCC < 7 does not support the const T(&)[] parameter syntax
9370 // so we have to ignore the length explicitly
9371 (void)N;
9372 return false;
9373 }
9374 template <typename T>
9375 constexpr bool empty(std::initializer_list<T> list) noexcept {
9376 return list.size() > 0;
9377 }
9378
9379
9380 template <typename Container>
9381 constexpr auto size(Container const& cont) -> decltype(cont.size()) {
9382 return cont.size();
9383 }
9384 template <typename T, std::size_t N>
9385 constexpr std::size_t size(const T(&)[N]) noexcept {
9386 return N;
9387 }
9388#endif // CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS
9389
9390} // end namespace Detail
9391} // end namespace Catch
9392
9393
9394
9395#endif // CATCH_CONTAINER_NONMEMBERS_HPP_INCLUDED
9396
9397
9398#ifndef CATCH_DEBUG_CONSOLE_HPP_INCLUDED
9399#define CATCH_DEBUG_CONSOLE_HPP_INCLUDED
9400
9401#include <string>
9402
9403namespace Catch {
9404 void writeToDebugConsole( std::string const& text );
9405}
9406
9407#endif // CATCH_DEBUG_CONSOLE_HPP_INCLUDED
9408
9409
9410#ifndef CATCH_DEBUGGER_HPP_INCLUDED
9411#define CATCH_DEBUGGER_HPP_INCLUDED
9412
9413
9414namespace Catch {
9415 bool isDebuggerActive();
9416}
9417
9418#ifdef CATCH_PLATFORM_MAC
9419
9420 #if defined(__i386__) || defined(__x86_64__)
9421 #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
9422 #elif defined(__aarch64__)
9423 #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
9424 #elif defined(__POWERPC__)
9425 #define CATCH_TRAP() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
9426 : : : "memory","r0","r3","r4" ) /* NOLINT */
9427 #endif
9428
9429#elif defined(CATCH_PLATFORM_IPHONE)
9430
9431 // use inline assembler
9432 #if defined(__i386__) || defined(__x86_64__)
9433 #define CATCH_TRAP() __asm__("int $3")
9434 #elif defined(__aarch64__)
9435 #define CATCH_TRAP() __asm__(".inst 0xd4200000")
9436 #elif defined(__arm__) && !defined(__thumb__)
9437 #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
9438 #elif defined(__arm__) && defined(__thumb__)
9439 #define CATCH_TRAP() __asm__(".inst 0xde01")
9440 #endif
9441
9442#elif defined(CATCH_PLATFORM_LINUX)
9443 // If we can use inline assembler, do it because this allows us to break
9444 // directly at the location of the failing check instead of breaking inside
9445 // raise() called from it, i.e. one stack frame below.
9446 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
9447 #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
9448 #else // Fall back to the generic way.
9449 #include <signal.h>
9450
9451 #define CATCH_TRAP() raise(SIGTRAP)
9452 #endif
9453#elif defined(_MSC_VER)
9454 #define CATCH_TRAP() __debugbreak()
9455#elif defined(__MINGW32__)
9456 extern "C" __declspec(dllimport) void __stdcall DebugBreak();
9457 #define CATCH_TRAP() DebugBreak()
9458#endif
9459
9460#ifndef CATCH_BREAK_INTO_DEBUGGER
9461 #ifdef CATCH_TRAP
9462 #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
9463 #else
9464 #define CATCH_BREAK_INTO_DEBUGGER() []{}()
9465 #endif
9466#endif
9467
9468#endif // CATCH_DEBUGGER_HPP_INCLUDED
9469
9470
9471#ifndef CATCH_ENFORCE_HPP_INCLUDED
9472#define CATCH_ENFORCE_HPP_INCLUDED
9473
9474
9475#include <exception>
9476
9477namespace Catch {
9478#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
9479 template <typename Ex>
9480 [[noreturn]]
9481 void throw_exception(Ex const& e) {
9482 throw e;
9483 }
9484#else // ^^ Exceptions are enabled // Exceptions are disabled vv
9485 [[noreturn]]
9486 void throw_exception(std::exception const& e);
9487#endif
9488
9489 [[noreturn]]
9490 void throw_logic_error(std::string const& msg);
9491 [[noreturn]]
9492 void throw_domain_error(std::string const& msg);
9493 [[noreturn]]
9494 void throw_runtime_error(std::string const& msg);
9495
9496} // namespace Catch;
9497
9498#define CATCH_MAKE_MSG(...) \
9499 (Catch::ReusableStringStream() << __VA_ARGS__).str()
9500
9501#define CATCH_INTERNAL_ERROR(...) \
9502 Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
9503
9504#define CATCH_ERROR(...) \
9505 Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
9506
9507#define CATCH_RUNTIME_ERROR(...) \
9508 Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
9509
9510#define CATCH_ENFORCE( condition, ... ) \
9511 do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
9512
9513
9514#endif // CATCH_ENFORCE_HPP_INCLUDED
9515
9516
9517#ifndef CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
9518#define CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
9519
9520
9521#include <vector>
9522
9523namespace Catch {
9524
9525 namespace Detail {
9526
9527 Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
9528
9529 class EnumValuesRegistry : public IMutableEnumValuesRegistry {
9530
9531 std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
9532
9533 EnumInfo const& registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values) override;
9534 };
9535
9536 std::vector<StringRef> parseEnums( StringRef enums );
9537
9538 } // Detail
9539
9540} // Catch
9541
9542#endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
9543
9544
9545#ifndef CATCH_ERRNO_GUARD_HPP_INCLUDED
9546#define CATCH_ERRNO_GUARD_HPP_INCLUDED
9547
9548namespace Catch {
9549
9552 class ErrnoGuard {
9553 public:
9554 // Keep these outlined to avoid dragging in macros from <cerrno>
9555
9556 ErrnoGuard();
9557 ~ErrnoGuard();
9558 private:
9559 int m_oldErrno;
9560 };
9561
9562}
9563
9564#endif // CATCH_ERRNO_GUARD_HPP_INCLUDED
9565
9566
9567#ifndef CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
9568#define CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
9569
9570
9571#include <vector>
9572#include <string>
9573
9574namespace Catch {
9575
9576 class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
9577 public:
9578 ~ExceptionTranslatorRegistry() override;
9579 void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator );
9580 std::string translateActiveException() const override;
9581
9582 private:
9583 ExceptionTranslators m_translators;
9584 };
9585}
9586
9587#endif // CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
9588
9589
9590#ifndef CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
9591#define CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
9592
9593#include <cassert>
9594
9595namespace Catch {
9596
9607 class FatalConditionHandler {
9608 bool m_started = false;
9609
9610 // Install/disengage implementation for specific platform.
9611 // Should be if-defed to work on current platform, can assume
9612 // engage-disengage 1:1 pairing.
9613 void engage_platform();
9614 void disengage_platform() noexcept;
9615 public:
9616 // Should also have platform-specific implementations as needed
9617 FatalConditionHandler();
9618 ~FatalConditionHandler();
9619
9620 void engage() {
9621 assert(!m_started && "Handler cannot be installed twice.");
9622 m_started = true;
9623 engage_platform();
9624 }
9625
9626 void disengage() noexcept {
9627 assert(m_started && "Handler cannot be uninstalled without being installed first");
9628 m_started = false;
9629 disengage_platform();
9630 }
9631 };
9632
9634 class FatalConditionHandlerGuard {
9635 FatalConditionHandler* m_handler;
9636 public:
9637 FatalConditionHandlerGuard(FatalConditionHandler* handler):
9638 m_handler(handler) {
9639 m_handler->engage();
9640 }
9641 ~FatalConditionHandlerGuard() {
9642 m_handler->disengage();
9643 }
9644 };
9645
9646} // end namespace Catch
9647
9648#endif // CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
9649
9650
9651#ifndef CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
9652#define CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
9653
9654
9655#include <cassert>
9656#include <cmath>
9657#include <cstdint>
9658#include <utility>
9659#include <limits>
9660
9661namespace Catch {
9662 namespace Detail {
9663
9664 uint32_t convertToBits(float f);
9665 uint64_t convertToBits(double d);
9666
9667 // Used when we know we want == comparison of two doubles
9668 // to centralize warning suppression
9669 bool directCompare( float lhs, float rhs );
9670 bool directCompare( double lhs, double rhs );
9671
9672 } // end namespace Detail
9673
9674
9675
9676#if defined( __GNUC__ ) || defined( __clang__ )
9677# pragma GCC diagnostic push
9678 // We do a bunch of direct compensations of floating point numbers,
9679 // because we know what we are doing and actually do want the direct
9680 // comparison behaviour.
9681# pragma GCC diagnostic ignored "-Wfloat-equal"
9682#endif
9683
9701 template <typename FP>
9702 uint64_t ulpDistance( FP lhs, FP rhs ) {
9703 assert( std::numeric_limits<FP>::is_iec559 &&
9704 "ulpDistance assumes IEEE-754 format for floating point types" );
9705 assert( !Catch::isnan( lhs ) &&
9706 "Distance between NaN and number is not meaningful" );
9707 assert( !Catch::isnan( rhs ) &&
9708 "Distance between NaN and number is not meaningful" );
9709
9710 // We want X == Y to imply 0 ULP distance even if X and Y aren't
9711 // bit-equal (-0 and 0), or X - Y != 0 (same sign infinities).
9712 if ( lhs == rhs ) { return 0; }
9713
9714 // We need a properly typed positive zero for type inference.
9715 static constexpr FP positive_zero{};
9716
9717 // We want to ensure that +/- 0 is always represented as positive zero
9718 if ( lhs == positive_zero ) { lhs = positive_zero; }
9719 if ( rhs == positive_zero ) { rhs = positive_zero; }
9720
9721 // If arguments have different signs, we can handle them by summing
9722 // how far are they from 0 each.
9723 if ( std::signbit( lhs ) != std::signbit( rhs ) ) {
9724 return ulpDistance( std::abs( lhs ), positive_zero ) +
9725 ulpDistance( std::abs( rhs ), positive_zero );
9726 }
9727
9728 // When both lhs and rhs are of the same sign, we can just
9729 // read the numbers bitwise as integers, and then subtract them
9730 // (assuming IEEE).
9731 uint64_t lc = Detail::convertToBits( lhs );
9732 uint64_t rc = Detail::convertToBits( rhs );
9733
9734 // The ulp distance between two numbers is symmetric, so to avoid
9735 // dealing with overflows we want the bigger converted number on the lhs
9736 if ( lc < rc ) {
9737 std::swap( lc, rc );
9738 }
9739
9740 return lc - rc;
9741 }
9742
9743#if defined( __GNUC__ ) || defined( __clang__ )
9744# pragma GCC diagnostic pop
9745#endif
9746
9747
9748} // end namespace Catch
9749
9750#endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
9751
9752
9753#ifndef CATCH_GETENV_HPP_INCLUDED
9754#define CATCH_GETENV_HPP_INCLUDED
9755
9756namespace Catch {
9757namespace Detail {
9758
9760 char const* getEnv(char const* varName);
9761
9762}
9763}
9764
9765#endif // CATCH_GETENV_HPP_INCLUDED
9766
9767
9768#ifndef CATCH_IS_PERMUTATION_HPP_INCLUDED
9769#define CATCH_IS_PERMUTATION_HPP_INCLUDED
9770
9771#include <algorithm>
9772#include <iterator>
9773
9774namespace Catch {
9775 namespace Detail {
9776
9777 template <typename ForwardIter,
9778 typename Sentinel,
9779 typename T,
9780 typename Comparator>
9781 constexpr
9782 ForwardIter find_sentinel( ForwardIter start,
9783 Sentinel sentinel,
9784 T const& value,
9785 Comparator cmp ) {
9786 while ( start != sentinel ) {
9787 if ( cmp( *start, value ) ) { break; }
9788 ++start;
9789 }
9790 return start;
9791 }
9792
9793 template <typename ForwardIter,
9794 typename Sentinel,
9795 typename T,
9796 typename Comparator>
9797 constexpr
9798 std::ptrdiff_t count_sentinel( ForwardIter start,
9799 Sentinel sentinel,
9800 T const& value,
9801 Comparator cmp ) {
9802 std::ptrdiff_t count = 0;
9803 while ( start != sentinel ) {
9804 if ( cmp( *start, value ) ) { ++count; }
9805 ++start;
9806 }
9807 return count;
9808 }
9809
9810 template <typename ForwardIter, typename Sentinel>
9811 constexpr
9812 std::enable_if_t<!std::is_same<ForwardIter, Sentinel>::value,
9813 std::ptrdiff_t>
9814 sentinel_distance( ForwardIter iter, const Sentinel sentinel ) {
9815 std::ptrdiff_t dist = 0;
9816 while ( iter != sentinel ) {
9817 ++iter;
9818 ++dist;
9819 }
9820 return dist;
9821 }
9822
9823 template <typename ForwardIter>
9824 constexpr std::ptrdiff_t sentinel_distance( ForwardIter first,
9825 ForwardIter last ) {
9826 return std::distance( first, last );
9827 }
9828
9829 template <typename ForwardIter1,
9830 typename Sentinel1,
9831 typename ForwardIter2,
9832 typename Sentinel2,
9833 typename Comparator>
9834 constexpr bool check_element_counts( ForwardIter1 first_1,
9835 const Sentinel1 end_1,
9836 ForwardIter2 first_2,
9837 const Sentinel2 end_2,
9838 Comparator cmp ) {
9839 auto cursor = first_1;
9840 while ( cursor != end_1 ) {
9841 if ( find_sentinel( first_1, cursor, *cursor, cmp ) ==
9842 cursor ) {
9843 // we haven't checked this element yet
9844 const auto count_in_range_2 =
9845 count_sentinel( first_2, end_2, *cursor, cmp );
9846 // Not a single instance in 2nd range, so it cannot be a
9847 // permutation of 1st range
9848 if ( count_in_range_2 == 0 ) { return false; }
9849
9850 const auto count_in_range_1 =
9851 count_sentinel( cursor, end_1, *cursor, cmp );
9852 if ( count_in_range_1 != count_in_range_2 ) {
9853 return false;
9854 }
9855 }
9856
9857 ++cursor;
9858 }
9859
9860 return true;
9861 }
9862
9863 template <typename ForwardIter1,
9864 typename Sentinel1,
9865 typename ForwardIter2,
9866 typename Sentinel2,
9867 typename Comparator>
9868 constexpr bool is_permutation( ForwardIter1 first_1,
9869 const Sentinel1 end_1,
9870 ForwardIter2 first_2,
9871 const Sentinel2 end_2,
9872 Comparator cmp ) {
9873 // TODO: no optimization for stronger iterators, because we would also have to constrain on sentinel vs not sentinel types
9874 // TODO: Comparator has to be "both sides", e.g. a == b => b == a
9875 // This skips shared prefix of the two ranges
9876 while (first_1 != end_1 && first_2 != end_2 && cmp(*first_1, *first_2)) {
9877 ++first_1;
9878 ++first_2;
9879 }
9880
9881 // We need to handle case where at least one of the ranges has no more elements
9882 if (first_1 == end_1 || first_2 == end_2) {
9883 return first_1 == end_1 && first_2 == end_2;
9884 }
9885
9886 // pair counting is n**2, so we pay linear walk to compare the sizes first
9887 auto dist_1 = sentinel_distance( first_1, end_1 );
9888 auto dist_2 = sentinel_distance( first_2, end_2 );
9889
9890 if (dist_1 != dist_2) { return false; }
9891
9892 // Since we do not try to handle stronger iterators pair (e.g.
9893 // bidir) optimally, the only thing left to do is to check counts in
9894 // the remaining ranges.
9895 return check_element_counts( first_1, end_1, first_2, end_2, cmp );
9896 }
9897
9898 } // namespace Detail
9899} // namespace Catch
9900
9901#endif // CATCH_IS_PERMUTATION_HPP_INCLUDED
9902
9903
9904#ifndef CATCH_ISTREAM_HPP_INCLUDED
9905#define CATCH_ISTREAM_HPP_INCLUDED
9906
9907
9908#include <iosfwd>
9909#include <cstddef>
9910#include <ostream>
9911#include <string>
9912
9913namespace Catch {
9914
9915 class IStream {
9916 public:
9917 virtual ~IStream(); // = default
9918 virtual std::ostream& stream() = 0;
9930 virtual bool isConsole() const { return false; }
9931 };
9932
9944 auto makeStream( std::string const& filename ) -> Detail::unique_ptr<IStream>;
9945
9946}
9947
9948#endif // CATCH_STREAM_HPP_INCLUDED
9949
9950
9951#ifndef CATCH_JSONWRITER_HPP_INCLUDED
9952#define CATCH_JSONWRITER_HPP_INCLUDED
9953
9954
9955#include <cstdint>
9956#include <sstream>
9957
9958namespace Catch {
9959 class JsonObjectWriter;
9960 class JsonArrayWriter;
9961
9962 struct JsonUtils {
9963 static void indent( std::ostream& os, std::uint64_t level );
9964 static void appendCommaNewline( std::ostream& os,
9965 bool& should_comma,
9966 std::uint64_t level );
9967 };
9968
9969 class JsonValueWriter {
9970 public:
9971 JsonValueWriter( std::ostream& os );
9972 JsonValueWriter( std::ostream& os, std::uint64_t indent_level );
9973
9974 JsonObjectWriter writeObject() &&;
9975 JsonArrayWriter writeArray() &&;
9976
9977 template <typename T>
9978 void write( T const& value ) && {
9979 writeImpl( value, !std::is_arithmetic<T>::value );
9980 }
9981 void write( StringRef value ) &&;
9982 void write( bool value ) &&;
9983
9984 private:
9985 void writeImpl( StringRef value, bool quote );
9986
9987 // Without this SFINAE, this overload is a better match
9988 // for `std::string`, `char const*`, `char const[N]` args.
9989 // While it would still work, it would cause code bloat
9990 // and multiple iteration over the strings
9991 template <typename T,
9992 typename = typename std::enable_if_t<
9993 !std::is_convertible<T, StringRef>::value>>
9994 void writeImpl( T const& value, bool quote_value ) {
9995 m_sstream << value;
9996 writeImpl( m_sstream.str(), quote_value );
9997 }
9998
9999 std::ostream& m_os;
10000 std::stringstream m_sstream;
10001 std::uint64_t m_indent_level;
10002 };
10003
10004 class JsonObjectWriter {
10005 public:
10006 JsonObjectWriter( std::ostream& os );
10007 JsonObjectWriter( std::ostream& os, std::uint64_t indent_level );
10008
10009 JsonObjectWriter( JsonObjectWriter&& source ) noexcept;
10010 JsonObjectWriter& operator=( JsonObjectWriter&& source ) = delete;
10011
10012 ~JsonObjectWriter();
10013
10014 JsonValueWriter write( StringRef key );
10015
10016 private:
10017 std::ostream& m_os;
10018 std::uint64_t m_indent_level;
10019 bool m_should_comma = false;
10020 bool m_active = true;
10021 };
10022
10023 class JsonArrayWriter {
10024 public:
10025 JsonArrayWriter( std::ostream& os );
10026 JsonArrayWriter( std::ostream& os, std::uint64_t indent_level );
10027
10028 JsonArrayWriter( JsonArrayWriter&& source ) noexcept;
10029 JsonArrayWriter& operator=( JsonArrayWriter&& source ) = delete;
10030
10031 ~JsonArrayWriter();
10032
10033 JsonObjectWriter writeObject();
10034 JsonArrayWriter writeArray();
10035
10036 template <typename T>
10037 JsonArrayWriter& write( T const& value ) {
10038 return writeImpl( value );
10039 }
10040
10041 JsonArrayWriter& write( bool value );
10042
10043 private:
10044 template <typename T>
10045 JsonArrayWriter& writeImpl( T const& value ) {
10046 JsonUtils::appendCommaNewline(
10047 m_os, m_should_comma, m_indent_level + 1 );
10048 JsonValueWriter{ m_os }.write( value );
10049
10050 return *this;
10051 }
10052
10053 std::ostream& m_os;
10054 std::uint64_t m_indent_level;
10055 bool m_should_comma = false;
10056 bool m_active = true;
10057 };
10058
10059} // namespace Catch
10060
10061#endif // CATCH_JSONWRITER_HPP_INCLUDED
10062
10063
10064#ifndef CATCH_LEAK_DETECTOR_HPP_INCLUDED
10065#define CATCH_LEAK_DETECTOR_HPP_INCLUDED
10066
10067namespace Catch {
10068
10069 struct LeakDetector {
10070 LeakDetector();
10071 ~LeakDetector();
10072 };
10073
10074}
10075#endif // CATCH_LEAK_DETECTOR_HPP_INCLUDED
10076
10077
10078#ifndef CATCH_LIST_HPP_INCLUDED
10079#define CATCH_LIST_HPP_INCLUDED
10080
10081
10082#include <set>
10083#include <string>
10084
10085
10086namespace Catch {
10087
10088 class IEventListener;
10089 class Config;
10090
10091
10092 struct ReporterDescription {
10093 std::string name, description;
10094 };
10095 struct ListenerDescription {
10096 StringRef name;
10097 std::string description;
10098 };
10099
10100 struct TagInfo {
10101 void add(StringRef spelling);
10102 std::string all() const;
10103
10104 std::set<StringRef> spellings;
10105 std::size_t count = 0;
10106 };
10107
10108 bool list( IEventListener& reporter, Config const& config );
10109
10110} // end namespace Catch
10111
10112#endif // CATCH_LIST_HPP_INCLUDED
10113
10114
10115#ifndef CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
10116#define CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
10117
10118
10119#include <cassert>
10120#include <string>
10121
10122namespace Catch {
10123
10124 class OutputRedirect {
10125 bool m_redirectActive = false;
10126 virtual void activateImpl() = 0;
10127 virtual void deactivateImpl() = 0;
10128 public:
10129 enum Kind {
10131 None,
10133 Streams,
10135 FileDescriptors,
10136 };
10137
10138 virtual ~OutputRedirect(); // = default;
10139
10140 // TODO: Do we want to check that redirect is not active before retrieving the output?
10141 virtual std::string getStdout() = 0;
10142 virtual std::string getStderr() = 0;
10143 virtual void clearBuffers() = 0;
10144 bool isActive() const { return m_redirectActive; }
10145 void activate() {
10146 assert( !m_redirectActive && "redirect is already active" );
10147 activateImpl();
10148 m_redirectActive = true;
10149 }
10150 void deactivate() {
10151 assert( m_redirectActive && "redirect is not active" );
10152 deactivateImpl();
10153 m_redirectActive = false;
10154 }
10155 };
10156
10157 bool isRedirectAvailable( OutputRedirect::Kind kind);
10158 Detail::unique_ptr<OutputRedirect> makeOutputRedirect( bool actual );
10159
10160 class RedirectGuard {
10161 OutputRedirect* m_redirect;
10162 bool m_activate;
10163 bool m_previouslyActive;
10164 bool m_moved = false;
10165
10166 public:
10167 RedirectGuard( bool activate, OutputRedirect& redirectImpl );
10168 ~RedirectGuard() noexcept( false );
10169
10170 RedirectGuard( RedirectGuard const& ) = delete;
10171 RedirectGuard& operator=( RedirectGuard const& ) = delete;
10172
10173 // C++14 needs move-able guards to return them from functions
10174 RedirectGuard( RedirectGuard&& rhs ) noexcept;
10175 RedirectGuard& operator=( RedirectGuard&& rhs ) noexcept;
10176 };
10177
10178 RedirectGuard scopedActivate( OutputRedirect& redirectImpl );
10179 RedirectGuard scopedDeactivate( OutputRedirect& redirectImpl );
10180
10181} // end namespace Catch
10182
10183#endif // CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
10184
10185
10186#ifndef CATCH_PARSE_NUMBERS_HPP_INCLUDED
10187#define CATCH_PARSE_NUMBERS_HPP_INCLUDED
10188
10189
10190#include <string>
10191
10192namespace Catch {
10193
10200 Optional<unsigned int> parseUInt(std::string const& input, int base = 10);
10201}
10202
10203#endif // CATCH_PARSE_NUMBERS_HPP_INCLUDED
10204
10205
10206#ifndef CATCH_REPORTER_REGISTRY_HPP_INCLUDED
10207#define CATCH_REPORTER_REGISTRY_HPP_INCLUDED
10208
10209
10210#include <map>
10211#include <string>
10212#include <vector>
10213
10214namespace Catch {
10215
10216 class IEventListener;
10217 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
10218 class IReporterFactory;
10219 using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
10220 struct ReporterConfig;
10221 class EventListenerFactory;
10222
10223 class ReporterRegistry {
10224 struct ReporterRegistryImpl;
10225 Detail::unique_ptr<ReporterRegistryImpl> m_impl;
10226
10227 public:
10228 ReporterRegistry();
10229 ~ReporterRegistry(); // = default;
10230
10231 IEventListenerPtr create( std::string const& name,
10232 ReporterConfig&& config ) const;
10233
10234 void registerReporter( std::string const& name,
10235 IReporterFactoryPtr factory );
10236
10237 void
10238 registerListener( Detail::unique_ptr<EventListenerFactory> factory );
10239
10240 std::map<std::string,
10242 Detail::CaseInsensitiveLess> const&
10243 getFactories() const;
10244
10245 std::vector<Detail::unique_ptr<EventListenerFactory>> const&
10246 getListeners() const;
10247 };
10248
10249} // end namespace Catch
10250
10251#endif // CATCH_REPORTER_REGISTRY_HPP_INCLUDED
10252
10253
10254#ifndef CATCH_RUN_CONTEXT_HPP_INCLUDED
10255#define CATCH_RUN_CONTEXT_HPP_INCLUDED
10256
10257
10258
10259#ifndef CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
10260#define CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
10261
10262
10263#include <string>
10264#include <vector>
10265
10266namespace Catch {
10267namespace TestCaseTracking {
10268
10269 struct NameAndLocation {
10270 std::string name;
10271 SourceLineInfo location;
10272
10273 NameAndLocation( std::string&& _name, SourceLineInfo const& _location );
10274 friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
10275 // This is a very cheap check that should have a very high hit rate.
10276 // If we get to SourceLineInfo::operator==, we will redo it, but the
10277 // cost of repeating is trivial at that point (we will be paying
10278 // multiple strcmp/memcmps at that point).
10279 if ( lhs.location.line != rhs.location.line ) { return false; }
10280 return lhs.name == rhs.name && lhs.location == rhs.location;
10281 }
10282 friend bool operator!=(NameAndLocation const& lhs,
10283 NameAndLocation const& rhs) {
10284 return !( lhs == rhs );
10285 }
10286 };
10287
10295 struct NameAndLocationRef {
10296 StringRef name;
10297 SourceLineInfo location;
10298
10299 constexpr NameAndLocationRef( StringRef name_,
10300 SourceLineInfo location_ ):
10301 name( name_ ), location( location_ ) {}
10302
10303 friend bool operator==( NameAndLocation const& lhs,
10304 NameAndLocationRef const& rhs ) {
10305 // This is a very cheap check that should have a very high hit rate.
10306 // If we get to SourceLineInfo::operator==, we will redo it, but the
10307 // cost of repeating is trivial at that point (we will be paying
10308 // multiple strcmp/memcmps at that point).
10309 if ( lhs.location.line != rhs.location.line ) { return false; }
10310 return StringRef( lhs.name ) == rhs.name &&
10311 lhs.location == rhs.location;
10312 }
10313 friend bool operator==( NameAndLocationRef const& lhs,
10314 NameAndLocation const& rhs ) {
10315 return rhs == lhs;
10316 }
10317 };
10318
10319 class ITracker;
10320
10321 using ITrackerPtr = Catch::Detail::unique_ptr<ITracker>;
10322
10323 class ITracker {
10324 NameAndLocation m_nameAndLocation;
10325
10326 using Children = std::vector<ITrackerPtr>;
10327
10328 protected:
10329 enum CycleState {
10330 NotStarted,
10331 Executing,
10332 ExecutingChildren,
10333 NeedsAnotherRun,
10334 CompletedSuccessfully,
10335 Failed
10336 };
10337
10338 ITracker* m_parent = nullptr;
10339 Children m_children;
10340 CycleState m_runState = NotStarted;
10341
10342 public:
10343 ITracker( NameAndLocation&& nameAndLoc, ITracker* parent ):
10344 m_nameAndLocation( CATCH_MOVE(nameAndLoc) ),
10345 m_parent( parent )
10346 {}
10347
10348
10349 // static queries
10350 NameAndLocation const& nameAndLocation() const {
10351 return m_nameAndLocation;
10352 }
10353 ITracker* parent() const {
10354 return m_parent;
10355 }
10356
10357 virtual ~ITracker(); // = default
10358
10359
10360 // dynamic queries
10361
10363 virtual bool isComplete() const = 0;
10365 bool isSuccessfullyCompleted() const {
10366 return m_runState == CompletedSuccessfully;
10367 }
10369 bool isOpen() const;
10371 bool hasStarted() const;
10372
10373 // actions
10374 virtual void close() = 0; // Successfully complete
10375 virtual void fail() = 0;
10376 void markAsNeedingAnotherRun();
10377
10379 void addChild( ITrackerPtr&& child );
10385 ITracker* findChild( NameAndLocationRef const& nameAndLocation );
10387 bool hasChildren() const {
10388 return !m_children.empty();
10389 }
10390
10391
10393 void openChild();
10394
10401 virtual bool isSectionTracker() const;
10408 virtual bool isGeneratorTracker() const;
10409 };
10410
10411 class TrackerContext {
10412
10413 enum RunState {
10414 NotStarted,
10415 Executing,
10416 CompletedCycle
10417 };
10418
10419 ITrackerPtr m_rootTracker;
10420 ITracker* m_currentTracker = nullptr;
10421 RunState m_runState = NotStarted;
10422
10423 public:
10424
10425 ITracker& startRun();
10426
10427 void startCycle() {
10428 m_currentTracker = m_rootTracker.get();
10429 m_runState = Executing;
10430 }
10431 void completeCycle();
10432
10433 bool completedCycle() const;
10434 ITracker& currentTracker() { return *m_currentTracker; }
10435 void setCurrentTracker( ITracker* tracker );
10436 };
10437
10438 class TrackerBase : public ITracker {
10439 protected:
10440
10441 TrackerContext& m_ctx;
10442
10443 public:
10444 TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent );
10445
10446 bool isComplete() const override;
10447
10448 void open();
10449
10450 void close() override;
10451 void fail() override;
10452
10453 private:
10454 void moveToParent();
10455 void moveToThis();
10456 };
10457
10458 class SectionTracker : public TrackerBase {
10459 std::vector<StringRef> m_filters;
10460 // Note that lifetime-wise we piggy back off the name stored in the `ITracker` parent`.
10461 // Currently it allocates owns the name, so this is safe. If it is later refactored
10462 // to not own the name, the name still has to outlive the `ITracker` parent, so
10463 // this should still be safe.
10464 StringRef m_trimmed_name;
10465 public:
10466 SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent );
10467
10468 bool isSectionTracker() const override;
10469
10470 bool isComplete() const override;
10471
10472 static SectionTracker& acquire( TrackerContext& ctx, NameAndLocationRef const& nameAndLocation );
10473
10474 void tryOpen();
10475
10476 void addInitialFilters( std::vector<std::string> const& filters );
10477 void addNextFilters( std::vector<StringRef> const& filters );
10479 std::vector<StringRef> const& getFilters() const { return m_filters; }
10481 StringRef trimmedName() const;
10482 };
10483
10484} // namespace TestCaseTracking
10485
10486using TestCaseTracking::ITracker;
10487using TestCaseTracking::TrackerContext;
10488using TestCaseTracking::SectionTracker;
10489
10490} // namespace Catch
10491
10492#endif // CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
10493
10494#include <string>
10495
10496namespace Catch {
10497
10498 class IGeneratorTracker;
10499 class IConfig;
10500 class IEventListener;
10501 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
10502 class OutputRedirect;
10503
10505
10506 class RunContext final : public IResultCapture {
10507
10508 public:
10509 RunContext( RunContext const& ) = delete;
10510 RunContext& operator =( RunContext const& ) = delete;
10511
10512 explicit RunContext( IConfig const* _config, IEventListenerPtr&& reporter );
10513
10514 ~RunContext() override;
10515
10516 Totals runTest(TestCaseHandle const& testCase);
10517
10518 public: // IResultCapture
10519
10520 // Assertion handlers
10521 void handleExpr
10522 ( AssertionInfo const& info,
10523 ITransientExpression const& expr,
10524 AssertionReaction& reaction ) override;
10525 void handleMessage
10526 ( AssertionInfo const& info,
10527 ResultWas::OfType resultType,
10528 std::string&& message,
10529 AssertionReaction& reaction ) override;
10530 void handleUnexpectedExceptionNotThrown
10531 ( AssertionInfo const& info,
10532 AssertionReaction& reaction ) override;
10533 void handleUnexpectedInflightException
10534 ( AssertionInfo const& info,
10535 std::string&& message,
10536 AssertionReaction& reaction ) override;
10537 void handleIncomplete
10538 ( AssertionInfo const& info ) override;
10539 void handleNonExpr
10540 ( AssertionInfo const &info,
10541 ResultWas::OfType resultType,
10542 AssertionReaction &reaction ) override;
10543
10544 void notifyAssertionStarted( AssertionInfo const& info ) override;
10545 bool sectionStarted( StringRef sectionName,
10546 SourceLineInfo const& sectionLineInfo,
10547 Counts& assertions ) override;
10548
10549 void sectionEnded( SectionEndInfo&& endInfo ) override;
10550 void sectionEndedEarly( SectionEndInfo&& endInfo ) override;
10551
10552 IGeneratorTracker*
10553 acquireGeneratorTracker( StringRef generatorName,
10554 SourceLineInfo const& lineInfo ) override;
10555 IGeneratorTracker* createGeneratorTracker(
10556 StringRef generatorName,
10557 SourceLineInfo lineInfo,
10558 Generators::GeneratorBasePtr&& generator ) override;
10559
10560
10561 void benchmarkPreparing( StringRef name ) override;
10562 void benchmarkStarting( BenchmarkInfo const& info ) override;
10563 void benchmarkEnded( BenchmarkStats<> const& stats ) override;
10564 void benchmarkFailed( StringRef error ) override;
10565
10566 void pushScopedMessage( MessageInfo const& message ) override;
10567 void popScopedMessage( MessageInfo const& message ) override;
10568
10569 void emplaceUnscopedMessage( MessageBuilder&& builder ) override;
10570
10571 std::string getCurrentTestName() const override;
10572
10573 const AssertionResult* getLastResult() const override;
10574
10575 void exceptionEarlyReported() override;
10576
10577 void handleFatalErrorCondition( StringRef message ) override;
10578
10579 bool lastAssertionPassed() override;
10580
10581 void assertionPassed() override;
10582
10583 public:
10584 // !TBD We need to do this another way!
10585 bool aborting() const;
10586
10587 private:
10588
10589 void runCurrentTest();
10590 void invokeActiveTestCase();
10591
10592 void resetAssertionInfo();
10593 bool testForMissingAssertions( Counts& assertions );
10594
10595 void assertionEnded( AssertionResult&& result );
10596 void reportExpr
10597 ( AssertionInfo const &info,
10598 ResultWas::OfType resultType,
10599 ITransientExpression const *expr,
10600 bool negated );
10601
10602 void populateReaction( AssertionReaction& reaction );
10603
10604 private:
10605
10606 void handleUnfinishedSections();
10607
10608 TestRunInfo m_runInfo;
10609 TestCaseHandle const* m_activeTestCase = nullptr;
10610 ITracker* m_testCaseTracker = nullptr;
10611 Optional<AssertionResult> m_lastResult;
10612
10613 IConfig const* m_config;
10614 Totals m_totals;
10615 IEventListenerPtr m_reporter;
10616 std::vector<MessageInfo> m_messages;
10617 std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
10618 AssertionInfo m_lastAssertionInfo;
10619 std::vector<SectionEndInfo> m_unfinishedSections;
10620 std::vector<ITracker*> m_activeSections;
10621 TrackerContext m_trackerContext;
10622 Detail::unique_ptr<OutputRedirect> m_outputRedirect;
10623 FatalConditionHandler m_fatalConditionhandler;
10624 bool m_lastAssertionPassed = false;
10625 bool m_shouldReportUnexpected = true;
10626 bool m_includeSuccessfulResults;
10627 };
10628
10629 void seedRng(IConfig const& config);
10630 unsigned int rngSeed();
10631} // end namespace Catch
10632
10633#endif // CATCH_RUN_CONTEXT_HPP_INCLUDED
10634
10635
10636#ifndef CATCH_SHARDING_HPP_INCLUDED
10637#define CATCH_SHARDING_HPP_INCLUDED
10638
10639#include <cassert>
10640#include <cmath>
10641#include <algorithm>
10642
10643namespace Catch {
10644
10645 template<typename Container>
10646 Container createShard(Container const& container, std::size_t const shardCount, std::size_t const shardIndex) {
10647 assert(shardCount > shardIndex);
10648
10649 if (shardCount == 1) {
10650 return container;
10651 }
10652
10653 const std::size_t totalTestCount = container.size();
10654
10655 const std::size_t shardSize = totalTestCount / shardCount;
10656 const std::size_t leftoverTests = totalTestCount % shardCount;
10657
10658 const std::size_t startIndex = shardIndex * shardSize + (std::min)(shardIndex, leftoverTests);
10659 const std::size_t endIndex = (shardIndex + 1) * shardSize + (std::min)(shardIndex + 1, leftoverTests);
10660
10661 auto startIterator = std::next(container.begin(), static_cast<std::ptrdiff_t>(startIndex));
10662 auto endIterator = std::next(container.begin(), static_cast<std::ptrdiff_t>(endIndex));
10663
10664 return Container(startIterator, endIterator);
10665 }
10666
10667}
10668
10669#endif // CATCH_SHARDING_HPP_INCLUDED
10670
10671
10672#ifndef CATCH_SINGLETONS_HPP_INCLUDED
10673#define CATCH_SINGLETONS_HPP_INCLUDED
10674
10675namespace Catch {
10676
10677 struct ISingleton {
10678 virtual ~ISingleton(); // = default
10679 };
10680
10681
10682 void addSingleton( ISingleton* singleton );
10683 void cleanupSingletons();
10684
10685
10686 template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
10687 class Singleton : SingletonImplT, public ISingleton {
10688
10689 static auto getInternal() -> Singleton* {
10690 static Singleton* s_instance = nullptr;
10691 if( !s_instance ) {
10692 s_instance = new Singleton;
10693 addSingleton( s_instance );
10694 }
10695 return s_instance;
10696 }
10697
10698 public:
10699 static auto get() -> InterfaceT const& {
10700 return *getInternal();
10701 }
10702 static auto getMutable() -> MutableInterfaceT& {
10703 return *getInternal();
10704 }
10705 };
10706
10707} // namespace Catch
10708
10709#endif // CATCH_SINGLETONS_HPP_INCLUDED
10710
10711
10712#ifndef CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
10713#define CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
10714
10715
10716#include <vector>
10717#include <exception>
10718
10719namespace Catch {
10720
10721 class StartupExceptionRegistry {
10722#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10723 public:
10724 void add(std::exception_ptr const& exception) noexcept;
10725 std::vector<std::exception_ptr> const& getExceptions() const noexcept;
10726 private:
10727 std::vector<std::exception_ptr> m_exceptions;
10728#endif
10729 };
10730
10731} // end namespace Catch
10732
10733#endif // CATCH_STARTUP_EXCEPTION_REGISTRY_HPP_INCLUDED
10734
10735
10736
10737#ifndef CATCH_STDSTREAMS_HPP_INCLUDED
10738#define CATCH_STDSTREAMS_HPP_INCLUDED
10739
10740#include <iosfwd>
10741
10742namespace Catch {
10743
10744 std::ostream& cout();
10745 std::ostream& cerr();
10746 std::ostream& clog();
10747
10748} // namespace Catch
10749
10750#endif
10751
10752
10753#ifndef CATCH_STRING_MANIP_HPP_INCLUDED
10754#define CATCH_STRING_MANIP_HPP_INCLUDED
10755
10756
10757#include <cstdint>
10758#include <string>
10759#include <iosfwd>
10760#include <vector>
10761
10762namespace Catch {
10763
10764 bool startsWith( std::string const& s, std::string const& prefix );
10765 bool startsWith( StringRef s, char prefix );
10766 bool endsWith( std::string const& s, std::string const& suffix );
10767 bool endsWith( std::string const& s, char suffix );
10768 bool contains( std::string const& s, std::string const& infix );
10769 void toLowerInPlace( std::string& s );
10770 std::string toLower( std::string const& s );
10771 char toLower( char c );
10773 std::string trim( std::string const& str );
10775 StringRef trim(StringRef ref);
10776
10777 // !!! Be aware, returns refs into original string - make sure original string outlives them
10778 std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
10779 bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
10780
10791 class pluralise {
10792 std::uint64_t m_count;
10793 StringRef m_label;
10794
10795 public:
10796 constexpr pluralise(std::uint64_t count, StringRef label):
10797 m_count(count),
10798 m_label(label)
10799 {}
10800
10801 friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
10802 };
10803}
10804
10805#endif // CATCH_STRING_MANIP_HPP_INCLUDED
10806
10807
10808#ifndef CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
10809#define CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
10810
10811
10812#include <map>
10813#include <string>
10814
10815namespace Catch {
10816 struct SourceLineInfo;
10817
10818 class TagAliasRegistry : public ITagAliasRegistry {
10819 public:
10820 ~TagAliasRegistry() override;
10821 TagAlias const* find( std::string const& alias ) const override;
10822 std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
10823 void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
10824
10825 private:
10826 std::map<std::string, TagAlias> m_registry;
10827 };
10828
10829} // end namespace Catch
10830
10831#endif // CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
10832
10833
10834#ifndef CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED
10835#define CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED
10836
10837#include <cstdint>
10838
10839namespace Catch {
10840
10841 struct TestCaseInfo;
10842
10843 class TestCaseInfoHasher {
10844 public:
10845 using hash_t = std::uint64_t;
10846 TestCaseInfoHasher( hash_t seed );
10847 uint32_t operator()( TestCaseInfo const& t ) const;
10848
10849 private:
10850 hash_t m_seed;
10851 };
10852
10853} // namespace Catch
10854
10855#endif /* CATCH_TEST_CASE_INFO_HASHER_HPP_INCLUDED */
10856
10857
10858#ifndef CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
10859#define CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
10860
10861
10862#include <vector>
10863
10864namespace Catch {
10865
10866 class IConfig;
10867 class ITestInvoker;
10868 class TestCaseHandle;
10869 class TestSpec;
10870
10871 std::vector<TestCaseHandle> sortTests( IConfig const& config, std::vector<TestCaseHandle> const& unsortedTestCases );
10872
10873 bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
10874
10875 std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
10876 std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );
10877
10878 class TestRegistry : public ITestCaseRegistry {
10879 public:
10880 void registerTest( Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker );
10881
10882 std::vector<TestCaseInfo*> const& getAllInfos() const override;
10883 std::vector<TestCaseHandle> const& getAllTests() const override;
10884 std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const override;
10885
10886 ~TestRegistry() override; // = default
10887
10888 private:
10889 std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
10890 // Keeps a materialized vector for `getAllInfos`.
10891 // We should get rid of that eventually (see interface note)
10892 std::vector<TestCaseInfo*> m_viewed_test_infos;
10893
10894 std::vector<Detail::unique_ptr<ITestInvoker>> m_invokers;
10895 std::vector<TestCaseHandle> m_handles;
10896 mutable TestRunOrder m_currentSortOrder = TestRunOrder::Declared;
10897 mutable std::vector<TestCaseHandle> m_sortedFunctions;
10898 };
10899
10901
10902
10903} // end namespace Catch
10904
10905
10906#endif // CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
10907
10908
10909#ifndef CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
10910#define CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
10911
10912#ifdef __clang__
10913#pragma clang diagnostic push
10914#pragma clang diagnostic ignored "-Wpadded"
10915#endif
10916
10917
10918#include <vector>
10919#include <string>
10920
10921namespace Catch {
10922
10923 class ITagAliasRegistry;
10924
10925 class TestSpecParser {
10926 enum Mode{ None, Name, QuotedName, Tag, EscapedName };
10927 Mode m_mode = None;
10928 Mode lastMode = None;
10929 bool m_exclusion = false;
10930 std::size_t m_pos = 0;
10931 std::size_t m_realPatternPos = 0;
10932 std::string m_arg;
10933 std::string m_substring;
10934 std::string m_patternName;
10935 std::vector<std::size_t> m_escapeChars;
10936 TestSpec::Filter m_currentFilter;
10937 TestSpec m_testSpec;
10938 ITagAliasRegistry const* m_tagAliases = nullptr;
10939
10940 public:
10941 TestSpecParser( ITagAliasRegistry const& tagAliases );
10942
10943 TestSpecParser& parse( std::string const& arg );
10944 TestSpec testSpec();
10945
10946 private:
10947 bool visitChar( char c );
10948 void startNewMode( Mode mode );
10949 bool processNoneChar( char c );
10950 void processNameChar( char c );
10951 bool processOtherChar( char c );
10952 void endMode();
10953 void escape();
10954 bool isControlChar( char c ) const;
10955 void saveLastMode();
10956 void revertBackToLastMode();
10957 void addFilter();
10958 bool separate();
10959
10960 // Handles common preprocessing of the pattern for name/tag patterns
10961 std::string preprocessPattern();
10962 // Adds the current pattern as a test name
10963 void addNamePattern();
10964 // Adds the current pattern as a tag
10965 void addTagPattern();
10966
10967 inline void addCharToPattern(char c) {
10968 m_substring += c;
10969 m_patternName += c;
10970 m_realPatternPos++;
10971 }
10972
10973 };
10974
10975} // namespace Catch
10976
10977#ifdef __clang__
10978#pragma clang diagnostic pop
10979#endif
10980
10981#endif // CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
10982
10983
10984#ifndef CATCH_TEXTFLOW_HPP_INCLUDED
10985#define CATCH_TEXTFLOW_HPP_INCLUDED
10986
10987
10988#include <cassert>
10989#include <string>
10990#include <vector>
10991
10992namespace Catch {
10993 namespace TextFlow {
10994
10995 class Columns;
10996
11009 class AnsiSkippingString {
11010 std::string m_string;
11011 std::size_t m_size = 0;
11012
11013 // perform 0xff replacement and calculate m_size
11014 void preprocessString();
11015
11016 public:
11017 class const_iterator;
11018 using iterator = const_iterator;
11019 // note: must be u-suffixed or this will cause a "truncation of
11020 // constant value" warning on MSVC
11021 static constexpr char sentinel = static_cast<char>( 0xffu );
11022
11023 explicit AnsiSkippingString( std::string const& text );
11024 explicit AnsiSkippingString( std::string&& text );
11025
11026 const_iterator begin() const;
11027 const_iterator end() const;
11028
11029 size_t size() const { return m_size; }
11030
11031 std::string substring( const_iterator begin,
11032 const_iterator end ) const;
11033 };
11034
11035 class AnsiSkippingString::const_iterator {
11036 friend AnsiSkippingString;
11037 struct EndTag {};
11038
11039 const std::string* m_string;
11040 std::string::const_iterator m_it;
11041
11042 explicit const_iterator( const std::string& string, EndTag ):
11043 m_string( &string ), m_it( string.end() ) {}
11044
11045 void tryParseAnsiEscapes();
11046 void advance();
11047 void unadvance();
11048
11049 public:
11050 using difference_type = std::ptrdiff_t;
11051 using value_type = char;
11052 using pointer = value_type*;
11053 using reference = value_type&;
11054 using iterator_category = std::bidirectional_iterator_tag;
11055
11056 explicit const_iterator( const std::string& string ):
11057 m_string( &string ), m_it( string.begin() ) {
11058 tryParseAnsiEscapes();
11059 }
11060
11061 char operator*() const { return *m_it; }
11062
11063 const_iterator& operator++() {
11064 advance();
11065 return *this;
11066 }
11067 const_iterator operator++( int ) {
11068 iterator prev( *this );
11069 operator++();
11070 return prev;
11071 }
11072 const_iterator& operator--() {
11073 unadvance();
11074 return *this;
11075 }
11076 const_iterator operator--( int ) {
11077 iterator prev( *this );
11078 operator--();
11079 return prev;
11080 }
11081
11082 bool operator==( const_iterator const& other ) const {
11083 return m_it == other.m_it;
11084 }
11085 bool operator!=( const_iterator const& other ) const {
11086 return !operator==( other );
11087 }
11088 bool operator<=( const_iterator const& other ) const {
11089 return m_it <= other.m_it;
11090 }
11091
11092 const_iterator oneBefore() const {
11093 auto it = *this;
11094 return --it;
11095 }
11096 };
11097
11105 class Column {
11106 // String to be written out
11107 AnsiSkippingString m_string;
11108 // Width of the column for linebreaking
11109 size_t m_width = CATCH_CONFIG_CONSOLE_WIDTH - 1;
11110 // Indentation of other lines (including first if initial indent is
11111 // unset)
11112 size_t m_indent = 0;
11113 // Indentation of the first line
11114 size_t m_initialIndent = std::string::npos;
11115
11116 public:
11120 class const_iterator {
11121 friend Column;
11122 struct EndTag {};
11123
11124 Column const& m_column;
11125 // Where does the current line start?
11126 AnsiSkippingString::const_iterator m_lineStart;
11127 // How long should the current line be?
11128 AnsiSkippingString::const_iterator m_lineEnd;
11129 // How far have we checked the string to iterate?
11130 AnsiSkippingString::const_iterator m_parsedTo;
11131 // Should a '-' be appended to the line?
11132 bool m_addHyphen = false;
11133
11134 const_iterator( Column const& column, EndTag ):
11135 m_column( column ),
11136 m_lineStart( m_column.m_string.end() ),
11137 m_lineEnd( column.m_string.end() ),
11138 m_parsedTo( column.m_string.end() ) {}
11139
11140 // Calculates the length of the current line
11141 void calcLength();
11142
11143 // Returns current indentation width
11144 size_t indentSize() const;
11145
11146 // Creates an indented and (optionally) suffixed string from
11147 // current iterator position, indentation and length.
11148 std::string addIndentAndSuffix(
11149 AnsiSkippingString::const_iterator start,
11150 AnsiSkippingString::const_iterator end ) const;
11151
11152 public:
11153 using difference_type = std::ptrdiff_t;
11154 using value_type = std::string;
11155 using pointer = value_type*;
11156 using reference = value_type&;
11157 using iterator_category = std::forward_iterator_tag;
11158
11159 explicit const_iterator( Column const& column );
11160
11161 std::string operator*() const;
11162
11163 const_iterator& operator++();
11164 const_iterator operator++( int );
11165
11166 bool operator==( const_iterator const& other ) const {
11167 return m_lineStart == other.m_lineStart &&
11168 &m_column == &other.m_column;
11169 }
11170 bool operator!=( const_iterator const& other ) const {
11171 return !operator==( other );
11172 }
11173 };
11174 using iterator = const_iterator;
11175
11176 explicit Column( std::string const& text ): m_string( text ) {}
11177 explicit Column( std::string&& text ):
11178 m_string( CATCH_MOVE( text ) ) {}
11179
11180 Column& width( size_t newWidth ) & {
11181 assert( newWidth > 0 );
11182 m_width = newWidth;
11183 return *this;
11184 }
11185 Column&& width( size_t newWidth ) && {
11186 assert( newWidth > 0 );
11187 m_width = newWidth;
11188 return CATCH_MOVE( *this );
11189 }
11190 Column& indent( size_t newIndent ) & {
11191 m_indent = newIndent;
11192 return *this;
11193 }
11194 Column&& indent( size_t newIndent ) && {
11195 m_indent = newIndent;
11196 return CATCH_MOVE( *this );
11197 }
11198 Column& initialIndent( size_t newIndent ) & {
11199 m_initialIndent = newIndent;
11200 return *this;
11201 }
11202 Column&& initialIndent( size_t newIndent ) && {
11203 m_initialIndent = newIndent;
11204 return CATCH_MOVE( *this );
11205 }
11206
11207 size_t width() const { return m_width; }
11208 const_iterator begin() const { return const_iterator( *this ); }
11209 const_iterator end() const {
11210 return { *this, const_iterator::EndTag{} };
11211 }
11212
11213 friend std::ostream& operator<<( std::ostream& os,
11214 Column const& col );
11215
11216 friend Columns operator+( Column const& lhs, Column const& rhs );
11217 friend Columns operator+( Column&& lhs, Column&& rhs );
11218 };
11219
11221 Column Spacer( size_t spaceWidth );
11222
11223 class Columns {
11224 std::vector<Column> m_columns;
11225
11226 public:
11227 class iterator {
11228 friend Columns;
11229 struct EndTag {};
11230
11231 std::vector<Column> const& m_columns;
11232 std::vector<Column::const_iterator> m_iterators;
11233 size_t m_activeIterators;
11234
11235 iterator( Columns const& columns, EndTag );
11236
11237 public:
11238 using difference_type = std::ptrdiff_t;
11239 using value_type = std::string;
11240 using pointer = value_type*;
11241 using reference = value_type&;
11242 using iterator_category = std::forward_iterator_tag;
11243
11244 explicit iterator( Columns const& columns );
11245
11246 auto operator==( iterator const& other ) const -> bool {
11247 return m_iterators == other.m_iterators;
11248 }
11249 auto operator!=( iterator const& other ) const -> bool {
11250 return m_iterators != other.m_iterators;
11251 }
11252 std::string operator*() const;
11253 iterator& operator++();
11254 iterator operator++( int );
11255 };
11256 using const_iterator = iterator;
11257
11258 iterator begin() const { return iterator( *this ); }
11259 iterator end() const { return { *this, iterator::EndTag() }; }
11260
11261 friend Columns& operator+=( Columns& lhs, Column const& rhs );
11262 friend Columns& operator+=( Columns& lhs, Column&& rhs );
11263 friend Columns operator+( Columns const& lhs, Column const& rhs );
11264 friend Columns operator+( Columns&& lhs, Column&& rhs );
11265
11266 friend std::ostream& operator<<( std::ostream& os,
11267 Columns const& cols );
11268 };
11269
11270 } // namespace TextFlow
11271} // namespace Catch
11272#endif // CATCH_TEXTFLOW_HPP_INCLUDED
11273
11274
11275#ifndef CATCH_TO_STRING_HPP_INCLUDED
11276#define CATCH_TO_STRING_HPP_INCLUDED
11277
11278#include <string>
11279
11280
11281namespace Catch {
11282 template <typename T>
11283 std::string to_string(T const& t) {
11284#if defined(CATCH_CONFIG_CPP11_TO_STRING)
11285 return std::to_string(t);
11286#else
11287 ReusableStringStream rss;
11288 rss << t;
11289 return rss.str();
11290#endif
11291 }
11292} // end namespace Catch
11293
11294#endif // CATCH_TO_STRING_HPP_INCLUDED
11295
11296
11297#ifndef CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
11298#define CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
11299
11300namespace Catch {
11301 bool uncaught_exceptions();
11302} // end namespace Catch
11303
11304#endif // CATCH_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
11305
11306
11307#ifndef CATCH_XMLWRITER_HPP_INCLUDED
11308#define CATCH_XMLWRITER_HPP_INCLUDED
11309
11310
11311#include <iosfwd>
11312#include <vector>
11313#include <cstdint>
11314
11315namespace Catch {
11316 enum class XmlFormatting : std::uint8_t {
11317 None = 0x00,
11318 Indent = 0x01,
11319 Newline = 0x02,
11320 };
11321
11322 constexpr XmlFormatting operator|( XmlFormatting lhs, XmlFormatting rhs ) {
11323 return static_cast<XmlFormatting>( static_cast<std::uint8_t>( lhs ) |
11324 static_cast<std::uint8_t>( rhs ) );
11325 }
11326
11327 constexpr XmlFormatting operator&( XmlFormatting lhs, XmlFormatting rhs ) {
11328 return static_cast<XmlFormatting>( static_cast<std::uint8_t>( lhs ) &
11329 static_cast<std::uint8_t>( rhs ) );
11330 }
11331
11332
11339 class XmlEncode {
11340 public:
11341 enum ForWhat { ForTextNodes, ForAttributes };
11342
11343 constexpr XmlEncode( StringRef str, ForWhat forWhat = ForTextNodes ):
11344 m_str( str ), m_forWhat( forWhat ) {}
11345
11346
11347 void encodeTo( std::ostream& os ) const;
11348
11349 friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
11350
11351 private:
11352 StringRef m_str;
11353 ForWhat m_forWhat;
11354 };
11355
11356 class XmlWriter {
11357 public:
11358
11359 class ScopedElement {
11360 public:
11361 ScopedElement( XmlWriter* writer, XmlFormatting fmt );
11362
11363 ScopedElement( ScopedElement&& other ) noexcept;
11364 ScopedElement& operator=( ScopedElement&& other ) noexcept;
11365
11366 ~ScopedElement();
11367
11368 ScopedElement&
11369 writeText( StringRef text,
11370 XmlFormatting fmt = XmlFormatting::Newline |
11371 XmlFormatting::Indent );
11372
11373 ScopedElement& writeAttribute( StringRef name,
11374 StringRef attribute );
11375 template <typename T,
11376 // Without this SFINAE, this overload is a better match
11377 // for `std::string`, `char const*`, `char const[N]` args.
11378 // While it would still work, it would cause code bloat
11379 // and multiple iteration over the strings
11380 typename = typename std::enable_if_t<
11381 !std::is_convertible<T, StringRef>::value>>
11382 ScopedElement& writeAttribute( StringRef name,
11383 T const& attribute ) {
11384 m_writer->writeAttribute( name, attribute );
11385 return *this;
11386 }
11387
11388 private:
11389 XmlWriter* m_writer = nullptr;
11390 XmlFormatting m_fmt;
11391 };
11392
11393 XmlWriter( std::ostream& os );
11394 ~XmlWriter();
11395
11396 XmlWriter( XmlWriter const& ) = delete;
11397 XmlWriter& operator=( XmlWriter const& ) = delete;
11398
11399 XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11400
11401 ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11402
11403 XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
11404
11406 XmlWriter& writeAttribute( StringRef name, StringRef attribute );
11407
11409 XmlWriter& writeAttribute( StringRef name, bool attribute );
11410
11412 XmlWriter& writeAttribute( StringRef name, char const* attribute );
11413
11416 template <typename T,
11417 // Without this SFINAE, this overload is a better match
11418 // for `std::string`, `char const*`, `char const[N]` args.
11419 // While it would still work, it would cause code bloat
11420 // and multiple iteration over the strings
11421 typename = typename std::enable_if_t<
11422 !std::is_convertible<T, StringRef>::value>>
11423 XmlWriter& writeAttribute( StringRef name, T const& attribute ) {
11424 ReusableStringStream rss;
11425 rss << attribute;
11426 return writeAttribute( name, rss.str() );
11427 }
11428
11430 XmlWriter& writeText( StringRef text,
11431 XmlFormatting fmt = XmlFormatting::Newline |
11432 XmlFormatting::Indent );
11433
11435 XmlWriter& writeComment( StringRef text,
11436 XmlFormatting fmt = XmlFormatting::Newline |
11437 XmlFormatting::Indent );
11438
11439 void writeStylesheetRef( StringRef url );
11440
11441 void ensureTagClosed();
11442
11443 private:
11444
11445 void applyFormatting(XmlFormatting fmt);
11446
11447 void writeDeclaration();
11448
11449 void newlineIfNecessary();
11450
11451 bool m_tagIsOpen = false;
11452 bool m_needsNewline = false;
11453 std::vector<std::string> m_tags;
11454 std::string m_indent;
11455 std::ostream& m_os;
11456 };
11457
11458}
11459
11460#endif // CATCH_XMLWRITER_HPP_INCLUDED
11461
11462
11474
11475#ifndef CATCH_MATCHERS_ALL_HPP_INCLUDED
11476#define CATCH_MATCHERS_ALL_HPP_INCLUDED
11477
11478
11479
11480#ifndef CATCH_MATCHERS_HPP_INCLUDED
11481#define CATCH_MATCHERS_HPP_INCLUDED
11482
11483
11484
11485#ifndef CATCH_MATCHERS_IMPL_HPP_INCLUDED
11486#define CATCH_MATCHERS_IMPL_HPP_INCLUDED
11487
11488
11489#include <string>
11490
11491namespace Catch {
11492
11493#ifdef __clang__
11494# pragma clang diagnostic push
11495# pragma clang diagnostic ignored "-Wsign-compare"
11496# pragma clang diagnostic ignored "-Wnon-virtual-dtor"
11497#elif defined __GNUC__
11498# pragma GCC diagnostic push
11499# pragma GCC diagnostic ignored "-Wsign-compare"
11500# pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
11501#endif
11502
11503 template<typename ArgT, typename MatcherT>
11504 class MatchExpr : public ITransientExpression {
11505 ArgT && m_arg;
11506 MatcherT const& m_matcher;
11507 public:
11508 constexpr MatchExpr( ArgT && arg, MatcherT const& matcher )
11509 : ITransientExpression{ true, matcher.match( arg ) }, // not forwarding arg here on purpose
11510 m_arg( CATCH_FORWARD(arg) ),
11511 m_matcher( matcher )
11512 {}
11513
11514 void streamReconstructedExpression( std::ostream& os ) const override {
11515 os << Catch::Detail::stringify( m_arg )
11516 << ' '
11517 << m_matcher.toString();
11518 }
11519 };
11520
11521#ifdef __clang__
11522# pragma clang diagnostic pop
11523#elif defined __GNUC__
11524# pragma GCC diagnostic pop
11525#endif
11526
11527
11528 namespace Matchers {
11529 template <typename ArgT>
11530 class MatcherBase;
11531 }
11532
11533 using StringMatcher = Matchers::MatcherBase<std::string>;
11534
11535 void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher );
11536
11537 template<typename ArgT, typename MatcherT>
11538 constexpr MatchExpr<ArgT, MatcherT>
11539 makeMatchExpr( ArgT&& arg, MatcherT const& matcher ) {
11540 return MatchExpr<ArgT, MatcherT>( CATCH_FORWARD(arg), matcher );
11541 }
11542
11543} // namespace Catch
11544
11545
11547#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
11548 do { \
11549 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
11550 INTERNAL_CATCH_TRY { \
11551 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher ) ); \
11552 } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
11553 catchAssertionHandler.complete(); \
11554 } while( false )
11555
11556
11558#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
11559 do { \
11560 Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
11561 if( catchAssertionHandler.allowThrows() ) \
11562 try { \
11563 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
11564 CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
11565 static_cast<void>(__VA_ARGS__ ); \
11566 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
11567 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
11568 } \
11569 catch( exceptionType const& ex ) { \
11570 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher ) ); \
11571 } \
11572 catch( ... ) { \
11573 catchAssertionHandler.handleUnexpectedInflightException(); \
11574 } \
11575 else \
11576 catchAssertionHandler.handleThrowingCallSkipped(); \
11577 catchAssertionHandler.complete(); \
11578 } while( false )
11579
11580
11581#endif // CATCH_MATCHERS_IMPL_HPP_INCLUDED
11582
11583#include <string>
11584#include <vector>
11585
11586namespace Catch {
11587namespace Matchers {
11588
11589 class MatcherUntypedBase {
11590 public:
11591 MatcherUntypedBase() = default;
11592
11593 MatcherUntypedBase(MatcherUntypedBase const&) = default;
11594 MatcherUntypedBase(MatcherUntypedBase&&) = default;
11595
11596 MatcherUntypedBase& operator = (MatcherUntypedBase const&) = delete;
11597 MatcherUntypedBase& operator = (MatcherUntypedBase&&) = delete;
11598
11599 std::string toString() const;
11600
11601 protected:
11602 virtual ~MatcherUntypedBase(); // = default;
11603 virtual std::string describe() const = 0;
11604 mutable std::string m_cachedToString;
11605 };
11606
11607
11608 template<typename T>
11609 class MatcherBase : public MatcherUntypedBase {
11610 public:
11611 virtual bool match( T const& arg ) const = 0;
11612 };
11613
11614 namespace Detail {
11615
11616 template<typename ArgT>
11617 class MatchAllOf final : public MatcherBase<ArgT> {
11618 std::vector<MatcherBase<ArgT> const*> m_matchers;
11619
11620 public:
11621 MatchAllOf() = default;
11622 MatchAllOf(MatchAllOf const&) = delete;
11623 MatchAllOf& operator=(MatchAllOf const&) = delete;
11624 MatchAllOf(MatchAllOf&&) = default;
11625 MatchAllOf& operator=(MatchAllOf&&) = default;
11626
11627
11628 bool match( ArgT const& arg ) const override {
11629 for( auto matcher : m_matchers ) {
11630 if (!matcher->match(arg))
11631 return false;
11632 }
11633 return true;
11634 }
11635 std::string describe() const override {
11636 std::string description;
11637 description.reserve( 4 + m_matchers.size()*32 );
11638 description += "( ";
11639 bool first = true;
11640 for( auto matcher : m_matchers ) {
11641 if( first )
11642 first = false;
11643 else
11644 description += " and ";
11645 description += matcher->toString();
11646 }
11647 description += " )";
11648 return description;
11649 }
11650
11651 friend MatchAllOf operator&& (MatchAllOf&& lhs, MatcherBase<ArgT> const& rhs) {
11652 lhs.m_matchers.push_back(&rhs);
11653 return CATCH_MOVE(lhs);
11654 }
11655 friend MatchAllOf operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf&& rhs) {
11656 rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
11657 return CATCH_MOVE(rhs);
11658 }
11659 };
11660
11663 template<typename ArgT>
11664 MatchAllOf<ArgT> operator&& (MatchAllOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
11667 template<typename ArgT>
11668 MatchAllOf<ArgT> operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf<ArgT> const& rhs) = delete;
11669
11670 template<typename ArgT>
11671 class MatchAnyOf final : public MatcherBase<ArgT> {
11672 std::vector<MatcherBase<ArgT> const*> m_matchers;
11673 public:
11674 MatchAnyOf() = default;
11675 MatchAnyOf(MatchAnyOf const&) = delete;
11676 MatchAnyOf& operator=(MatchAnyOf const&) = delete;
11677 MatchAnyOf(MatchAnyOf&&) = default;
11678 MatchAnyOf& operator=(MatchAnyOf&&) = default;
11679
11680 bool match( ArgT const& arg ) const override {
11681 for( auto matcher : m_matchers ) {
11682 if (matcher->match(arg))
11683 return true;
11684 }
11685 return false;
11686 }
11687 std::string describe() const override {
11688 std::string description;
11689 description.reserve( 4 + m_matchers.size()*32 );
11690 description += "( ";
11691 bool first = true;
11692 for( auto matcher : m_matchers ) {
11693 if( first )
11694 first = false;
11695 else
11696 description += " or ";
11697 description += matcher->toString();
11698 }
11699 description += " )";
11700 return description;
11701 }
11702
11703 friend MatchAnyOf operator|| (MatchAnyOf&& lhs, MatcherBase<ArgT> const& rhs) {
11704 lhs.m_matchers.push_back(&rhs);
11705 return CATCH_MOVE(lhs);
11706 }
11707 friend MatchAnyOf operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf&& rhs) {
11708 rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
11709 return CATCH_MOVE(rhs);
11710 }
11711 };
11712
11715 template<typename ArgT>
11716 MatchAnyOf<ArgT> operator|| (MatchAnyOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
11719 template<typename ArgT>
11720 MatchAnyOf<ArgT> operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf<ArgT> const& rhs) = delete;
11721
11722 template<typename ArgT>
11723 class MatchNotOf final : public MatcherBase<ArgT> {
11724 MatcherBase<ArgT> const& m_underlyingMatcher;
11725
11726 public:
11727 explicit MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ):
11728 m_underlyingMatcher( underlyingMatcher )
11729 {}
11730
11731 bool match( ArgT const& arg ) const override {
11732 return !m_underlyingMatcher.match( arg );
11733 }
11734
11735 std::string describe() const override {
11736 return "not " + m_underlyingMatcher.toString();
11737 }
11738 };
11739
11740 } // namespace Detail
11741
11742 template <typename T>
11743 Detail::MatchAllOf<T> operator&& (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
11744 return Detail::MatchAllOf<T>{} && lhs && rhs;
11745 }
11746 template <typename T>
11747 Detail::MatchAnyOf<T> operator|| (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
11748 return Detail::MatchAnyOf<T>{} || lhs || rhs;
11749 }
11750
11751 template <typename T>
11752 Detail::MatchNotOf<T> operator! (MatcherBase<T> const& matcher) {
11753 return Detail::MatchNotOf<T>{ matcher };
11754 }
11755
11756
11757} // namespace Matchers
11758} // namespace Catch
11759
11760
11761#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
11762 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
11763 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
11764
11765 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11766 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11767
11768 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
11769 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11770
11771#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
11772
11773 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
11774 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
11775
11776 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
11777 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
11778
11779 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
11780 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
11781
11782#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
11783
11784 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
11785 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
11786
11787 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11788 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11789
11790 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
11791 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11792
11793#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
11794
11795 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
11796 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
11797
11798 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
11799 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
11800
11801 #define CHECK_THAT( arg, matcher ) (void)(0)
11802 #define REQUIRE_THAT( arg, matcher ) (void)(0)
11803
11804#endif // end of user facing macro declarations
11805
11806#endif // CATCH_MATCHERS_HPP_INCLUDED
11807
11808
11809#ifndef CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
11810#define CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
11811
11812
11813
11814#ifndef CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
11815#define CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
11816
11817
11818#include <array>
11819#include <algorithm>
11820#include <string>
11821#include <type_traits>
11822
11823namespace Catch {
11824namespace Matchers {
11825 class MatcherGenericBase : public MatcherUntypedBase {
11826 public:
11827 MatcherGenericBase() = default;
11828 ~MatcherGenericBase() override; // = default;
11829
11830 MatcherGenericBase(MatcherGenericBase const&) = default;
11831 MatcherGenericBase(MatcherGenericBase&&) = default;
11832
11833 MatcherGenericBase& operator=(MatcherGenericBase const&) = delete;
11834 MatcherGenericBase& operator=(MatcherGenericBase&&) = delete;
11835 };
11836
11837
11838 namespace Detail {
11839 template<std::size_t N, std::size_t M>
11840 std::array<void const*, N + M> array_cat(std::array<void const*, N> && lhs, std::array<void const*, M> && rhs) {
11841 std::array<void const*, N + M> arr{};
11842 std::copy_n(lhs.begin(), N, arr.begin());
11843 std::copy_n(rhs.begin(), M, arr.begin() + N);
11844 return arr;
11845 }
11846
11847 template<std::size_t N>
11848 std::array<void const*, N+1> array_cat(std::array<void const*, N> && lhs, void const* rhs) {
11849 std::array<void const*, N+1> arr{};
11850 std::copy_n(lhs.begin(), N, arr.begin());
11851 arr[N] = rhs;
11852 return arr;
11853 }
11854
11855 template<std::size_t N>
11856 std::array<void const*, N+1> array_cat(void const* lhs, std::array<void const*, N> && rhs) {
11857 std::array<void const*, N + 1> arr{ {lhs} };
11858 std::copy_n(rhs.begin(), N, arr.begin() + 1);
11859 return arr;
11860 }
11861
11862 template<typename T>
11863 using is_generic_matcher = std::is_base_of<
11864 Catch::Matchers::MatcherGenericBase,
11865 std::remove_cv_t<std::remove_reference_t<T>>
11866 >;
11867
11868 template<typename... Ts>
11869 using are_generic_matchers = Catch::Detail::conjunction<is_generic_matcher<Ts>...>;
11870
11871 template<typename T>
11872 using is_matcher = std::is_base_of<
11873 Catch::Matchers::MatcherUntypedBase,
11874 std::remove_cv_t<std::remove_reference_t<T>>
11875 >;
11876
11877
11878 template<std::size_t N, typename Arg>
11879 bool match_all_of(Arg&&, std::array<void const*, N> const&, std::index_sequence<>) {
11880 return true;
11881 }
11882
11883 template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
11884 bool match_all_of(Arg&& arg, std::array<void const*, N> const& matchers, std::index_sequence<Idx, Indices...>) {
11885 return static_cast<T const*>(matchers[Idx])->match(arg) && match_all_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
11886 }
11887
11888
11889 template<std::size_t N, typename Arg>
11890 bool match_any_of(Arg&&, std::array<void const*, N> const&, std::index_sequence<>) {
11891 return false;
11892 }
11893
11894 template<typename T, typename... MatcherTs, std::size_t N, typename Arg, std::size_t Idx, std::size_t... Indices>
11895 bool match_any_of(Arg&& arg, std::array<void const*, N> const& matchers, std::index_sequence<Idx, Indices...>) {
11896 return static_cast<T const*>(matchers[Idx])->match(arg) || match_any_of<MatcherTs...>(arg, matchers, std::index_sequence<Indices...>{});
11897 }
11898
11899 std::string describe_multi_matcher(StringRef combine, std::string const* descriptions_begin, std::string const* descriptions_end);
11900
11901 template<typename... MatcherTs, std::size_t... Idx>
11902 std::string describe_multi_matcher(StringRef combine, std::array<void const*, sizeof...(MatcherTs)> const& matchers, std::index_sequence<Idx...>) {
11903 std::array<std::string, sizeof...(MatcherTs)> descriptions {{
11904 static_cast<MatcherTs const*>(matchers[Idx])->toString()...
11905 }};
11906
11907 return describe_multi_matcher(combine, descriptions.data(), descriptions.data() + descriptions.size());
11908 }
11909
11910
11911 template<typename... MatcherTs>
11912 class MatchAllOfGeneric final : public MatcherGenericBase {
11913 public:
11914 MatchAllOfGeneric(MatchAllOfGeneric const&) = delete;
11915 MatchAllOfGeneric& operator=(MatchAllOfGeneric const&) = delete;
11916 MatchAllOfGeneric(MatchAllOfGeneric&&) = default;
11917 MatchAllOfGeneric& operator=(MatchAllOfGeneric&&) = default;
11918
11919 MatchAllOfGeneric(MatcherTs const&... matchers) : m_matchers{ {std::addressof(matchers)...} } {}
11920 explicit MatchAllOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
11921
11922 template<typename Arg>
11923 bool match(Arg&& arg) const {
11924 return match_all_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
11925 }
11926
11927 std::string describe() const override {
11928 return describe_multi_matcher<MatcherTs...>(" and "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
11929 }
11930
11931 // Has to be public to enable the concatenating operators
11932 // below, because they are not friend of the RHS, only LHS,
11933 // and thus cannot access private fields of RHS
11934 std::array<void const*, sizeof...( MatcherTs )> m_matchers;
11935
11936
11938 template<typename... MatchersRHS>
11939 friend
11940 MatchAllOfGeneric<MatcherTs..., MatchersRHS...> operator && (
11941 MatchAllOfGeneric<MatcherTs...>&& lhs,
11942 MatchAllOfGeneric<MatchersRHS...>&& rhs) {
11943 return MatchAllOfGeneric<MatcherTs..., MatchersRHS...>{array_cat(CATCH_MOVE(lhs.m_matchers), CATCH_MOVE(rhs.m_matchers))};
11944 }
11945
11947 template<typename MatcherRHS>
11948 friend std::enable_if_t<is_matcher<MatcherRHS>::value,
11949 MatchAllOfGeneric<MatcherTs..., MatcherRHS>> operator && (
11950 MatchAllOfGeneric<MatcherTs...>&& lhs,
11951 MatcherRHS const& rhs) {
11952 return MatchAllOfGeneric<MatcherTs..., MatcherRHS>{array_cat(CATCH_MOVE(lhs.m_matchers), static_cast<void const*>(&rhs))};
11953 }
11954
11956 template<typename MatcherLHS>
11957 friend std::enable_if_t<is_matcher<MatcherLHS>::value,
11958 MatchAllOfGeneric<MatcherLHS, MatcherTs...>> operator && (
11959 MatcherLHS const& lhs,
11960 MatchAllOfGeneric<MatcherTs...>&& rhs) {
11961 return MatchAllOfGeneric<MatcherLHS, MatcherTs...>{array_cat(static_cast<void const*>(std::addressof(lhs)), CATCH_MOVE(rhs.m_matchers))};
11962 }
11963 };
11964
11965
11966 template<typename... MatcherTs>
11967 class MatchAnyOfGeneric final : public MatcherGenericBase {
11968 public:
11969 MatchAnyOfGeneric(MatchAnyOfGeneric const&) = delete;
11970 MatchAnyOfGeneric& operator=(MatchAnyOfGeneric const&) = delete;
11971 MatchAnyOfGeneric(MatchAnyOfGeneric&&) = default;
11972 MatchAnyOfGeneric& operator=(MatchAnyOfGeneric&&) = default;
11973
11974 MatchAnyOfGeneric(MatcherTs const&... matchers) : m_matchers{ {std::addressof(matchers)...} } {}
11975 explicit MatchAnyOfGeneric(std::array<void const*, sizeof...(MatcherTs)> matchers) : m_matchers{matchers} {}
11976
11977 template<typename Arg>
11978 bool match(Arg&& arg) const {
11979 return match_any_of<MatcherTs...>(arg, m_matchers, std::index_sequence_for<MatcherTs...>{});
11980 }
11981
11982 std::string describe() const override {
11983 return describe_multi_matcher<MatcherTs...>(" or "_sr, m_matchers, std::index_sequence_for<MatcherTs...>{});
11984 }
11985
11986
11987 // Has to be public to enable the concatenating operators
11988 // below, because they are not friend of the RHS, only LHS,
11989 // and thus cannot access private fields of RHS
11990 std::array<void const*, sizeof...( MatcherTs )> m_matchers;
11991
11993 template<typename... MatchersRHS>
11994 friend MatchAnyOfGeneric<MatcherTs..., MatchersRHS...> operator || (
11995 MatchAnyOfGeneric<MatcherTs...>&& lhs,
11996 MatchAnyOfGeneric<MatchersRHS...>&& rhs) {
11997 return MatchAnyOfGeneric<MatcherTs..., MatchersRHS...>{array_cat(CATCH_MOVE(lhs.m_matchers), CATCH_MOVE(rhs.m_matchers))};
11998 }
11999
12001 template<typename MatcherRHS>
12002 friend std::enable_if_t<is_matcher<MatcherRHS>::value,
12003 MatchAnyOfGeneric<MatcherTs..., MatcherRHS>> operator || (
12004 MatchAnyOfGeneric<MatcherTs...>&& lhs,
12005 MatcherRHS const& rhs) {
12006 return MatchAnyOfGeneric<MatcherTs..., MatcherRHS>{array_cat(CATCH_MOVE(lhs.m_matchers), static_cast<void const*>(std::addressof(rhs)))};
12007 }
12008
12010 template<typename MatcherLHS>
12011 friend std::enable_if_t<is_matcher<MatcherLHS>::value,
12012 MatchAnyOfGeneric<MatcherLHS, MatcherTs...>> operator || (
12013 MatcherLHS const& lhs,
12014 MatchAnyOfGeneric<MatcherTs...>&& rhs) {
12015 return MatchAnyOfGeneric<MatcherLHS, MatcherTs...>{array_cat(static_cast<void const*>(std::addressof(lhs)), CATCH_MOVE(rhs.m_matchers))};
12016 }
12017 };
12018
12019
12020 template<typename MatcherT>
12021 class MatchNotOfGeneric final : public MatcherGenericBase {
12022 MatcherT const& m_matcher;
12023
12024 public:
12025 MatchNotOfGeneric(MatchNotOfGeneric const&) = delete;
12026 MatchNotOfGeneric& operator=(MatchNotOfGeneric const&) = delete;
12027 MatchNotOfGeneric(MatchNotOfGeneric&&) = default;
12028 MatchNotOfGeneric& operator=(MatchNotOfGeneric&&) = default;
12029
12030 explicit MatchNotOfGeneric(MatcherT const& matcher) : m_matcher{matcher} {}
12031
12032 template<typename Arg>
12033 bool match(Arg&& arg) const {
12034 return !m_matcher.match(arg);
12035 }
12036
12037 std::string describe() const override {
12038 return "not " + m_matcher.toString();
12039 }
12040
12042 friend MatcherT const& operator ! (MatchNotOfGeneric<MatcherT> const& matcher) {
12043 return matcher.m_matcher;
12044 }
12045 };
12046 } // namespace Detail
12047
12048
12049 // compose only generic matchers
12050 template<typename MatcherLHS, typename MatcherRHS>
12051 std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherRHS>>
12052 operator && (MatcherLHS const& lhs, MatcherRHS const& rhs) {
12053 return { lhs, rhs };
12054 }
12055
12056 template<typename MatcherLHS, typename MatcherRHS>
12057 std::enable_if_t<Detail::are_generic_matchers<MatcherLHS, MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherRHS>>
12058 operator || (MatcherLHS const& lhs, MatcherRHS const& rhs) {
12059 return { lhs, rhs };
12060 }
12061
12063 template<typename MatcherT>
12064 std::enable_if_t<Detail::is_generic_matcher<MatcherT>::value, Detail::MatchNotOfGeneric<MatcherT>>
12065 operator ! (MatcherT const& matcher) {
12066 return Detail::MatchNotOfGeneric<MatcherT>{matcher};
12067 }
12068
12069
12070 // compose mixed generic and non-generic matchers
12071 template<typename MatcherLHS, typename ArgRHS>
12072 std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAllOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
12073 operator && (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
12074 return { lhs, rhs };
12075 }
12076
12077 template<typename ArgLHS, typename MatcherRHS>
12078 std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAllOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
12079 operator && (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
12080 return { lhs, rhs };
12081 }
12082
12083 template<typename MatcherLHS, typename ArgRHS>
12084 std::enable_if_t<Detail::is_generic_matcher<MatcherLHS>::value, Detail::MatchAnyOfGeneric<MatcherLHS, MatcherBase<ArgRHS>>>
12085 operator || (MatcherLHS const& lhs, MatcherBase<ArgRHS> const& rhs) {
12086 return { lhs, rhs };
12087 }
12088
12089 template<typename ArgLHS, typename MatcherRHS>
12090 std::enable_if_t<Detail::is_generic_matcher<MatcherRHS>::value, Detail::MatchAnyOfGeneric<MatcherBase<ArgLHS>, MatcherRHS>>
12091 operator || (MatcherBase<ArgLHS> const& lhs, MatcherRHS const& rhs) {
12092 return { lhs, rhs };
12093 }
12094
12095} // namespace Matchers
12096} // namespace Catch
12097
12098#endif // CATCH_MATCHERS_TEMPLATED_HPP_INCLUDED
12099
12100namespace Catch {
12101 namespace Matchers {
12102
12103 class IsEmptyMatcher final : public MatcherGenericBase {
12104 public:
12105 template <typename RangeLike>
12106 bool match(RangeLike&& rng) const {
12107#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
12108 using Catch::Detail::empty;
12109#else
12110 using std::empty;
12111#endif
12112 return empty(rng);
12113 }
12114
12115 std::string describe() const override;
12116 };
12117
12118 class HasSizeMatcher final : public MatcherGenericBase {
12119 std::size_t m_target_size;
12120 public:
12121 explicit HasSizeMatcher(std::size_t target_size):
12122 m_target_size(target_size)
12123 {}
12124
12125 template <typename RangeLike>
12126 bool match(RangeLike&& rng) const {
12127#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
12128 using Catch::Detail::size;
12129#else
12130 using std::size;
12131#endif
12132 return size(rng) == m_target_size;
12133 }
12134
12135 std::string describe() const override;
12136 };
12137
12138 template <typename Matcher>
12139 class SizeMatchesMatcher final : public MatcherGenericBase {
12140 Matcher m_matcher;
12141 public:
12142 explicit SizeMatchesMatcher(Matcher m):
12143 m_matcher(CATCH_MOVE(m))
12144 {}
12145
12146 template <typename RangeLike>
12147 bool match(RangeLike&& rng) const {
12148#if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS)
12149 using Catch::Detail::size;
12150#else
12151 using std::size;
12152#endif
12153 return m_matcher.match(size(rng));
12154 }
12155
12156 std::string describe() const override {
12157 return "size matches " + m_matcher.describe();
12158 }
12159 };
12160
12161
12163 IsEmptyMatcher IsEmpty();
12165 HasSizeMatcher SizeIs(std::size_t sz);
12166 template <typename Matcher>
12167 std::enable_if_t<Detail::is_matcher<Matcher>::value,
12168 SizeMatchesMatcher<Matcher>> SizeIs(Matcher&& m) {
12169 return SizeMatchesMatcher<Matcher>{CATCH_FORWARD(m)};
12170 }
12171
12172 } // end namespace Matchers
12173} // end namespace Catch
12174
12175#endif // CATCH_MATCHERS_CONTAINER_PROPERTIES_HPP_INCLUDED
12176
12177
12178#ifndef CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
12179#define CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
12180
12181
12182#include <algorithm>
12183#include <functional>
12184
12185namespace Catch {
12186 namespace Matchers {
12188 template <typename T, typename Equality>
12189 class ContainsElementMatcher final : public MatcherGenericBase {
12190 T m_desired;
12191 Equality m_eq;
12192 public:
12193 template <typename T2, typename Equality2>
12194 ContainsElementMatcher(T2&& target, Equality2&& predicate):
12195 m_desired(CATCH_FORWARD(target)),
12196 m_eq(CATCH_FORWARD(predicate))
12197 {}
12198
12199 std::string describe() const override {
12200 return "contains element " + Catch::Detail::stringify(m_desired);
12201 }
12202
12203 template <typename RangeLike>
12204 bool match( RangeLike&& rng ) const {
12205 for ( auto&& elem : rng ) {
12206 if ( m_eq( elem, m_desired ) ) { return true; }
12207 }
12208 return false;
12209 }
12210 };
12211
12213 template <typename Matcher>
12214 class ContainsMatcherMatcher final : public MatcherGenericBase {
12215 Matcher m_matcher;
12216 public:
12217 // Note that we do a copy+move to avoid having to SFINAE this
12218 // constructor (and also avoid some perfect forwarding failure
12219 // cases)
12220 ContainsMatcherMatcher(Matcher matcher):
12221 m_matcher(CATCH_MOVE(matcher))
12222 {}
12223
12224 template <typename RangeLike>
12225 bool match(RangeLike&& rng) const {
12226 for (auto&& elem : rng) {
12227 if (m_matcher.match(elem)) {
12228 return true;
12229 }
12230 }
12231 return false;
12232 }
12233
12234 std::string describe() const override {
12235 return "contains element matching " + m_matcher.describe();
12236 }
12237 };
12238
12244 template <typename T>
12245 std::enable_if_t<!Detail::is_matcher<T>::value,
12246 ContainsElementMatcher<T, std::equal_to<>>> Contains(T&& elem) {
12247 return { CATCH_FORWARD(elem), std::equal_to<>{} };
12248 }
12249
12251 template <typename Matcher>
12252 std::enable_if_t<Detail::is_matcher<Matcher>::value,
12253 ContainsMatcherMatcher<Matcher>> Contains(Matcher&& matcher) {
12254 return { CATCH_FORWARD(matcher) };
12255 }
12256
12262 template <typename T, typename Equality>
12263 ContainsElementMatcher<T, Equality> Contains(T&& elem, Equality&& eq) {
12264 return { CATCH_FORWARD(elem), CATCH_FORWARD(eq) };
12265 }
12266
12267 }
12268}
12269
12270#endif // CATCH_MATCHERS_CONTAINS_HPP_INCLUDED
12271
12272
12273#ifndef CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
12274#define CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
12275
12276
12277namespace Catch {
12278namespace Matchers {
12279
12280class ExceptionMessageMatcher final : public MatcherBase<std::exception> {
12281 std::string m_message;
12282public:
12283
12284 ExceptionMessageMatcher(std::string const& message):
12285 m_message(message)
12286 {}
12287
12288 bool match(std::exception const& ex) const override;
12289
12290 std::string describe() const override;
12291};
12292
12294ExceptionMessageMatcher Message(std::string const& message);
12295
12296template <typename StringMatcherType>
12297class ExceptionMessageMatchesMatcher final
12298 : public MatcherBase<std::exception> {
12299 StringMatcherType m_matcher;
12300
12301public:
12302 ExceptionMessageMatchesMatcher( StringMatcherType matcher ):
12303 m_matcher( CATCH_MOVE( matcher ) ) {}
12304
12305 bool match( std::exception const& ex ) const override {
12306 return m_matcher.match( ex.what() );
12307 }
12308
12309 std::string describe() const override {
12310 return " matches \"" + m_matcher.describe() + '"';
12311 }
12312};
12313
12316template <typename StringMatcherType>
12317ExceptionMessageMatchesMatcher<StringMatcherType>
12318MessageMatches( StringMatcherType&& matcher ) {
12319 return { CATCH_FORWARD( matcher ) };
12320}
12321
12322} // namespace Matchers
12323} // namespace Catch
12324
12325#endif // CATCH_MATCHERS_EXCEPTION_HPP_INCLUDED
12326
12327
12328#ifndef CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
12329#define CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
12330
12331
12332namespace Catch {
12333namespace Matchers {
12334
12335 namespace Detail {
12336 enum class FloatingPointKind : uint8_t;
12337 }
12338
12339 class WithinAbsMatcher final : public MatcherBase<double> {
12340 public:
12341 WithinAbsMatcher(double target, double margin);
12342 bool match(double const& matchee) const override;
12343 std::string describe() const override;
12344 private:
12345 double m_target;
12346 double m_margin;
12347 };
12348
12350 WithinAbsMatcher WithinAbs( double target, double margin );
12351
12352
12353
12354 class WithinUlpsMatcher final : public MatcherBase<double> {
12355 public:
12356 WithinUlpsMatcher( double target,
12357 uint64_t ulps,
12358 Detail::FloatingPointKind baseType );
12359 bool match(double const& matchee) const override;
12360 std::string describe() const override;
12361 private:
12362 double m_target;
12363 uint64_t m_ulps;
12364 Detail::FloatingPointKind m_type;
12365 };
12366
12368 WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
12370 WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
12371
12372
12373
12374 // Given IEEE-754 format for floats and doubles, we can assume
12375 // that float -> double promotion is lossless. Given this, we can
12376 // assume that if we do the standard relative comparison of
12377 // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
12378 // the same result if we do this for floats, as if we do this for
12379 // doubles that were promoted from floats.
12380 class WithinRelMatcher final : public MatcherBase<double> {
12381 public:
12382 WithinRelMatcher( double target, double epsilon );
12383 bool match(double const& matchee) const override;
12384 std::string describe() const override;
12385 private:
12386 double m_target;
12387 double m_epsilon;
12388 };
12389
12391 WithinRelMatcher WithinRel(double target, double eps);
12393 WithinRelMatcher WithinRel(double target);
12395 WithinRelMatcher WithinRel(float target, float eps);
12397 WithinRelMatcher WithinRel(float target);
12398
12399
12400
12401 class IsNaNMatcher final : public MatcherBase<double> {
12402 public:
12403 IsNaNMatcher() = default;
12404 bool match( double const& matchee ) const override;
12405 std::string describe() const override;
12406 };
12407
12408 IsNaNMatcher IsNaN();
12409
12410} // namespace Matchers
12411} // namespace Catch
12412
12413#endif // CATCH_MATCHERS_FLOATING_POINT_HPP_INCLUDED
12414
12415
12416#ifndef CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
12417#define CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
12418
12419
12420#include <string>
12421
12422namespace Catch {
12423namespace Matchers {
12424
12425namespace Detail {
12426 std::string finalizeDescription(const std::string& desc);
12427} // namespace Detail
12428
12429template <typename T, typename Predicate>
12430class PredicateMatcher final : public MatcherBase<T> {
12431 Predicate m_predicate;
12432 std::string m_description;
12433public:
12434
12435 PredicateMatcher(Predicate&& elem, std::string const& descr)
12436 :m_predicate(CATCH_FORWARD(elem)),
12437 m_description(Detail::finalizeDescription(descr))
12438 {}
12439
12440 bool match( T const& item ) const override {
12441 return m_predicate(item);
12442 }
12443
12444 std::string describe() const override {
12445 return m_description;
12446 }
12447};
12448
12454 template<typename T, typename Pred>
12455 PredicateMatcher<T, Pred> Predicate(Pred&& predicate, std::string const& description = "") {
12456 static_assert(is_callable<Pred(T)>::value, "Predicate not callable with argument T");
12457 static_assert(std::is_same<bool, FunctionReturnType<Pred, T>>::value, "Predicate does not return bool");
12458 return PredicateMatcher<T, Pred>(CATCH_FORWARD(predicate), description);
12459 }
12460
12461} // namespace Matchers
12462} // namespace Catch
12463
12464#endif // CATCH_MATCHERS_PREDICATE_HPP_INCLUDED
12465
12466
12467#ifndef CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
12468#define CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
12469
12470
12471namespace Catch {
12472 namespace Matchers {
12473 // Matcher for checking that all elements in range matches a given matcher.
12474 template <typename Matcher>
12475 class AllMatchMatcher final : public MatcherGenericBase {
12476 Matcher m_matcher;
12477 public:
12478 AllMatchMatcher(Matcher matcher):
12479 m_matcher(CATCH_MOVE(matcher))
12480 {}
12481
12482 std::string describe() const override {
12483 return "all match " + m_matcher.describe();
12484 }
12485
12486 template <typename RangeLike>
12487 bool match(RangeLike&& rng) const {
12488 for (auto&& elem : rng) {
12489 if (!m_matcher.match(elem)) {
12490 return false;
12491 }
12492 }
12493 return true;
12494 }
12495 };
12496
12497 // Matcher for checking that no element in range matches a given matcher.
12498 template <typename Matcher>
12499 class NoneMatchMatcher final : public MatcherGenericBase {
12500 Matcher m_matcher;
12501 public:
12502 NoneMatchMatcher(Matcher matcher):
12503 m_matcher(CATCH_MOVE(matcher))
12504 {}
12505
12506 std::string describe() const override {
12507 return "none match " + m_matcher.describe();
12508 }
12509
12510 template <typename RangeLike>
12511 bool match(RangeLike&& rng) const {
12512 for (auto&& elem : rng) {
12513 if (m_matcher.match(elem)) {
12514 return false;
12515 }
12516 }
12517 return true;
12518 }
12519 };
12520
12521 // Matcher for checking that at least one element in range matches a given matcher.
12522 template <typename Matcher>
12523 class AnyMatchMatcher final : public MatcherGenericBase {
12524 Matcher m_matcher;
12525 public:
12526 AnyMatchMatcher(Matcher matcher):
12527 m_matcher(CATCH_MOVE(matcher))
12528 {}
12529
12530 std::string describe() const override {
12531 return "any match " + m_matcher.describe();
12532 }
12533
12534 template <typename RangeLike>
12535 bool match(RangeLike&& rng) const {
12536 for (auto&& elem : rng) {
12537 if (m_matcher.match(elem)) {
12538 return true;
12539 }
12540 }
12541 return false;
12542 }
12543 };
12544
12545 // Matcher for checking that all elements in range are true.
12546 class AllTrueMatcher final : public MatcherGenericBase {
12547 public:
12548 std::string describe() const override;
12549
12550 template <typename RangeLike>
12551 bool match(RangeLike&& rng) const {
12552 for (auto&& elem : rng) {
12553 if (!elem) {
12554 return false;
12555 }
12556 }
12557 return true;
12558 }
12559 };
12560
12561 // Matcher for checking that no element in range is true.
12562 class NoneTrueMatcher final : public MatcherGenericBase {
12563 public:
12564 std::string describe() const override;
12565
12566 template <typename RangeLike>
12567 bool match(RangeLike&& rng) const {
12568 for (auto&& elem : rng) {
12569 if (elem) {
12570 return false;
12571 }
12572 }
12573 return true;
12574 }
12575 };
12576
12577 // Matcher for checking that any element in range is true.
12578 class AnyTrueMatcher final : public MatcherGenericBase {
12579 public:
12580 std::string describe() const override;
12581
12582 template <typename RangeLike>
12583 bool match(RangeLike&& rng) const {
12584 for (auto&& elem : rng) {
12585 if (elem) {
12586 return true;
12587 }
12588 }
12589 return false;
12590 }
12591 };
12592
12593 // Creates a matcher that checks whether all elements in a range match a matcher
12594 template <typename Matcher>
12595 AllMatchMatcher<Matcher> AllMatch(Matcher&& matcher) {
12596 return { CATCH_FORWARD(matcher) };
12597 }
12598
12599 // Creates a matcher that checks whether no element in a range matches a matcher.
12600 template <typename Matcher>
12601 NoneMatchMatcher<Matcher> NoneMatch(Matcher&& matcher) {
12602 return { CATCH_FORWARD(matcher) };
12603 }
12604
12605 // Creates a matcher that checks whether any element in a range matches a matcher.
12606 template <typename Matcher>
12607 AnyMatchMatcher<Matcher> AnyMatch(Matcher&& matcher) {
12608 return { CATCH_FORWARD(matcher) };
12609 }
12610
12611 // Creates a matcher that checks whether all elements in a range are true
12612 AllTrueMatcher AllTrue();
12613
12614 // Creates a matcher that checks whether no element in a range is true
12615 NoneTrueMatcher NoneTrue();
12616
12617 // Creates a matcher that checks whether any element in a range is true
12618 AnyTrueMatcher AnyTrue();
12619 }
12620}
12621
12622#endif // CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
12623
12624
12625#ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
12626#define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
12627
12628
12629#include <algorithm>
12630#include <utility>
12631
12632namespace Catch {
12633 namespace Matchers {
12634
12639 template <typename TargetRangeLike, typename Equality>
12640 class RangeEqualsMatcher final : public MatcherGenericBase {
12641 TargetRangeLike m_desired;
12642 Equality m_predicate;
12643
12644 public:
12645 template <typename TargetRangeLike2, typename Equality2>
12646 constexpr
12647 RangeEqualsMatcher( TargetRangeLike2&& range,
12648 Equality2&& predicate ):
12649 m_desired( CATCH_FORWARD( range ) ),
12650 m_predicate( CATCH_FORWARD( predicate ) ) {}
12651
12652 template <typename RangeLike>
12653 constexpr
12654 bool match( RangeLike&& rng ) const {
12655 auto rng_start = begin( rng );
12656 const auto rng_end = end( rng );
12657 auto target_start = begin( m_desired );
12658 const auto target_end = end( m_desired );
12659
12660 while (rng_start != rng_end && target_start != target_end) {
12661 if (!m_predicate(*rng_start, *target_start)) {
12662 return false;
12663 }
12664 ++rng_start;
12665 ++target_start;
12666 }
12667 return rng_start == rng_end && target_start == target_end;
12668 }
12669
12670 std::string describe() const override {
12671 return "elements are " + Catch::Detail::stringify( m_desired );
12672 }
12673 };
12674
12679 template <typename TargetRangeLike, typename Equality>
12680 class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
12681 TargetRangeLike m_desired;
12682 Equality m_predicate;
12683
12684 public:
12685 template <typename TargetRangeLike2, typename Equality2>
12686 constexpr
12687 UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
12688 Equality2&& predicate ):
12689 m_desired( CATCH_FORWARD( range ) ),
12690 m_predicate( CATCH_FORWARD( predicate ) ) {}
12691
12692 template <typename RangeLike>
12693 constexpr
12694 bool match( RangeLike&& rng ) const {
12695 using std::begin;
12696 using std::end;
12697 return Catch::Detail::is_permutation( begin( m_desired ),
12698 end( m_desired ),
12699 begin( rng ),
12700 end( rng ),
12701 m_predicate );
12702 }
12703
12704 std::string describe() const override {
12705 return "unordered elements are " +
12706 ::Catch::Detail::stringify( m_desired );
12707 }
12708 };
12709
12717 template <typename RangeLike,
12718 typename Equality = decltype( std::equal_to<>{} )>
12719 constexpr
12720 RangeEqualsMatcher<RangeLike, Equality>
12721 RangeEquals( RangeLike&& range,
12722 Equality&& predicate = std::equal_to<>{} ) {
12723 return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
12724 }
12725
12733 template <typename T,
12734 typename Equality = decltype( std::equal_to<>{} )>
12735 constexpr
12736 RangeEqualsMatcher<std::initializer_list<T>, Equality>
12737 RangeEquals( std::initializer_list<T> range,
12738 Equality&& predicate = std::equal_to<>{} ) {
12739 return { range, CATCH_FORWARD( predicate ) };
12740 }
12741
12749 template <typename RangeLike,
12750 typename Equality = decltype( std::equal_to<>{} )>
12751 constexpr
12752 UnorderedRangeEqualsMatcher<RangeLike, Equality>
12753 UnorderedRangeEquals( RangeLike&& range,
12754 Equality&& predicate = std::equal_to<>{} ) {
12755 return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
12756 }
12757
12765 template <typename T,
12766 typename Equality = decltype( std::equal_to<>{} )>
12767 constexpr
12768 UnorderedRangeEqualsMatcher<std::initializer_list<T>, Equality>
12769 UnorderedRangeEquals( std::initializer_list<T> range,
12770 Equality&& predicate = std::equal_to<>{} ) {
12771 return { range, CATCH_FORWARD( predicate ) };
12772 }
12773 } // namespace Matchers
12774} // namespace Catch
12775
12776#endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
12777
12778
12779#ifndef CATCH_MATCHERS_STRING_HPP_INCLUDED
12780#define CATCH_MATCHERS_STRING_HPP_INCLUDED
12781
12782
12783#include <string>
12784
12785namespace Catch {
12786namespace Matchers {
12787
12788 struct CasedString {
12789 CasedString( std::string const& str, CaseSensitive caseSensitivity );
12790 std::string adjustString( std::string const& str ) const;
12791 StringRef caseSensitivitySuffix() const;
12792
12793 CaseSensitive m_caseSensitivity;
12794 std::string m_str;
12795 };
12796
12797 class StringMatcherBase : public MatcherBase<std::string> {
12798 protected:
12799 CasedString m_comparator;
12800 StringRef m_operation;
12801
12802 public:
12803 StringMatcherBase( StringRef operation,
12804 CasedString const& comparator );
12805 std::string describe() const override;
12806 };
12807
12808 class StringEqualsMatcher final : public StringMatcherBase {
12809 public:
12810 StringEqualsMatcher( CasedString const& comparator );
12811 bool match( std::string const& source ) const override;
12812 };
12813 class StringContainsMatcher final : public StringMatcherBase {
12814 public:
12815 StringContainsMatcher( CasedString const& comparator );
12816 bool match( std::string const& source ) const override;
12817 };
12818 class StartsWithMatcher final : public StringMatcherBase {
12819 public:
12820 StartsWithMatcher( CasedString const& comparator );
12821 bool match( std::string const& source ) const override;
12822 };
12823 class EndsWithMatcher final : public StringMatcherBase {
12824 public:
12825 EndsWithMatcher( CasedString const& comparator );
12826 bool match( std::string const& source ) const override;
12827 };
12828
12829 class RegexMatcher final : public MatcherBase<std::string> {
12830 std::string m_regex;
12831 CaseSensitive m_caseSensitivity;
12832
12833 public:
12834 RegexMatcher( std::string regex, CaseSensitive caseSensitivity );
12835 bool match( std::string const& matchee ) const override;
12836 std::string describe() const override;
12837 };
12838
12840 StringEqualsMatcher Equals( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
12842 StringContainsMatcher ContainsSubstring( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
12844 EndsWithMatcher EndsWith( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
12846 StartsWithMatcher StartsWith( std::string const& str, CaseSensitive caseSensitivity = CaseSensitive::Yes );
12848 RegexMatcher Matches( std::string const& regex, CaseSensitive caseSensitivity = CaseSensitive::Yes );
12849
12850} // namespace Matchers
12851} // namespace Catch
12852
12853#endif // CATCH_MATCHERS_STRING_HPP_INCLUDED
12854
12855
12856#ifndef CATCH_MATCHERS_VECTOR_HPP_INCLUDED
12857#define CATCH_MATCHERS_VECTOR_HPP_INCLUDED
12858
12859
12860#include <algorithm>
12861
12862namespace Catch {
12863namespace Matchers {
12864
12865 template<typename T, typename Alloc>
12866 class VectorContainsElementMatcher final : public MatcherBase<std::vector<T, Alloc>> {
12867 T const& m_comparator;
12868
12869 public:
12870 VectorContainsElementMatcher(T const& comparator):
12871 m_comparator(comparator)
12872 {}
12873
12874 bool match(std::vector<T, Alloc> const& v) const override {
12875 for (auto const& el : v) {
12876 if (el == m_comparator) {
12877 return true;
12878 }
12879 }
12880 return false;
12881 }
12882
12883 std::string describe() const override {
12884 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
12885 }
12886 };
12887
12888 template<typename T, typename AllocComp, typename AllocMatch>
12889 class ContainsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12890 std::vector<T, AllocComp> const& m_comparator;
12891
12892 public:
12893 ContainsMatcher(std::vector<T, AllocComp> const& comparator):
12894 m_comparator( comparator )
12895 {}
12896
12897 bool match(std::vector<T, AllocMatch> const& v) const override {
12898 // !TBD: see note in EqualsMatcher
12899 if (m_comparator.size() > v.size())
12900 return false;
12901 for (auto const& comparator : m_comparator) {
12902 auto present = false;
12903 for (const auto& el : v) {
12904 if (el == comparator) {
12905 present = true;
12906 break;
12907 }
12908 }
12909 if (!present) {
12910 return false;
12911 }
12912 }
12913 return true;
12914 }
12915 std::string describe() const override {
12916 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
12917 }
12918 };
12919
12920 template<typename T, typename AllocComp, typename AllocMatch>
12921 class EqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12922 std::vector<T, AllocComp> const& m_comparator;
12923
12924 public:
12925 EqualsMatcher(std::vector<T, AllocComp> const& comparator):
12926 m_comparator( comparator )
12927 {}
12928
12929 bool match(std::vector<T, AllocMatch> const& v) const override {
12930 // !TBD: This currently works if all elements can be compared using !=
12931 // - a more general approach would be via a compare template that defaults
12932 // to using !=. but could be specialised for, e.g. std::vector<T> etc
12933 // - then just call that directly
12934 if ( m_comparator.size() != v.size() ) { return false; }
12935 for ( std::size_t i = 0; i < v.size(); ++i ) {
12936 if ( !( m_comparator[i] == v[i] ) ) { return false; }
12937 }
12938 return true;
12939 }
12940 std::string describe() const override {
12941 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
12942 }
12943 };
12944
12945 template<typename T, typename AllocComp, typename AllocMatch>
12946 class ApproxMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12947 std::vector<T, AllocComp> const& m_comparator;
12948 mutable Catch::Approx approx = Catch::Approx::custom();
12949
12950 public:
12951 ApproxMatcher(std::vector<T, AllocComp> const& comparator):
12952 m_comparator( comparator )
12953 {}
12954
12955 bool match(std::vector<T, AllocMatch> const& v) const override {
12956 if (m_comparator.size() != v.size())
12957 return false;
12958 for (std::size_t i = 0; i < v.size(); ++i)
12959 if (m_comparator[i] != approx(v[i]))
12960 return false;
12961 return true;
12962 }
12963 std::string describe() const override {
12964 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
12965 }
12966 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
12967 ApproxMatcher& epsilon( T const& newEpsilon ) {
12968 approx.epsilon(static_cast<double>(newEpsilon));
12969 return *this;
12970 }
12971 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
12972 ApproxMatcher& margin( T const& newMargin ) {
12973 approx.margin(static_cast<double>(newMargin));
12974 return *this;
12975 }
12976 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
12977 ApproxMatcher& scale( T const& newScale ) {
12978 approx.scale(static_cast<double>(newScale));
12979 return *this;
12980 }
12981 };
12982
12983 template<typename T, typename AllocComp, typename AllocMatch>
12984 class UnorderedEqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
12985 std::vector<T, AllocComp> const& m_target;
12986
12987 public:
12988 UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target):
12989 m_target(target)
12990 {}
12991 bool match(std::vector<T, AllocMatch> const& vec) const override {
12992 if (m_target.size() != vec.size()) {
12993 return false;
12994 }
12995 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
12996 }
12997
12998 std::string describe() const override {
12999 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
13000 }
13001 };
13002
13003
13004 // The following functions create the actual matcher objects.
13005 // This allows the types to be inferred
13006
13008 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
13009 ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
13010 return ContainsMatcher<T, AllocComp, AllocMatch>(comparator);
13011 }
13012
13014 template<typename T, typename Alloc = std::allocator<T>>
13015 VectorContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
13016 return VectorContainsElementMatcher<T, Alloc>(comparator);
13017 }
13018
13020 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
13021 EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
13022 return EqualsMatcher<T, AllocComp, AllocMatch>(comparator);
13023 }
13024
13026 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
13027 ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
13028 return ApproxMatcher<T, AllocComp, AllocMatch>(comparator);
13029 }
13030
13032 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
13033 UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
13034 return UnorderedEqualsMatcher<T, AllocComp, AllocMatch>(target);
13035 }
13036
13037} // namespace Matchers
13038} // namespace Catch
13039
13040#endif // CATCH_MATCHERS_VECTOR_HPP_INCLUDED
13041
13042#endif // CATCH_MATCHERS_ALL_HPP_INCLUDED
13043
13044
13057
13058#ifndef CATCH_REPORTERS_ALL_HPP_INCLUDED
13059#define CATCH_REPORTERS_ALL_HPP_INCLUDED
13060
13061
13062
13063#ifndef CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
13064#define CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
13065
13066
13067
13068#ifndef CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
13069#define CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
13070
13071
13072
13073#ifndef CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
13074#define CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
13075
13076
13077#include <map>
13078#include <string>
13079
13080namespace Catch {
13081 class ColourImpl;
13082
13093 class ReporterBase : public IEventListener {
13094 protected:
13096 Detail::unique_ptr<IStream> m_wrapped_stream;
13099 std::ostream& m_stream;
13101 Detail::unique_ptr<ColourImpl> m_colour;
13103 std::map<std::string, std::string> m_customOptions;
13104
13105 public:
13106 ReporterBase( ReporterConfig&& config );
13107 ~ReporterBase() override; // = default;
13108
13115 void listReporters(
13116 std::vector<ReporterDescription> const& descriptions ) override;
13123 void listListeners(
13124 std::vector<ListenerDescription> const& descriptions ) override;
13132 void listTests( std::vector<TestCaseHandle> const& tests ) override;
13139 void listTags( std::vector<TagInfo> const& tags ) override;
13140 };
13141} // namespace Catch
13142
13143#endif // CATCH_REPORTER_COMMON_BASE_HPP_INCLUDED
13144
13145#include <vector>
13146
13147namespace Catch {
13148
13149 class StreamingReporterBase : public ReporterBase {
13150 public:
13151 // GCC5 compat: we cannot use inherited constructor, because it
13152 // doesn't implement backport of P0136
13153 StreamingReporterBase(ReporterConfig&& _config):
13154 ReporterBase(CATCH_MOVE(_config))
13155 {}
13156 ~StreamingReporterBase() override;
13157
13158 void benchmarkPreparing( StringRef ) override {}
13159 void benchmarkStarting( BenchmarkInfo const& ) override {}
13160 void benchmarkEnded( BenchmarkStats<> const& ) override {}
13161 void benchmarkFailed( StringRef ) override {}
13162
13163 void fatalErrorEncountered( StringRef /*error*/ ) override {}
13164 void noMatchingTestCases( StringRef /*unmatchedSpec*/ ) override {}
13165 void reportInvalidTestSpec( StringRef /*invalidArgument*/ ) override {}
13166
13167 void testRunStarting( TestRunInfo const& _testRunInfo ) override;
13168
13169 void testCaseStarting(TestCaseInfo const& _testInfo) override {
13170 currentTestCaseInfo = &_testInfo;
13171 }
13172 void testCasePartialStarting( TestCaseInfo const&, uint64_t ) override {}
13173 void sectionStarting(SectionInfo const& _sectionInfo) override {
13174 m_sectionStack.push_back(_sectionInfo);
13175 }
13176
13177 void assertionStarting( AssertionInfo const& ) override {}
13178 void assertionEnded( AssertionStats const& ) override {}
13179
13180 void sectionEnded(SectionStats const& /* _sectionStats */) override {
13181 m_sectionStack.pop_back();
13182 }
13183 void testCasePartialEnded( TestCaseStats const&, uint64_t ) override {}
13184 void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
13185 currentTestCaseInfo = nullptr;
13186 }
13187 void testRunEnded( TestRunStats const& /* _testRunStats */ ) override;
13188
13189 void skipTest(TestCaseInfo const&) override {
13190 // Don't do anything with this by default.
13191 // It can optionally be overridden in the derived class.
13192 }
13193
13194 protected:
13195 TestRunInfo currentTestRunInfo{ "test run has not started yet"_sr };
13196 TestCaseInfo const* currentTestCaseInfo = nullptr;
13197
13199 std::vector<SectionInfo> m_sectionStack;
13200 };
13201
13202} // end namespace Catch
13203
13204#endif // CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
13205
13206#include <string>
13207
13208namespace Catch {
13209
13210 class AutomakeReporter final : public StreamingReporterBase {
13211 public:
13212 // GCC5 compat: we cannot use inherited constructor, because it
13213 // doesn't implement backport of P0136
13214 AutomakeReporter(ReporterConfig&& _config):
13215 StreamingReporterBase(CATCH_MOVE(_config))
13216 {}
13217 ~AutomakeReporter() override;
13218
13219 static std::string getDescription() {
13220 using namespace std::string_literals;
13221 return "Reports test results in the format of Automake .trs files"s;
13222 }
13223
13224 void testCaseEnded(TestCaseStats const& _testCaseStats) override;
13225 void skipTest(TestCaseInfo const& testInfo) override;
13226 };
13227
13228} // end namespace Catch
13229
13230#endif // CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
13231
13232
13233#ifndef CATCH_REPORTER_COMPACT_HPP_INCLUDED
13234#define CATCH_REPORTER_COMPACT_HPP_INCLUDED
13235
13236
13237
13238
13239namespace Catch {
13240
13241 class CompactReporter final : public StreamingReporterBase {
13242 public:
13243 using StreamingReporterBase::StreamingReporterBase;
13244
13245 ~CompactReporter() override;
13246
13247 static std::string getDescription();
13248
13249 void noMatchingTestCases( StringRef unmatchedSpec ) override;
13250
13251 void testRunStarting( TestRunInfo const& _testInfo ) override;
13252
13253 void assertionEnded(AssertionStats const& _assertionStats) override;
13254
13255 void sectionEnded(SectionStats const& _sectionStats) override;
13256
13257 void testRunEnded(TestRunStats const& _testRunStats) override;
13258
13259 };
13260
13261} // end namespace Catch
13262
13263#endif // CATCH_REPORTER_COMPACT_HPP_INCLUDED
13264
13265
13266#ifndef CATCH_REPORTER_CONSOLE_HPP_INCLUDED
13267#define CATCH_REPORTER_CONSOLE_HPP_INCLUDED
13268
13269
13270namespace Catch {
13271 // Fwd decls
13272 class TablePrinter;
13273
13274 class ConsoleReporter final : public StreamingReporterBase {
13275 Detail::unique_ptr<TablePrinter> m_tablePrinter;
13276
13277 public:
13278 ConsoleReporter(ReporterConfig&& config);
13279 ~ConsoleReporter() override;
13280 static std::string getDescription();
13281
13282 void noMatchingTestCases( StringRef unmatchedSpec ) override;
13283 void reportInvalidTestSpec( StringRef arg ) override;
13284
13285 void assertionStarting(AssertionInfo const&) override;
13286
13287 void assertionEnded(AssertionStats const& _assertionStats) override;
13288
13289 void sectionStarting(SectionInfo const& _sectionInfo) override;
13290 void sectionEnded(SectionStats const& _sectionStats) override;
13291
13292 void benchmarkPreparing( StringRef name ) override;
13293 void benchmarkStarting(BenchmarkInfo const& info) override;
13294 void benchmarkEnded(BenchmarkStats<> const& stats) override;
13295 void benchmarkFailed( StringRef error ) override;
13296
13297 void testCaseEnded(TestCaseStats const& _testCaseStats) override;
13298 void testRunEnded(TestRunStats const& _testRunStats) override;
13299 void testRunStarting(TestRunInfo const& _testRunInfo) override;
13300
13301 private:
13302 void lazyPrint();
13303
13304 void lazyPrintWithoutClosingBenchmarkTable();
13305 void lazyPrintRunInfo();
13306 void printTestCaseAndSectionHeader();
13307
13308 void printClosedHeader(std::string const& _name);
13309 void printOpenHeader(std::string const& _name);
13310
13311 // if string has a : in first line will set indent to follow it on
13312 // subsequent lines
13313 void printHeaderString(std::string const& _string, std::size_t indent = 0);
13314
13315 void printTotalsDivider(Totals const& totals);
13316
13317 bool m_headerPrinted = false;
13318 bool m_testRunInfoPrinted = false;
13319 };
13320
13321} // end namespace Catch
13322
13323#endif // CATCH_REPORTER_CONSOLE_HPP_INCLUDED
13324
13325
13326#ifndef CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
13327#define CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
13328
13329
13330#include <string>
13331#include <vector>
13332
13333namespace Catch {
13334
13335 namespace Detail {
13336
13338 class AssertionOrBenchmarkResult {
13339 // This should really be a variant, but this is much faster
13340 // to write and the data layout here is already terrible
13341 // enough that we do not have to care about the object size.
13342 Optional<AssertionStats> m_assertion;
13343 Optional<BenchmarkStats<>> m_benchmark;
13344 public:
13345 AssertionOrBenchmarkResult(AssertionStats const& assertion);
13346 AssertionOrBenchmarkResult(BenchmarkStats<> const& benchmark);
13347
13348 bool isAssertion() const;
13349 bool isBenchmark() const;
13350
13351 AssertionStats const& asAssertion() const;
13352 BenchmarkStats<> const& asBenchmark() const;
13353 };
13354 }
13355
13376 class CumulativeReporterBase : public ReporterBase {
13377 public:
13378 template<typename T, typename ChildNodeT>
13379 struct Node {
13380 explicit Node( T const& _value ) : value( _value ) {}
13381
13382 using ChildNodes = std::vector<Detail::unique_ptr<ChildNodeT>>;
13383 T value;
13384 ChildNodes children;
13385 };
13386 struct SectionNode {
13387 explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
13388
13389 bool operator == (SectionNode const& other) const {
13390 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
13391 }
13392
13393 bool hasAnyAssertions() const;
13394
13395 SectionStats stats;
13396 std::vector<Detail::unique_ptr<SectionNode>> childSections;
13397 std::vector<Detail::AssertionOrBenchmarkResult> assertionsAndBenchmarks;
13398 std::string stdOut;
13399 std::string stdErr;
13400 };
13401
13402
13403 using TestCaseNode = Node<TestCaseStats, SectionNode>;
13404 using TestRunNode = Node<TestRunStats, TestCaseNode>;
13405
13406 // GCC5 compat: we cannot use inherited constructor, because it
13407 // doesn't implement backport of P0136
13408 CumulativeReporterBase(ReporterConfig&& _config):
13409 ReporterBase(CATCH_MOVE(_config))
13410 {}
13411 ~CumulativeReporterBase() override;
13412
13413 void benchmarkPreparing( StringRef ) override {}
13414 void benchmarkStarting( BenchmarkInfo const& ) override {}
13415 void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
13416 void benchmarkFailed( StringRef ) override {}
13417
13418 void noMatchingTestCases( StringRef ) override {}
13419 void reportInvalidTestSpec( StringRef ) override {}
13420 void fatalErrorEncountered( StringRef /*error*/ ) override {}
13421
13422 void testRunStarting( TestRunInfo const& ) override {}
13423
13424 void testCaseStarting( TestCaseInfo const& ) override {}
13425 void testCasePartialStarting( TestCaseInfo const&, uint64_t ) override {}
13426 void sectionStarting( SectionInfo const& sectionInfo ) override;
13427
13428 void assertionStarting( AssertionInfo const& ) override {}
13429
13430 void assertionEnded( AssertionStats const& assertionStats ) override;
13431 void sectionEnded( SectionStats const& sectionStats ) override;
13432 void testCasePartialEnded( TestCaseStats const&, uint64_t ) override {}
13433 void testCaseEnded( TestCaseStats const& testCaseStats ) override;
13434 void testRunEnded( TestRunStats const& testRunStats ) override;
13436 virtual void testRunEndedCumulative() = 0;
13437
13438 void skipTest(TestCaseInfo const&) override {}
13439
13440 protected:
13442 bool m_shouldStoreSuccesfulAssertions = true;
13444 bool m_shouldStoreFailedAssertions = true;
13445
13446 // We need lazy construction here. We should probably refactor it
13447 // later, after the events are redone.
13449 Detail::unique_ptr<TestRunNode> m_testRun;
13450
13451 private:
13452 // Note: We rely on pointer identity being stable, which is why
13453 // we store pointers to the nodes rather than the values.
13454 std::vector<Detail::unique_ptr<TestCaseNode>> m_testCases;
13455 // Root section of the _current_ test case
13456 Detail::unique_ptr<SectionNode> m_rootSection;
13457 // Deepest section of the _current_ test case
13458 SectionNode* m_deepestSection = nullptr;
13459 // Stack of _active_ sections in the _current_ test case
13460 std::vector<SectionNode*> m_sectionStack;
13461 };
13462
13463} // end namespace Catch
13464
13465#endif // CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
13466
13467
13468#ifndef CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
13469#define CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
13470
13471
13472namespace Catch {
13473
13481 class EventListenerBase : public IEventListener {
13482 public:
13483 using IEventListener::IEventListener;
13484
13485 void reportInvalidTestSpec( StringRef unmatchedSpec ) override;
13486 void fatalErrorEncountered( StringRef error ) override;
13487
13488 void benchmarkPreparing( StringRef name ) override;
13489 void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
13490 void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
13491 void benchmarkFailed( StringRef error ) override;
13492
13493 void assertionStarting( AssertionInfo const& assertionInfo ) override;
13494 void assertionEnded( AssertionStats const& assertionStats ) override;
13495
13496 void listReporters(
13497 std::vector<ReporterDescription> const& descriptions ) override;
13498 void listListeners(
13499 std::vector<ListenerDescription> const& descriptions ) override;
13500 void listTests( std::vector<TestCaseHandle> const& tests ) override;
13501 void listTags( std::vector<TagInfo> const& tagInfos ) override;
13502
13503 void noMatchingTestCases( StringRef unmatchedSpec ) override;
13504 void testRunStarting( TestRunInfo const& testRunInfo ) override;
13505 void testCaseStarting( TestCaseInfo const& testInfo ) override;
13506 void testCasePartialStarting( TestCaseInfo const& testInfo,
13507 uint64_t partNumber ) override;
13508 void sectionStarting( SectionInfo const& sectionInfo ) override;
13509 void sectionEnded( SectionStats const& sectionStats ) override;
13510 void testCasePartialEnded( TestCaseStats const& testCaseStats,
13511 uint64_t partNumber ) override;
13512 void testCaseEnded( TestCaseStats const& testCaseStats ) override;
13513 void testRunEnded( TestRunStats const& testRunStats ) override;
13514 void skipTest( TestCaseInfo const& testInfo ) override;
13515 };
13516
13517} // end namespace Catch
13518
13519#endif // CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
13520
13521
13522#ifndef CATCH_REPORTER_HELPERS_HPP_INCLUDED
13523#define CATCH_REPORTER_HELPERS_HPP_INCLUDED
13524
13525#include <iosfwd>
13526#include <string>
13527#include <vector>
13528
13529
13530namespace Catch {
13531
13532 class IConfig;
13533 class TestCaseHandle;
13534 class ColourImpl;
13535
13536 // Returns double formatted as %.3f (format expected on output)
13537 std::string getFormattedDuration( double duration );
13538
13540 bool shouldShowDuration( IConfig const& config, double duration );
13541
13542 std::string serializeFilters( std::vector<std::string> const& filters );
13543
13544 struct lineOfChars {
13545 char c;
13546 constexpr lineOfChars( char c_ ): c( c_ ) {}
13547
13548 friend std::ostream& operator<<( std::ostream& out, lineOfChars value );
13549 };
13550
13559 void
13560 defaultListReporters( std::ostream& out,
13561 std::vector<ReporterDescription> const& descriptions,
13562 Verbosity verbosity );
13563
13568 void defaultListListeners( std::ostream& out,
13569 std::vector<ListenerDescription> const& descriptions );
13570
13578 void defaultListTags( std::ostream& out, std::vector<TagInfo> const& tags, bool isFiltered );
13579
13589 void defaultListTests( std::ostream& out,
13590 ColourImpl* streamColour,
13591 std::vector<TestCaseHandle> const& tests,
13592 bool isFiltered,
13593 Verbosity verbosity );
13594
13600 void printTestRunTotals( std::ostream& stream,
13601 ColourImpl& streamColour,
13602 Totals const& totals );
13603
13604} // end namespace Catch
13605
13606#endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED
13607
13608
13609
13610#ifndef CATCH_REPORTER_JSON_HPP_INCLUDED
13611#define CATCH_REPORTER_JSON_HPP_INCLUDED
13612
13613
13614#include <stack>
13615
13616namespace Catch {
13617 class JsonReporter : public StreamingReporterBase {
13618 public:
13619 JsonReporter( ReporterConfig&& config );
13620
13621 ~JsonReporter() override;
13622
13623 static std::string getDescription();
13624
13625 public: // StreamingReporterBase
13626 void testRunStarting( TestRunInfo const& runInfo ) override;
13627 void testRunEnded( TestRunStats const& runStats ) override;
13628
13629 void testCaseStarting( TestCaseInfo const& tcInfo ) override;
13630 void testCaseEnded( TestCaseStats const& tcStats ) override;
13631
13632 void testCasePartialStarting( TestCaseInfo const& tcInfo,
13633 uint64_t index ) override;
13634 void testCasePartialEnded( TestCaseStats const& tcStats,
13635 uint64_t index ) override;
13636
13637 void sectionStarting( SectionInfo const& sectionInfo ) override;
13638 void sectionEnded( SectionStats const& sectionStats ) override;
13639
13640 void assertionStarting( AssertionInfo const& assertionInfo ) override;
13641 void assertionEnded( AssertionStats const& assertionStats ) override;
13642
13643 //void testRunEndedCumulative() override;
13644
13645 void benchmarkPreparing( StringRef name ) override;
13646 void benchmarkStarting( BenchmarkInfo const& ) override;
13647 void benchmarkEnded( BenchmarkStats<> const& ) override;
13648 void benchmarkFailed( StringRef error ) override;
13649
13650 void listReporters(
13651 std::vector<ReporterDescription> const& descriptions ) override;
13652 void listListeners(
13653 std::vector<ListenerDescription> const& descriptions ) override;
13654 void listTests( std::vector<TestCaseHandle> const& tests ) override;
13655 void listTags( std::vector<TagInfo> const& tags ) override;
13656
13657 private:
13658 Timer m_testCaseTimer;
13659 enum class Writer {
13660 Object,
13661 Array
13662 };
13663
13664 JsonArrayWriter& startArray();
13665 JsonArrayWriter& startArray( StringRef key );
13666
13667 JsonObjectWriter& startObject();
13668 JsonObjectWriter& startObject( StringRef key );
13669
13670 void endObject();
13671 void endArray();
13672
13673 bool isInside( Writer writer );
13674
13675 void startListing();
13676 void endListing();
13677
13678 // Invariant:
13679 // When m_writers is not empty and its top element is
13680 // - Writer::Object, then m_objectWriters is not be empty
13681 // - Writer::Array, then m_arrayWriters shall not be empty
13682 std::stack<JsonObjectWriter> m_objectWriters{};
13683 std::stack<JsonArrayWriter> m_arrayWriters{};
13684 std::stack<Writer> m_writers{};
13685
13686 bool m_startedListing = false;
13687
13688 // std::size_t m_sectionDepth = 0;
13689 // std::size_t m_sectionStarted = 0;
13690 };
13691} // namespace Catch
13692
13693#endif // CATCH_REPORTER_JSON_HPP_INCLUDED
13694
13695
13696#ifndef CATCH_REPORTER_JUNIT_HPP_INCLUDED
13697#define CATCH_REPORTER_JUNIT_HPP_INCLUDED
13698
13699
13700
13701namespace Catch {
13702
13703 class JunitReporter final : public CumulativeReporterBase {
13704 public:
13705 JunitReporter(ReporterConfig&& _config);
13706
13707 static std::string getDescription();
13708
13709 void testRunStarting(TestRunInfo const& runInfo) override;
13710
13711 void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
13712 void assertionEnded(AssertionStats const& assertionStats) override;
13713
13714 void testCaseEnded(TestCaseStats const& testCaseStats) override;
13715
13716 void testRunEndedCumulative() override;
13717
13718 private:
13719 void writeRun(TestRunNode const& testRunNode, double suiteTime);
13720
13721 void writeTestCase(TestCaseNode const& testCaseNode);
13722
13723 void writeSection( std::string const& className,
13724 std::string const& rootName,
13725 SectionNode const& sectionNode,
13726 bool testOkToFail );
13727
13728 void writeAssertions(SectionNode const& sectionNode);
13729 void writeAssertion(AssertionStats const& stats);
13730
13731 XmlWriter xml;
13732 Timer suiteTimer;
13733 std::string stdOutForSuite;
13734 std::string stdErrForSuite;
13735 unsigned int unexpectedExceptions = 0;
13736 bool m_okToFail = false;
13737 };
13738
13739} // end namespace Catch
13740
13741#endif // CATCH_REPORTER_JUNIT_HPP_INCLUDED
13742
13743
13744#ifndef CATCH_REPORTER_MULTI_HPP_INCLUDED
13745#define CATCH_REPORTER_MULTI_HPP_INCLUDED
13746
13747
13748namespace Catch {
13749
13750 class MultiReporter final : public IEventListener {
13751 /*
13752 * Stores all added reporters and listeners
13753 *
13754 * All Listeners are stored before all reporters, and individual
13755 * listeners/reporters are stored in order of insertion.
13756 */
13757 std::vector<IEventListenerPtr> m_reporterLikes;
13758 bool m_haveNoncapturingReporters = false;
13759
13760 // Keep track of how many listeners we have already inserted,
13761 // so that we can insert them into the main vector at the right place
13762 size_t m_insertedListeners = 0;
13763
13764 void updatePreferences(IEventListener const& reporterish);
13765
13766 public:
13767 using IEventListener::IEventListener;
13768
13769 void addListener( IEventListenerPtr&& listener );
13770 void addReporter( IEventListenerPtr&& reporter );
13771
13772 public: // IEventListener
13773
13774 void noMatchingTestCases( StringRef unmatchedSpec ) override;
13775 void fatalErrorEncountered( StringRef error ) override;
13776 void reportInvalidTestSpec( StringRef arg ) override;
13777
13778 void benchmarkPreparing( StringRef name ) override;
13779 void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
13780 void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
13781 void benchmarkFailed( StringRef error ) override;
13782
13783 void testRunStarting( TestRunInfo const& testRunInfo ) override;
13784 void testCaseStarting( TestCaseInfo const& testInfo ) override;
13785 void testCasePartialStarting(TestCaseInfo const& testInfo, uint64_t partNumber) override;
13786 void sectionStarting( SectionInfo const& sectionInfo ) override;
13787 void assertionStarting( AssertionInfo const& assertionInfo ) override;
13788
13789 void assertionEnded( AssertionStats const& assertionStats ) override;
13790 void sectionEnded( SectionStats const& sectionStats ) override;
13791 void testCasePartialEnded(TestCaseStats const& testStats, uint64_t partNumber) override;
13792 void testCaseEnded( TestCaseStats const& testCaseStats ) override;
13793 void testRunEnded( TestRunStats const& testRunStats ) override;
13794
13795 void skipTest( TestCaseInfo const& testInfo ) override;
13796
13797 void listReporters(std::vector<ReporterDescription> const& descriptions) override;
13798 void listListeners(std::vector<ListenerDescription> const& descriptions) override;
13799 void listTests(std::vector<TestCaseHandle> const& tests) override;
13800 void listTags(std::vector<TagInfo> const& tags) override;
13801
13802
13803 };
13804
13805} // end namespace Catch
13806
13807#endif // CATCH_REPORTER_MULTI_HPP_INCLUDED
13808
13809
13810#ifndef CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
13811#define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
13812
13813
13814#include <type_traits>
13815
13816namespace Catch {
13817
13818 namespace Detail {
13819
13820 template <typename T, typename = void>
13821 struct has_description : std::false_type {};
13822
13823 template <typename T>
13824 struct has_description<
13825 T,
13826 void_t<decltype( T::getDescription() )>>
13827 : std::true_type {};
13828
13831 void registerReporterImpl( std::string const& name,
13832 IReporterFactoryPtr reporterPtr );
13834 void registerListenerImpl( Detail::unique_ptr<EventListenerFactory> listenerFactory );
13835 } // namespace Detail
13836
13837 class IEventListener;
13838 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
13839
13840 template <typename T>
13841 class ReporterFactory : public IReporterFactory {
13842
13843 IEventListenerPtr create( ReporterConfig&& config ) const override {
13844 return Detail::make_unique<T>( CATCH_MOVE(config) );
13845 }
13846
13847 std::string getDescription() const override {
13848 return T::getDescription();
13849 }
13850 };
13851
13852
13853 template<typename T>
13854 class ReporterRegistrar {
13855 public:
13856 explicit ReporterRegistrar( std::string const& name ) {
13858 Detail::make_unique<ReporterFactory<T>>() );
13859 }
13860 };
13861
13862 template<typename T>
13863 class ListenerRegistrar {
13864
13865 class TypedListenerFactory : public EventListenerFactory {
13866 StringRef m_listenerName;
13867
13868 std::string getDescriptionImpl( std::true_type ) const {
13869 return T::getDescription();
13870 }
13871
13872 std::string getDescriptionImpl( std::false_type ) const {
13873 return "(No description provided)";
13874 }
13875
13876 public:
13877 TypedListenerFactory( StringRef listenerName ):
13878 m_listenerName( listenerName ) {}
13879
13880 IEventListenerPtr create( IConfig const* config ) const override {
13881 return Detail::make_unique<T>( config );
13882 }
13883
13884 StringRef getName() const override {
13885 return m_listenerName;
13886 }
13887
13888 std::string getDescription() const override {
13889 return getDescriptionImpl( Detail::has_description<T>{} );
13890 }
13891 };
13892
13893 public:
13894 ListenerRegistrar(StringRef listenerName) {
13895 registerListenerImpl( Detail::make_unique<TypedListenerFactory>(listenerName) );
13896 }
13897 };
13898}
13899
13900#if !defined(CATCH_CONFIG_DISABLE)
13901
13902# define CATCH_REGISTER_REPORTER( name, reporterType ) \
13903 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
13904 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
13905 namespace { \
13906 Catch::ReporterRegistrar<reporterType> INTERNAL_CATCH_UNIQUE_NAME( \
13907 catch_internal_RegistrarFor )( name ); \
13908 } \
13909 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
13910
13911# define CATCH_REGISTER_LISTENER( listenerType ) \
13912 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
13913 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
13914 namespace { \
13915 Catch::ListenerRegistrar<listenerType> INTERNAL_CATCH_UNIQUE_NAME( \
13916 catch_internal_RegistrarFor )( #listenerType##_catch_sr ); \
13917 } \
13918 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
13919
13920#else // CATCH_CONFIG_DISABLE
13921
13922#define CATCH_REGISTER_REPORTER(name, reporterType)
13923#define CATCH_REGISTER_LISTENER(listenerType)
13924
13925#endif // CATCH_CONFIG_DISABLE
13926
13927#endif // CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
13928
13929
13930#ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
13931#define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
13932
13933
13934
13935namespace Catch {
13936
13937 class SonarQubeReporter final : public CumulativeReporterBase {
13938 public:
13939 SonarQubeReporter(ReporterConfig&& config)
13940 : CumulativeReporterBase(CATCH_MOVE(config))
13941 , xml(m_stream) {
13942 m_preferences.shouldRedirectStdOut = true;
13943 m_preferences.shouldReportAllAssertions = false;
13944 m_shouldStoreSuccesfulAssertions = false;
13945 }
13946
13947 static std::string getDescription() {
13948 using namespace std::string_literals;
13949 return "Reports test results in the Generic Test Data SonarQube XML format"s;
13950 }
13951
13952 void testRunStarting( TestRunInfo const& testRunInfo ) override;
13953
13954 void testRunEndedCumulative() override {
13955 writeRun( *m_testRun );
13956 xml.endElement();
13957 }
13958
13959 void writeRun( TestRunNode const& runNode );
13960
13961 void writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes);
13962
13963 void writeTestCase(TestCaseNode const& testCaseNode);
13964
13965 void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail);
13966
13967 void writeAssertions(SectionNode const& sectionNode, bool okToFail);
13968
13969 void writeAssertion(AssertionStats const& stats, bool okToFail);
13970
13971 private:
13972 XmlWriter xml;
13973 };
13974
13975
13976} // end namespace Catch
13977
13978#endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
13979
13980
13981#ifndef CATCH_REPORTER_TAP_HPP_INCLUDED
13982#define CATCH_REPORTER_TAP_HPP_INCLUDED
13983
13984
13985namespace Catch {
13986
13987 class TAPReporter final : public StreamingReporterBase {
13988 public:
13989 TAPReporter( ReporterConfig&& config ):
13990 StreamingReporterBase( CATCH_MOVE(config) ) {
13991 m_preferences.shouldReportAllAssertions = true;
13992 }
13993
13994 static std::string getDescription() {
13995 using namespace std::string_literals;
13996 return "Reports test results in TAP format, suitable for test harnesses"s;
13997 }
13998
13999 void testRunStarting( TestRunInfo const& testInfo ) override;
14000
14001 void noMatchingTestCases( StringRef unmatchedSpec ) override;
14002
14003 void assertionEnded(AssertionStats const& _assertionStats) override;
14004
14005 void testRunEnded(TestRunStats const& _testRunStats) override;
14006
14007 private:
14008 std::size_t counter = 0;
14009 };
14010
14011} // end namespace Catch
14012
14013#endif // CATCH_REPORTER_TAP_HPP_INCLUDED
14014
14015
14016#ifndef CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
14017#define CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
14018
14019
14020#include <cstring>
14021
14022#ifdef __clang__
14023# pragma clang diagnostic push
14024# pragma clang diagnostic ignored "-Wpadded"
14025#endif
14026
14027namespace Catch {
14028
14029 class TeamCityReporter final : public StreamingReporterBase {
14030 public:
14031 TeamCityReporter( ReporterConfig&& _config )
14032 : StreamingReporterBase( CATCH_MOVE(_config) )
14033 {
14034 m_preferences.shouldRedirectStdOut = true;
14035 }
14036
14037 ~TeamCityReporter() override;
14038
14039 static std::string getDescription() {
14040 using namespace std::string_literals;
14041 return "Reports test results as TeamCity service messages"s;
14042 }
14043
14044 void testRunStarting( TestRunInfo const& runInfo ) override;
14045 void testRunEnded( TestRunStats const& runStats ) override;
14046
14047
14048 void assertionEnded(AssertionStats const& assertionStats) override;
14049
14050 void sectionStarting(SectionInfo const& sectionInfo) override {
14051 m_headerPrintedForThisSection = false;
14052 StreamingReporterBase::sectionStarting( sectionInfo );
14053 }
14054
14055 void testCaseStarting(TestCaseInfo const& testInfo) override;
14056
14057 void testCaseEnded(TestCaseStats const& testCaseStats) override;
14058
14059 private:
14060 void printSectionHeader(std::ostream& os);
14061
14062 bool m_headerPrintedForThisSection = false;
14063 Timer m_testTimer;
14064 };
14065
14066} // end namespace Catch
14067
14068#ifdef __clang__
14069# pragma clang diagnostic pop
14070#endif
14071
14072#endif // CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
14073
14074
14075#ifndef CATCH_REPORTER_XML_HPP_INCLUDED
14076#define CATCH_REPORTER_XML_HPP_INCLUDED
14077
14078
14079
14080
14081namespace Catch {
14082 class XmlReporter : public StreamingReporterBase {
14083 public:
14084 XmlReporter(ReporterConfig&& _config);
14085
14086 ~XmlReporter() override;
14087
14088 static std::string getDescription();
14089
14090 virtual std::string getStylesheetRef() const;
14091
14092 void writeSourceInfo(SourceLineInfo const& sourceInfo);
14093
14094 public: // StreamingReporterBase
14095
14096 void testRunStarting(TestRunInfo const& testInfo) override;
14097
14098 void testCaseStarting(TestCaseInfo const& testInfo) override;
14099
14100 void sectionStarting(SectionInfo const& sectionInfo) override;
14101
14102 void assertionStarting(AssertionInfo const&) override;
14103
14104 void assertionEnded(AssertionStats const& assertionStats) override;
14105
14106 void sectionEnded(SectionStats const& sectionStats) override;
14107
14108 void testCaseEnded(TestCaseStats const& testCaseStats) override;
14109
14110 void testRunEnded(TestRunStats const& testRunStats) override;
14111
14112 void benchmarkPreparing( StringRef name ) override;
14113 void benchmarkStarting(BenchmarkInfo const&) override;
14114 void benchmarkEnded(BenchmarkStats<> const&) override;
14115 void benchmarkFailed( StringRef error ) override;
14116
14117 void listReporters(std::vector<ReporterDescription> const& descriptions) override;
14118 void listListeners(std::vector<ListenerDescription> const& descriptions) override;
14119 void listTests(std::vector<TestCaseHandle> const& tests) override;
14120 void listTags(std::vector<TagInfo> const& tags) override;
14121
14122 private:
14123 Timer m_testCaseTimer;
14124 XmlWriter m_xml;
14125 int m_sectionDepth = 0;
14126 };
14127
14128} // end namespace Catch
14129
14130#endif // CATCH_REPORTER_XML_HPP_INCLUDED
14131
14132#endif // CATCH_REPORTERS_ALL_HPP_INCLUDED
14133
14134#endif // CATCH_ALL_HPP_INCLUDED
14135#endif // CATCH_AMALGAMATED_HPP_INCLUDED
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR(id, op)
Definition catch_amalgamated.hpp:5485
#define CATCH_DEFINE_COMPARABLE_TRAIT(id, op)
Definition catch_amalgamated.hpp:5088
#define CarryBits(x)
#define CATCH_CATCH_ANON(type)
Definition catch_amalgamated.hpp:522
#define CATCH_MOVE(...)
Replacement for std::move with better compile time performance.
Definition catch_amalgamated.hpp:610
#define CATCH_EXPORT
Definition catch_amalgamated.hpp:548
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(op)
Definition catch_amalgamated.hpp:5537
std::ostream & operator<<(std::ostream &, Catch_global_namespace_dummy)
#define SizedUnsignedTypeHelper(TYPE)
#define CATCH_TRY
Definition catch_amalgamated.hpp:520
#define CATCH_FORWARD(...)
Replacement for std::forward with better compile time performance.
Definition catch_amalgamated.hpp:613
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR(id, op)
Definition catch_amalgamated.hpp:5431
#define CATCH_CATCH_ALL
Definition catch_amalgamated.hpp:521
Approx(double value)
Definition catch_amalgamated.cpp:566
void setMargin(double margin)
Definition catch_amalgamated.cpp:597
Approx operator-() const
Definition catch_amalgamated.cpp:577
bool equalityComparisonImpl(double other) const
Definition catch_amalgamated.cpp:590
void setEpsilon(double epsilon)
Definition catch_amalgamated.cpp:604
static Approx custom()
Definition catch_amalgamated.cpp:573
Approx & epsilon(T const &newEpsilon)
Definition catch_amalgamated.hpp:3186
Approx & margin(T const &newMargin)
Definition catch_amalgamated.hpp:3193
Definition catch_amalgamated.hpp:3115
Approx(double value)
Definition catch_amalgamated.cpp:566
Approx(T const &value)
Definition catch_amalgamated.hpp:3140
double m_value
Definition catch_amalgamated.hpp:3211
void setMargin(double margin)
Definition catch_amalgamated.cpp:597
Approx operator()(T const &value) const
Definition catch_amalgamated.hpp:3131
bool equalityComparisonImpl(double other) const
Definition catch_amalgamated.cpp:590
double m_epsilon
Definition catch_amalgamated.hpp:3208
Approx & scale(T const &newScale)
Definition catch_amalgamated.hpp:3200
void setEpsilon(double epsilon)
Definition catch_amalgamated.cpp:604
double m_scale
Definition catch_amalgamated.hpp:3210
static Approx custom()
Definition catch_amalgamated.cpp:573
friend bool operator==(const T &lhs, Approx const &rhs)
Definition catch_amalgamated.hpp:3145
Approx & epsilon(T const &newEpsilon)
Definition catch_amalgamated.hpp:3186
double m_margin
Definition catch_amalgamated.hpp:3209
Approx & margin(T const &newMargin)
Definition catch_amalgamated.hpp:3193
Definition catch_amalgamated.hpp:5617
~AssertionHandler()
Definition catch_amalgamated.hpp:5629
bool m_completed
Definition catch_amalgamated.hpp:5620
AssertionHandler(StringRef macroName, SourceLineInfo const &lineInfo, StringRef capturedExpression, ResultDisposition::Flags resultDisposition)
Definition catch_amalgamated.cpp:2529
AssertionReaction m_reaction
Definition catch_amalgamated.hpp:5619
constexpr void handleExpr(ExprLhs< T > const &expr)
Definition catch_amalgamated.hpp:5637
AssertionInfo m_assertionInfo
Definition catch_amalgamated.hpp:5618
IResultCapture & m_resultCapture
Definition catch_amalgamated.hpp:5621
Definition catch_amalgamated.hpp:3338
StringRef getMessage() const
Definition catch_amalgamated.cpp:710
StringRef getTestMacroName() const
Definition catch_amalgamated.cpp:717
std::string getExpression() const
Definition catch_amalgamated.cpp:673
AssertionInfo m_info
Definition catch_amalgamated.hpp:3357
bool hasExpandedExpression() const
Definition catch_amalgamated.cpp:699
SourceLineInfo getSourceInfo() const
Definition catch_amalgamated.cpp:713
std::string getExpandedExpression() const
Definition catch_amalgamated.cpp:703
std::string getExpressionInMacro() const
Definition catch_amalgamated.cpp:686
bool hasMessage() const
Definition catch_amalgamated.cpp:669
bool hasExpression() const
Definition catch_amalgamated.cpp:665
bool succeeded() const
Definition catch_amalgamated.cpp:652
ResultWas::OfType getResultType() const
Definition catch_amalgamated.cpp:661
AssertionResultData m_resultData
Definition catch_amalgamated.hpp:3358
bool isOk() const
Definition catch_amalgamated.cpp:657
Definition catch_amalgamated.hpp:5334
LhsT m_lhs
Definition catch_amalgamated.hpp:5335
RhsT m_rhs
Definition catch_amalgamated.hpp:5337
StringRef m_op
Definition catch_amalgamated.hpp:5336
constexpr BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
Definition catch_amalgamated.hpp:5345
void streamReconstructedExpression(std::ostream &os) const override
This function has to be overriden by the derived class.
Definition catch_amalgamated.hpp:5339
void captureValue(size_t index, std::string const &value)
Definition catch_amalgamated.cpp:1066
size_t m_captured
Definition catch_amalgamated.hpp:4018
IResultCapture & m_resultCapture
Definition catch_amalgamated.hpp:4017
void captureValues(size_t index, T const &value)
Definition catch_amalgamated.hpp:4030
Capturer & operator=(Capturer const &)=delete
void captureValues(size_t index, T const &value, Ts const &... values)
Definition catch_amalgamated.hpp:4035
Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names)
Definition catch_amalgamated.cpp:995
Capturer(Capturer const &)=delete
std::vector< MessageInfo > m_messages
Definition catch_amalgamated.hpp:4016
Definition catch_amalgamated.hpp:4730
Detail::InternalParseResult parse(std::string const &, Detail::TokenStream tokens) const override
Definition catch_amalgamated.cpp:2776
Definition catch_amalgamated.hpp:4879
StringRef m_exeName
Definition catch_amalgamated.hpp:4881
std::vector< StringRef > m_args
Definition catch_amalgamated.hpp:4882
StringRef exeName() const
Definition catch_amalgamated.hpp:4889
Args(int argc, char const *const *argv)
Definition catch_amalgamated.cpp:3055
Definition catch_amalgamated.hpp:4406
static auto ok(U &&value) -> BasicResult
Definition catch_amalgamated.hpp:4416
static auto ok() -> BasicResult
Definition catch_amalgamated.hpp:4419
BasicResult(BasicResult< U > const &other)
Definition catch_amalgamated.hpp:4409
auto errorMessage() const -> std::string const &
Definition catch_amalgamated.hpp:4433
std::string m_errorMessage
Definition catch_amalgamated.hpp:4449
void enforceOk() const override
Definition catch_amalgamated.hpp:4438
BasicResult(ResultType type, std::string &&message)
Definition catch_amalgamated.hpp:4451
static auto runtimeError(std::string &&message) -> BasicResult
Definition catch_amalgamated.hpp:4424
auto type() const -> ResultType
Definition catch_amalgamated.hpp:4432
static auto logicError(std::string &&message) -> BasicResult
Definition catch_amalgamated.hpp:4420
Definition catch_amalgamated.hpp:4653
auto operator|(T const &other) const -> Parser
ParseState(ParseResultType type, TokenStream remainingTokens)
Definition catch_amalgamated.cpp:2757
TokenStream && remainingTokens() &&
Definition catch_amalgamated.hpp:4470
ParseResultType type() const
Definition catch_amalgamated.hpp:4466
TokenStream const & remainingTokens() const &
Definition catch_amalgamated.hpp:4467
TokenStream m_remainingTokens
Definition catch_amalgamated.hpp:4476
ParseResultType m_type
Definition catch_amalgamated.hpp:4475
Definition catch_amalgamated.hpp:4640
virtual auto parse(std::string const &exeName, TokenStream tokens) const -> InternalParseResult=0
virtual auto validate() const -> Result
Definition catch_amalgamated.hpp:4643
virtual size_t cardinality() const
Definition catch_amalgamated.cpp:2751
Definition catch_amalgamated.hpp:4661
ParserRefImpl(std::shared_ptr< BoundRef > const &ref)
Definition catch_amalgamated.hpp:4668
DerivedT && operator()(StringRef description) &&
Definition catch_amalgamated.hpp:4697
ParserRefImpl(T &ref, StringRef hint)
Definition catch_amalgamated.hpp:4682
ParserRefImpl(LambdaT const &ref, StringRef hint)
Definition catch_amalgamated.hpp:4689
StringRef m_description
Definition catch_amalgamated.hpp:4666
DerivedT & operator()(StringRef description) &
Definition catch_amalgamated.hpp:4693
Optionality m_optionality
Definition catch_amalgamated.hpp:4663
auto isOptional() const -> bool
Definition catch_amalgamated.hpp:4712
auto optional() -> DerivedT &
Definition catch_amalgamated.hpp:4702
ParserRefImpl(accept_many_t, LambdaT const &ref, StringRef hint)
Definition catch_amalgamated.hpp:4673
StringRef m_hint
Definition catch_amalgamated.hpp:4665
auto cardinality() const -> size_t override
Definition catch_amalgamated.hpp:4716
StringRef hint() const
Definition catch_amalgamated.hpp:4723
auto required() -> DerivedT &
Definition catch_amalgamated.hpp:4707
std::shared_ptr< BoundRef > m_ref
Definition catch_amalgamated.hpp:4664
ResultBase(ResultType type)
Definition catch_amalgamated.hpp:4323
ResultBase(ResultBase const &)=default
ResultBase & operator=(ResultBase const &)=default
ResultBase & operator=(ResultBase &&)=default
ResultBase(ResultBase &&)=default
virtual void enforceOk() const =0
ResultType m_type
Definition catch_amalgamated.hpp:4334
ResultBase(ResultType type)
Definition catch_amalgamated.hpp:4323
Definition catch_amalgamated.hpp:4338
ResultValueBase(ResultType, T const &value)
Definition catch_amalgamated.hpp:4364
ResultValueBase & operator=(ResultValueBase const &other)
Definition catch_amalgamated.hpp:4373
ResultValueBase & operator=(ResultValueBase &&other)
Definition catch_amalgamated.hpp:4381
ResultValueBase(ResultType, T &&value)
Definition catch_amalgamated.hpp:4368
T m_value
Definition catch_amalgamated.hpp:4396
ResultValueBase(ResultValueBase const &other)
Definition catch_amalgamated.hpp:4352
T const & value() const &
Definition catch_amalgamated.hpp:4340
ResultValueBase(ResultType type)
Definition catch_amalgamated.hpp:4350
ResultValueBase(ResultValueBase &&other)
Definition catch_amalgamated.hpp:4357
~ResultValueBase() override
Definition catch_amalgamated.hpp:4390
T && value() &&
Definition catch_amalgamated.hpp:4344
Definition catch_amalgamated.hpp:4281
Token const * operator->() const
Definition catch_amalgamated.hpp:4305
std::vector< StringRef >::const_iterator Iterator
Definition catch_amalgamated.hpp:4282
size_t count() const
Definition catch_amalgamated.hpp:4296
void loadBuffer()
Definition catch_amalgamated.cpp:2669
Iterator it
Definition catch_amalgamated.hpp:4283
Token operator*() const
Definition catch_amalgamated.hpp:4300
TokenStream(Args const &args)
Definition catch_amalgamated.cpp:2708
Iterator itEnd
Definition catch_amalgamated.hpp:4284
std::vector< Token > m_tokenBuffer
Definition catch_amalgamated.hpp:4285
Definition catch_amalgamated.hpp:4792
ExeName()
Definition catch_amalgamated.cpp:2898
std::string const & name() const
Definition catch_amalgamated.hpp:4811
ExeName(LambdaT const &lambda)
Definition catch_amalgamated.hpp:4801
std::shared_ptr< std::string > m_name
Definition catch_amalgamated.hpp:4793
std::shared_ptr< Detail::BoundValueRefBase > m_ref
Definition catch_amalgamated.hpp:4794
Definition catch_amalgamated.hpp:4741
Opt & operator[](StringRef optName) &
Definition catch_amalgamated.hpp:4769
Opt(LambdaT const &ref, StringRef hint)
Definition catch_amalgamated.hpp:4756
std::vector< StringRef > m_optNames
Definition catch_amalgamated.hpp:4743
Opt(LambdaT const &ref)
Definition catch_amalgamated.hpp:4747
Opt && operator[](StringRef optName) &&
Definition catch_amalgamated.hpp:4773
Opt(T &ref, StringRef hint)
Definition catch_amalgamated.hpp:4766
Opt(accept_many_t, LambdaT const &ref, StringRef hint)
Definition catch_amalgamated.hpp:4760
Definition catch_amalgamated.hpp:4817
friend Parser & operator|=(Parser &p, Opt const &opt)
Definition catch_amalgamated.hpp:4834
ExeName m_exeName
Definition catch_amalgamated.hpp:4818
auto operator|=(Arg const &arg) -> Parser &
Definition catch_amalgamated.hpp:4829
friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream &
Definition catch_amalgamated.hpp:4862
std::vector< Arg > m_args
Definition catch_amalgamated.hpp:4820
friend Parser operator|(Parser &&p, T &&rhs)
Definition catch_amalgamated.hpp:4853
friend Parser operator|(Parser const &p, T &&rhs)
Definition catch_amalgamated.hpp:4846
auto operator|=(ExeName const &exeName) -> Parser &
Definition catch_amalgamated.hpp:4824
friend Parser & operator|=(Parser &p, Opt &&opt)
Definition catch_amalgamated.hpp:4838
std::vector< Opt > m_options
Definition catch_amalgamated.hpp:4819
Definition catch_amalgamated.hpp:3809
unsigned int shardCount() const override
Definition catch_amalgamated.cpp:907
std::vector< std::string > const & getTestsOrTags() const override
Definition catch_amalgamated.cpp:875
double benchmarkConfidenceInterval() const override
Definition catch_amalgamated.cpp:918
bool hasTestFilters() const override
Definition catch_amalgamated.cpp:888
ColourMode defaultColourMode() const override
Definition catch_amalgamated.cpp:909
unsigned int benchmarkSamples() const override
Definition catch_amalgamated.cpp:917
TestSpec m_testSpec
Definition catch_amalgamated.hpp:3864
std::vector< std::string > const & getSectionsToRun() const override
Definition catch_amalgamated.cpp:876
std::vector< ProcessedReporterSpec > m_processedReporterSpecs
Definition catch_amalgamated.hpp:3863
bool listTests() const
Definition catch_amalgamated.cpp:870
bool listReporters() const
Definition catch_amalgamated.cpp:872
bool warnAboutMissingAssertions() const override
Definition catch_amalgamated.cpp:896
unsigned int benchmarkResamples() const override
Definition catch_amalgamated.cpp:919
std::vector< ProcessedReporterSpec > const & getProcessedReporterSpecs() const
Definition catch_amalgamated.cpp:883
bool showInvisibles() const override
Definition catch_amalgamated.cpp:912
bool m_hasTestFilters
Definition catch_amalgamated.hpp:3865
bool includeSuccessfulResults() const override
Definition catch_amalgamated.cpp:895
bool listTags() const
Definition catch_amalgamated.cpp:871
std::chrono::milliseconds benchmarkWarmupTime() const override
Definition catch_amalgamated.cpp:920
std::vector< ReporterSpec > const & getReporterSpecs() const
Definition catch_amalgamated.cpp:878
TestSpec const & testSpec() const override
Definition catch_amalgamated.cpp:887
~Config() override
bool benchmarkNoAnalysis() const override
Definition catch_amalgamated.cpp:916
ShowDurations showDurations() const override
Definition catch_amalgamated.cpp:903
Verbosity verbosity() const override
Definition catch_amalgamated.cpp:913
double minDuration() const override
Definition catch_amalgamated.cpp:904
bool listListeners() const
Definition catch_amalgamated.cpp:873
StringRef name() const override
Definition catch_amalgamated.cpp:894
void readBazelEnvVars()
Definition catch_amalgamated.cpp:922
bool warnAboutUnmatchedTestSpecs() const override
Definition catch_amalgamated.cpp:899
bool skipBenchmarks() const override
Definition catch_amalgamated.cpp:915
bool zeroTestsCountAsSuccess() const override
Definition catch_amalgamated.cpp:902
TestRunOrder runOrder() const override
Definition catch_amalgamated.cpp:905
int abortAfter() const override
Definition catch_amalgamated.cpp:911
ConfigData m_data
Definition catch_amalgamated.hpp:3862
unsigned int shardIndex() const override
Definition catch_amalgamated.cpp:908
bool allowThrows() const override
Definition catch_amalgamated.cpp:893
bool shouldDebugBreak() const override
Definition catch_amalgamated.cpp:910
Config()=default
uint32_t rngSeed() const override
Definition catch_amalgamated.cpp:906
bool showHelp() const
Definition catch_amalgamated.cpp:890
Definition catch_amalgamated.hpp:563
IConfig const * m_config
Definition catch_amalgamated.hpp:564
IResultCapture * m_resultCapture
Definition catch_amalgamated.hpp:565
constexpr void setResultCapture(IResultCapture *resultCapture)
Definition catch_amalgamated.hpp:578
static void createContext()
Definition catch_amalgamated.cpp:3652
constexpr IConfig const * getConfig() const
Definition catch_amalgamated.hpp:577
constexpr void setConfig(IConfig const *config)
Definition catch_amalgamated.hpp:581
friend Context & getCurrentMutableContext()
Definition catch_amalgamated.cpp:3656
friend void cleanUpContext()
Definition catch_amalgamated.cpp:3648
static CATCH_EXPORT Context * currentContext
Definition catch_amalgamated.hpp:567
friend Context const & getCurrentContext()
Definition catch_amalgamated.hpp:587
constexpr IResultCapture * getResultCapture() const
Definition catch_amalgamated.hpp:574
Definition catch_amalgamated.hpp:2500
static auto test(int) -> decltype(std::declval< Stream & >()<< std::declval< U >(), std::true_type())
static const bool value
Definition catch_amalgamated.hpp:2509
static auto test(...) -> std::false_type
Deriving classes become noncopyable and nonmovable.
Definition catch_amalgamated.hpp:1131
NonCopyable & operator=(NonCopyable &&)=delete
NonCopyable & operator=(NonCopyable const &)=delete
NonCopyable(NonCopyable &&)=delete
NonCopyable(NonCopyable const &)=delete
NonCopyable() noexcept=default
Definition catch_amalgamated.hpp:890
T & operator*()
Definition catch_amalgamated.hpp:929
unique_ptr(unique_ptr &&rhs) noexcept
Definition catch_amalgamated.hpp:915
unique_ptr & operator=(unique_ptr &&rhs) noexcept
Definition catch_amalgamated.hpp:919
friend void swap(unique_ptr &lhs, unique_ptr &rhs)
Definition catch_amalgamated.hpp:964
constexpr unique_ptr(std::nullptr_t=nullptr)
Definition catch_amalgamated.hpp:893
T * operator->() noexcept
Definition catch_amalgamated.hpp:937
GeneratorUntypedBase * m_ptr
Definition catch_amalgamated.hpp:891
T * get()
Definition catch_amalgamated.hpp:946
GeneratorUntypedBase * release()
Definition catch_amalgamated.hpp:954
~unique_ptr()
Definition catch_amalgamated.hpp:925
unique_ptr & operator=(unique_ptr const &)=delete
unique_ptr(unique_ptr const &)=delete
void reset(T *ptr=nullptr)
Definition catch_amalgamated.hpp:949
T const * operator->() const noexcept
Definition catch_amalgamated.hpp:941
unique_ptr & operator=(unique_ptr< U > &&from)
Definition catch_amalgamated.hpp:906
T const & operator*() const
Definition catch_amalgamated.hpp:933
constexpr unique_ptr(T *ptr)
Definition catch_amalgamated.hpp:896
T const * get() const
Definition catch_amalgamated.hpp:947
unique_ptr(unique_ptr< U > &&from)
Definition catch_amalgamated.hpp:901
std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override
Definition catch_amalgamated.hpp:7255
constexpr ExceptionTranslator(std::string(*translateFunction)(T const &))
Definition catch_amalgamated.hpp:7251
std::string(* m_translateFunction)(T const &)
Definition catch_amalgamated.hpp:7272
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T const &))
Definition catch_amalgamated.hpp:7277
Definition catch_amalgamated.hpp:5426
constexpr auto makeUnaryExpr() const -> UnaryExpr< LhsT >
Definition catch_amalgamated.hpp:5574
constexpr ExprLhs(LhsT lhs)
Definition catch_amalgamated.hpp:5429
LhsT m_lhs
Definition catch_amalgamated.hpp:5427
GeneratorException(const char *msg)
Definition catch_amalgamated.hpp:7390
const char *const m_msg
Definition catch_amalgamated.hpp:7387
size_t m_chunk_size
Definition catch_amalgamated.hpp:7904
bool m_used_up
Definition catch_amalgamated.hpp:7906
ChunkGenerator(size_t size, GeneratorWrapper< T > generator)
Definition catch_amalgamated.hpp:7908
bool next() override
Definition catch_amalgamated.hpp:7925
GeneratorWrapper< T > m_generator
Definition catch_amalgamated.hpp:7905
std::vector< T > m_chunk
Definition catch_amalgamated.hpp:7903
std::vector< T > const & get() const override
Definition catch_amalgamated.hpp:7922
Definition catch_amalgamated.hpp:7765
bool next() override
Definition catch_amalgamated.hpp:7788
Predicate m_predicate
Definition catch_amalgamated.hpp:7767
GeneratorWrapper< T > m_generator
Definition catch_amalgamated.hpp:7766
T const & get() const override
Definition catch_amalgamated.hpp:7784
FilterGenerator(P &&pred, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7770
Definition catch_amalgamated.hpp:7561
size_t m_idx
Definition catch_amalgamated.hpp:7566
std::vector< T > m_values
Definition catch_amalgamated.hpp:7565
bool next() override
Definition catch_amalgamated.hpp:7573
FixedValuesGenerator(std::initializer_list< T > values)
Definition catch_amalgamated.hpp:7568
T const & get() const override
Definition catch_amalgamated.hpp:7570
Definition catch_amalgamated.hpp:7416
bool countedNext()
Definition catch_amalgamated.cpp:2399
std::string m_stringReprCache
Definition catch_amalgamated.hpp:7419
GeneratorUntypedBase & operator=(GeneratorUntypedBase const &)=default
GeneratorUntypedBase(GeneratorUntypedBase const &)=default
virtual std::string stringifyImpl() const =0
Customization point for currentElementAsString
std::size_t m_currentElementIndex
Definition catch_amalgamated.hpp:7422
std::size_t currentElementIndex() const
Definition catch_amalgamated.hpp:7456
Definition catch_amalgamated.hpp:7523
T const & get() const
Definition catch_amalgamated.hpp:7532
GeneratorWrapper(GeneratorPtr< T > generator)
Definition catch_amalgamated.hpp:7529
GeneratorWrapper(IGenerator< T > *generator)
Takes ownership of the passed pointer.
Definition catch_amalgamated.hpp:7527
bool next()
Definition catch_amalgamated.hpp:7535
GeneratorPtr< T > m_generator
Definition catch_amalgamated.hpp:7524
Definition catch_amalgamated.hpp:7591
Generators(Gs &&... moreGenerators)
Definition catch_amalgamated.hpp:7622
std::vector< GeneratorWrapper< T > > m_generators
Definition catch_amalgamated.hpp:7592
void add_generator(GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7595
size_t m_current
Definition catch_amalgamated.hpp:7593
void add_generators(U &&valueOrGenerator)
Definition catch_amalgamated.hpp:7610
void add_generator(T const &val)
Definition catch_amalgamated.hpp:7598
bool next() override
Definition catch_amalgamated.hpp:7631
T const & get() const override
Definition catch_amalgamated.hpp:7627
std::enable_if_t<!std::is_same< std::decay_t< U >, T >::value > add_generator(U &&val)
Definition catch_amalgamated.hpp:7606
void add_generator(T &&val)
Definition catch_amalgamated.hpp:7601
void add_generators(U &&valueOrGenerator, Gs &&... moreGenerators)
Definition catch_amalgamated.hpp:7615
Definition catch_amalgamated.hpp:7505
virtual T const & get() const =0
T type
Definition catch_amalgamated.hpp:7516
std::string stringifyImpl() const override
Customization point for currentElementAsString
Definition catch_amalgamated.hpp:7506
Definition catch_amalgamated.hpp:7861
MapGenerator(F2 &&function, GeneratorWrapper< U > &&generator)
Definition catch_amalgamated.hpp:7869
GeneratorWrapper< U > m_generator
Definition catch_amalgamated.hpp:7863
T m_cache
Definition catch_amalgamated.hpp:7866
bool next() override
Definition catch_amalgamated.hpp:7878
T const & get() const override
Definition catch_amalgamated.hpp:7875
Func m_function
Definition catch_amalgamated.hpp:7864
Definition catch_amalgamated.hpp:7805
T const & get() const override
Definition catch_amalgamated.hpp:7822
bool next() override
Definition catch_amalgamated.hpp:7830
RepeatGenerator(size_t repeats, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7815
size_t m_repeat_index
Definition catch_amalgamated.hpp:7813
size_t m_current_repeat
Definition catch_amalgamated.hpp:7812
GeneratorWrapper< T > m_generator
Definition catch_amalgamated.hpp:7809
std::vector< T > m_returned
Definition catch_amalgamated.hpp:7810
size_t m_target_repeats
Definition catch_amalgamated.hpp:7811
Definition catch_amalgamated.hpp:7542
bool next() override
Definition catch_amalgamated.hpp:7555
SingleValueGenerator(T const &value)
Definition catch_amalgamated.hpp:7545
SingleValueGenerator(T &&value)
Definition catch_amalgamated.hpp:7548
T m_value
Definition catch_amalgamated.hpp:7543
T const & get() const override
Definition catch_amalgamated.hpp:7552
Definition catch_amalgamated.hpp:7728
size_t m_returned
Definition catch_amalgamated.hpp:7730
GeneratorWrapper< T > m_generator
Definition catch_amalgamated.hpp:7729
T const & get() const override
Definition catch_amalgamated.hpp:7739
size_t m_target
Definition catch_amalgamated.hpp:7731
TakeGenerator(size_t target, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7733
bool next() override
Definition catch_amalgamated.hpp:7742
Definition catch_amalgamated.hpp:1197
virtual ~IConfig()
virtual double minDuration() const =0
virtual unsigned int benchmarkSamples() const =0
virtual ColourMode defaultColourMode() const =0
virtual bool includeSuccessfulResults() const =0
virtual int abortAfter() const =0
virtual unsigned int benchmarkResamples() const =0
virtual std::vector< std::string > const & getTestsOrTags() const =0
virtual bool hasTestFilters() const =0
virtual std::chrono::milliseconds benchmarkWarmupTime() const =0
virtual Verbosity verbosity() const =0
virtual ShowDurations showDurations() const =0
virtual bool shouldDebugBreak() const =0
virtual bool warnAboutUnmatchedTestSpecs() const =0
virtual TestSpec const & testSpec() const =0
virtual bool zeroTestsCountAsSuccess() const =0
virtual uint32_t rngSeed() const =0
virtual bool warnAboutMissingAssertions() const =0
virtual unsigned int shardIndex() const =0
virtual bool showInvisibles() const =0
virtual bool benchmarkNoAnalysis() const =0
virtual bool allowThrows() const =0
virtual bool skipBenchmarks() const =0
virtual unsigned int shardCount() const =0
virtual StringRef name() const =0
virtual double benchmarkConfidenceInterval() const =0
virtual std::vector< std::string > const & getSectionsToRun() const =0
virtual TestRunOrder runOrder() const =0
Definition catch_amalgamated.hpp:7228
virtual std::string translateActiveException() const =0
Definition catch_amalgamated.hpp:7222
virtual std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const =0
Definition catch_amalgamated.hpp:7477
virtual auto getGenerator() const -> Generators::GeneratorBasePtr const &=0
virtual void setGenerator(Generators::GeneratorBasePtr &&generator)=0
virtual auto hasGenerator() const -> bool=0
Definition catch_amalgamated.hpp:2434
virtual Detail::EnumInfo const & registerEnum(StringRef enumName, StringRef allEnums, std::vector< int > const &values)=0
Detail::EnumInfo const & registerEnum(StringRef enumName, StringRef allEnums, std::initializer_list< E > values)
Definition catch_amalgamated.hpp:2441
Definition catch_amalgamated.hpp:1273
virtual void registerTest(Detail::unique_ptr< TestCaseInfo > &&testInfo, Detail::unique_ptr< ITestInvoker > &&invoker)=0
virtual void registerStartupException() noexcept=0
virtual void registerListener(Detail::unique_ptr< EventListenerFactory > factory)=0
virtual void registerReporter(std::string const &name, IReporterFactoryPtr factory)=0
virtual IMutableEnumValuesRegistry & getMutableEnumValuesRegistry()=0
virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo)=0
virtual void registerTranslator(Detail::unique_ptr< IExceptionTranslator > &&translator)=0
Definition catch_amalgamated.hpp:1260
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
virtual ITagAliasRegistry const & getTagAliasRegistry() const =0
virtual ~IRegistryHub()
virtual StartupExceptionRegistry const & getStartupExceptionRegistry() const =0
virtual IExceptionTranslatorRegistry const & getExceptionTranslatorRegistry() const =0
virtual ReporterRegistry const & getReporterRegistry() const =0
Definition catch_amalgamated.hpp:1048
virtual void emplaceUnscopedMessage(MessageBuilder &&builder)=0
virtual void benchmarkStarting(BenchmarkInfo const &info)=0
virtual void benchmarkEnded(BenchmarkStats<> const &stats)=0
virtual const AssertionResult * getLastResult() const =0
virtual IGeneratorTracker * createGeneratorTracker(StringRef generatorName, SourceLineInfo lineInfo, Generators::GeneratorBasePtr &&generator)=0
virtual void popScopedMessage(MessageInfo const &message)=0
virtual void handleFatalErrorCondition(StringRef message)=0
virtual void handleUnexpectedInflightException(AssertionInfo const &info, std::string &&message, AssertionReaction &reaction)=0
virtual void handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction)=0
virtual void notifyAssertionStarted(AssertionInfo const &info)=0
virtual void handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, std::string &&message, AssertionReaction &reaction)=0
virtual void handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction)=0
virtual void benchmarkFailed(StringRef error)=0
virtual void handleIncomplete(AssertionInfo const &info)=0
virtual void sectionEnded(SectionEndInfo &&endInfo)=0
virtual void pushScopedMessage(MessageInfo const &message)=0
virtual bool lastAssertionPassed()=0
virtual void assertionPassed()=0
virtual IGeneratorTracker * acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo)=0
virtual bool sectionStarted(StringRef sectionName, SourceLineInfo const &sectionLineInfo, Counts &assertions)=0
virtual void handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction)=0
virtual void sectionEndedEarly(SectionEndInfo &&endInfo)=0
virtual void exceptionEarlyReported()=0
virtual std::string getCurrentTestName() const =0
virtual void benchmarkPreparing(StringRef name)=0
Definition catch_amalgamated.hpp:5967
virtual void prepareTestCase()
Definition catch_amalgamated.cpp:7095
virtual void invoke() const =0
virtual void tearDownTestCase()
Definition catch_amalgamated.cpp:7096
virtual ~ITestInvoker()
Definition catch_amalgamated.hpp:5304
bool m_result
Definition catch_amalgamated.hpp:5306
friend std::ostream & operator<<(std::ostream &out, ITransientExpression const &expr)
Definition catch_amalgamated.hpp:5325
constexpr auto getResult() const -> bool
Definition catch_amalgamated.hpp:5313
constexpr ITransientExpression(bool isBinaryExpression, bool result)
Definition catch_amalgamated.hpp:5317
bool m_isBinaryExpression
Definition catch_amalgamated.hpp:5305
constexpr auto isBinaryExpression() const -> bool
Definition catch_amalgamated.hpp:5312
virtual void streamReconstructedExpression(std::ostream &os) const
This function has to be overriden by the derived class.
Definition catch_amalgamated.cpp:3819
constexpr ITransientExpression(ITransientExpression const &)=default
constexpr ITransientExpression & operator=(ITransientExpression const &)=default
Definition catch_amalgamated.hpp:3295
friend class AssertionHandler
Definition catch_amalgamated.hpp:3296
ITransientExpression const * m_transientExpression
Definition catch_amalgamated.hpp:3300
friend struct AssertionStats
Definition catch_amalgamated.hpp:3297
bool m_isNegated
Definition catch_amalgamated.hpp:3301
constexpr LazyExpression(bool isNegated)
Definition catch_amalgamated.hpp:3303
constexpr LazyExpression(LazyExpression const &other)=default
friend class RunContext
Definition catch_amalgamated.hpp:3298
Definition catch_amalgamated.hpp:3537
friend bool operator!=(Optional const &a, Optional const &b)
Definition catch_amalgamated.hpp:3624
char storage[sizeof(T)]
Definition catch_amalgamated.hpp:3630
Optional(T const &_value)
Definition catch_amalgamated.hpp:3542
T const & operator*() const
Definition catch_amalgamated.hpp:3590
bool some() const
Definition catch_amalgamated.hpp:3607
T * operator->()
Definition catch_amalgamated.hpp:3594
T & operator*()
Definition catch_amalgamated.hpp:3586
Optional & operator=(T const &_value)
Definition catch_amalgamated.hpp:3547
bool none() const
Definition catch_amalgamated.hpp:3608
~Optional()
Definition catch_amalgamated.hpp:3540
void reset()
Definition catch_amalgamated.hpp:3581
Optional & operator=(T &&_value)
Definition catch_amalgamated.hpp:3552
Optional & operator=(Optional const &_other)
Definition catch_amalgamated.hpp:3564
T * nullableValue
Definition catch_amalgamated.hpp:3629
friend bool operator==(Optional const &a, Optional const &b)
Definition catch_amalgamated.hpp:3615
Optional(T &&_value)
Definition catch_amalgamated.hpp:3544
T valueOr(T const &defaultValue) const
Definition catch_amalgamated.hpp:3603
Optional(Optional &&_other)
Definition catch_amalgamated.hpp:3560
Optional()
Definition catch_amalgamated.hpp:3539
const T * operator->() const
Definition catch_amalgamated.hpp:3598
Optional & operator=(Optional &&_other)
Definition catch_amalgamated.hpp:3571
Optional(Optional const &_other)
Definition catch_amalgamated.hpp:3558
Definition catch_amalgamated.hpp:3686
Optional< ColourMode > const & colourMode() const
Definition catch_amalgamated.hpp:3712
Optional< ColourMode > m_colourMode
Definition catch_amalgamated.hpp:3689
std::map< std::string, std::string > m_customOptions
Definition catch_amalgamated.hpp:3690
friend bool operator==(ReporterSpec const &lhs, ReporterSpec const &rhs)
Definition catch_amalgamated.cpp:5469
std::map< std::string, std::string > const & customOptions() const
Definition catch_amalgamated.hpp:3714
friend bool operator!=(ReporterSpec const &lhs, ReporterSpec const &rhs)
Definition catch_amalgamated.hpp:3694
Optional< std::string > const & outputFile() const
Definition catch_amalgamated.hpp:3708
std::string const & name() const
Definition catch_amalgamated.hpp:3706
ReporterSpec(std::string name, Optional< std::string > outputFileName, Optional< ColourMode > colourMode, std::map< std::string, std::string > customOptions)
Definition catch_amalgamated.cpp:5533
std::string m_name
Definition catch_amalgamated.hpp:3687
Optional< std::string > m_outputFileName
Definition catch_amalgamated.hpp:3688
Definition catch_amalgamated.hpp:2355
std::string str() const
Returns the serialized state.
Definition catch_amalgamated.cpp:5588
auto get() -> std::ostream &
Definition catch_amalgamated.hpp:2388
std::size_t m_index
Definition catch_amalgamated.hpp:2356
ReusableStringStream()
Definition catch_amalgamated.cpp:5577
std::ostream * m_oss
Definition catch_amalgamated.hpp:2357
bool m_moved
Definition catch_amalgamated.hpp:4012
ScopedMessage(ScopedMessage &duplicate)=delete
ScopedMessage(MessageBuilder &&builder)
Definition catch_amalgamated.cpp:977
MessageInfo m_info
Definition catch_amalgamated.hpp:4011
bool m_sectionIncluded
Definition catch_amalgamated.hpp:5886
Timer m_timer
Definition catch_amalgamated.hpp:5887
SectionInfo m_info
Definition catch_amalgamated.hpp:5883
Section(SectionInfo &&info)
Definition catch_amalgamated.cpp:6310
Counts m_assertions
Definition catch_amalgamated.hpp:5885
void useConfigData(ConfigData const &configData)
Definition catch_amalgamated.cpp:1395
void showHelp() const
Definition catch_amalgamated.cpp:1328
Session()
Definition catch_amalgamated.cpp:1290
bool m_startupExceptions
Definition catch_amalgamated.hpp:4973
ConfigData m_configData
Definition catch_amalgamated.hpp:4971
Detail::unique_ptr< Config > m_config
Definition catch_amalgamated.hpp:4972
int run(int argc, CharT const *const argv[])
Definition catch_amalgamated.hpp:4952
ConfigData & configData()
Definition catch_amalgamated.cpp:1419
Clara::Parser m_cli
Definition catch_amalgamated.hpp:4970
void libIdentify()
Definition catch_amalgamated.cpp:1334
int applyCommandLine(int argc, char const *const *argv)
Definition catch_amalgamated.cpp:1342
Definition catch_amalgamated.hpp:7968
SimplePcg32()
Definition catch_amalgamated.hpp:7980
std::uint32_t result_type
Definition catch_amalgamated.hpp:7971
static const std::uint64_t s_inc
Definition catch_amalgamated.hpp:8002
static constexpr result_type min()
Definition catch_amalgamated.hpp:7972
static constexpr result_type max()
Definition catch_amalgamated.hpp:7975
std::uint64_t m_state
Definition catch_amalgamated.hpp:7997
std::uint64_t state_type
Definition catch_amalgamated.hpp:7969
Definition catch_amalgamated.hpp:711
char const * m_start
Definition catch_amalgamated.hpp:721
std::size_t size_type
Definition catch_amalgamated.hpp:713
constexpr auto empty() const noexcept -> bool
Definition catch_amalgamated.hpp:760
friend std::string operator+(StringRef lhs, StringRef rhs)
Definition catch_amalgamated.cpp:6605
auto operator!=(StringRef other) const noexcept -> bool
Definition catch_amalgamated.hpp:748
constexpr auto operator[](size_type index) const noexcept -> char
Definition catch_amalgamated.hpp:752
static constexpr char const *const s_empty
Definition catch_amalgamated.hpp:719
constexpr const_iterator end() const
Definition catch_amalgamated.hpp:785
friend std::ostream & operator<<(std::ostream &os, StringRef str)
Definition catch_amalgamated.cpp:6601
int compare(StringRef rhs) const
Definition catch_amalgamated.cpp:6580
static constexpr size_type npos
Definition catch_amalgamated.hpp:716
bool operator<(StringRef rhs) const noexcept
Definition catch_amalgamated.cpp:6573
constexpr StringRef() noexcept=default
auto operator==(StringRef other) const noexcept -> bool
Definition catch_amalgamated.hpp:744
constexpr char const * data() const noexcept
Definition catch_amalgamated.hpp:780
StringRef(std::string const &stdString) noexcept
Definition catch_amalgamated.hpp:734
size_type m_size
Definition catch_amalgamated.hpp:722
constexpr StringRef substr(size_type start, size_type length) const noexcept
Definition catch_amalgamated.hpp:770
constexpr const_iterator begin() const
Definition catch_amalgamated.hpp:784
const char * const_iterator
Definition catch_amalgamated.hpp:714
constexpr auto size() const noexcept -> size_type
Definition catch_amalgamated.hpp:763
friend std::string & operator+=(std::string &lhs, StringRef rhs)
Definition catch_amalgamated.cpp:6613
TestCaseInfo * m_info
Definition catch_amalgamated.hpp:7168
void invoke() const
Definition catch_amalgamated.hpp:7182
void prepareTestCase() const
Definition catch_amalgamated.hpp:7174
constexpr TestCaseInfo const & getTestCaseInfo() const
Definition catch_amalgamated.hpp:7186
ITestInvoker * m_invoker
Definition catch_amalgamated.hpp:7169
void tearDownTestCase() const
Definition catch_amalgamated.hpp:7178
constexpr TestCaseHandle(TestCaseInfo *info, ITestInvoker *invoker)
Definition catch_amalgamated.hpp:7171
void(C::* m_testAsMethod)()
Definition catch_amalgamated.hpp:6006
void invoke() const override
Definition catch_amalgamated.hpp:6011
constexpr TestInvokerAsMethod(void(C::*testAsMethod)()) noexcept
Definition catch_amalgamated.hpp:6008
void invoke() const override
Definition catch_amalgamated.hpp:6041
constexpr TestInvokerFixture(void(C::*testAsMethod)() const) noexcept
Definition catch_amalgamated.hpp:6030
Detail::unique_ptr< C > m_fixture
Definition catch_amalgamated.hpp:6027
void tearDownTestCase() override
Definition catch_amalgamated.hpp:6037
void(C::* m_testAsMethod)() const
Definition catch_amalgamated.hpp:6026
void prepareTestCase() override
Definition catch_amalgamated.hpp:6033
NamePattern(std::string const &name, std::string const &filterString)
Definition catch_amalgamated.cpp:1794
WildcardPattern m_wildcardPattern
Definition catch_amalgamated.hpp:3461
bool matches(TestCaseInfo const &testCase) const override
Definition catch_amalgamated.cpp:1799
void serializeTo(std::ostream &out) const override
Definition catch_amalgamated.cpp:1803
friend std::ostream & operator<<(std::ostream &out, Pattern const &pattern)
Definition catch_amalgamated.hpp:3445
Pattern(std::string const &name)
Definition catch_amalgamated.cpp:1783
virtual bool matches(TestCaseInfo const &testCase) const =0
std::string const & name() const
Definition catch_amalgamated.cpp:1789
virtual void serializeTo(std::ostream &out) const =0
std::string const m_name
Definition catch_amalgamated.hpp:3451
std::string m_tag
Definition catch_amalgamated.hpp:3471
bool matches(TestCaseInfo const &testCase) const override
Definition catch_amalgamated.cpp:1813
void serializeTo(std::ostream &out) const override
Definition catch_amalgamated.cpp:1819
TagPattern(std::string const &tag, std::string const &filterString)
Definition catch_amalgamated.cpp:1808
Definition catch_amalgamated.hpp:3434
std::vector< FilterMatch > Matches
Definition catch_amalgamated.hpp:3496
bool matches(TestCaseInfo const &testCase) const
Definition catch_amalgamated.cpp:1868
friend std::ostream & operator<<(std::ostream &out, TestSpec const &spec)
Definition catch_amalgamated.hpp:3512
friend class TestSpecParser
Definition catch_amalgamated.hpp:3508
std::vector< std::string > vectorStrings
Definition catch_amalgamated.hpp:3497
std::vector< std::string > m_invalidSpecs
Definition catch_amalgamated.hpp:3506
bool hasFilters() const
Definition catch_amalgamated.cpp:1864
Matches matchesByFilter(std::vector< TestCaseHandle > const &testCases, IConfig const &config) const
Definition catch_amalgamated.cpp:1872
const vectorStrings & getInvalidSpecs() const
Definition catch_amalgamated.cpp:1887
void serializeTo(std::ostream &out) const
Serializes this test spec into a string that would be parsed into equivalent test spec.
Definition catch_amalgamated.cpp:1891
std::vector< Filter > m_filters
Definition catch_amalgamated.hpp:3505
Definition catch_amalgamated.hpp:5855
auto getElapsedSeconds() const -> double
Definition catch_amalgamated.cpp:1928
void start()
Definition catch_amalgamated.cpp:1916
auto getElapsedMilliseconds() const -> unsigned int
Definition catch_amalgamated.cpp:1925
auto getElapsedMicroseconds() const -> uint64_t
Definition catch_amalgamated.cpp:1922
auto getElapsedNanoseconds() const -> uint64_t
Definition catch_amalgamated.cpp:1919
uint64_t m_nanoseconds
Definition catch_amalgamated.hpp:5856
Definition catch_amalgamated.hpp:5410
LhsT m_lhs
Definition catch_amalgamated.hpp:5411
constexpr UnaryExpr(LhsT lhs)
Definition catch_amalgamated.hpp:5418
void streamReconstructedExpression(std::ostream &os) const override
This function has to be overriden by the derived class.
Definition catch_amalgamated.hpp:5413
Definition catch_amalgamated.hpp:3401
std::string m_pattern
Definition catch_amalgamated.hpp:3418
WildcardPattern(std::string const &pattern, CaseSensitive caseSensitivity)
Definition catch_amalgamated.cpp:7786
CaseSensitive m_caseSensitivity
Definition catch_amalgamated.hpp:3416
WildcardPosition m_wildcard
Definition catch_amalgamated.hpp:3417
WildcardPosition
Definition catch_amalgamated.hpp:3402
@ WildcardAtEnd
Definition catch_amalgamated.hpp:3405
@ WildcardAtBothEnds
Definition catch_amalgamated.hpp:3406
@ NoWildcard
Definition catch_amalgamated.hpp:3403
@ WildcardAtStart
Definition catch_amalgamated.hpp:3404
constexpr auto warmup_iterations
Definition catch_amalgamated.hpp:1977
Estimate< double > bootstrap(double confidence_level, double *first, double *last, sample const &resample, double(*estimator)(double const *, double const *))
Definition catch_amalgamated.cpp:447
constexpr auto warmup_seed
Definition catch_amalgamated.hpp:1980
bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, double *first, double *last)
Definition catch_amalgamated.cpp:504
constexpr auto clock_cost_estimation_tick_limit
Definition catch_amalgamated.hpp:1983
TimingOf< Fun, Args... > measure(Fun &&fun, Args &&... args)
Definition catch_amalgamated.hpp:1791
constexpr auto clock_cost_estimation_time_limit
Definition catch_amalgamated.hpp:1982
SampleAnalysis analyse(const IConfig &cfg, FDuration *first, FDuration *last)
Definition catch_amalgamated.cpp:60
TimingOf< Fun, run_for_at_least_argument_t< Clock, Fun > > run_for_at_least(IDuration how_long, const int initial_iterations, Fun &&fun)
Definition catch_amalgamated.hpp:1830
OutlierClassification classify_outliers(double const *first, double const *last)
Definition catch_amalgamated.cpp:384
double weighted_average_quantile(int k, int q, double *first, double *last)
Definition catch_amalgamated.cpp:365
EnvironmentEstimate estimate_clock_resolution(int iterations)
Definition catch_amalgamated.hpp:1993
double erfc_inv(double x)
Definition catch_amalgamated.cpp:426
TimingOf< Fun, int > measure_one(Fun &&fun, int iters, std::false_type)
Definition catch_amalgamated.hpp:1810
int warmup()
Definition catch_amalgamated.hpp:1988
constexpr auto clock_resolution_estimation_time
Definition catch_amalgamated.hpp:1981
constexpr auto clock_cost_estimation_iterations
Definition catch_amalgamated.hpp:1985
constexpr auto clock_cost_estimation_time
Definition catch_amalgamated.hpp:1984
repeater< std::decay_t< Fun > > repeat(Fun &&fun)
Definition catch_amalgamated.hpp:1689
double normal_cdf(double x)
Definition catch_amalgamated.cpp:422
CompleteType_t< FunctionReturnType< Fun, Args... > > complete_invoke(Fun &&fun, Args &&... args)
Definition catch_amalgamated.hpp:1748
typename CompleteType< T >::type CompleteType_t
Definition catch_amalgamated.hpp:1728
EnvironmentEstimate estimate_clock_cost(FDuration resolution)
Definition catch_amalgamated.hpp:2002
double mean(double const *first, double const *last)
Definition catch_amalgamated.cpp:412
void throw_optimized_away_error()
Definition catch_amalgamated.cpp:158
constexpr auto warmup_time
Definition catch_amalgamated.hpp:1978
std::vector< double > sample
Definition catch_amalgamated.hpp:1909
Environment measure_environment()
Definition catch_amalgamated.hpp:2032
std::conditional_t< is_callable< Fun(Chronometer)>::value, Chronometer, int > run_for_at_least_argument_t
Definition catch_amalgamated.hpp:1822
constexpr auto minimum_ticks
Definition catch_amalgamated.hpp:1979
double normal_quantile(double p)
Definition catch_amalgamated.cpp:430
std::vector< double > resolution(int k)
Definition catch_amalgamated.hpp:1958
Definition catch_amalgamated.cpp:44
std::chrono::nanoseconds IDuration
Definition catch_amalgamated.hpp:1001
Detail::ObjectStorage< T, false > destructable_object
Definition catch_amalgamated.hpp:2290
std::chrono::duration< double, std::nano > FDuration
Definition catch_amalgamated.hpp:1002
std::chrono::steady_clock default_clock
Definition catch_amalgamated.hpp:1007
Detail::ObjectStorage< T, true > storage_for
Definition catch_amalgamated.hpp:2287
typename Clock::time_point TimePoint
Definition catch_amalgamated.hpp:1005
auto invoke_deoptimized(Fn &&fn, Args &&... args) -> std::enable_if_t<!std::is_same< void, decltype(fn(args...))>::value >
Definition catch_amalgamated.hpp:1480
Detail::CompleteType_t< FunctionReturnType< Fun > > user_code(Fun &&fun)
Definition catch_amalgamated.hpp:1755
void deoptimize_value(T &&x)
Definition catch_amalgamated.hpp:1475
Timing< Detail::CompleteType_t< FunctionReturnType< Func, Args... > > > TimingOf
Definition catch_amalgamated.hpp:1781
Definition catch_amalgamated.cpp:2667
ResultType
Denotes type of a parsing result.
Definition catch_amalgamated.hpp:4314
@ RuntimeError
Error in parsing inputs.
Definition catch_amalgamated.hpp:4318
@ LogicError
Error in user-specified arguments for construction.
Definition catch_amalgamated.hpp:4316
@ Ok
No errors.
Definition catch_amalgamated.hpp:4315
BasicResult< ParseResultType > ParserResult
Definition catch_amalgamated.hpp:4480
TokenType
Definition catch_amalgamated.hpp:4273
@ Option
Definition catch_amalgamated.hpp:4273
@ Argument
Definition catch_amalgamated.hpp:4273
BasicResult< ParseState > InternalParseResult
Definition catch_amalgamated.hpp:4481
auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult
Definition catch_amalgamated.hpp:4589
Optionality
Definition catch_amalgamated.hpp:4638
@ Required
Definition catch_amalgamated.hpp:4638
@ Optional
Definition catch_amalgamated.hpp:4638
ParserResult convertInto(std::string const &source, std::string &target)
Definition catch_amalgamated.cpp:2727
BasicResult< void > Result
Definition catch_amalgamated.hpp:4479
ParseResultType
Definition catch_amalgamated.hpp:4223
@ ShortCircuitSame
Definition catch_amalgamated.hpp:4227
@ ShortCircuitAll
Definition catch_amalgamated.hpp:4226
@ Matched
Definition catch_amalgamated.hpp:4224
@ NoMatch
Definition catch_amalgamated.hpp:4225
constexpr accept_many_t accept_many
Definition catch_amalgamated.hpp:4231
Definition catch_amalgamated.cpp:1943
typename make_void< Ts... >::type void_t
Definition catch_amalgamated.hpp:2406
bool directCompare(float lhs, float rhs)
Definition catch_amalgamated.cpp:4281
std::string convertIntoString(StringRef string, bool escapeInvisibles)
Encases `string in quotes, and optionally escapes invisibles.
Definition catch_amalgamated.cpp:1984
std::string convertUnknownEnumToString(E e)
Definition catch_amalgamated.hpp:2586
unique_ptr< T > make_unique(Args &&... args)
Definition catch_amalgamated.hpp:976
std::enable_if_t< !std::is_enum< T >::value &&!std::is_base_of< std::exception, T >::value, std::string > convertUnstreamable(T const &)
Definition catch_amalgamated.hpp:2518
std::vector< StringRef > parseEnums(StringRef enums)
Definition catch_amalgamated.cpp:3893
Catch::Detail::unique_ptr< EnumInfo > makeEnumInfo(StringRef enumName, StringRef allValueNames, std::vector< int > const &values)
Definition catch_amalgamated.cpp:3913
void registerTranslatorImpl(Detail::unique_ptr< IExceptionTranslator > &&translator)
Definition catch_amalgamated.cpp:2247
char const * getEnv(char const *varName)
Definition catch_amalgamated.cpp:4305
constexpr StringRef unprintableString
Definition catch_amalgamated.hpp:2483
std::remove_cv_t< std::remove_reference_t< T > > RemoveCVRef_t
Definition catch_amalgamated.hpp:5281
void registerListenerImpl(Detail::unique_ptr< EventListenerFactory > listenerFactory)
Definition catch_amalgamated.cpp:10943
std::string rawMemoryToString(const void *object, std::size_t size)
Definition catch_amalgamated.cpp:2026
std::string rangeToString(InputIterator first, Sentinel last)
Definition catch_amalgamated.hpp:2775
uint32_t convertToBits(float f)
Definition catch_amalgamated.cpp:4263
std::size_t catch_strnlen(const char *str, std::size_t n)
Definition catch_amalgamated.hpp:2475
std::string stringify(const T &e)
Definition catch_amalgamated.hpp:2581
void registerReporterImpl(std::string const &name, IReporterFactoryPtr reporterPtr)
Definition catch_amalgamated.cpp:10930
void throw_generator_exception(char const *msg)
Throws GeneratorException with the provided message.
Definition catch_amalgamated.cpp:2315
Definition catch_amalgamated.cpp:2310
GeneratorWrapper< DecayedT > value(T &&value)
Definition catch_amalgamated.hpp:7580
auto generate(StringRef generatorName, SourceLineInfo const &lineInfo, L const &generatorExpression) -> typename decltype(generatorExpression())::type
Definition catch_amalgamated.hpp:7678
IGeneratorTracker * createGeneratorTracker(StringRef generatorName, SourceLineInfo lineInfo, GeneratorBasePtr &&generator)
Definition catch_amalgamated.cpp:2326
GeneratorWrapper< std::tuple< std::decay_t< Ts >... > > table(std::initializer_list< std::tuple< std::decay_t< Ts >... > > tuples)
Definition catch_amalgamated.hpp:7646
GeneratorWrapper< T > filter(Predicate &&pred, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7800
GeneratorWrapper< T > repeat(size_t repeats, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7856
auto makeGenerators(GeneratorWrapper< T > &&generator, Gs &&... moreGenerators) -> Generators< T >
Definition catch_amalgamated.hpp:7655
Catch::Detail::unique_ptr< GeneratorUntypedBase > GeneratorBasePtr
Definition catch_amalgamated.hpp:1044
IGeneratorTracker * acquireGeneratorTracker(StringRef generatorName, SourceLineInfo const &lineInfo)
Definition catch_amalgamated.cpp:2322
Catch::Detail::unique_ptr< IGenerator< T > > GeneratorPtr
Definition catch_amalgamated.hpp:7520
GeneratorWrapper< std::vector< T > > chunk(size_t size, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7938
GeneratorWrapper< T > take(size_t target, GeneratorWrapper< T > &&generator)
Definition catch_amalgamated.hpp:7759
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< U > &&generator)
Definition catch_amalgamated.hpp:7888
GeneratorWrapper< T > values(std::initializer_list< T > values)
Definition catch_amalgamated.hpp:7586
std::string describe_multi_matcher(StringRef combine, std::string const *descriptions_begin, std::string const *descriptions_end)
Definition catch_amalgamated.cpp:8565
FloatingPointKind
Definition catch_amalgamated.cpp:8263
@ Float
Definition catch_amalgamated.cpp:8264
NoneTrueMatcher NoneTrue()
Definition catch_amalgamated.cpp:8444
IsNaNMatcher IsNaN()
Definition catch_amalgamated.cpp:8418
EndsWithMatcher EndsWith(std::string const &str, CaseSensitive caseSensitivity)
Definition catch_amalgamated.cpp:8543
WithinAbsMatcher WithinAbs(double target, double margin)
Definition catch_amalgamated.cpp:8387
StringContainsMatcher ContainsSubstring(std::string const &str, CaseSensitive caseSensitivity)
Definition catch_amalgamated.cpp:8540
ExceptionMessageMatcher Message(std::string const &message)
Definition catch_amalgamated.cpp:8201
AllTrueMatcher AllTrue()
Definition catch_amalgamated.cpp:8440
HasSizeMatcher SizeIs(std::size_t sz)
Definition catch_amalgamated.cpp:8181
WithinRelMatcher WithinRel(double target, double eps)
Definition catch_amalgamated.cpp:8391
WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff)
Definition catch_amalgamated.cpp:8379
AnyTrueMatcher AnyTrue()
Definition catch_amalgamated.cpp:8448
IsEmptyMatcher IsEmpty()
Definition catch_amalgamated.cpp:8177
StringEqualsMatcher Equals(std::string const &str, CaseSensitive caseSensitivity)
Definition catch_amalgamated.cpp:8537
StartsWithMatcher StartsWith(std::string const &str, CaseSensitive caseSensitivity)
Definition catch_amalgamated.cpp:8546
RegexMatcher Matches(std::string const &regex, CaseSensitive caseSensitivity)
Definition catch_amalgamated.cpp:8550
Column Spacer(size_t spaceWidth)
Definition catch_amalgamated.cpp:7657
Definition catch_amalgamated.cpp:611
Definition catch_amalgamated.cpp:43
std::ostream & cout()
Definition catch_amalgamated.cpp:6445
void toLowerInPlace(std::string &s)
Definition catch_amalgamated.cpp:6476
std::string trim(std::string const &str)
Definition catch_amalgamated.cpp:6490
GenerateFrom
Definition catch_amalgamated.hpp:3645
@ Default
Currently equivalent to RandomDevice, but can change at any point.
Definition catch_amalgamated.hpp:3649
@ RandomDevice
Definition catch_amalgamated.hpp:3647
@ Time
Definition catch_amalgamated.hpp:3646
void cleanUp()
Definition catch_amalgamated.cpp:1151
bool list(IEventListener &reporter, Config const &config)
Definition catch_amalgamated.cpp:4740
bool isThrowSafe(TestCaseHandle const &testCase, IConfig const &config)
Definition catch_amalgamated.cpp:6788
void seedRng(IConfig const &config)
Definition catch_amalgamated.cpp:6296
std::uint32_t generateRandomSeed(GenerateFrom from)
Definition catch_amalgamated.cpp:5290
std::ostream & clog()
Definition catch_amalgamated.cpp:6447
auto operator+=(std::string &lhs, StringRef rhs) -> std::string &
Definition catch_amalgamated.cpp:6613
void throw_test_failure_exception()
Definition catch_amalgamated.cpp:7071
void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str)
Definition catch_amalgamated.cpp:2589
Detail::unique_ptr< ITestInvoker > makeTestInvokerFixture(void(C::*testAsMethod)() const)
Definition catch_amalgamated.hpp:6048
bool operator==(ProcessedReporterSpec const &lhs, ProcessedReporterSpec const &rhs)
Definition catch_amalgamated.cpp:793
void defaultListTags(std::ostream &out, std::vector< TagInfo > const &tags, bool isFiltered)
Definition catch_amalgamated.cpp:9911
Version const & libraryVersion()
Definition catch_amalgamated.cpp:2285
Optional< unsigned int > parseUInt(std::string const &input, int base)
Definition catch_amalgamated.cpp:5147
auto makeStream(std::string const &filename) -> Detail::unique_ptr< IStream >
Definition catch_amalgamated.cpp:4445
std::remove_reference_t< std::remove_cv_t< std::result_of_t< Func(U...)> > > FunctionReturnType
Definition catch_amalgamated.hpp:1524
void throw_exception(std::exception const &e)
Definition catch_amalgamated.cpp:3844
Detail::unique_ptr< ITestInvoker > makeTestInvoker(void(*testAsFunction)())
Definition catch_amalgamated.cpp:7141
void throw_runtime_error(std::string const &msg)
Definition catch_amalgamated.cpp:3862
bool uncaught_exceptions()
Definition catch_amalgamated.cpp:7771
constexpr bool isOk(ResultWas::OfType resultType)
Definition catch_amalgamated.hpp:842
void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs)
Definition catch_amalgamated.cpp:3826
std::ostream & cerr()
Definition catch_amalgamated.cpp:6446
IMutableRegistryHub & getMutableRegistryHub()
Definition catch_amalgamated.cpp:1148
IRegistryHub const & getRegistryHub()
Definition catch_amalgamated.cpp:1145
constexpr bool shouldSuppressFailure(int flags)
Definition catch_amalgamated.hpp:866
constexpr ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
Definition catch_amalgamated.hpp:857
Detail::unique_ptr< ColourImpl > makeColourImpl(ColourMode colourSelection, IStream *stream)
Definition catch_amalgamated.cpp:3591
std::vector< StringRef > splitStringRef(StringRef str, char delimiter)
Definition catch_amalgamated.cpp:6536
bool startsWith(std::string const &s, std::string const &prefix)
Definition catch_amalgamated.cpp:6461
constexpr bool isFalseTest(int flags)
Definition catch_amalgamated.hpp:863
void defaultListTests(std::ostream &out, ColourImpl *streamColour, std::vector< TestCaseHandle > const &tests, bool isFiltered, Verbosity verbosity)
Definition catch_amalgamated.cpp:9933
void throw_logic_error(std::string const &msg)
Definition catch_amalgamated.cpp:3852
bool isRedirectAvailable(OutputRedirect::Kind kind)
Definition catch_amalgamated.cpp:5047
bool isColourImplAvailable(ColourMode colourSelection)
Definition catch_amalgamated.cpp:3620
void addSingleton(ISingleton *singleton)
Definition catch_amalgamated.cpp:6374
Detail::unique_ptr< IReporterFactory > IReporterFactoryPtr
Definition catch_amalgamated.hpp:1258
void throw_test_skip_exception()
Definition catch_amalgamated.cpp:7079
std::string(*)() exceptionTranslateFunction
Definition catch_amalgamated.hpp:7217
void defaultListReporters(std::ostream &out, std::vector< ReporterDescription > const &descriptions, Verbosity verbosity)
Definition catch_amalgamated.cpp:9846
Context const & getCurrentContext()
Definition catch_amalgamated.hpp:587
void cleanupSingletons()
Definition catch_amalgamated.cpp:6377
void defaultListListeners(std::ostream &out, std::vector< ListenerDescription > const &descriptions)
Definition catch_amalgamated.cpp:9879
ColourMode
Definition catch_amalgamated.hpp:1177
@ None
Don't use any colour.
Definition catch_amalgamated.hpp:1185
@ PlatformDefault
Let Catch2 pick implementation based on platform detection.
Definition catch_amalgamated.hpp:1179
@ Win32
Use Win32 console colour API.
Definition catch_amalgamated.hpp:1183
@ ANSI
Use ANSI colour code escapes.
Definition catch_amalgamated.hpp:1181
SimplePcg32 & sharedRng()
Definition catch_amalgamated.cpp:3662
bool contains(std::string const &s, std::string const &infix)
Definition catch_amalgamated.cpp:6473
void writeToDebugConsole(std::string const &text)
Definition catch_amalgamated.cpp:3695
TestCaseProperties
Definition catch_amalgamated.hpp:7108
@ None
Definition catch_amalgamated.hpp:7109
@ IsHidden
Definition catch_amalgamated.hpp:7110
@ Benchmark
Definition catch_amalgamated.hpp:7115
@ Throws
Definition catch_amalgamated.hpp:7113
@ ShouldFail
Definition catch_amalgamated.hpp:7111
@ NonPortable
Definition catch_amalgamated.hpp:7114
@ MayFail
Definition catch_amalgamated.hpp:7112
TestRunOrder
Definition catch_amalgamated.hpp:1172
@ Declared
Definition catch_amalgamated.hpp:1173
@ LexicographicallySorted
Definition catch_amalgamated.hpp:1174
@ Randomized
Definition catch_amalgamated.hpp:1175
std::vector< TestCaseHandle > const & getAllTestCasesSorted(IConfig const &config)
Definition catch_amalgamated.cpp:6803
bool isDebuggerActive()
Definition catch_amalgamated.cpp:3810
bool operator!=(SimplePcg32 const &lhs, SimplePcg32 const &rhs)
Definition catch_amalgamated.cpp:5276
std::uint32_t getSeed()
Returns Catch2's current RNG seed.
Definition catch_amalgamated.cpp:962
std::string toLower(std::string const &s)
Definition catch_amalgamated.cpp:6481
CaseSensitive
Definition catch_amalgamated.hpp:3371
@ Yes
Definition catch_amalgamated.hpp:3371
@ No
Definition catch_amalgamated.hpp:3371
std::vector< Detail::unique_ptr< IExceptionTranslator const > > ExceptionTranslators
Definition catch_amalgamated.hpp:7220
unsigned int rngSeed()
Definition catch_amalgamated.cpp:6300
constexpr bool isJustInfo(int flags)
Definition catch_amalgamated.hpp:845
std::vector< TestCaseHandle > sortTests(IConfig const &config, std::vector< TestCaseHandle > const &unsortedTestCases)
Definition catch_amalgamated.cpp:6737
bool endsWith(std::string const &s, std::string const &suffix)
Definition catch_amalgamated.cpp:6467
std::string translateActiveException()
Definition catch_amalgamated.cpp:1155
std::string operator+(StringRef lhs, StringRef rhs)
Definition catch_amalgamated.cpp:6605
void cleanUpContext()
Definition catch_amalgamated.cpp:3648
std::string serializeFilters(std::vector< std::string > const &filters)
Definition catch_amalgamated.cpp:9816
float nextafter(float x, float y)
Definition catch_amalgamated.cpp:5211
void throw_domain_error(std::string const &msg)
Definition catch_amalgamated.cpp:3857
Detail::unique_ptr< OutputRedirect > makeOutputRedirect(bool actual)
Definition catch_amalgamated.cpp:5062
Context & getCurrentMutableContext()
Definition catch_amalgamated.cpp:3656
void printTestRunTotals(std::ostream &stream, ColourImpl &streamColour, Totals const &totals)
Definition catch_amalgamated.cpp:10033
bool shouldShowDuration(IConfig const &config, double duration)
Definition catch_amalgamated.cpp:9805
std::string rangeToString(Range const &range)
Definition catch_amalgamated.hpp:2936
std::vector< TestCaseHandle > filterTests(std::vector< TestCaseHandle > const &testCases, TestSpec const &testSpec, IConfig const &config)
Definition catch_amalgamated.cpp:6792
std::string getFormattedDuration(double duration)
Definition catch_amalgamated.cpp:9785
IResultCapture & getResultCapture()
Definition catch_amalgamated.cpp:6289
Verbosity
Definition catch_amalgamated.hpp:1153
@ Quiet
Definition catch_amalgamated.hpp:1154
@ High
Definition catch_amalgamated.hpp:1156
@ Normal
Definition catch_amalgamated.hpp:1155
ShowDurations
Definition catch_amalgamated.hpp:1167
@ DefaultForReporter
Definition catch_amalgamated.hpp:1168
@ Always
Definition catch_amalgamated.hpp:1169
@ Never
Definition catch_amalgamated.hpp:1170
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis)
Definition catch_amalgamated.cpp:6510
bool isnan(float f)
Definition catch_amalgamated.cpp:5191
void close()
Definition matplotlibcpp.h:2567
void text(Numeric x, Numeric y, const std::string &s="")
Definition matplotlibcpp.h:1834
Definition catch_amalgamated.hpp:1529
Definition catch_amalgamated.hpp:3267
SourceLineInfo lineInfo
Definition catch_amalgamated.hpp:3271
ResultDisposition::Flags resultDisposition
Definition catch_amalgamated.hpp:3273
StringRef macroName
Definition catch_amalgamated.hpp:3270
StringRef capturedExpression
Definition catch_amalgamated.hpp:3272
Definition catch_amalgamated.hpp:5611
bool shouldThrow
Definition catch_amalgamated.hpp:5613
bool shouldSkip
Definition catch_amalgamated.hpp:5614
bool shouldDebugBreak
Definition catch_amalgamated.hpp:5612
Definition catch_amalgamated.hpp:3325
std::string reconstructExpression() const
Definition catch_amalgamated.cpp:634
ResultWas::OfType resultType
Definition catch_amalgamated.hpp:3333
std::string reconstructedExpression
Definition catch_amalgamated.hpp:3331
std::string message
Definition catch_amalgamated.hpp:3330
LazyExpression lazyExpression
Definition catch_amalgamated.hpp:3332
AutoReg(Detail::unique_ptr< ITestInvoker > invoker, SourceLineInfo const &lineInfo, StringRef classOrMethod, NameAndTags const &nameAndTags) noexcept
Definition catch_amalgamated.cpp:7145
Definition catch_amalgamated.hpp:1350
double clockCost
Definition catch_amalgamated.hpp:1357
unsigned int samples
Definition catch_amalgamated.hpp:1354
unsigned int resamples
Definition catch_amalgamated.hpp:1355
int iterations
Definition catch_amalgamated.hpp:1353
double estimatedDuration
Definition catch_amalgamated.hpp:1352
std::string name
Definition catch_amalgamated.hpp:1351
double clockResolution
Definition catch_amalgamated.hpp:1356
Definition catch_amalgamated.hpp:1363
Benchmark::OutlierClassification outliers
Definition catch_amalgamated.hpp:1369
Benchmark::Estimate< Benchmark::FDuration > standardDeviation
Definition catch_amalgamated.hpp:1368
double outlierVariance
Definition catch_amalgamated.hpp:1370
std::vector< Benchmark::FDuration > samples
Definition catch_amalgamated.hpp:1366
BenchmarkInfo info
Definition catch_amalgamated.hpp:1364
Benchmark::Estimate< Benchmark::FDuration > mean
Definition catch_amalgamated.hpp:1367
Detail::BenchmarkFunction fun
Definition catch_amalgamated.hpp:2185
Benchmark & operator=(Fun func)
Definition catch_amalgamated.hpp:2171
Benchmark(std::string &&benchmarkName, FUN &&func)
Definition catch_amalgamated.hpp:2114
std::string name
Definition catch_amalgamated.hpp:2186
Benchmark(std::string &&benchmarkName)
Definition catch_amalgamated.hpp:2110
void run()
Definition catch_amalgamated.hpp:2127
ExecutionPlan prepare(const IConfig &cfg, Environment env)
Definition catch_amalgamated.hpp:2118
Definition catch_amalgamated.hpp:1562
int runs() const
Definition catch_amalgamated.hpp:1567
void measure(Fun &&fun)
Definition catch_amalgamated.hpp:1565
Chronometer(Detail::ChronometerConcept &meter, int repeats_)
Definition catch_amalgamated.hpp:1569
void measure(Fun &&fun, std::true_type)
Definition catch_amalgamated.hpp:1580
Detail::ChronometerConcept * impl
Definition catch_amalgamated.hpp:1588
int repeats
Definition catch_amalgamated.hpp:1589
void measure(Fun &&fun, std::false_type)
Definition catch_amalgamated.hpp:1575
virtual void call(Chronometer meter) const =0
Definition catch_amalgamated.hpp:1623
void call(Chronometer meter, std::true_type) const
Definition catch_amalgamated.hpp:1630
void call(Chronometer meter) const override
Definition catch_amalgamated.hpp:1627
model(Fun &&fun_)
Definition catch_amalgamated.hpp:1624
void call(Chronometer meter, std::false_type) const
Definition catch_amalgamated.hpp:1633
model(Fun const &fun_)
Definition catch_amalgamated.hpp:1625
Fun fun
Definition catch_amalgamated.hpp:1637
Definition catch_amalgamated.hpp:1612
BenchmarkFunction & operator=(BenchmarkFunction &&that) noexcept
Definition catch_amalgamated.hpp:1652
BenchmarkFunction()
Definition catch_amalgamated.cpp:136
BenchmarkFunction(BenchmarkFunction &&that) noexcept
Definition catch_amalgamated.hpp:1648
BenchmarkFunction(Fun &&fun)
Definition catch_amalgamated.hpp:1645
Catch::Detail::unique_ptr< callable > f
Definition catch_amalgamated.hpp:1660
void operator()(Chronometer meter) const
Definition catch_amalgamated.hpp:1657
Definition catch_amalgamated.hpp:1538
ChronometerConcept & operator=(ChronometerConcept const &)=default
ChronometerConcept(ChronometerConcept const &)=default
Definition catch_amalgamated.hpp:1548
void finish() override
Definition catch_amalgamated.hpp:1550
TimePoint< Clock > started
Definition catch_amalgamated.hpp:1557
void start() override
Definition catch_amalgamated.hpp:1549
IDuration elapsed() const
Definition catch_amalgamated.hpp:1552
TimePoint< Clock > finished
Definition catch_amalgamated.hpp:1558
static CompleteType_t< void > invoke(Fun &&fun, Args &&... args)
Definition catch_amalgamated.hpp:1740
Definition catch_amalgamated.hpp:1731
static Result invoke(Fun &&fun, Args &&... args)
Definition catch_amalgamated.hpp:1733
Definition catch_amalgamated.hpp:1725
Definition catch_amalgamated.hpp:1723
T type
Definition catch_amalgamated.hpp:1723
Definition catch_amalgamated.hpp:2234
ObjectStorage(const ObjectStorage &other)
Definition catch_amalgamated.hpp:2237
ObjectStorage(ObjectStorage &&other)
Definition catch_amalgamated.hpp:2242
~ObjectStorage()
Definition catch_amalgamated.hpp:2247
T const & stored_object() const
Definition catch_amalgamated.hpp:2275
void destruct_on_exit(std::enable_if_t< Destruct, U > *=nullptr)
Definition catch_amalgamated.hpp:2264
unsigned char data[sizeof(T)]
Definition catch_amalgamated.hpp:2282
std::enable_if_t< AllowManualDestruction > destruct()
Definition catch_amalgamated.hpp:2256
T & stored_object()
Definition catch_amalgamated.hpp:2273
void destruct_on_exit(std::enable_if_t<!Destruct, U > *=nullptr)
Definition catch_amalgamated.hpp:2267
void construct(Args &&... args)
Definition catch_amalgamated.hpp:2250
Definition catch_amalgamated.hpp:1934
Estimate< double > standard_deviation
Definition catch_amalgamated.hpp:1936
double outlier_variance
Definition catch_amalgamated.hpp:1937
Estimate< double > mean
Definition catch_amalgamated.hpp:1935
Definition catch_amalgamated.hpp:1680
void operator()(int k) const
Definition catch_amalgamated.hpp:1681
Fun fun
Definition catch_amalgamated.hpp:1686
Definition catch_amalgamated.hpp:1387
OutlierClassification outliers
Definition catch_amalgamated.hpp:1389
FDuration mean
Definition catch_amalgamated.hpp:1388
Definition catch_amalgamated.hpp:1391
EnvironmentEstimate clock_cost
Definition catch_amalgamated.hpp:1393
EnvironmentEstimate clock_resolution
Definition catch_amalgamated.hpp:1392
Definition catch_amalgamated.hpp:1308
Type lower_bound
Definition catch_amalgamated.hpp:1310
Type point
Definition catch_amalgamated.hpp:1309
double confidence_interval
Definition catch_amalgamated.hpp:1312
Type upper_bound
Definition catch_amalgamated.hpp:1311
Definition catch_amalgamated.hpp:1854
Detail::BenchmarkFunction benchmark
Definition catch_amalgamated.hpp:1857
FDuration warmup_time
Definition catch_amalgamated.hpp:1858
int iterations_per_sample
Definition catch_amalgamated.hpp:1855
std::vector< FDuration > run(const IConfig &cfg, Environment env) const
Definition catch_amalgamated.hpp:1862
int warmup_iterations
Definition catch_amalgamated.hpp:1859
FDuration estimated_duration
Definition catch_amalgamated.hpp:1856
Definition catch_amalgamated.hpp:1327
int high_severe
Definition catch_amalgamated.hpp:1332
int high_mild
Definition catch_amalgamated.hpp:1331
constexpr int total() const
Definition catch_amalgamated.hpp:1334
int low_severe
Definition catch_amalgamated.hpp:1329
int low_mild
Definition catch_amalgamated.hpp:1330
int samples_seen
Definition catch_amalgamated.hpp:1328
Definition catch_amalgamated.hpp:2076
double outlier_variance
Definition catch_amalgamated.hpp:2081
OutlierClassification outliers
Definition catch_amalgamated.hpp:2080
Estimate< FDuration > standard_deviation
Definition catch_amalgamated.hpp:2079
Estimate< FDuration > mean
Definition catch_amalgamated.hpp:2078
std::vector< FDuration > samples
Definition catch_amalgamated.hpp:2077
Definition catch_amalgamated.hpp:1775
Detail::CompleteType_t< FunctionReturnType< Func, Args... > > result
Definition catch_amalgamated.hpp:1777
BoundFlagLambda(L const &lambda)
Definition catch_amalgamated.hpp:4629
L m_lambda
Definition catch_amalgamated.hpp:4619
auto setFlag(bool flag) -> ParserResult override
Definition catch_amalgamated.hpp:4632
Definition catch_amalgamated.hpp:4526
bool isFlag() const override
Definition catch_amalgamated.cpp:2772
virtual auto setFlag(bool flag) -> ParserResult=0
bool & m_ref
Definition catch_amalgamated.hpp:4560
BoundFlagRef(bool &ref)
Definition catch_amalgamated.hpp:4562
Definition catch_amalgamated.hpp:4598
BoundLambda(L const &lambda)
Definition catch_amalgamated.hpp:4604
auto setValue(std::string const &arg) -> ParserResult override
Definition catch_amalgamated.hpp:4606
L m_lambda
Definition catch_amalgamated.hpp:4599
Definition catch_amalgamated.hpp:4613
BoundManyLambda(L const &lambda)
Definition catch_amalgamated.hpp:4614
bool isContainer() const override
Definition catch_amalgamated.hpp:4615
Definition catch_amalgamated.hpp:4517
virtual bool isContainer() const
Definition catch_amalgamated.cpp:2768
virtual bool isFlag() const
Definition catch_amalgamated.cpp:2770
Definition catch_amalgamated.hpp:4522
virtual auto setValue(std::string const &arg) -> ParserResult=0
BoundValueRef(std::vector< T > &ref)
Definition catch_amalgamated.hpp:4545
auto isContainer() const -> bool override
Definition catch_amalgamated.hpp:4547
std::vector< T > & m_ref
Definition catch_amalgamated.hpp:4543
auto setValue(std::string const &arg) -> ParserResult override
Definition catch_amalgamated.hpp:4549
Definition catch_amalgamated.hpp:4531
ParserResult setValue(std::string const &arg) override
Definition catch_amalgamated.hpp:4536
T & m_ref
Definition catch_amalgamated.hpp:4532
BoundValueRef(T &ref)
Definition catch_amalgamated.hpp:4534
Definition catch_amalgamated.hpp:4483
StringRef descriptions
Definition catch_amalgamated.hpp:4485
std::string left
Definition catch_amalgamated.hpp:4484
static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult
Definition catch_amalgamated.hpp:4581
Definition catch_amalgamated.hpp:4567
static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult
Definition catch_amalgamated.hpp:4573
Definition catch_amalgamated.hpp:4274
TokenType type
Definition catch_amalgamated.hpp:4275
StringRef token
Definition catch_amalgamated.hpp:4276
static const bool isValid
Definition catch_amalgamated.hpp:4263
std::remove_const_t< std::remove_reference_t< ArgT > > ArgType
Definition catch_amalgamated.hpp:4264
static const bool isValid
Definition catch_amalgamated.hpp:4258
Definition catch_amalgamated.hpp:4254
Definition catch_amalgamated.hpp:4234
Definition catch_amalgamated.hpp:4240
Help(bool &showHelpFlag)
Definition catch_amalgamated.cpp:3063
Definition catch_amalgamated.hpp:4230
Definition catch_amalgamated.hpp:3762
bool listTests
Definition catch_amalgamated.hpp:3764
bool benchmarkNoAnalysis
Definition catch_amalgamated.hpp:3785
bool showHelp
Definition catch_amalgamated.hpp:3772
std::chrono::milliseconds::rep benchmarkWarmupTime
Definition catch_amalgamated.hpp:3789
bool allowZeroTests
Definition catch_amalgamated.hpp:3776
std::vector< ReporterSpec > reporterSpecifications
Definition catch_amalgamated.hpp:3802
bool libIdentify
Definition catch_amalgamated.hpp:3775
int abortAfter
Definition catch_amalgamated.hpp:3778
bool showInvisibles
Definition catch_amalgamated.hpp:3773
unsigned int benchmarkResamples
Definition catch_amalgamated.hpp:3788
bool listReporters
Definition catch_amalgamated.hpp:3766
bool listListeners
Definition catch_amalgamated.hpp:3767
bool filenamesAsTags
Definition catch_amalgamated.hpp:3774
TestRunOrder runOrder
Definition catch_amalgamated.hpp:3795
bool skipBenchmarks
Definition catch_amalgamated.hpp:3784
std::string name
Definition catch_amalgamated.hpp:3800
bool noThrow
Definition catch_amalgamated.hpp:3771
std::vector< std::string > sectionsToRun
Definition catch_amalgamated.hpp:3805
ShowDurations showDurations
Definition catch_amalgamated.hpp:3793
unsigned int shardCount
Definition catch_amalgamated.hpp:3781
ColourMode defaultColourMode
Definition catch_amalgamated.hpp:3796
WaitForKeypress::When waitForKeypress
Definition catch_amalgamated.hpp:3797
std::vector< std::string > testsOrTags
Definition catch_amalgamated.hpp:3804
Verbosity verbosity
Definition catch_amalgamated.hpp:3791
uint32_t rngSeed
Definition catch_amalgamated.hpp:3779
double benchmarkConfidenceInterval
Definition catch_amalgamated.hpp:3787
std::string processName
Definition catch_amalgamated.hpp:3801
std::string defaultOutputFilename
Definition catch_amalgamated.hpp:3799
double minDuration
Definition catch_amalgamated.hpp:3794
unsigned int benchmarkSamples
Definition catch_amalgamated.hpp:3786
bool showSuccessfulTests
Definition catch_amalgamated.hpp:3769
WarnAbout::What warnings
Definition catch_amalgamated.hpp:3792
unsigned int shardIndex
Definition catch_amalgamated.hpp:3782
bool listTags
Definition catch_amalgamated.hpp:3765
bool shouldDebugBreak
Definition catch_amalgamated.hpp:3770
Definition catch_amalgamated.hpp:4116
bool allOk() const
Definition catch_amalgamated.cpp:2210
std::uint64_t skipped
Definition catch_amalgamated.hpp:4127
std::uint64_t total() const
Definition catch_amalgamated.cpp:2204
bool allPassed() const
Definition catch_amalgamated.cpp:2207
std::uint64_t failed
Definition catch_amalgamated.hpp:4125
std::uint64_t passed
Definition catch_amalgamated.hpp:4124
std::uint64_t failedButOk
Definition catch_amalgamated.hpp:4126
Definition catch_amalgamated.hpp:5579
Definition catch_amalgamated.hpp:2424
StringRef m_name
Definition catch_amalgamated.hpp:2425
StringRef lookup(int value) const
Definition catch_amalgamated.cpp:3905
std::vector< std::pair< int, StringRef > > m_values
Definition catch_amalgamated.hpp:2426
Definition catch_amalgamated.hpp:5144
Definition catch_amalgamated.hpp:5150
Definition catch_amalgamated.hpp:2919
Definition catch_amalgamated.hpp:2403
void type
Definition catch_amalgamated.hpp:2403
Definition catch_amalgamated.hpp:5157
Definition catch_amalgamated.hpp:7652
Definition catch_amalgamated.hpp:3989
MessageBuilder(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
Definition catch_amalgamated.hpp:3990
MessageInfo m_info
Definition catch_amalgamated.hpp:4001
Definition catch_amalgamated.hpp:3945
static unsigned int globalCount
Definition catch_amalgamated.hpp:3963
StringRef macroName
Definition catch_amalgamated.hpp:3950
unsigned int sequence
Definition catch_amalgamated.hpp:3954
SourceLineInfo lineInfo
Definition catch_amalgamated.hpp:3952
std::string message
Definition catch_amalgamated.hpp:3951
ResultWas::OfType type
Definition catch_amalgamated.hpp:3953
MessageInfo(StringRef _macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
Definition catch_amalgamated.cpp:4797
Definition catch_amalgamated.hpp:3978
ReusableStringStream m_stream
Definition catch_amalgamated.hpp:3986
Definition catch_amalgamated.hpp:6052
StringRef tags
Definition catch_amalgamated.hpp:6057
StringRef name
Definition catch_amalgamated.hpp:6056
constexpr NameAndTags(StringRef name_=StringRef(), StringRef tags_=StringRef()) noexcept
Definition catch_amalgamated.hpp:6053
Definition catch_amalgamated.hpp:3749
std::string outputFilename
Definition catch_amalgamated.hpp:3751
friend bool operator!=(ProcessedReporterSpec const &lhs, ProcessedReporterSpec const &rhs)
Definition catch_amalgamated.hpp:3756
std::string name
Definition catch_amalgamated.hpp:3750
std::map< std::string, std::string > customOptions
Definition catch_amalgamated.hpp:3753
ColourMode colourMode
Definition catch_amalgamated.hpp:3752
friend bool operator==(ProcessedReporterSpec const &lhs, ProcessedReporterSpec const &rhs)
Definition catch_amalgamated.cpp:793
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
Definition catch_amalgamated.cpp:1511
Definition catch_amalgamated.hpp:849
Flags
Definition catch_amalgamated.hpp:849
@ SuppressFail
Definition catch_amalgamated.hpp:854
@ FalseTest
Definition catch_amalgamated.hpp:853
@ ContinueOnFailure
Definition catch_amalgamated.hpp:852
@ Normal
Definition catch_amalgamated.hpp:850
Definition catch_amalgamated.hpp:820
OfType
Definition catch_amalgamated.hpp:820
@ FailureBit
Definition catch_amalgamated.hpp:828
@ Info
Definition catch_amalgamated.hpp:823
@ ThrewException
Definition catch_amalgamated.hpp:835
@ ExpressionFailed
Definition catch_amalgamated.hpp:830
@ Unknown
Definition catch_amalgamated.hpp:821
@ Warning
Definition catch_amalgamated.hpp:824
@ FatalErrorCondition
Definition catch_amalgamated.hpp:838
@ DidntThrowException
Definition catch_amalgamated.hpp:836
@ ExplicitSkip
Definition catch_amalgamated.hpp:826
@ Exception
Definition catch_amalgamated.hpp:833
@ ExplicitFailure
Definition catch_amalgamated.hpp:831
@ Ok
Definition catch_amalgamated.hpp:822
Definition catch_amalgamated.hpp:4162
SectionInfo sectionInfo
Definition catch_amalgamated.hpp:4163
double durationInSeconds
Definition catch_amalgamated.hpp:4165
Counts prevAssertions
Definition catch_amalgamated.hpp:4164
Definition catch_amalgamated.hpp:4148
SectionInfo(SourceLineInfo const &_lineInfo, std::string _name, const char *const =nullptr)
Definition catch_amalgamated.hpp:4152
std::string name
Definition catch_amalgamated.hpp:4158
SourceLineInfo lineInfo
Definition catch_amalgamated.hpp:4159
Definition catch_amalgamated.hpp:3242
constexpr SourceLineInfo(char const *_file, std::size_t _line) noexcept
Definition catch_amalgamated.hpp:3245
std::size_t line
Definition catch_amalgamated.hpp:3254
char const * file
Definition catch_amalgamated.hpp:3253
Definition catch_amalgamated.hpp:3923
constexpr friend T const & operator+(T const &value, StreamEndStop)
Definition catch_amalgamated.hpp:3927
constexpr StringRef operator+() const
Definition catch_amalgamated.hpp:3924
static std::string convert(Catch::Approx const &value)
Definition catch_amalgamated.cpp:620
static std::string convert(R C::*p)
Definition catch_amalgamated.hpp:2755
static std::string convert(U *p)
Definition catch_amalgamated.hpp:2744
static std::string convert(T const(&arr)[SZ])
Definition catch_amalgamated.hpp:2966
static std::string convert(bool b)
Definition catch_amalgamated.hpp:2702
static std::string convert(char c)
Definition catch_amalgamated.cpp:2162
static std::string convert(char *str)
Definition catch_amalgamated.cpp:2068
static std::string convert(char const *str)
static std::string convert(char const *str)
Definition catch_amalgamated.hpp:2647
static std::string convert(double value)
Definition catch_amalgamated.cpp:2177
static CATCH_EXPORT int precision
Definition catch_amalgamated.hpp:2738
static std::string convert(float value)
Definition catch_amalgamated.cpp:2171
static CATCH_EXPORT int precision
Definition catch_amalgamated.hpp:2732
static std::string convert(int value)
Definition catch_amalgamated.cpp:2115
static std::string convert(long value)
Definition catch_amalgamated.cpp:2118
static std::string convert(long long value)
static std::string convert(signed char value)
static std::string convert(signed char const *str)
Definition catch_amalgamated.hpp:2654
static std::string convert(std::chrono::duration< Value, Ratio > const &duration)
Definition catch_amalgamated.hpp:3021
static std::string convert(std::chrono::duration< Value, std::ratio< 1 > > const &duration)
Definition catch_amalgamated.hpp:3029
static std::string convert(std::chrono::duration< Value, std::ratio< 3600 > > const &duration)
Definition catch_amalgamated.hpp:3045
static std::string convert(std::chrono::duration< Value, std::ratio< 60 > > const &duration)
Definition catch_amalgamated.hpp:3037
static std::string convert(std::chrono::time_point< Clock, Duration > const &time_point)
Definition catch_amalgamated.hpp:3057
static std::string convert(std::chrono::time_point< std::chrono::system_clock, Duration > const &time_point)
Definition catch_amalgamated.hpp:3064
static std::string convert(std::nullptr_t)
Definition catch_amalgamated.hpp:2723
static std::string convert(const std::string &str)
Definition catch_amalgamated.cpp:2051
static std::string convert(const std::wstring &wstr)
Definition catch_amalgamated.cpp:2077
static std::string convert(unsigned char value)
static std::string convert(unsigned char const *str)
Definition catch_amalgamated.hpp:2662
static std::string convert(unsigned int value)
static std::string convert(unsigned long value)
static std::string convert(unsigned long long value)
static std::string convert(wchar_t *str)
Definition catch_amalgamated.cpp:2099
static std::string convert(wchar_t const *str)
Definition catch_amalgamated.hpp:2552
static std::enable_if_t<!::Catch::Detail::IsStreamInsertable< Fake >::value, std::string > convert(const Fake &value)
Definition catch_amalgamated.hpp:2567
static std::enable_if_t<::Catch::Detail::IsStreamInsertable< Fake >::value, std::string > convert(const Fake &value)
Definition catch_amalgamated.hpp:2556
SourceLineInfo lineInfo
Definition catch_amalgamated.hpp:4996
std::string tag
Definition catch_amalgamated.hpp:4995
TagAlias(std::string const &_tag, SourceLineInfo _lineInfo)
Definition catch_amalgamated.hpp:4990
constexpr Tag(StringRef original_)
Definition catch_amalgamated.hpp:7096
friend bool operator==(Tag const &lhs, Tag const &rhs)
Definition catch_amalgamated.cpp:1622
StringRef original
Definition catch_amalgamated.hpp:7099
Definition catch_amalgamated.hpp:7127
TestCaseInfo(StringRef _className, NameAndTags const &_nameAndTags, SourceLineInfo const &_lineInfo)
Definition catch_amalgamated.cpp:1634
std::string tagsAsString() const
Definition catch_amalgamated.cpp:1731
std::vector< Tag > tags
Definition catch_amalgamated.hpp:7156
StringRef className
Definition catch_amalgamated.hpp:7149
std::string name
Definition catch_amalgamated.hpp:7148
bool okToFail() const
Definition catch_amalgamated.cpp:1718
TestCaseProperties properties
Definition catch_amalgamated.hpp:7158
bool isHidden() const
Definition catch_amalgamated.cpp:1712
friend bool operator<(TestCaseInfo const &lhs, TestCaseInfo const &rhs)
Orders by name, classname and tags.
Definition catch_amalgamated.cpp:1757
std::string backingTags
Definition catch_amalgamated.hpp:7151
SourceLineInfo lineInfo
Definition catch_amalgamated.hpp:7157
bool expectedToFail() const
Definition catch_amalgamated.cpp:1721
void addFilenameTag()
Definition catch_amalgamated.cpp:1725
void internalAppendTag(StringRef tagString)
Definition catch_amalgamated.cpp:1748
Used to signal that an assertion macro failed.
Definition catch_amalgamated.hpp:624
Used to signal that the remainder of a test should be skipped.
Definition catch_amalgamated.hpp:626
Definition catch_amalgamated.hpp:3492
std::string name
Definition catch_amalgamated.hpp:3493
std::vector< TestCaseHandle const * > tests
Definition catch_amalgamated.hpp:3494
Definition catch_amalgamated.hpp:3474
std::vector< Detail::unique_ptr< Pattern > > m_required
Definition catch_amalgamated.hpp:3475
std::vector< Detail::unique_ptr< Pattern > > m_forbidden
Definition catch_amalgamated.hpp:3476
friend std::ostream & operator<<(std::ostream &out, Filter const &f)
Definition catch_amalgamated.hpp:3481
void serializeTo(std::ostream &out) const
Serializes this filter into a string that would be parsed into an equivalent filter.
Definition catch_amalgamated.cpp:1839
Definition catch_amalgamated.hpp:4130
Totals delta(Totals const &prevTotals) const
Definition catch_amalgamated.cpp:2227
Counts assertions
Definition catch_amalgamated.hpp:4137
Counts testCases
Definition catch_amalgamated.hpp:4138
Definition catch_amalgamated.hpp:7322
unsigned int const buildNumber
Definition catch_amalgamated.hpp:7337
char const *const branchName
Definition catch_amalgamated.hpp:7336
Version & operator=(Version const &)=delete
unsigned int const minorVersion
Definition catch_amalgamated.hpp:7332
unsigned int const majorVersion
Definition catch_amalgamated.hpp:7331
unsigned int const patchNumber
Definition catch_amalgamated.hpp:7333
Version(Version const &)=delete
Definition catch_amalgamated.hpp:1187
When
Definition catch_amalgamated.hpp:1187
@ Never
Definition catch_amalgamated.hpp:1188
@ BeforeStart
Definition catch_amalgamated.hpp:1189
@ BeforeExit
Definition catch_amalgamated.hpp:1190
@ BeforeStartAndExit
Definition catch_amalgamated.hpp:1191
Definition catch_amalgamated.hpp:1159
What
Definition catch_amalgamated.hpp:1159
@ UnmatchedTestSpec
A command line test spec matched no test cases.
Definition catch_amalgamated.hpp:1164
@ NoAssertions
A test case or leaf section did not run any assertions.
Definition catch_amalgamated.hpp:1162
@ Nothing
Definition catch_amalgamated.hpp:1160
Definition catch_amalgamated.hpp:5302
Definition catch_amalgamated.hpp:5290
Definition catch_amalgamated.hpp:1503
static true_given< decltype(std::declval< Fun >()(std::declval< Args >()...))> test(int)
static std::false_type test(...)
Definition catch_amalgamated.hpp:1511
Definition catch_amalgamated.hpp:2926
static char symbol()
Definition catch_amalgamated.hpp:2994
static char symbol()
Definition catch_amalgamated.hpp:2998
static char symbol()
Definition catch_amalgamated.hpp:3010
static char symbol()
Definition catch_amalgamated.hpp:3014
static char symbol()
Definition catch_amalgamated.hpp:3006
static char symbol()
Definition catch_amalgamated.hpp:3002
Definition catch_amalgamated.hpp:2983
static std::string symbol()
Definition catch_amalgamated.hpp:2984
Definition catch_amalgamated.hpp:1501
Definition catch_amalgamated.hpp:2465