blob: 82a2129a80d996431482da2b02855fa8e3e062fe [file] [log] [blame]
/*
* Catch v2.13.7
* Generated: 2021-07-28 20:29:27.753164
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it
* directly Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
// start catch.hpp
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 13
#define CATCH_VERSION_PATCH 7
#ifdef __clang__
#pragma clang system_header
#elif defined __GNUC__
#pragma GCC system_header
#endif
// start catch_suppress_warnings.h
#ifdef __clang__
#ifdef __ICC // icpc defines the __clang__ macro
#pragma warning(push)
#pragma warning(disable : 161 1682)
#else // __ICC
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#endif
#elif defined __GNUC__
// Because REQUIREs trigger GCC's -Wparentheses, and because still
// supported version of g++ have only buggy support for _Pragmas,
// Wparentheses have to be suppressed globally.
#pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wpadded"
#endif
// end catch_suppress_warnings.h
#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
#define CATCH_IMPL
#define CATCH_CONFIG_ALL_PARTS
#endif
// In the impl file, we want to have access to all parts of the headers
// Can also be used to sanely support PCHs
#if defined(CATCH_CONFIG_ALL_PARTS)
#define CATCH_CONFIG_EXTERNAL_INTERFACES
#if defined(CATCH_CONFIG_DISABLE_MATCHERS)
#undef CATCH_CONFIG_DISABLE_MATCHERS
#endif
#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#endif
#endif
#if !defined(CATCH_CONFIG_IMPL_ONLY)
// start catch_platform.h
// See e.g.:
// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
#ifdef __APPLE__
#include <TargetConditionals.h>
#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
#define CATCH_PLATFORM_MAC
#elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
#define CATCH_PLATFORM_IPHONE
#endif
#elif defined(linux) || defined(__linux) || defined(__linux__)
#define CATCH_PLATFORM_LINUX
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || \
defined(__MINGW32__)
#define CATCH_PLATFORM_WINDOWS
#endif
// end catch_platform.h
#ifdef CATCH_IMPL
#ifndef CLARA_CONFIG_MAIN
#define CLARA_CONFIG_MAIN_NOT_DEFINED
#define CLARA_CONFIG_MAIN
#endif
#endif
// start catch_user_interfaces.h
namespace Catch {
unsigned int rngSeed();
}
// end catch_user_interfaces.h
// start catch_tag_alias_autoregistrar.h
// start catch_common.h
// start catch_compiler_capabilities.h
// Detect a number of compiler features - by compiler
// The following features are defined:
//
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
// ****************
// Note to maintainers: if new toggles are added please document them
// in configuration.md, too
// ****************
// In general each macro has a _NO_<feature name> form
// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
// Many features, at point of detection, define an _INTERNAL_ macro, so they
// can be combined, en-mass, with the _NO_ forms later.
#ifdef __cplusplus
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#define CATCH_CPP14_OR_GREATER
#endif
#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#define CATCH_CPP17_OR_GREATER
#endif
#endif
// Only GCC compiler should be used in this block, so other compilers trying to
// mask themselves as GCC should be ignored.
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && \
!defined(__LCC__)
#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic push")
#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic pop")
#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
#endif
#if defined(__clang__)
#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("clang diagnostic push")
#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("clang diagnostic pop")
// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
// which results in calls to destructors being emitted for each temporary,
// without a matching initialization. In practice, this can result in something
// like `std::string::~string` being called on an uninitialized value.
//
// For example, this code will likely segfault under IBM XL:
// ```
// REQUIRE(std::string("12") + "34" == "1234")
// ```
//
// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
#if !defined(__ibmxl__) && !defined(__CUDACC__)
#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) \
(void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, \
hicpp-vararg) */
#endif
#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
_Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \
_Pragma("clang diagnostic ignored \"-Wglobal-constructors\"")
#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
_Pragma("clang diagnostic ignored \"-Wparentheses\"")
#define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
_Pragma("clang diagnostic ignored \"-Wunused-variable\"")
#define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
_Pragma("clang diagnostic ignored " \
"\"-Wgnu-zero-variadic-macro-arguments\"")
#define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
_Pragma("clang diagnostic ignored \"-Wunused-template\"")
#endif // __clang__
////////////////////////////////////////////////////////////////////////////////
// Assume that non-Windows platforms support posix signals by default
#if !defined(CATCH_PLATFORM_WINDOWS)
#define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
#endif
////////////////////////////////////////////////////////////////////////////////
// We know some environments not to support full POSIX signals
#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
#endif
#ifdef __OS400__
#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
#define CATCH_CONFIG_COLOUR_NONE
#endif
////////////////////////////////////////////////////////////////////////////////
// Android somehow still does not support std::to_string
#if defined(__ANDROID__)
#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
#define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
#endif
////////////////////////////////////////////////////////////////////////////////
// Not all Windows environments support SEH properly
#if defined(__MINGW32__)
#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
#endif
////////////////////////////////////////////////////////////////////////////////
// PS4
#if defined(__ORBIS__)
#define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
#endif
////////////////////////////////////////////////////////////////////////////////
// Cygwin
#ifdef __CYGWIN__
// Required for some versions of Cygwin to declare gettimeofday
// see:
// http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
#define _BSD_SOURCE
// some versions of cygwin (most) do not support std::to_string. Use the libstd
// check.
// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html
// line 2812-2813
#if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) && \
!defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
#endif
#endif // __CYGWIN__
////////////////////////////////////////////////////////////////////////////////
// Visual C++
#if defined(_MSC_VER)
#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma(warning(push))
#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma(warning(pop))
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define CATCH_CONFIG_COLOUR_NONE
#else
#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
#endif
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
#if !defined(__clang__) // Handle Clang masquerading for msvc
#if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
#define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#endif // MSVC_TRADITIONAL
#endif // __clang__
#endif // _MSC_VER
#if defined(_REENTRANT) || defined(_MSC_VER)
// Enable async processing, as -pthread is specified or no additional linking is
// required
#define CATCH_INTERNAL_CONFIG_USE_ASYNC
#endif // _MSC_VER
////////////////////////////////////////////////////////////////////////////////
// Check if we are compiled with -fno-exceptions or equivalent
#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
#define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
#endif
////////////////////////////////////////////////////////////////////////////////
// DJGPP
#ifdef __DJGPP__
#define CATCH_INTERNAL_CONFIG_NO_WCHAR
#endif // __DJGPP__
////////////////////////////////////////////////////////////////////////////////
// Embarcadero C++Build
#if defined(__BORLANDC__)
#define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
#endif
////////////////////////////////////////////////////////////////////////////////
// Use of __COUNTER__ is suppressed during code analysis in
// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
// handled by it.
// Otherwise all supported compilers support COUNTER macro,
// but user still might want to turn it off
#if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L)
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
////////////////////////////////////////////////////////////////////////////////
// RTX is a special version of Windows that is real time.
// This means that it is detected as Windows, but does not provide
// the same set of capabilities as real Windows does.
#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
#define CATCH_INTERNAL_CONFIG_NO_ASYNC
#define CATCH_CONFIG_COLOUR_NONE
#endif
#if !defined(_GLIBCXX_USE_C99_MATH_TR1)
#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
#endif
// Various stdlib support checks that require __has_include
#if defined(__has_include)
// Check if string_view is available and usable
#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
#define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
#endif
// Check if optional is available and usable
#if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
#define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
#endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
// Check if byte is available and usable
#if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
#include <cstddef>
#if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
#define CATCH_INTERNAL_CONFIG_CPP17_BYTE
#endif
#endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
// Check if variant is available and usable
#if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
#if defined(__clang__) && (__clang_major__ < 8)
// work around clang bug with libstdc++
// https://bugs.llvm.org/show_bug.cgi?id=31852 fix should be in clang 8,
// workaround in libstdc++ 8.2
#include <ciso646>
#if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
#define CATCH_CONFIG_NO_CPP17_VARIANT
#else
#define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
#endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE
// < 9)
#else
#define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
#endif // defined(__clang__) && (__clang_major__ < 8)
#endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
#endif // defined(__has_include)
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && \
!defined(CATCH_CONFIG_COUNTER)
#define CATCH_CONFIG_COUNTER
#endif
#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)
#define CATCH_CONFIG_WINDOWS_SEH
#endif
// This is set by default, because we assume that unix compilers are
// posix-signal-compatible by default.
#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)
#define CATCH_CONFIG_POSIX_SIGNALS
#endif
// This is set by default, because we assume that compilers with no wchar_t
// support are just rare exceptions.
#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && \
!defined(CATCH_CONFIG_WCHAR)
#define CATCH_CONFIG_WCHAR
#endif
#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && \
!defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
#define CATCH_CONFIG_CPP11_TO_STRING
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && \
!defined(CATCH_CONFIG_CPP17_OPTIONAL)
#define CATCH_CONFIG_CPP17_OPTIONAL
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && \
!defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
#define CATCH_CONFIG_CPP17_STRING_VIEW
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && \
!defined(CATCH_CONFIG_CPP17_VARIANT)
#define CATCH_CONFIG_CPP17_VARIANT
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && \
!defined(CATCH_CONFIG_CPP17_BYTE)
#define CATCH_CONFIG_CPP17_BYTE
#endif
#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
#define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
#endif
#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)
#define CATCH_CONFIG_NEW_CAPTURE
#endif
#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
#define CATCH_CONFIG_DISABLE_EXCEPTIONS
#endif
#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && \
!defined(CATCH_CONFIG_POLYFILL_ISNAN)
#define CATCH_CONFIG_POLYFILL_ISNAN
#endif
#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && \
!defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
#define CATCH_CONFIG_USE_ASYNC
#endif
#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && \
!defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
#define CATCH_CONFIG_ANDROID_LOGWRITE
#endif
#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && \
!defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
#define CATCH_CONFIG_GLOBAL_NEXTAFTER
#endif
// Even if we do not think the compiler has that warning, we still have
// to provide a macro that can be used by the code.
#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
#endif
#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
#define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
#define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
#endif
// The goal of this macro is to avoid evaluation of the arguments, but
// still have the compiler warn on problems inside...
#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
#define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
#endif
#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
#undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#elif defined(__clang__) && (__clang_major__ < 5)
#undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
#define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#endif
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
#define CATCH_TRY if ((true))
#define CATCH_CATCH_ALL if ((false))
#define CATCH_CATCH_ANON(type) if ((false))
#else
#define CATCH_TRY try
#define CATCH_CATCH_ALL catch (...)
#define CATCH_CATCH_ANON(type) catch (type)
#endif
#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && \
!defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && \
!defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#endif
// end catch_compiler_capabilities.h
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line)
#ifdef CATCH_CONFIG_COUNTER
#define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__)
#else
#define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__)
#endif
#include <iosfwd>
#include <string>
#include <cstdint>
// We need a dummy global operator<< so we can bring it into Catch namespace
// later
struct Catch_global_namespace_dummy {};
std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
namespace Catch {
struct CaseSensitive {
enum Choice { Yes, No };
};
class NonCopyable {
NonCopyable(NonCopyable const&) = delete;
NonCopyable(NonCopyable&&) = delete;
NonCopyable& operator=(NonCopyable const&) = delete;
NonCopyable& operator=(NonCopyable&&) = delete;
protected:
NonCopyable();
virtual ~NonCopyable();
};
struct SourceLineInfo {
SourceLineInfo() = delete;
SourceLineInfo(char const* _file, std::size_t _line) noexcept : file(_file), line(_line) {}
SourceLineInfo(SourceLineInfo const& other) = default;
SourceLineInfo& operator=(SourceLineInfo const&) = default;
SourceLineInfo(SourceLineInfo&&) noexcept = default;
SourceLineInfo& operator=(SourceLineInfo&&) noexcept = default;
bool empty() const noexcept { return file[0] == '\0'; }
bool operator==(SourceLineInfo const& other) const noexcept;
bool operator<(SourceLineInfo const& other) const noexcept;
char const* file;
std::size_t line;
};
std::ostream& operator<<(std::ostream& os, SourceLineInfo const& info);
// Bring in operator<< from global namespace into Catch namespace
// This is necessary because the overload of operator<< above makes
// lookup stop at namespace Catch
using ::operator<<;
// Use this in variadic streaming macros to allow
// >> +StreamEndStop
// as well as
// >> stuff +StreamEndStop
struct StreamEndStop {
std::string operator+() const;
};
template <typename T> T const& operator+(T const& value, StreamEndStop) { return value; }
} // namespace Catch
#define CATCH_INTERNAL_LINEINFO \
::Catch::SourceLineInfo(__FILE__, static_cast<std::size_t>(__LINE__))
// end catch_common.h
namespace Catch {
struct RegistrarForTagAliases {
RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo);
};
} // end namespace Catch
#define CATCH_REGISTER_TAG_ALIAS(alias, spec) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace { \
Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME(AutoRegisterTagAlias)( \
alias, spec, CATCH_INTERNAL_LINEINFO); \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
// end catch_tag_alias_autoregistrar.h
// start catch_test_registry.h
// start catch_interfaces_testcase.h
#include <vector>
namespace Catch {
class TestSpec;
struct ITestInvoker {
virtual void invoke() const = 0;
virtual ~ITestInvoker();
};
class TestCase;
struct IConfig;
struct ITestCaseRegistry {
virtual ~ITestCaseRegistry();
virtual std::vector<TestCase> const& getAllTests() const = 0;
virtual std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const = 0;
};
bool isThrowSafe(TestCase const& testCase, IConfig const& config);
bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases,
TestSpec const& testSpec,
IConfig const& config);
std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
} // namespace Catch
// end catch_interfaces_testcase.h
// start catch_stringref.h
#include <cstddef>
#include <string>
#include <iosfwd>
#include <cassert>
namespace Catch {
/// A non-owning string class (similar to the forthcoming std::string_view)
/// Note that, because a StringRef may be a substring of another string,
/// it may not be null terminated.
class StringRef {
public:
using size_type = std::size_t;
using const_iterator = const char*;
private:
static constexpr char const* const s_empty = "";
char const* m_start = s_empty;
size_type m_size = 0;
public: // construction
constexpr StringRef() noexcept = default;
StringRef(char const* rawChars) noexcept;
constexpr StringRef(char const* rawChars, size_type size) noexcept :
m_start(rawChars), m_size(size) {}
StringRef(std::string const& stdString) noexcept :
m_start(stdString.c_str()), m_size(stdString.size()) {}
explicit operator std::string() const { return std::string(m_start, m_size); }
public: // operators
auto operator==(StringRef const& other) const noexcept -> bool;
auto operator!=(StringRef const& other) const noexcept -> bool { return !(*this == other); }
auto operator[](size_type index) const noexcept -> char {
assert(index < m_size);
return m_start[index];
}
public: // named queries
constexpr auto empty() const noexcept -> bool { return m_size == 0; }
constexpr auto size() const noexcept -> size_type { return m_size; }
// Returns the current start pointer. If the StringRef is not
// null-terminated, throws std::domain_exception
auto c_str() const -> char const*;
public: // substrings and searches
// Returns a substring of [start, start + length).
// If start + length > size(), then the substring is [start, size()).
// If start > size(), then the substring is empty.
auto substr(size_type start, size_type length) const noexcept -> StringRef;
// Returns the current start pointer. May not be null-terminated.
auto data() const noexcept -> char const*;
constexpr auto isNullTerminated() const noexcept -> bool { return m_start[m_size] == '\0'; }
public: // iterators
constexpr const_iterator begin() const { return m_start; }
constexpr const_iterator end() const { return m_start + m_size; }
};
auto operator+=(std::string& lhs, StringRef const& sr) -> std::string&;
auto operator<<(std::ostream& os, StringRef const& sr) -> std::ostream&;
constexpr auto operator"" _sr(char const* rawChars, std::size_t size) noexcept -> StringRef {
return StringRef(rawChars, size);
}
} // namespace Catch
constexpr auto operator"" _catch_sr(char const* rawChars, std::size_t size) noexcept
-> Catch::StringRef {
return Catch::StringRef(rawChars, size);
}
// end catch_stringref.h
// start catch_preprocessor.hpp
#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
#define CATCH_RECURSION_LEVEL1(...) \
CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL2(...) \
CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL3(...) \
CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL4(...) \
CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
#define CATCH_RECURSION_LEVEL5(...) \
CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
// MSVC needs more evaluations
#define CATCH_RECURSION_LEVEL6(...) \
CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
#else
#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
#endif
#define CATCH_REC_END(...)
#define CATCH_REC_OUT
#define CATCH_EMPTY()
#define CATCH_DEFER(id) id CATCH_EMPTY()
#define CATCH_REC_GET_END2() 0, CATCH_REC_END
#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
#define CATCH_REC_NEXT1(test, next) CATCH_DEFER(CATCH_REC_NEXT0)(test, next, 0)
#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
#define CATCH_REC_LIST0(f, x, peek, ...) \
, f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
#define CATCH_REC_LIST1(f, x, peek, ...) \
, f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0))(f, peek, __VA_ARGS__)
#define CATCH_REC_LIST2(f, x, peek, ...) \
f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__)
#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__)
#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__)
#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__)
// Applies the function macro `f` to each of the remaining parameters, inserts
// commas between the results, and passes userdata as the first parameter to
// each invocation, e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a),
// f(x, b), f(x, c)
#define CATCH_REC_LIST_UD(f, userdata, ...) \
CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
#define CATCH_REC_LIST(f, ...) \
CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) \
INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
#else
// MSVC is adding extra space and needs another indirection to expand
// INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) \
(INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
#endif
#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) \
decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) \
INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
#else
#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) \
INTERNAL_CATCH_EXPAND_VARGS( \
decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) \
INTERNAL_CATCH_EXPAND_VARGS( \
INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
#endif
#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...) \
CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST, __VA_ARGS__)
#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) \
INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) \
INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
#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)
#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)
#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)
#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) \
INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
#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)
#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)
#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)
#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)
#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define INTERNAL_CATCH_TYPE_GEN \
template <typename...> struct TypeList {}; \
template <typename... Ts> constexpr auto get_wrapper() noexcept->TypeList<Ts...> { \
return {}; \
} \
template <template <typename...> class...> struct TemplateTypeList {}; \
template <template <typename...> class... Cs> \
constexpr auto get_wrapper() noexcept->TemplateTypeList<Cs...> { \
return {}; \
} \
template <typename...> struct append; \
template <typename...> struct rewrap; \
template <template <typename...> class, typename...> struct create; \
template <template <typename...> class, typename> struct convert; \
\
template <typename T> struct append<T> { using type = T; }; \
template <template <typename...> class L1, \
typename... E1, \
template <typename...> \
class L2, \
typename... E2, \
typename... Rest> \
struct append<L1<E1...>, L2<E2...>, Rest...> { \
using type = typename append<L1<E1..., E2...>, Rest...>::type; \
}; \
template <template <typename...> class L1, typename... E1, typename... Rest> \
struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { \
using type = L1<E1...>; \
}; \
\
template <template <typename...> class Container, \
template <typename...> \
class List, \
typename... elems> \
struct rewrap<TemplateTypeList<Container>, List<elems...>> { \
using type = TypeList<Container<elems...>>; \
}; \
template <template <typename...> class Container, \
template <typename...> \
class List, \
class... Elems, \
typename... Elements> \
struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { \
using type = typename append< \
TypeList<Container<Elems...>>, \
typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; \
}; \
\
template <template <typename...> class Final, \
template <typename...> \
class... Containers, \
typename... Types> \
struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { \
using type = typename append< \
Final<>, \
typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; \
}; \
template <template <typename...> class Final, \
template <typename...> \
class List, \
typename... Ts> \
struct convert<Final, List<Ts...>> { \
using type = typename append<Final<>, TypeList<Ts>...>::type; \
};
#define INTERNAL_CATCH_NTTP_1(signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp {}; \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
constexpr auto get_wrapper() noexcept->Nttp<__VA_ARGS__> { \
return {}; \
} \
template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> \
struct NttpTemplateTypeList {}; \
template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class... Cs> \
constexpr auto get_wrapper() noexcept->NttpTemplateTypeList<Cs...> { \
return {}; \
} \
\
template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
class List, \
INTERNAL_CATCH_REMOVE_PARENS(signature)> \
struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { \
using type = TypeList<Container<__VA_ARGS__>>; \
}; \
template <template <INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
class List, \
INTERNAL_CATCH_REMOVE_PARENS(signature), \
typename... Elements> \
struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { \
using type = typename append< \
TypeList<Container<__VA_ARGS__>>, \
typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; \
}; \
template <template <typename...> class Final, \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
class... Containers, \
typename... Types> \
struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { \
using type = typename append< \
Final<>, \
typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; \
};
#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> static void TestName()
#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature) \
template <typename Type> void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags) { \
Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Type>), \
CATCH_INTERNAL_LINEINFO, \
Catch::StringRef(), \
nameAndTags); \
}
#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags) { \
Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), \
CATCH_INTERNAL_LINEINFO, \
Catch::StringRef(), \
nameAndTags); \
}
#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...) \
template <typename Type> \
void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags) { \
Catch::AutoReg(Catch::makeTestInvoker(&TestName<Type>::test), \
CATCH_INTERNAL_LINEINFO, \
className, \
nameAndTags); \
}
#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags) { \
Catch::AutoReg(Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), \
CATCH_INTERNAL_LINEINFO, \
className, \
nameAndTags); \
}
#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature) \
template <typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
void test(); \
}
#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
void test(); \
}
#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature) \
template <typename TestType> \
void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...) \
template <INTERNAL_CATCH_REMOVE_PARENS(signature)> \
void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_NTTP_0
#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)
#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__)
#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__)
#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__)
#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__)
#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__)
#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__)
#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__)
#else
#define INTERNAL_CATCH_NTTP_0(signature)
#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__))
#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__))
#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__))
#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__))
#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__))
#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__))
#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__))
#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__))
#endif
// end catch_preprocessor.hpp
// start catch_meta.hpp
#include <type_traits>
namespace Catch {
template <typename T> struct always_false : std::false_type {};
template <typename> struct true_given : std::true_type {};
struct is_callable_tester {
template <typename Fun, typename... Args>
true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
template <typename...> std::false_type static test(...);
};
template <typename T> struct is_callable;
template <typename Fun, typename... Args>
struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
// std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
// replaced with std::invoke_result here.
template <typename Func, typename... U>
using FunctionReturnType =
std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
#else
// Keep ::type here because we still support C++11
template <typename Func, typename... U>
using FunctionReturnType = typename std::remove_reference<
typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
#endif
} // namespace Catch
namespace mpl_ {
struct na;
}
// end catch_meta.hpp
namespace Catch {
template <typename C> class TestInvokerAsMethod : public ITestInvoker {
void (C::*m_testAsMethod)();
public:
TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod) {}
void invoke() const override {
C obj;
(obj.*m_testAsMethod)();
}
};
auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker*;
template <typename C>
auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker* {
return new (std::nothrow) TestInvokerAsMethod<C>(testAsMethod);
}
struct NameAndTags {
NameAndTags(StringRef const& name_ = StringRef(),
StringRef const& tags_ = StringRef()) noexcept;
StringRef name;
StringRef tags;
};
struct AutoReg : NonCopyable {
AutoReg(ITestInvoker* invoker,
SourceLineInfo const& lineInfo,
StringRef const& classOrMethod,
NameAndTags const& nameAndTags) noexcept;
~AutoReg();
};
} // end namespace Catch
#if defined(CATCH_CONFIG_DISABLE)
#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(TestName, ...) static void TestName()
#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(TestName, ClassName, ...) \
namespace { \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
}; \
} \
void TestName::test()
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( \
TestName, TestFunc, Name, Tags, Signature, ...) \
INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( \
TestNameClass, TestName, ClassName, Name, Tags, Signature, ...) \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD( \
TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
} \
} \
INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(ClassName, Name, Tags, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( \
ClassName, Name, Tags, Signature, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( \
ClassName, Name, Tags, Signature, ...) \
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__))
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2(TestName, ...) \
static void TestName(); \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace { \
Catch::AutoReg \
INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName), \
CATCH_INTERNAL_LINEINFO, \
Catch::StringRef(), \
Catch::NameAndTags{__VA_ARGS__}); \
} /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
#define INTERNAL_CATCH_TESTCASE(...) \
INTERNAL_CATCH_TESTCASE2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), __VA_ARGS__)
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE(QualifiedMethod, ...) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace { \
Catch::AutoReg \
INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&QualifiedMethod), \
CATCH_INTERNAL_LINEINFO, \
"&" #QualifiedMethod, \
Catch::NameAndTags{__VA_ARGS__}); \
} /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD2(TestName, ClassName, ...) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace { \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)( \
Catch::makeTestInvoker(&TestName::test), \
CATCH_INTERNAL_LINEINFO, \
#ClassName, \
Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD(ClassName, ...) \
INTERNAL_CATCH_TEST_CASE_METHOD2( \
INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), ClassName, __VA_ARGS__)
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE(Function, ...) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)( \
Catch::makeTestInvoker(Function), \
CATCH_INTERNAL_LINEINFO, \
Catch::StringRef(), \
Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ...) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
INTERNAL_CATCH_TYPE_GEN \
INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
template <typename... Types> struct TestName { \
TestName() { \
int index = 0; \
constexpr char const* tmpl_types[] = { \
CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; \
using expander = int[]; \
(void)expander{ \
(reg_test(Types{}, \
Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), \
Tags}), \
index++)...}; /* NOLINT */ \
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>(); \
return 0; \
}(); \
} \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
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__))
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( \
TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template <typename TestType> static void TestFuncName(); \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
INTERNAL_CATCH_TYPE_GEN \
INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
template <typename... Types> struct TestName { \
void reg_tests() { \
int index = 0; \
using expander = int[]; \
constexpr char const* tmpl_types[] = { \
CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, \
INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))}; \
constexpr char const* types_list[] = { \
CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, \
INTERNAL_CATCH_REMOVE_PARENS(TypesList))}; \
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]); \
(void)expander{ \
(Catch::AutoReg(Catch::makeTestInvoker(&TestFuncName<Types>), \
CATCH_INTERNAL_LINEINFO, \
Catch::StringRef(), \
Catch::NameAndTags{ \
Name " - " + \
std::string(tmpl_types[index / num_types]) + "<" + \
std::string(types_list[index % num_types]) + ">", \
Tags}), \
index++)...}; /* NOLINT */ \
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
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; \
TestInit t; \
t.reg_tests(); \
return 0; \
}(); \
} \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template <typename TestType> static void TestFuncName()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...) \
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__))
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template <typename TestType> static void TestFunc(); \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
INTERNAL_CATCH_TYPE_GEN \
template <typename... Types> struct TestName { \
void reg_tests() { \
int index = 0; \
using expander = int[]; \
(void)expander{ \
(Catch::AutoReg(Catch::makeTestInvoker(&TestFunc<Types>), \
CATCH_INTERNAL_LINEINFO, \
Catch::StringRef(), \
Catch::NameAndTags{ \
Name " - " + \
std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \
" - " + std::to_string(index), \
Tags}), \
index++)...}; /* NOLINT */ \
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
using TestInit = typename convert<TestName, TmplList>::type; \
TestInit t; \
t.reg_tests(); \
return 0; \
}(); \
} \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template <typename TestType> static void TestFunc()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
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)
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( \
TestNameClass, TestName, ClassName, Name, Tags, Signature, ...) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
INTERNAL_CATCH_TYPE_GEN \
INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD( \
TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature)); \
INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
template <typename... Types> struct TestNameClass { \
TestNameClass() { \
int index = 0; \
constexpr char const* tmpl_types[] = { \
CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; \
using expander = int[]; \
(void)expander{ \
(reg_test(Types{}, \
#ClassName, \
Catch::NameAndTags{Name " - " + std::string(tmpl_types[index]), \
Tags}), \
index++)...}; /* NOLINT */ \
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>(); \
return 0; \
}(); \
} \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(ClassName, Name, Tags, Signature, ...) \
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__))
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( \
TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template <typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) { \
void test(); \
}; \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) { \
INTERNAL_CATCH_TYPE_GEN \
INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
template <typename... Types> struct TestNameClass { \
void reg_tests() { \
int index = 0; \
using expander = int[]; \
constexpr char const* tmpl_types[] = { \
CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, \
INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))}; \
constexpr char const* types_list[] = { \
CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, \
INTERNAL_CATCH_REMOVE_PARENS(TypesList))}; \
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]); \
(void)expander{ \
(Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), \
CATCH_INTERNAL_LINEINFO, \
#ClassName, \
Catch::NameAndTags{ \
Name " - " + \
std::string(tmpl_types[index / num_types]) + "<" + \
std::string(types_list[index % num_types]) + ">", \
Tags}), \
index++)...}; /* NOLINT */ \
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
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; \
TestInit t; \
t.reg_tests(); \
return 0; \
}(); \
} \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template <typename TestType> void TestName<TestType>::test()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(ClassName, Name, Tags, ...) \
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__))
#endif
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( \
ClassName, Name, Tags, Signature, ...) \
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__)
#else
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( \
ClassName, Name, Tags, Signature, ...) \
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__))
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( \
TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template <typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName<TestType>) { \
void test(); \
}; \
namespace { \
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
INTERNAL_CATCH_TYPE_GEN \
template <typename... Types> struct TestNameClass { \
void reg_tests() { \
int index = 0; \
using expander = int[]; \
(void)expander{ \
(Catch::AutoReg(Catch::makeTestInvoker(&TestName<Types>::test), \
CATCH_INTERNAL_LINEINFO, \
#ClassName, \
Catch::NameAndTags{ \
Name " - " + \
std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \
" - " + std::to_string(index), \
Tags}), \
index++)...}; /* NOLINT */ \
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME(globalRegistrar) = []() { \
using TestInit = typename convert<TestNameClass, TmplList>::type; \
TestInit t; \
t.reg_tests(); \
return 0; \
}(); \
} \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template <typename TestType> void TestName<TestType>::test()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
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)
// end catch_test_registry.h
// start catch_capture.hpp
// start catch_assertionhandler.h
// start catch_assertioninfo.h
// start catch_result_type.h
namespace Catch {
// ResultWas::OfType enum
struct ResultWas {
enum OfType {
Unknown = -1,
Ok = 0,
Info = 1,
Warning = 2,
FailureBit = 0x10,
ExpressionFailed = FailureBit | 1,
ExplicitFailure = FailureBit | 2,
Exception = 0x100 | FailureBit,
ThrewException = Exception | 1,
DidntThrowException = Exception | 2,
FatalErrorCondition = 0x200 | FailureBit
};
};
bool isOk(ResultWas::OfType resultType);
bool isJustInfo(int flags);
// ResultDisposition::Flags enum
struct ResultDisposition {
enum Flags {
Normal = 0x01,
ContinueOnFailure = 0x02, // Failures fail test, but execution continues
FalseTest = 0x04, // Prefix expression with !
SuppressFail = 0x08 // Failures are reported but do not fail the test
};
};
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs);
bool shouldContinueOnFailure(int flags);
inline bool isFalseTest(int flags) { return (flags & ResultDisposition::FalseTest) != 0; }
bool shouldSuppressFailure(int flags);
} // end namespace Catch
// end catch_result_type.h
namespace Catch {
struct AssertionInfo {
StringRef macroName;
SourceLineInfo lineInfo;
StringRef capturedExpression;
ResultDisposition::Flags resultDisposition;
// We want to delete this constructor but a compiler bug in 4.8 means
// the struct is then treated as non-aggregate
// AssertionInfo() = delete;
};
} // end namespace Catch
// end catch_assertioninfo.h
// start catch_decomposer.h
// start catch_tostring.h
#include <vector>
#include <cstddef>
#include <type_traits>
#include <string>
// start catch_stream.h
#include <iosfwd>
#include <cstddef>
#include <ostream>
namespace Catch {
std::ostream& cout();
std::ostream& cerr();
std::ostream& clog();
class StringRef;
struct IStream {
virtual ~IStream();
virtual std::ostream& stream() const = 0;
};
auto makeStream(StringRef const& filename) -> IStream const*;
class ReusableStringStream : NonCopyable {
std::size_t m_index;
std::ostream* m_oss;
public:
ReusableStringStream();
~ReusableStringStream();
auto str() const -> std::string;
template <typename T> auto operator<<(T const& value) -> ReusableStringStream& {
*m_oss << value;
return *this;
}
auto get() -> std::ostream& { return *m_oss; }
};
} // namespace Catch
// end catch_stream.h
// start catch_interfaces_enum_values_registry.h
#include <vector>
namespace Catch {
namespace Detail {
struct EnumInfo {
StringRef m_name;
std::vector<std::pair<int, StringRef>> m_values;
~EnumInfo();
StringRef lookup(int value) const;
};
} // namespace Detail
struct IMutableEnumValuesRegistry {
virtual ~IMutableEnumValuesRegistry();
virtual Detail::EnumInfo const&
registerEnum(StringRef enumName, StringRef allEnums, std::vector<int> const& values) = 0;
template <typename E>
Detail::EnumInfo const&
registerEnum(StringRef enumName, StringRef allEnums, std::initializer_list<E> values) {
static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
std::vector<int> intValues;
intValues.reserve(values.size());
for (auto enumValue : values)
intValues.push_back(static_cast<int>(enumValue));
return registerEnum(enumName, allEnums, intValues);
}
};
} // namespace Catch
// end catch_interfaces_enum_values_registry.h
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
#include <string_view>
#endif
#ifdef __OBJC__
// start catch_objc_arc.hpp
#import <Foundation/Foundation.h>
#ifdef __has_feature
#define CATCH_ARC_ENABLED __has_feature(objc_arc)
#else
#define CATCH_ARC_ENABLED 0
#endif
void arcSafeRelease(NSObject* obj);
id performOptionalSelector(id obj, SEL sel);
#if !CATCH_ARC_ENABLED
inline void arcSafeRelease(NSObject* obj) { [obj release]; }
inline id performOptionalSelector(id obj, SEL sel) {
if ([obj respondsToSelector:sel])
return [obj performSelector:sel];
return nil;
}
#define CATCH_UNSAFE_UNRETAINED
#define CATCH_ARC_STRONG
#else
inline void arcSafeRelease(NSObject*) {}
inline id performOptionalSelector(id obj, SEL sel) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
#endif
if ([obj respondsToSelector:sel])
return [obj performSelector:sel];
#ifdef __clang__
#pragma clang diagnostic pop
#endif
return nil;
}
#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
#define CATCH_ARC_STRONG __strong
#endif
// end catch_objc_arc.hpp
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4180) // We attempt to stream a function (address) by const&,
// which MSVC complains about but is harmless
#endif
namespace Catch {
namespace Detail {
extern const std::string unprintableString;
std::string rawMemoryToString(const void* object, std::size_t size);
template <typename T> std::string rawMemoryToString(const T& object) {
return rawMemoryToString(&object, sizeof(object));
}
template <typename T> class IsStreamInsertable {
template <typename Stream, typename U>
static auto test(int)
-> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
template <typename, typename> static auto test(...) -> std::false_type;
public:
static const bool value = decltype(test<std::ostream, const T&>(0))::value;
};
template <typename E> std::string convertUnknownEnumToString(E e);
template <typename T>
typename std::enable_if<!std::is_enum<T>::value &&
!std::is_base_of<std::exception, T>::value,
std::string>::type
convertUnstreamable(T const&) {
return Detail::unprintableString;
}
template <typename T>
typename std::enable_if<!std::is_enum<T>::value &&
std::is_base_of<std::exception, T>::value,
std::string>::type
convertUnstreamable(T const& ex) {
return ex.what();
}
template <typename T>
typename std::enable_if<std::is_enum<T>::value, std::string>::type
convertUnstreamable(T const& value) {
return convertUnknownEnumToString(value);
}
#if defined(_MANAGED)
//! Convert a CLR string to a utf8 std::string
template <typename T> std::string clrReferenceToString(T ^ ref) {
if (ref == nullptr)
return std::string("null");
auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
cli::pin_ptr<System::Byte> p = &bytes[0];
return std::string(reinterpret_cast<char const*>(p), bytes->Length);
}
#endif
} // namespace Detail
// If we decide for C++14, change these to enable_if_ts
template <typename T, typename = void> struct StringMaker {
template <typename Fake = T>
static typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value,
std::string>::type
convert(const Fake& value) {
ReusableStringStream rss;
// NB: call using the function-like syntax to avoid ambiguity with
// user-defined templated operator<< under clang.
rss.operator<<(value);
return rss.str();
}
template <typename Fake = T>
static typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value,
std::string>::type
convert(const Fake& value) {
#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
return Detail::convertUnstreamable(value);
#else
return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
#endif
}
};
namespace Detail {
// This function dispatches all stringification requests inside of
// Catch. Should be preferably called fully qualified, like
// ::Catch::Detail::stringify
template <typename T> std::string stringify(const T& e) {
return ::Catch::StringMaker<
typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
}
template <typename E> std::string convertUnknownEnumToString(E e) {
return ::Catch::Detail::stringify(
static_cast<typename std::underlying_type<E>::type>(e));
}
#if defined(_MANAGED)
template <typename T> std::string stringify(T ^ e) {
return ::Catch::StringMaker<T ^>::convert(e);
}
#endif
} // namespace Detail
// Some predefined specializations
template <> struct StringMaker<std::string> {
static std::string convert(const std::string& str);
};
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
template <> struct StringMaker<std::string_view> {
static std::string convert(std::string_view str);
};
#endif
template <> struct StringMaker<char const*> { static std::string convert(char const* str); };
template <> struct StringMaker<char*> { static std::string convert(char* str); };
#ifdef CATCH_CONFIG_WCHAR
template <> struct StringMaker<std::wstring> {
static std::string convert(const std::wstring& wstr);
};
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
template <> struct StringMaker<std::wstring_view> {
static std::string convert(std::wstring_view str);
};
#endif
template <> struct StringMaker<wchar_t const*> {
static std::string convert(wchar_t const* str);
};
template <> struct StringMaker<wchar_t*> { static std::string convert(wchar_t* str); };
#endif
// TBD: Should we use `strnlen` to ensure that we don't go out of the
// buffer,
// while keeping string semantics?
template <int SZ> struct StringMaker<char[SZ]> {
static std::string convert(char const* str) {
return ::Catch::Detail::stringify(std::string{str});
}
};
template <int SZ> struct StringMaker<signed char[SZ]> {
static std::string convert(signed char const* str) {
return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const*>(str)});
}
};
template <int SZ> struct StringMaker<unsigned char[SZ]> {
static std::string convert(unsigned char const* str) {
return ::Catch::Detail::stringify(std::string{reinterpret_cast<char const*>(str)});
}
};
#if defined(CATCH_CONFIG_CPP17_BYTE)
template <> struct StringMaker<std::byte> { static std::string convert(std::byte value); };
#endif // defined(CATCH_CONFIG_CPP17_BYTE)
template <> struct StringMaker<int> { static std::string convert(int value); };
template <> struct StringMaker<long> { static std::string convert(long value); };
template <> struct StringMaker<long long> { static std::string convert(long long value); };
template <> struct StringMaker<unsigned int> {
static std::string convert(unsigned int value);
};
template <> struct StringMaker<unsigned long> {
static std::string convert(unsigned long value);
};
template <> struct StringMaker<unsigned long long> {
static std::string convert(unsigned long long value);
};
template <> struct StringMaker<bool> { static std::string convert(bool b); };
template <> struct StringMaker<char> { static std::string convert(char c); };
template <> struct StringMaker<signed char> { static std::string convert(signed char c); };
template <> struct StringMaker<unsigned char> { static std::string convert(unsigned char c); };
template <> struct StringMaker<std::nullptr_t> { static std::string convert(std::nullptr_t); };
template <> struct StringMaker<float> {
static std::string convert(float value);
static int precision;
};
template <> struct StringMaker<double> {
static std::string convert(double value);
static int precision;
};
template <typename T> struct StringMaker<T*> {
template <typename U> static std::string convert(U* p) {
if (p) {
return ::Catch::Detail::rawMemoryToString(p);
} else {
return "nullptr";
}
}
};
template <typename R, typename C> struct StringMaker<R C::*> {
static std::string convert(R C::*p) {
if (p) {
return ::Catch::Detail::rawMemoryToString(p);
} else {
return "nullptr";
}
}
};
#if defined(_MANAGED)
template <typename T> struct StringMaker<T ^> {
static std::string convert(T ^ ref) { return ::Catch::Detail::clrReferenceToString(ref); }
};
#endif
namespace Detail {
template <typename InputIterator, typename Sentinel = InputIterator>
std::string rangeToString(InputIterator first, Sentinel last) {
ReusableStringStream rss;
rss << "{ ";
if (first != last) {
rss << ::Catch::Detail::stringify(*first);
for (++first; first != last; ++first)
rss << ", " << ::Catch::Detail::stringify(*first);
}
rss << " }";
return rss.str();
}
} // namespace Detail
#ifdef __OBJC__
template <> struct StringMaker<NSString*> {
static std::string convert(NSString* nsstring) {
if (!nsstring)
return "nil";
return std::string("@") + [nsstring UTF8String];
}
};
template <> struct StringMaker<NSObject*> {
static std::string convert(NSObject* nsObject) {
return ::Catch::Detail::stringify([nsObject description]);
}
};
namespace Detail {
inline std::string stringify(NSString* nsstring) {
return StringMaker<NSString*>::convert(nsstring);
}
} // namespace Detail
#endif // __OBJC__
} // namespace Catch
//////////////////////////////////////////////////////
// Separate std-lib types stringification, so it can be selectively enabled
// This means that we do not bring in
#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
#define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
#define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
#define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
#endif
// Separate std::pair specialization
#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
#include <utility>
namespace Catch {
template <typename T1, typename T2> struct StringMaker<std::pair<T1, T2>> {
static std::string convert(const std::pair<T1, T2>& pair) {
ReusableStringStream rss;
rss << "{ " << ::Catch::Detail::stringify(pair.first) << ", "
<< ::Catch::Detail::stringify(pair.second) << " }";
return rss.str();
}
};
} // namespace Catch
#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
#include <optional>
namespace Catch {
template <typename T> struct StringMaker<std::optional<T>> {
static std::string convert(const std::optional<T>& optional) {
ReusableStringStream rss;
if (optional.has_value()) {
rss << ::Catch::Detail::stringify(*optional);
} else {
rss << "{ }";
}
return rss.str();
}
};
} // namespace Catch
#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
// Separate std::tuple specialization
#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
#include <tuple>
namespace Catch {
namespace Detail {
template <typename Tuple, std::size_t N = 0, bool = (N < std::tuple_size<Tuple>::value)>
struct TupleElementPrinter {
static void print(const Tuple& tuple, std::ostream& os) {
os << (N ? ", " : " ") << ::Catch::Detail::stringify(std::get<N>(tuple));
TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
}
};
template <typename Tuple, std::size_t N> struct TupleElementPrinter<Tuple, N, false> {
static void print(const Tuple&, std::ostream&) {}
};
} // namespace Detail
template <typename... Types> struct StringMaker<std::tuple<Types...>> {
static std::string convert(const std::tuple<Types...>& tuple) {
ReusableStringStream rss;
rss << '{';
Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
rss << " }";
return rss.str();
}
};
} // namespace Catch
#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
#include <variant>
namespace Catch {
template <> struct StringMaker<std::monostate> {
static std::string convert(const std::monostate&) { return "{ }"; }
};
template <typename... Elements> struct StringMaker<std::variant<Elements...>> {
static std::string convert(const std::variant<Elements...>& variant) {
if (variant.valueless_by_exception()) {
return "{valueless variant}";
} else {
return std::visit(
[](const auto& value) { return ::Catch::Detail::stringify(value); }, variant);
}
}
};
} // namespace Catch
#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
namespace Catch {
// Import begin/ end from std here
using std::begin;
using std::end;
namespace detail {
template <typename...> struct void_type { using type = void; };
template <typename T, typename = void> struct is_range_impl : std::false_type {};
template <typename T>
struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type>
: std::true_type {};
} // namespace detail
template <typename T> struct is_range : detail::is_range_impl<T> {};
#if defined(_MANAGED) // Managed types are never ranges
template <typename T> struct is_range<T ^> { static const bool value = false; };
#endif
template <typename Range> std::string rangeToString(Range const& range) {
return ::Catch::Detail::rangeToString(begin(range), end(range));
}
// Handle vector<bool> specially
template <typename Allocator> std::string rangeToString(std::vector<bool, Allocator> const& v) {
ReusableStringStream rss;
rss << "{ ";
bool first = true;
for (bool b : v) {
if (first)
first = false;
else
rss << ", ";
rss << ::Catch::Detail::stringify(b);
}
rss << " }";
return rss.str();
}
template <typename R>
struct StringMaker<
R,
typename std::enable_if<is_range<R>::value &&
!::Catch::Detail::IsStreamInsertable<R>::value>::type> {
static std::string convert(R const& range) { return rangeToString(range); }
};
template <typename T, int SZ> struct StringMaker<T[SZ]> {
static std::string convert(T const (&arr)[SZ]) { return rangeToString(arr); }
};
} // namespace Catch
// Separate std::chrono::duration specialization
#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
#include <ctime>
#include <ratio>
#include <chrono>
namespace Catch {
template <class Ratio> struct ratio_string { static std::string symbol(); };
template <class Ratio> std::string ratio_string<Ratio>::symbol() {
Catch::ReusableStringStream rss;
rss << '[' << Ratio::num << '/' << Ratio::den << ']';
return rss.str();
}
template <> struct ratio_string<std::atto> { static std::string symbol(); };
template <> struct ratio_string<std::femto> { static std::string symbol(); };
template <> struct ratio_string<std::pico> { static std::string symbol(); };
template <> struct ratio_string<std::nano> { static std::string symbol(); };
template <> struct ratio_string<std::micro> { static std::string symbol(); };
template <> struct ratio_string<std::milli> { static std::string symbol(); };
////////////
// std::chrono::duration specializations
template <typename Value, typename Ratio>
struct StringMaker<std::chrono::duration<Value, Ratio>> {
static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
ReusableStringStream rss;
rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
return rss.str();
}
};
template <typename Value> struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
ReusableStringStream rss;
rss << duration.count() << " s";
return rss.str();
}
};
template <typename Value> struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
ReusableStringStream rss;
rss << duration.count() << " m";
return rss.str();
}
};
template <typename Value> struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
ReusableStringStream rss;
rss << duration.count() << " h";
return rss.str();
}
};
////////////
// std::chrono::time_point specialization
// Generic time_point cannot be specialized, only
// std::chrono::time_point<system_clock>
template <typename Clock, typename Duration>
struct StringMaker<std::chrono::time_point<Clock, Duration>> {
static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
}
};
// std::chrono::time_point<system_clock> specialization
template <typename Duration>
struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
static std::string
convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
auto converted = std::chrono::system_clock::to_time_t(time_point);
#ifdef _MSC_VER
std::tm timeInfo = {};
gmtime_s(&timeInfo, &converted);
#else
std::tm* timeInfo = std::gmtime(&converted);
#endif
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
char timeStamp[timeStampSize];
const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
#ifdef _MSC_VER
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
#else
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
#endif
return std::string(timeStamp);
}
};
} // namespace Catch
#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#define INTERNAL_CATCH_REGISTER_ENUM(enumName, ...) \
namespace Catch { \
template <> struct StringMaker<enumName> { \
static std::string convert(enumName value) { \
static const auto& enumInfo = \
::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( \
#enumName, #__VA_ARGS__, {__VA_ARGS__}); \
return static_cast<std::string>(enumInfo.lookup(static_cast<int>(value))); \
} \
}; \
}
#define CATCH_REGISTER_ENUM(enumName, ...) INTERNAL_CATCH_REGISTER_ENUM(enumName, __VA_ARGS__)
#ifdef _MSC_VER
#pragma warning(pop)
#endif
// end catch_tostring.h
#include <iosfwd>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4389) // '==' : signed/unsigned mismatch
#pragma warning(disable : 4018) // more "signed/unsigned mismatch"
#pragma warning(disable : 4312) // Converting int to T* using reinterpret_cast
// (issue on x64 platform)
#pragma warning(disable : 4180) // qualifier applied to function type has no meaning
#pragma warning(disable : 4800) // Forcing result to true or false
#endif
namespace Catch {
struct ITransientExpression {
auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
auto getResult() const -> bool { return m_result; }
virtual void streamReconstructedExpression(std::ostream& os) const = 0;
ITransientExpression(bool isBinaryExpression, bool result) :
m_isBinaryExpression(isBinaryExpression), m_result(result) {}
// We don't actually need a virtual destructor, but many static
// analysers complain if it's not here :-(
virtual ~ITransientExpression();
bool m_isBinaryExpression;
bool m_result;
};
void formatReconstructedExpression(std::ostream& os,
std::string const& lhs,
StringRef op,
std::string const& rhs);
template <typename LhsT, typename RhsT> class BinaryExpr : public ITransientExpression {
LhsT m_lhs;
StringRef m_op;
RhsT m_rhs;
void streamReconstructedExpression(std::ostream& os) const override {
formatReconstructedExpression(
os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
}
public:
BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs) :
ITransientExpression{true, comparisonResult}, m_lhs(lhs), m_op(op), m_rhs(rhs) {}
template <typename T> auto operator&&(T) const -> BinaryExpr<LhsT, RhsT const&> const {
static_assert(always_false<T>::value,
"chained comparisons are not supported inside assertions, "
"wrap the expression inside parentheses, or decompose it");
}
template <typename T> auto operator||(T) const -> BinaryExpr<LhsT, RhsT const&> const {
static_assert(always_false<T>::value,
"chained comparisons are not supported inside assertions, "
"wrap the expression inside parentheses, or decompose it");
}
template <typename T> auto operator==(T) const -> BinaryExpr<LhsT, RhsT const&> const {
static_assert(always_false<T>::value,
"chained comparisons are not supported inside assertions, "
"wrap the expression inside parentheses, or decompose it");
}
template <typename T> auto operator!=(T) const -> BinaryExpr<LhsT, RhsT const&> const {
static_assert(always_false<T>::value,
"chained comparisons are not supported inside assertions, "
"wrap the expression inside parentheses, or decompose