xref: /trafficserver/tests/include/catch.hpp (revision 95601e9b)
1 /*
2  *  Catch v2.11.0
3  *  Generated: 2019-11-15 15:01:56.628356
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
7  *
8  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
9  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 // start catch.hpp
14 
15 
16 #define CATCH_VERSION_MAJOR 2
17 #define CATCH_VERSION_MINOR 11
18 #define CATCH_VERSION_PATCH 0
19 
20 #ifdef __clang__
21 #    pragma clang system_header
22 #elif defined __GNUC__
23 #    pragma GCC system_header
24 #endif
25 
26 // start catch_suppress_warnings.h
27 
28 #ifdef __clang__
29 #   ifdef __ICC // icpc defines the __clang__ macro
30 #       pragma warning(push)
31 #       pragma warning(disable: 161 1682)
32 #   else // __ICC
33 #       pragma clang diagnostic push
34 #       pragma clang diagnostic ignored "-Wpadded"
35 #       pragma clang diagnostic ignored "-Wswitch-enum"
36 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
37 #    endif
38 #elif defined __GNUC__
39      // Because REQUIREs trigger GCC's -Wparentheses, and because still
40      // supported version of g++ have only buggy support for _Pragmas,
41      // Wparentheses have to be suppressed globally.
42 #    pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
43 
44 #    pragma GCC diagnostic push
45 #    pragma GCC diagnostic ignored "-Wunused-variable"
46 #    pragma GCC diagnostic ignored "-Wpadded"
47 #endif
48 // end catch_suppress_warnings.h
49 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
50 #  define CATCH_IMPL
51 #  define CATCH_CONFIG_ALL_PARTS
52 #endif
53 
54 // In the impl file, we want to have access to all parts of the headers
55 // Can also be used to sanely support PCHs
56 #if defined(CATCH_CONFIG_ALL_PARTS)
57 #  define CATCH_CONFIG_EXTERNAL_INTERFACES
58 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
59 #    undef CATCH_CONFIG_DISABLE_MATCHERS
60 #  endif
61 #  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
62 #    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
63 #  endif
64 #endif
65 
66 #if !defined(CATCH_CONFIG_IMPL_ONLY)
67 // start catch_platform.h
68 
69 #ifdef __APPLE__
70 # include <TargetConditionals.h>
71 # if TARGET_OS_OSX == 1
72 #  define CATCH_PLATFORM_MAC
73 # elif TARGET_OS_IPHONE == 1
74 #  define CATCH_PLATFORM_IPHONE
75 # endif
76 
77 #elif defined(linux) || defined(__linux) || defined(__linux__)
78 #  define CATCH_PLATFORM_LINUX
79 
80 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
81 #  define CATCH_PLATFORM_WINDOWS
82 #endif
83 
84 // end catch_platform.h
85 
86 #ifdef CATCH_IMPL
87 #  ifndef CLARA_CONFIG_MAIN
88 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
89 #    define CLARA_CONFIG_MAIN
90 #  endif
91 #endif
92 
93 // start catch_user_interfaces.h
94 
95 namespace Catch {
96     unsigned int rngSeed();
97 }
98 
99 // end catch_user_interfaces.h
100 // start catch_tag_alias_autoregistrar.h
101 
102 // start catch_common.h
103 
104 // start catch_compiler_capabilities.h
105 
106 // Detect a number of compiler features - by compiler
107 // The following features are defined:
108 //
109 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
110 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
111 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
112 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
113 // ****************
114 // Note to maintainers: if new toggles are added please document them
115 // in configuration.md, too
116 // ****************
117 
118 // In general each macro has a _NO_<feature name> form
119 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
120 // Many features, at point of detection, define an _INTERNAL_ macro, so they
121 // can be combined, en-mass, with the _NO_ forms later.
122 
123 #ifdef __cplusplus
124 
125 #  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
126 #    define CATCH_CPP14_OR_GREATER
127 #  endif
128 
129 #  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
130 #    define CATCH_CPP17_OR_GREATER
131 #  endif
132 
133 #endif
134 
135 #if defined(CATCH_CPP17_OR_GREATER)
136 #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
137 #endif
138 
139 // We have to avoid both ICC and Clang, because they try to mask themselves
140 // as gcc, and we want only GCC in this block
141 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
142 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
143 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "GCC diagnostic pop" )
144 #endif
145 
146 #if defined(__clang__)
147 
148 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
149 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
150 
151 #    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
152          _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
153          _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
154 
155 #    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
156          _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
157 
158 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
159          _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
160 
161 #    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
162          _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
163 
164 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
165          _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
166 
167 #endif // __clang__
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 // Assume that non-Windows platforms support posix signals by default
171 #if !defined(CATCH_PLATFORM_WINDOWS)
172     #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
173 #endif
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 // We know some environments not to support full POSIX signals
177 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
178     #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
179 #endif
180 
181 #ifdef __OS400__
182 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
183 #       define CATCH_CONFIG_COLOUR_NONE
184 #endif
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 // Android somehow still does not support std::to_string
188 #if defined(__ANDROID__)
189 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
190 #    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
191 #endif
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 // Not all Windows environments support SEH properly
195 #if defined(__MINGW32__)
196 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
197 #endif
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 // PS4
201 #if defined(__ORBIS__)
202 #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
203 #endif
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 // Cygwin
207 #ifdef __CYGWIN__
208 
209 // Required for some versions of Cygwin to declare gettimeofday
210 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
211 #   define _BSD_SOURCE
212 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
213 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
214 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
215            && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
216 
217 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
218 
219 # endif
220 #endif // __CYGWIN__
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 // Visual C++
224 #if defined(_MSC_VER)
225 
226 #  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
227 #  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
228 
229 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
230 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
231 #  endif
232 
233 // Universal Windows platform does not support SEH
234 // Or console colours (or console at all...)
235 #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
236 #    define CATCH_CONFIG_COLOUR_NONE
237 #  else
238 #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
239 #  endif
240 
241 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
242 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
243 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
244 #  if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
245 #    define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
246 #  endif
247 #endif // _MSC_VER
248 
249 #if defined(_REENTRANT) || defined(_MSC_VER)
250 // Enable async processing, as -pthread is specified or no additional linking is required
251 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
252 #endif // _MSC_VER
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 // Check if we are compiled with -fno-exceptions or equivalent
256 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
257 #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
258 #endif
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 // DJGPP
262 #ifdef __DJGPP__
263 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
264 #endif // __DJGPP__
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 // Embarcadero C++Build
268 #if defined(__BORLANDC__)
269     #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
270 #endif
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 
274 // Use of __COUNTER__ is suppressed during code analysis in
275 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
276 // handled by it.
277 // Otherwise all supported compilers support COUNTER macro,
278 // but user still might want to turn it off
279 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
280     #define CATCH_INTERNAL_CONFIG_COUNTER
281 #endif
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 
285 // RTX is a special version of Windows that is real time.
286 // This means that it is detected as Windows, but does not provide
287 // the same set of capabilities as real Windows does.
288 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
289     #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
290     #define CATCH_INTERNAL_CONFIG_NO_ASYNC
291     #define CATCH_CONFIG_COLOUR_NONE
292 #endif
293 
294 #if defined(__UCLIBC__)
295 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
296 #endif
297 
298 // Various stdlib support checks that require __has_include
299 #if defined(__has_include)
300   // Check if string_view is available and usable
301   #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
302   #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
303   #endif
304 
305   // Check if optional is available and usable
306   #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
307   #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
308   #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
309 
310   // Check if byte is available and usable
311   #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
312   #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
313   #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
314 
315   // Check if variant is available and usable
316   #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
317   #    if defined(__clang__) && (__clang_major__ < 8)
318          // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
319          // fix should be in clang 8, workaround in libstdc++ 8.2
320   #      include <ciso646>
321   #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
322   #        define CATCH_CONFIG_NO_CPP17_VARIANT
323   #      else
324   #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
325   #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
326   #    else
327   #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
328   #    endif // defined(__clang__) && (__clang_major__ < 8)
329   #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
330 #endif // defined(__has_include)
331 
332 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
333 #   define CATCH_CONFIG_COUNTER
334 #endif
335 #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)
336 #   define CATCH_CONFIG_WINDOWS_SEH
337 #endif
338 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
339 #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)
340 #   define CATCH_CONFIG_POSIX_SIGNALS
341 #endif
342 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
343 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
344 #   define CATCH_CONFIG_WCHAR
345 #endif
346 
347 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
348 #    define CATCH_CONFIG_CPP11_TO_STRING
349 #endif
350 
351 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
352 #  define CATCH_CONFIG_CPP17_OPTIONAL
353 #endif
354 
355 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
356 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
357 #endif
358 
359 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
360 #  define CATCH_CONFIG_CPP17_STRING_VIEW
361 #endif
362 
363 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
364 #  define CATCH_CONFIG_CPP17_VARIANT
365 #endif
366 
367 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
368 #  define CATCH_CONFIG_CPP17_BYTE
369 #endif
370 
371 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
372 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
373 #endif
374 
375 #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)
376 #  define CATCH_CONFIG_NEW_CAPTURE
377 #endif
378 
379 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
380 #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
381 #endif
382 
383 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
384 #  define CATCH_CONFIG_POLYFILL_ISNAN
385 #endif
386 
387 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
388 #  define CATCH_CONFIG_USE_ASYNC
389 #endif
390 
391 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
392 #  define CATCH_CONFIG_ANDROID_LOGWRITE
393 #endif
394 
395 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
396 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
397 #endif
398 
399 // Even if we do not think the compiler has that warning, we still have
400 // to provide a macro that can be used by the code.
401 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
402 #   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
403 #endif
404 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
405 #   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
406 #endif
407 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
408 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
409 #endif
410 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
411 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
412 #endif
413 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
414 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
415 #endif
416 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
417 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
418 #endif
419 
420 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
421 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
422 #elif defined(__clang__) && (__clang_major__ < 5)
423 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
424 #endif
425 
426 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
427 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
428 #endif
429 
430 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
431 #define CATCH_TRY if ((true))
432 #define CATCH_CATCH_ALL if ((false))
433 #define CATCH_CATCH_ANON(type) if ((false))
434 #else
435 #define CATCH_TRY try
436 #define CATCH_CATCH_ALL catch (...)
437 #define CATCH_CATCH_ANON(type) catch (type)
438 #endif
439 
440 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
441 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
442 #endif
443 
444 // end catch_compiler_capabilities.h
445 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
446 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
447 #ifdef CATCH_CONFIG_COUNTER
448 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
449 #else
450 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
451 #endif
452 
453 #include <iosfwd>
454 #include <string>
455 #include <cstdint>
456 
457 // We need a dummy global operator<< so we can bring it into Catch namespace later
458 struct Catch_global_namespace_dummy {};
459 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
460 
461 namespace Catch {
462 
463     struct CaseSensitive { enum Choice {
464         Yes,
465         No
466     }; };
467 
468     class NonCopyable {
469         NonCopyable( NonCopyable const& )              = delete;
470         NonCopyable( NonCopyable && )                  = delete;
471         NonCopyable& operator = ( NonCopyable const& ) = delete;
472         NonCopyable& operator = ( NonCopyable && )     = delete;
473 
474     protected:
475         NonCopyable();
476         virtual ~NonCopyable();
477     };
478 
479     struct SourceLineInfo {
480 
481         SourceLineInfo() = delete;
SourceLineInfoCatch::SourceLineInfo482         SourceLineInfo( char const* _file, std::size_t _line ) noexcept
483         :   file( _file ),
484             line( _line )
485         {}
486 
487         SourceLineInfo( SourceLineInfo const& other )            = default;
488         SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
489         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
490         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
491 
emptyCatch::SourceLineInfo492         bool empty() const noexcept { return file[0] == '\0'; }
493         bool operator == ( SourceLineInfo const& other ) const noexcept;
494         bool operator < ( SourceLineInfo const& other ) const noexcept;
495 
496         char const* file;
497         std::size_t line;
498     };
499 
500     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
501 
502     // Bring in operator<< from global namespace into Catch namespace
503     // This is necessary because the overload of operator<< above makes
504     // lookup stop at namespace Catch
505     using ::operator<<;
506 
507     // Use this in variadic streaming macros to allow
508     //    >> +StreamEndStop
509     // as well as
510     //    >> stuff +StreamEndStop
511     struct StreamEndStop {
512         std::string operator+() const;
513     };
514     template<typename T>
operator +(T const & value,StreamEndStop)515     T const& operator + ( T const& value, StreamEndStop ) {
516         return value;
517     }
518 }
519 
520 #define CATCH_INTERNAL_LINEINFO \
521     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
522 
523 // end catch_common.h
524 namespace Catch {
525 
526     struct RegistrarForTagAliases {
527         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
528     };
529 
530 } // end namespace Catch
531 
532 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
533     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
534     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
535     namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
536     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
537 
538 // end catch_tag_alias_autoregistrar.h
539 // start catch_test_registry.h
540 
541 // start catch_interfaces_testcase.h
542 
543 #include <vector>
544 
545 namespace Catch {
546 
547     class TestSpec;
548 
549     struct ITestInvoker {
550         virtual void invoke () const = 0;
551         virtual ~ITestInvoker();
552     };
553 
554     class TestCase;
555     struct IConfig;
556 
557     struct ITestCaseRegistry {
558         virtual ~ITestCaseRegistry();
559         virtual std::vector<TestCase> const& getAllTests() const = 0;
560         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
561     };
562 
563     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
564     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
565     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
566     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
567 
568 }
569 
570 // end catch_interfaces_testcase.h
571 // start catch_stringref.h
572 
573 #include <cstddef>
574 #include <string>
575 #include <iosfwd>
576 #include <cassert>
577 
578 namespace Catch {
579 
580     /// A non-owning string class (similar to the forthcoming std::string_view)
581     /// Note that, because a StringRef may be a substring of another string,
582     /// it may not be null terminated.
583     class StringRef {
584     public:
585         using size_type = std::size_t;
586         using const_iterator = const char*;
587 
588     private:
589         static constexpr char const* const s_empty = "";
590 
591         char const* m_start = s_empty;
592         size_type m_size = 0;
593 
594     public: // construction
595         constexpr StringRef() noexcept = default;
596 
597         StringRef( char const* rawChars ) noexcept;
598 
StringRef(char const * rawChars,size_type size)599         constexpr StringRef( char const* rawChars, size_type size ) noexcept
600         :   m_start( rawChars ),
601             m_size( size )
602         {}
603 
StringRef(std::string const & stdString)604         StringRef( std::string const& stdString ) noexcept
605         :   m_start( stdString.c_str() ),
606             m_size( stdString.size() )
607         {}
608 
609         explicit operator std::string() const {
610             return std::string(m_start, m_size);
611         }
612 
613     public: // operators
614         auto operator == ( StringRef const& other ) const noexcept -> bool;
operator !=(StringRef const & other) const615         auto operator != (StringRef const& other) const noexcept -> bool {
616             return !(*this == other);
617         }
618 
operator [](size_type index) const619         auto operator[] ( size_type index ) const noexcept -> char {
620             assert(index < m_size);
621             return m_start[index];
622         }
623 
624     public: // named queries
empty() const625         constexpr auto empty() const noexcept -> bool {
626             return m_size == 0;
627         }
size() const628         constexpr auto size() const noexcept -> size_type {
629             return m_size;
630         }
631 
632         // Returns the current start pointer. If the StringRef is not
633         // null-terminated, throws std::domain_exception
634         auto c_str() const -> char const*;
635 
636     public: // substrings and searches
637         // Returns a substring of [start, start + length).
638         // If start + length > size(), then the substring is [start, size()).
639         // If start > size(), then the substring is empty.
640         auto substr( size_type start, size_type length ) const noexcept -> StringRef;
641 
642         // Returns the current start pointer. May not be null-terminated.
643         auto data() const noexcept -> char const*;
644 
isNullTerminated() const645         constexpr auto isNullTerminated() const noexcept -> bool {
646             return m_start[m_size] == '\0';
647         }
648 
649     public: // iterators
begin() const650         constexpr const_iterator begin() const { return m_start; }
end() const651         constexpr const_iterator end() const { return m_start + m_size; }
652     };
653 
654     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
655     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
656 
657     constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
658         return StringRef( rawChars, size );
659     }
660 } // namespace Catch
661 
662 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
663     return Catch::StringRef( rawChars, size );
664 }
665 
666 // end catch_stringref.h
667 // start catch_preprocessor.hpp
668 
669 
670 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
671 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
672 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
673 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
674 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
675 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
676 
677 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
678 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
679 // MSVC needs more evaluations
680 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
681 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
682 #else
683 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
684 #endif
685 
686 #define CATCH_REC_END(...)
687 #define CATCH_REC_OUT
688 
689 #define CATCH_EMPTY()
690 #define CATCH_DEFER(id) id CATCH_EMPTY()
691 
692 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
693 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
694 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
695 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
696 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
697 #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
698 
699 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
700 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
701 #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
702 
703 #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__ )
704 #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__ )
705 #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__ )
706 
707 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
708 // and passes userdata as the first parameter to each invocation,
709 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
710 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
711 
712 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
713 
714 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
715 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
716 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
717 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
718 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
719 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
720 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
721 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
722 #else
723 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
724 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
725 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
726 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
727 #endif
728 
729 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
730 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
731 
732 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
733 
734 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
735 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
736 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
737 #else
738 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
739 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
740 #endif
741 
742 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
743     CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
744 
745 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
746 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
747 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
748 #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)
749 #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)
750 #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)
751 #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, _4, _5, _6)
752 #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)
753 #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)
754 #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)
755 #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)
756 
757 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
758 
759 #define INTERNAL_CATCH_TYPE_GEN\
760     template<typename...> struct TypeList {};\
761     template<typename...Ts>\
762     constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
763     template<template<typename...> class...> struct TemplateTypeList{};\
764     template<template<typename...> class...Cs>\
765     constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
766     template<typename...>\
767     struct append;\
768     template<typename...>\
769     struct rewrap;\
770     template<template<typename...> class, typename...>\
771     struct create;\
772     template<template<typename...> class, typename>\
773     struct convert;\
774     \
775     template<typename T> \
776     struct append<T> { using type = T; };\
777     template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
778     struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
779     template< template<typename...> class L1, typename...E1, typename...Rest>\
780     struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
781     \
782     template< template<typename...> class Container, template<typename...> class List, typename...elems>\
783     struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
784     template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
785     struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
786     \
787     template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
788     struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
789     template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
790     struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
791 
792 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
793     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
794     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
795     constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
796     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
797     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
798     constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
799     \
800     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
801     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
802     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
803     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
804     template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
805     struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
806 
807 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
808 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
809     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
810     static void TestName()
811 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
812     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
813     static void TestName()
814 
815 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
816 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
817     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
818     static void TestName()
819 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
820     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
821     static void TestName()
822 
823 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
824     template<typename Type>\
825     void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
826     {\
827         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
828     }
829 
830 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
831     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
832     void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
833     {\
834         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
835     }
836 
837 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
838     template<typename Type>\
839     void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
840     {\
841         Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
842     }
843 
844 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
845     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
846     void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
847     {\
848         Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
849     }
850 
851 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
852 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
853     template<typename TestType> \
854     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
855         void test();\
856     }
857 
858 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
859     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
860     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
861         void test();\
862     }
863 
864 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
865 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
866     template<typename TestType> \
867     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
868 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
869     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
870     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
871 
872 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
873 #define INTERNAL_CATCH_NTTP_0
874 #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)
875 #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__)
876 #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__)
877 #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__)
878 #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__)
879 #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__)
880 #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__)
881 #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__)
882 #else
883 #define INTERNAL_CATCH_NTTP_0(signature)
884 #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__))
885 #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__))
886 #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__))
887 #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__))
888 #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__))
889 #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__))
890 #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__))
891 #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__))
892 #endif
893 
894 // end catch_preprocessor.hpp
895 // start catch_meta.hpp
896 
897 
898 #include <type_traits>
899 
900 namespace Catch {
901     template<typename T>
902     struct always_false : std::false_type {};
903 
904     template <typename> struct true_given : std::true_type {};
905     struct is_callable_tester {
906         template <typename Fun, typename... Args>
907         true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
908         template <typename...>
909         std::false_type static test(...);
910     };
911 
912     template <typename T>
913     struct is_callable;
914 
915     template <typename Fun, typename... Args>
916     struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
917 
918 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
919     // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
920     // replaced with std::invoke_result here. Also *_t format is preferred over
921     // typename *::type format.
922     template <typename Func, typename U>
923     using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
924 #else
925     template <typename Func, typename U>
926     using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
927 #endif
928 
929 } // namespace Catch
930 
931 namespace mpl_{
932     struct na;
933 }
934 
935 // end catch_meta.hpp
936 namespace Catch {
937 
938 template<typename C>
939 class TestInvokerAsMethod : public ITestInvoker {
940     void (C::*m_testAsMethod)();
941 public:
TestInvokerAsMethod(void (C::* testAsMethod)())942     TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
943 
invoke() const944     void invoke() const override {
945         C obj;
946         (obj.*m_testAsMethod)();
947     }
948 };
949 
950 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
951 
952 template<typename C>
makeTestInvoker(void (C::* testAsMethod)())953 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
954     return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
955 }
956 
957 struct NameAndTags {
958     NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
959     StringRef name;
960     StringRef tags;
961 };
962 
963 struct AutoReg : NonCopyable {
964     AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
965     ~AutoReg();
966 };
967 
968 } // end namespace Catch
969 
970 #if defined(CATCH_CONFIG_DISABLE)
971     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
972         static void TestName()
973     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
974         namespace{                        \
975             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
976                 void test();              \
977             };                            \
978         }                                 \
979         void TestName::test()
980     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
981         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
982     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
983         namespace{                                                                                  \
984             namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
985             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
986         }                                                                                           \
987         }                                                                                           \
988         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
989 
990     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
991         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
992             INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
993     #else
994         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
995             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
996     #endif
997 
998     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
999         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1000             INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
1001     #else
1002         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
1003             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
1004     #endif
1005 
1006     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1007         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1008             INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
1009     #else
1010         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
1011             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
1012     #endif
1013 
1014     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1015         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1016             INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
1017     #else
1018         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
1019             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
1020     #endif
1021 #endif
1022 
1023     ///////////////////////////////////////////////////////////////////////////////
1024     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
1025         static void TestName(); \
1026         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1027         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1028         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1029         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1030         static void TestName()
1031     #define INTERNAL_CATCH_TESTCASE( ... ) \
1032         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
1033 
1034     ///////////////////////////////////////////////////////////////////////////////
1035     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
1036         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1037         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1038         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
1039         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1040 
1041     ///////////////////////////////////////////////////////////////////////////////
1042     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
1043         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1044         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1045         namespace{ \
1046             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
1047                 void test(); \
1048             }; \
1049             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1050         } \
1051         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1052         void TestName::test()
1053     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
1054         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
1055 
1056     ///////////////////////////////////////////////////////////////////////////////
1057     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
1058         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1059         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1060         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
1061         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
1062 
1063     ///////////////////////////////////////////////////////////////////////////////
1064     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
1065         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1066         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1067         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1068         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1069         INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1070         namespace {\
1071         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1072             INTERNAL_CATCH_TYPE_GEN\
1073             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1074             INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1075             template<typename...Types> \
1076             struct TestName{\
1077                 TestName(){\
1078                     int index = 0;                                    \
1079                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1080                     using expander = int[];\
1081                     (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
1082                 }\
1083             };\
1084             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1085             TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1086             return 0;\
1087         }();\
1088         }\
1089         }\
1090         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1091         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
1092 
1093 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1094     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1095         INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
1096 #else
1097     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
1098         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
1099 #endif
1100 
1101 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1102     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1103         INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
1104 #else
1105     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
1106         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
1107 #endif
1108 
1109     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
1110         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
1111         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
1112         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
1113         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
1114         template<typename TestType> static void TestFuncName();       \
1115         namespace {\
1116         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
1117             INTERNAL_CATCH_TYPE_GEN                                                  \
1118             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
1119             template<typename... Types>                               \
1120             struct TestName {                                         \
1121                 void reg_tests() {                                          \
1122                     int index = 0;                                    \
1123                     using expander = int[];                           \
1124                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1125                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1126                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1127                     (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++, 0)... };/* NOLINT */\
1128                 }                                                     \
1129             };                                                        \
1130             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1131                 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; \
1132                 TestInit t;                                           \
1133                 t.reg_tests();                                        \
1134                 return 0;                                             \
1135             }();                                                      \
1136         }                                                             \
1137         }                                                             \
1138         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
1139         template<typename TestType>                                   \
1140         static void TestFuncName()
1141 
1142 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1143     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1144         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
1145 #else
1146     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
1147         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
1148 #endif
1149 
1150 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1151     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1152         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
1153 #else
1154     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
1155         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
1156 #endif
1157 
1158     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
1159         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1160         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1161         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1162         template<typename TestType> static void TestFunc();       \
1163         namespace {\
1164         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
1165         INTERNAL_CATCH_TYPE_GEN\
1166         template<typename... Types>                               \
1167         struct TestName {                                         \
1168             void reg_tests() {                                          \
1169                 int index = 0;                                    \
1170                 using expander = int[];                           \
1171                 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
1172             }                                                     \
1173         };\
1174         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
1175                 using TestInit = typename convert<TestName, TmplList>::type; \
1176                 TestInit t;                                           \
1177                 t.reg_tests();                                        \
1178                 return 0;                                             \
1179             }();                                                      \
1180         }}\
1181         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
1182         template<typename TestType>                                   \
1183         static void TestFunc()
1184 
1185     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
1186         INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
1187 
1188     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
1189         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1190         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1191         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1192         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1193         namespace {\
1194         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1195             INTERNAL_CATCH_TYPE_GEN\
1196             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1197             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
1198             INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1199             template<typename...Types> \
1200             struct TestNameClass{\
1201                 TestNameClass(){\
1202                     int index = 0;                                    \
1203                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
1204                     using expander = int[];\
1205                     (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
1206                 }\
1207             };\
1208             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1209                 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
1210                 return 0;\
1211         }();\
1212         }\
1213         }\
1214         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1215         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
1216 
1217 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1218     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1219         INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
1220 #else
1221     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1222         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
1223 #endif
1224 
1225 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1226     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1227         INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
1228 #else
1229     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
1230         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
1231 #endif
1232 
1233     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
1234         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1235         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1236         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
1237         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1238         template<typename TestType> \
1239             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1240                 void test();\
1241             };\
1242         namespace {\
1243         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
1244             INTERNAL_CATCH_TYPE_GEN                  \
1245             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
1246             template<typename...Types>\
1247             struct TestNameClass{\
1248                 void reg_tests(){\
1249                     int index = 0;\
1250                     using expander = int[];\
1251                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1252                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1253                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1254                     (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++, 0)... };/* NOLINT */ \
1255                 }\
1256             };\
1257             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1258                 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;\
1259                 TestInit t;\
1260                 t.reg_tests();\
1261                 return 0;\
1262             }(); \
1263         }\
1264         }\
1265         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1266         template<typename TestType> \
1267         void TestName<TestType>::test()
1268 
1269 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1270     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1271         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
1272 #else
1273     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1274         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
1275 #endif
1276 
1277 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1278     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1279         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
1280 #else
1281     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
1282         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
1283 #endif
1284 
1285     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
1286         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
1287         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1288         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
1289         template<typename TestType> \
1290         struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1291             void test();\
1292         };\
1293         namespace {\
1294         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
1295             INTERNAL_CATCH_TYPE_GEN\
1296             template<typename...Types>\
1297             struct TestNameClass{\
1298                 void reg_tests(){\
1299                     int index = 0;\
1300                     using expander = int[];\
1301                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
1302                 }\
1303             };\
1304             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1305                 using TestInit = typename convert<TestNameClass, TmplList>::type;\
1306                 TestInit t;\
1307                 t.reg_tests();\
1308                 return 0;\
1309             }(); \
1310         }}\
1311         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
1312         template<typename TestType> \
1313         void TestName<TestType>::test()
1314 
1315 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
1316         INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
1317 
1318 // end catch_test_registry.h
1319 // start catch_capture.hpp
1320 
1321 // start catch_assertionhandler.h
1322 
1323 // start catch_assertioninfo.h
1324 
1325 // start catch_result_type.h
1326 
1327 namespace Catch {
1328 
1329     // ResultWas::OfType enum
1330     struct ResultWas { enum OfType {
1331         Unknown = -1,
1332         Ok = 0,
1333         Info = 1,
1334         Warning = 2,
1335 
1336         FailureBit = 0x10,
1337 
1338         ExpressionFailed = FailureBit | 1,
1339         ExplicitFailure = FailureBit | 2,
1340 
1341         Exception = 0x100 | FailureBit,
1342 
1343         ThrewException = Exception | 1,
1344         DidntThrowException = Exception | 2,
1345 
1346         FatalErrorCondition = 0x200 | FailureBit
1347 
1348     }; };
1349 
1350     bool isOk( ResultWas::OfType resultType );
1351     bool isJustInfo( int flags );
1352 
1353     // ResultDisposition::Flags enum
1354     struct ResultDisposition { enum Flags {
1355         Normal = 0x01,
1356 
1357         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
1358         FalseTest = 0x04,           // Prefix expression with !
1359         SuppressFail = 0x08         // Failures are reported but do not fail the test
1360     }; };
1361 
1362     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
1363 
1364     bool shouldContinueOnFailure( int flags );
isFalseTest(int flags)1365     inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
1366     bool shouldSuppressFailure( int flags );
1367 
1368 } // end namespace Catch
1369 
1370 // end catch_result_type.h
1371 namespace Catch {
1372 
1373     struct AssertionInfo
1374     {
1375         StringRef macroName;
1376         SourceLineInfo lineInfo;
1377         StringRef capturedExpression;
1378         ResultDisposition::Flags resultDisposition;
1379 
1380         // We want to delete this constructor but a compiler bug in 4.8 means
1381         // the struct is then treated as non-aggregate
1382         //AssertionInfo() = delete;
1383     };
1384 
1385 } // end namespace Catch
1386 
1387 // end catch_assertioninfo.h
1388 // start catch_decomposer.h
1389 
1390 // start catch_tostring.h
1391 
1392 #include <vector>
1393 #include <cstddef>
1394 #include <type_traits>
1395 #include <string>
1396 // start catch_stream.h
1397 
1398 #include <iosfwd>
1399 #include <cstddef>
1400 #include <ostream>
1401 
1402 namespace Catch {
1403 
1404     std::ostream& cout();
1405     std::ostream& cerr();
1406     std::ostream& clog();
1407 
1408     class StringRef;
1409 
1410     struct IStream {
1411         virtual ~IStream();
1412         virtual std::ostream& stream() const = 0;
1413     };
1414 
1415     auto makeStream( StringRef const &filename ) -> IStream const*;
1416 
1417     class ReusableStringStream : NonCopyable {
1418         std::size_t m_index;
1419         std::ostream* m_oss;
1420     public:
1421         ReusableStringStream();
1422         ~ReusableStringStream();
1423 
1424         auto str() const -> std::string;
1425 
1426         template<typename T>
operator <<(T const & value)1427         auto operator << ( T const& value ) -> ReusableStringStream& {
1428             *m_oss << value;
1429             return *this;
1430         }
get()1431         auto get() -> std::ostream& { return *m_oss; }
1432     };
1433 }
1434 
1435 // end catch_stream.h
1436 // start catch_interfaces_enum_values_registry.h
1437 
1438 #include <vector>
1439 
1440 namespace Catch {
1441 
1442     namespace Detail {
1443         struct EnumInfo {
1444             StringRef m_name;
1445             std::vector<std::pair<int, StringRef>> m_values;
1446 
1447             ~EnumInfo();
1448 
1449             StringRef lookup( int value ) const;
1450         };
1451     } // namespace Detail
1452 
1453     struct IMutableEnumValuesRegistry {
1454         virtual ~IMutableEnumValuesRegistry();
1455 
1456         virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
1457 
1458         template<typename E>
registerEnumCatch::IMutableEnumValuesRegistry1459         Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
1460             static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
1461             std::vector<int> intValues;
1462             intValues.reserve( values.size() );
1463             for( auto enumValue : values )
1464                 intValues.push_back( static_cast<int>( enumValue ) );
1465             return registerEnum( enumName, allEnums, intValues );
1466         }
1467     };
1468 
1469 } // Catch
1470 
1471 // end catch_interfaces_enum_values_registry.h
1472 
1473 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1474 #include <string_view>
1475 #endif
1476 
1477 #ifdef __OBJC__
1478 // start catch_objc_arc.hpp
1479 
1480 #import <Foundation/Foundation.h>
1481 
1482 #ifdef __has_feature
1483 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1484 #else
1485 #define CATCH_ARC_ENABLED 0
1486 #endif
1487 
1488 void arcSafeRelease( NSObject* obj );
1489 id performOptionalSelector( id obj, SEL sel );
1490 
1491 #if !CATCH_ARC_ENABLED
arcSafeRelease(NSObject * obj)1492 inline void arcSafeRelease( NSObject* obj ) {
1493     [obj release];
1494 }
performOptionalSelector(id obj,SEL sel)1495 inline id performOptionalSelector( id obj, SEL sel ) {
1496     if( [obj respondsToSelector: sel] )
1497         return [obj performSelector: sel];
1498     return nil;
1499 }
1500 #define CATCH_UNSAFE_UNRETAINED
1501 #define CATCH_ARC_STRONG
1502 #else
arcSafeRelease(NSObject *)1503 inline void arcSafeRelease( NSObject* ){}
performOptionalSelector(id obj,SEL sel)1504 inline id performOptionalSelector( id obj, SEL sel ) {
1505 #ifdef __clang__
1506 #pragma clang diagnostic push
1507 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1508 #endif
1509     if( [obj respondsToSelector: sel] )
1510         return [obj performSelector: sel];
1511 #ifdef __clang__
1512 #pragma clang diagnostic pop
1513 #endif
1514     return nil;
1515 }
1516 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1517 #define CATCH_ARC_STRONG __strong
1518 #endif
1519 
1520 // end catch_objc_arc.hpp
1521 #endif
1522 
1523 #ifdef _MSC_VER
1524 #pragma warning(push)
1525 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1526 #endif
1527 
1528 namespace Catch {
1529     namespace Detail {
1530 
1531         extern const std::string unprintableString;
1532 
1533         std::string rawMemoryToString( const void *object, std::size_t size );
1534 
1535         template<typename T>
rawMemoryToString(const T & object)1536         std::string rawMemoryToString( const T& object ) {
1537           return rawMemoryToString( &object, sizeof(object) );
1538         }
1539 
1540         template<typename T>
1541         class IsStreamInsertable {
1542             template<typename Stream, typename U>
1543             static auto test(int)
1544                 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
1545 
1546             template<typename, typename>
1547             static auto test(...)->std::false_type;
1548 
1549         public:
1550             static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1551         };
1552 
1553         template<typename E>
1554         std::string convertUnknownEnumToString( E e );
1555 
1556         template<typename T>
1557         typename std::enable_if<
1558             !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
convertUnstreamable(T const &)1559         std::string>::type convertUnstreamable( T const& ) {
1560             return Detail::unprintableString;
1561         }
1562         template<typename T>
1563         typename std::enable_if<
1564             !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
convertUnstreamable(T const & ex)1565          std::string>::type convertUnstreamable(T const& ex) {
1566             return ex.what();
1567         }
1568 
1569         template<typename T>
1570         typename std::enable_if<
1571             std::is_enum<T>::value
convertUnstreamable(T const & value)1572         , std::string>::type convertUnstreamable( T const& value ) {
1573             return convertUnknownEnumToString( value );
1574         }
1575 
1576 #if defined(_MANAGED)
1577         //! Convert a CLR string to a utf8 std::string
1578         template<typename T>
1579         std::string clrReferenceToString( T^ ref ) {
1580             if (ref == nullptr)
1581                 return std::string("null");
1582             auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1583             cli::pin_ptr<System::Byte> p = &bytes[0];
1584             return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1585         }
1586 #endif
1587 
1588     } // namespace Detail
1589 
1590     // If we decide for C++14, change these to enable_if_ts
1591     template <typename T, typename = void>
1592     struct StringMaker {
1593         template <typename Fake = T>
1594         static
1595         typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
convertCatch::StringMaker1596             convert(const Fake& value) {
1597                 ReusableStringStream rss;
1598                 // NB: call using the function-like syntax to avoid ambiguity with
1599                 // user-defined templated operator<< under clang.
1600                 rss.operator<<(value);
1601                 return rss.str();
1602         }
1603 
1604         template <typename Fake = T>
1605         static
1606         typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1607             convert( const Fake& value ) {
1608 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1609             return Detail::convertUnstreamable(value);
1610 #else
1611             return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1612 #endif
1613         }
1614     };
1615 
1616     namespace Detail {
1617 
1618         // This function dispatches all stringification requests inside of Catch.
1619         // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1620         template <typename T>
stringify(const T & e)1621         std::string stringify(const T& e) {
1622             return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1623         }
1624 
1625         template<typename E>
convertUnknownEnumToString(E e)1626         std::string convertUnknownEnumToString( E e ) {
1627             return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1628         }
1629 
1630 #if defined(_MANAGED)
1631         template <typename T>
1632         std::string stringify( T^ e ) {
1633             return ::Catch::StringMaker<T^>::convert(e);
1634         }
1635 #endif
1636 
1637     } // namespace Detail
1638 
1639     // Some predefined specializations
1640 
1641     template<>
1642     struct StringMaker<std::string> {
1643         static std::string convert(const std::string& str);
1644     };
1645 
1646 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1647     template<>
1648     struct StringMaker<std::string_view> {
1649         static std::string convert(std::string_view str);
1650     };
1651 #endif
1652 
1653     template<>
1654     struct StringMaker<char const *> {
1655         static std::string convert(char const * str);
1656     };
1657     template<>
1658     struct StringMaker<char *> {
1659         static std::string convert(char * str);
1660     };
1661 
1662 #ifdef CATCH_CONFIG_WCHAR
1663     template<>
1664     struct StringMaker<std::wstring> {
1665         static std::string convert(const std::wstring& wstr);
1666     };
1667 
1668 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1669     template<>
1670     struct StringMaker<std::wstring_view> {
1671         static std::string convert(std::wstring_view str);
1672     };
1673 # endif
1674 
1675     template<>
1676     struct StringMaker<wchar_t const *> {
1677         static std::string convert(wchar_t const * str);
1678     };
1679     template<>
1680     struct StringMaker<wchar_t *> {
1681         static std::string convert(wchar_t * str);
1682     };
1683 #endif
1684 
1685     // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1686     //      while keeping string semantics?
1687     template<int SZ>
1688     struct StringMaker<char[SZ]> {
convertCatch::StringMaker1689         static std::string convert(char const* str) {
1690             return ::Catch::Detail::stringify(std::string{ str });
1691         }
1692     };
1693     template<int SZ>
1694     struct StringMaker<signed char[SZ]> {
convertCatch::StringMaker1695         static std::string convert(signed char const* str) {
1696             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1697         }
1698     };
1699     template<int SZ>
1700     struct StringMaker<unsigned char[SZ]> {
convertCatch::StringMaker1701         static std::string convert(unsigned char const* str) {
1702             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1703         }
1704     };
1705 
1706 #if defined(CATCH_CONFIG_CPP17_BYTE)
1707     template<>
1708     struct StringMaker<std::byte> {
1709         static std::string convert(std::byte value);
1710     };
1711 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
1712     template<>
1713     struct StringMaker<int> {
1714         static std::string convert(int value);
1715     };
1716     template<>
1717     struct StringMaker<long> {
1718         static std::string convert(long value);
1719     };
1720     template<>
1721     struct StringMaker<long long> {
1722         static std::string convert(long long value);
1723     };
1724     template<>
1725     struct StringMaker<unsigned int> {
1726         static std::string convert(unsigned int value);
1727     };
1728     template<>
1729     struct StringMaker<unsigned long> {
1730         static std::string convert(unsigned long value);
1731     };
1732     template<>
1733     struct StringMaker<unsigned long long> {
1734         static std::string convert(unsigned long long value);
1735     };
1736 
1737     template<>
1738     struct StringMaker<bool> {
1739         static std::string convert(bool b);
1740     };
1741 
1742     template<>
1743     struct StringMaker<char> {
1744         static std::string convert(char c);
1745     };
1746     template<>
1747     struct StringMaker<signed char> {
1748         static std::string convert(signed char c);
1749     };
1750     template<>
1751     struct StringMaker<unsigned char> {
1752         static std::string convert(unsigned char c);
1753     };
1754 
1755     template<>
1756     struct StringMaker<std::nullptr_t> {
1757         static std::string convert(std::nullptr_t);
1758     };
1759 
1760     template<>
1761     struct StringMaker<float> {
1762         static std::string convert(float value);
1763         static int precision;
1764     };
1765 
1766     template<>
1767     struct StringMaker<double> {
1768         static std::string convert(double value);
1769         static int precision;
1770     };
1771 
1772     template <typename T>
1773     struct StringMaker<T*> {
1774         template <typename U>
convertCatch::StringMaker1775         static std::string convert(U* p) {
1776             if (p) {
1777                 return ::Catch::Detail::rawMemoryToString(p);
1778             } else {
1779                 return "nullptr";
1780             }
1781         }
1782     };
1783 
1784     template <typename R, typename C>
1785     struct StringMaker<R C::*> {
convertCatch::StringMaker1786         static std::string convert(R C::* p) {
1787             if (p) {
1788                 return ::Catch::Detail::rawMemoryToString(p);
1789             } else {
1790                 return "nullptr";
1791             }
1792         }
1793     };
1794 
1795 #if defined(_MANAGED)
1796     template <typename T>
1797     struct StringMaker<T^> {
1798         static std::string convert( T^ ref ) {
1799             return ::Catch::Detail::clrReferenceToString(ref);
1800         }
1801     };
1802 #endif
1803 
1804     namespace Detail {
1805         template<typename InputIterator>
rangeToString(InputIterator first,InputIterator last)1806         std::string rangeToString(InputIterator first, InputIterator last) {
1807             ReusableStringStream rss;
1808             rss << "{ ";
1809             if (first != last) {
1810                 rss << ::Catch::Detail::stringify(*first);
1811                 for (++first; first != last; ++first)
1812                     rss << ", " << ::Catch::Detail::stringify(*first);
1813             }
1814             rss << " }";
1815             return rss.str();
1816         }
1817     }
1818 
1819 #ifdef __OBJC__
1820     template<>
1821     struct StringMaker<NSString*> {
convertCatch::StringMaker1822         static std::string convert(NSString * nsstring) {
1823             if (!nsstring)
1824                 return "nil";
1825             return std::string("@") + [nsstring UTF8String];
1826         }
1827     };
1828     template<>
1829     struct StringMaker<NSObject*> {
convertCatch::StringMaker1830         static std::string convert(NSObject* nsObject) {
1831             return ::Catch::Detail::stringify([nsObject description]);
1832         }
1833 
1834     };
1835     namespace Detail {
stringify(NSString * nsstring)1836         inline std::string stringify( NSString* nsstring ) {
1837             return StringMaker<NSString*>::convert( nsstring );
1838         }
1839 
1840     } // namespace Detail
1841 #endif // __OBJC__
1842 
1843 } // namespace Catch
1844 
1845 //////////////////////////////////////////////////////
1846 // Separate std-lib types stringification, so it can be selectively enabled
1847 // This means that we do not bring in
1848 
1849 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1850 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1851 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1852 #  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1853 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1854 #  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1855 #endif
1856 
1857 // Separate std::pair specialization
1858 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1859 #include <utility>
1860 namespace Catch {
1861     template<typename T1, typename T2>
1862     struct StringMaker<std::pair<T1, T2> > {
convertCatch::StringMaker1863         static std::string convert(const std::pair<T1, T2>& pair) {
1864             ReusableStringStream rss;
1865             rss << "{ "
1866                 << ::Catch::Detail::stringify(pair.first)
1867                 << ", "
1868                 << ::Catch::Detail::stringify(pair.second)
1869                 << " }";
1870             return rss.str();
1871         }
1872     };
1873 }
1874 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1875 
1876 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
1877 #include <optional>
1878 namespace Catch {
1879     template<typename T>
1880     struct StringMaker<std::optional<T> > {
convertCatch::StringMaker1881         static std::string convert(const std::optional<T>& optional) {
1882             ReusableStringStream rss;
1883             if (optional.has_value()) {
1884                 rss << ::Catch::Detail::stringify(*optional);
1885             } else {
1886                 rss << "{ }";
1887             }
1888             return rss.str();
1889         }
1890     };
1891 }
1892 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1893 
1894 // Separate std::tuple specialization
1895 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1896 #include <tuple>
1897 namespace Catch {
1898     namespace Detail {
1899         template<
1900             typename Tuple,
1901             std::size_t N = 0,
1902             bool = (N < std::tuple_size<Tuple>::value)
1903             >
1904             struct TupleElementPrinter {
printCatch::Detail::TupleElementPrinter1905             static void print(const Tuple& tuple, std::ostream& os) {
1906                 os << (N ? ", " : " ")
1907                     << ::Catch::Detail::stringify(std::get<N>(tuple));
1908                 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1909             }
1910         };
1911 
1912         template<
1913             typename Tuple,
1914             std::size_t N
1915         >
1916             struct TupleElementPrinter<Tuple, N, false> {
printCatch::Detail::TupleElementPrinter1917             static void print(const Tuple&, std::ostream&) {}
1918         };
1919 
1920     }
1921 
1922     template<typename ...Types>
1923     struct StringMaker<std::tuple<Types...>> {
convertCatch::StringMaker1924         static std::string convert(const std::tuple<Types...>& tuple) {
1925             ReusableStringStream rss;
1926             rss << '{';
1927             Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1928             rss << " }";
1929             return rss.str();
1930         }
1931     };
1932 }
1933 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1934 
1935 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1936 #include <variant>
1937 namespace Catch {
1938     template<>
1939     struct StringMaker<std::monostate> {
convertCatch::StringMaker1940         static std::string convert(const std::monostate&) {
1941             return "{ }";
1942         }
1943     };
1944 
1945     template<typename... Elements>
1946     struct StringMaker<std::variant<Elements...>> {
convertCatch::StringMaker1947         static std::string convert(const std::variant<Elements...>& variant) {
1948             if (variant.valueless_by_exception()) {
1949                 return "{valueless variant}";
1950             } else {
1951                 return std::visit(
1952                     [](const auto& value) {
1953                         return ::Catch::Detail::stringify(value);
1954                     },
1955                     variant
1956                 );
1957             }
1958         }
1959     };
1960 }
1961 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1962 
1963 namespace Catch {
1964     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
1965 
1966     // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
1967     using std::begin;
1968     using std::end;
1969 
1970     not_this_one begin( ... );
1971     not_this_one end( ... );
1972 
1973     template <typename T>
1974     struct is_range {
1975         static const bool value =
1976             !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
1977             !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
1978     };
1979 
1980 #if defined(_MANAGED) // Managed types are never ranges
1981     template <typename T>
1982     struct is_range<T^> {
1983         static const bool value = false;
1984     };
1985 #endif
1986 
1987     template<typename Range>
rangeToString(Range const & range)1988     std::string rangeToString( Range const& range ) {
1989         return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
1990     }
1991 
1992     // Handle vector<bool> specially
1993     template<typename Allocator>
rangeToString(std::vector<bool,Allocator> const & v)1994     std::string rangeToString( std::vector<bool, Allocator> const& v ) {
1995         ReusableStringStream rss;
1996         rss << "{ ";
1997         bool first = true;
1998         for( bool b : v ) {
1999             if( first )
2000                 first = false;
2001             else
2002                 rss << ", ";
2003             rss << ::Catch::Detail::stringify( b );
2004         }
2005         rss << " }";
2006         return rss.str();
2007     }
2008 
2009     template<typename R>
2010     struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
convertCatch::StringMaker2011         static std::string convert( R const& range ) {
2012             return rangeToString( range );
2013         }
2014     };
2015 
2016     template <typename T, int SZ>
2017     struct StringMaker<T[SZ]> {
convertCatch::StringMaker2018         static std::string convert(T const(&arr)[SZ]) {
2019             return rangeToString(arr);
2020         }
2021     };
2022 
2023 } // namespace Catch
2024 
2025 // Separate std::chrono::duration specialization
2026 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
2027 #include <ctime>
2028 #include <ratio>
2029 #include <chrono>
2030 
2031 namespace Catch {
2032 
2033 template <class Ratio>
2034 struct ratio_string {
2035     static std::string symbol();
2036 };
2037 
2038 template <class Ratio>
symbol()2039 std::string ratio_string<Ratio>::symbol() {
2040     Catch::ReusableStringStream rss;
2041     rss << '[' << Ratio::num << '/'
2042         << Ratio::den << ']';
2043     return rss.str();
2044 }
2045 template <>
2046 struct ratio_string<std::atto> {
2047     static std::string symbol();
2048 };
2049 template <>
2050 struct ratio_string<std::femto> {
2051     static std::string symbol();
2052 };
2053 template <>
2054 struct ratio_string<std::pico> {
2055     static std::string symbol();
2056 };
2057 template <>
2058 struct ratio_string<std::nano> {
2059     static std::string symbol();
2060 };
2061 template <>
2062 struct ratio_string<std::micro> {
2063     static std::string symbol();
2064 };
2065 template <>
2066 struct ratio_string<std::milli> {
2067     static std::string symbol();
2068 };
2069 
2070     ////////////
2071     // std::chrono::duration specializations
2072     template<typename Value, typename Ratio>
2073     struct StringMaker<std::chrono::duration<Value, Ratio>> {
convertCatch::StringMaker2074         static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
2075             ReusableStringStream rss;
2076             rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
2077             return rss.str();
2078         }
2079     };
2080     template<typename Value>
2081     struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
convertCatch::StringMaker2082         static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
2083             ReusableStringStream rss;
2084             rss << duration.count() << " s";
2085             return rss.str();
2086         }
2087     };
2088     template<typename Value>
2089     struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
convertCatch::StringMaker2090         static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
2091             ReusableStringStream rss;
2092             rss << duration.count() << " m";
2093             return rss.str();
2094         }
2095     };
2096     template<typename Value>
2097     struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
convertCatch::StringMaker2098         static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
2099             ReusableStringStream rss;
2100             rss << duration.count() << " h";
2101             return rss.str();
2102         }
2103     };
2104 
2105     ////////////
2106     // std::chrono::time_point specialization
2107     // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
2108     template<typename Clock, typename Duration>
2109     struct StringMaker<std::chrono::time_point<Clock, Duration>> {
convertCatch::StringMaker2110         static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
2111             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
2112         }
2113     };
2114     // std::chrono::time_point<system_clock> specialization
2115     template<typename Duration>
2116     struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
convertCatch::StringMaker2117         static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
2118             auto converted = std::chrono::system_clock::to_time_t(time_point);
2119 
2120 #ifdef _MSC_VER
2121             std::tm timeInfo = {};
2122             gmtime_s(&timeInfo, &converted);
2123 #else
2124             std::tm* timeInfo = std::gmtime(&converted);
2125 #endif
2126 
2127             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
2128             char timeStamp[timeStampSize];
2129             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
2130 
2131 #ifdef _MSC_VER
2132             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
2133 #else
2134             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
2135 #endif
2136             return std::string(timeStamp);
2137         }
2138     };
2139 }
2140 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
2141 
2142 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
2143 namespace Catch { \
2144     template<> struct StringMaker<enumName> { \
2145         static std::string convert( enumName value ) { \
2146             static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
2147             return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
2148         } \
2149     }; \
2150 }
2151 
2152 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
2153 
2154 #ifdef _MSC_VER
2155 #pragma warning(pop)
2156 #endif
2157 
2158 // end catch_tostring.h
2159 #include <iosfwd>
2160 
2161 #ifdef _MSC_VER
2162 #pragma warning(push)
2163 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
2164 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
2165 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
2166 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
2167 #pragma warning(disable:4800) // Forcing result to true or false
2168 #endif
2169 
2170 namespace Catch {
2171 
2172     struct ITransientExpression {
isBinaryExpressionCatch::ITransientExpression2173         auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
getResultCatch::ITransientExpression2174         auto getResult() const -> bool { return m_result; }
2175         virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
2176 
ITransientExpressionCatch::ITransientExpression2177         ITransientExpression( bool isBinaryExpression, bool result )
2178         :   m_isBinaryExpression( isBinaryExpression ),
2179             m_result( result )
2180         {}
2181 
2182         // We don't actually need a virtual destructor, but many static analysers
2183         // complain if it's not here :-(
2184         virtual ~ITransientExpression();
2185 
2186         bool m_isBinaryExpression;
2187         bool m_result;
2188 
2189     };
2190 
2191     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
2192 
2193     template<typename LhsT, typename RhsT>
2194     class BinaryExpr  : public ITransientExpression {
2195         LhsT m_lhs;
2196         StringRef m_op;
2197         RhsT m_rhs;
2198 
streamReconstructedExpression(std::ostream & os) const2199         void streamReconstructedExpression( std::ostream &os ) const override {
2200             formatReconstructedExpression
2201                     ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
2202         }
2203 
2204     public:
BinaryExpr(bool comparisonResult,LhsT lhs,StringRef op,RhsT rhs)2205         BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
2206         :   ITransientExpression{ true, comparisonResult },
2207             m_lhs( lhs ),
2208             m_op( op ),
2209             m_rhs( rhs )
2210         {}
2211 
2212         template<typename T>
operator &&(T) const2213         auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2214             static_assert(always_false<T>::value,
2215             "chained comparisons are not supported inside assertions, "
2216             "wrap the expression inside parentheses, or decompose it");
2217         }
2218 
2219         template<typename T>
operator ||(T) const2220         auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2221             static_assert(always_false<T>::value,
2222             "chained comparisons are not supported inside assertions, "
2223             "wrap the expression inside parentheses, or decompose it");
2224         }
2225 
2226         template<typename T>
operator ==(T) const2227         auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2228             static_assert(always_false<T>::value,
2229             "chained comparisons are not supported inside assertions, "
2230             "wrap the expression inside parentheses, or decompose it");
2231         }
2232 
2233         template<typename T>
operator !=(T) const2234         auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2235             static_assert(always_false<T>::value,
2236             "chained comparisons are not supported inside assertions, "
2237             "wrap the expression inside parentheses, or decompose it");
2238         }
2239 
2240         template<typename T>
operator >(T) const2241         auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2242             static_assert(always_false<T>::value,
2243             "chained comparisons are not supported inside assertions, "
2244             "wrap the expression inside parentheses, or decompose it");
2245         }
2246 
2247         template<typename T>
operator <(T) const2248         auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2249             static_assert(always_false<T>::value,
2250             "chained comparisons are not supported inside assertions, "
2251             "wrap the expression inside parentheses, or decompose it");
2252         }
2253 
2254         template<typename T>
operator >=(T) const2255         auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2256             static_assert(always_false<T>::value,
2257             "chained comparisons are not supported inside assertions, "
2258             "wrap the expression inside parentheses, or decompose it");
2259         }
2260 
2261         template<typename T>
operator <=(T) const2262         auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
2263             static_assert(always_false<T>::value,
2264             "chained comparisons are not supported inside assertions, "
2265             "wrap the expression inside parentheses, or decompose it");
2266         }
2267     };
2268 
2269     template<typename LhsT>
2270     class UnaryExpr : public ITransientExpression {
2271         LhsT m_lhs;
2272 
streamReconstructedExpression(std::ostream & os) const2273         void streamReconstructedExpression( std::ostream &os ) const override {
2274             os << Catch::Detail::stringify( m_lhs );
2275         }
2276 
2277     public:
UnaryExpr(LhsT lhs)2278         explicit UnaryExpr( LhsT lhs )
2279         :   ITransientExpression{ false, static_cast<bool>(lhs) },
2280             m_lhs( lhs )
2281         {}
2282     };
2283 
2284     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
2285     template<typename LhsT, typename RhsT>
compareEqual(LhsT const & lhs,RhsT const & rhs)2286     auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
2287     template<typename T>
compareEqual(T * const & lhs,int rhs)2288     auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2289     template<typename T>
compareEqual(T * const & lhs,long rhs)2290     auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
2291     template<typename T>
compareEqual(int lhs,T * const & rhs)2292     auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2293     template<typename T>
compareEqual(long lhs,T * const & rhs)2294     auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
2295 
2296     template<typename LhsT, typename RhsT>
compareNotEqual(LhsT const & lhs,RhsT && rhs)2297     auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
2298     template<typename T>
compareNotEqual(T * const & lhs,int rhs)2299     auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2300     template<typename T>
compareNotEqual(T * const & lhs,long rhs)2301     auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
2302     template<typename T>
compareNotEqual(int lhs,T * const & rhs)2303     auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2304     template<typename T>
compareNotEqual(long lhs,T * const & rhs)2305     auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
2306 
2307     template<typename LhsT>
2308     class ExprLhs {
2309         LhsT m_lhs;
2310     public:
ExprLhs(LhsT lhs)2311         explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
2312 
2313         template<typename RhsT>
operator ==(RhsT const & rhs)2314         auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2315             return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
2316         }
operator ==(bool rhs)2317         auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2318             return { m_lhs == rhs, m_lhs, "==", rhs };
2319         }
2320 
2321         template<typename RhsT>
operator !=(RhsT const & rhs)2322         auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2323             return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
2324         }
operator !=(bool rhs)2325         auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2326             return { m_lhs != rhs, m_lhs, "!=", rhs };
2327         }
2328 
2329         template<typename RhsT>
operator >(RhsT const & rhs)2330         auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2331             return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
2332         }
2333         template<typename RhsT>
operator <(RhsT const & rhs)2334         auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2335             return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
2336         }
2337         template<typename RhsT>
operator >=(RhsT const & rhs)2338         auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2339             return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
2340         }
2341         template<typename RhsT>
operator <=(RhsT const & rhs)2342         auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2343             return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
2344         }
2345 
2346         template<typename RhsT>
operator &&(RhsT const &)2347         auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2348             static_assert(always_false<RhsT>::value,
2349             "operator&& is not supported inside assertions, "
2350             "wrap the expression inside parentheses, or decompose it");
2351         }
2352 
2353         template<typename RhsT>
operator ||(RhsT const &)2354         auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2355             static_assert(always_false<RhsT>::value,
2356             "operator|| is not supported inside assertions, "
2357             "wrap the expression inside parentheses, or decompose it");
2358         }
2359 
makeUnaryExpr() const2360         auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
2361             return UnaryExpr<LhsT>{ m_lhs };
2362         }
2363     };
2364 
2365     void handleExpression( ITransientExpression const& expr );
2366 
2367     template<typename T>
handleExpression(ExprLhs<T> const & expr)2368     void