diff options
| author | Billy O'Neal <bion@microsoft.com> | 2021-02-04 10:15:44 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-04 10:15:44 -0800 |
| commit | aa60b7efa56a83ead743718941d8b320ef4a05af (patch) | |
| tree | db9f9ebd6fa37598b2f5f2ad564eb858cdeddcb0 /toolsrc/include | |
| parent | f226416d2eafc495dd03572cb61542fb1670ffdc (diff) | |
| download | vcpkg-aa60b7efa56a83ead743718941d8b320ef4a05af.tar.gz vcpkg-aa60b7efa56a83ead743718941d8b320ef4a05af.zip | |
[vcpkg] Download vcpkg.exe rather than building it in bootstrap on Windows. (#15474)
This reduces bootstrap cost for Windows customers, resolving the issue initially submitted as #12502 .
The `toolsrc` tree was extracted to https://github.com/microsoft/vcpkg-tool. `bootstrap.sh` was changed to download the right source tarball, extract, and build it. This was chosen over the previous attempt, a submodule, over concerns of accidentally destroying people's local modifications.
Diffstat (limited to 'toolsrc/include')
128 files changed, 0 insertions, 24446 deletions
diff --git a/toolsrc/include/catch2/catch.hpp b/toolsrc/include/catch2/catch.hpp deleted file mode 100644 index f471a2ec6..000000000 --- a/toolsrc/include/catch2/catch.hpp +++ /dev/null @@ -1,16865 +0,0 @@ -/* - * Catch v2.9.1 - * Generated: 2019-06-17 11:59:24.363643 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2019 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 9 -#define CATCH_VERSION_PATCH 1 - -#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 - -#ifdef __APPLE__ -# include <TargetConditionals.h> -# if TARGET_OS_OSX == 1 -# define CATCH_PLATFORM_MAC -# elif 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 - -#if defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -#endif - -#ifdef __clang__ - -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -#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 -#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++ -#ifdef _MSC_VER - -# if _MSC_VER >= 1900 // Visual Studio 2015 or newer -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -# endif - -// 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(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif -#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 - -//////////////////////////////////////////////////////////////////////////////// -// Check if string_view is available and usable -// The check is split apart to work around v140 (VS2015) preprocessor issue... -#if defined(__has_include) -#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW -#endif -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Check if optional is available and usable -#if defined(__has_include) -# if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL -# endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER) -#endif // __has_include - -//////////////////////////////////////////////////////////////////////////////// -// Check if variant is available and usable -#if defined(__has_include) -# 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 // __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_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -#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_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_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_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; - 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; - } -} - -#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_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS - -// 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 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 ); - -} - -// end catch_interfaces_testcase.h -// start catch_stringref.h - -#include <cstddef> -#include <string> -#include <iosfwd> - -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. c_str() must return a null terminated - /// string, however, and so the StringRef will internally take ownership - /// (taking a copy), if necessary. In theory this ownership is not externally - /// visible - but it does mean (substring) StringRefs should not be shared between - /// threads. - class StringRef { - public: - using size_type = std::size_t; - - private: - friend struct StringRefTestAccess; - - char const* m_start; - size_type m_size; - - char* m_data = nullptr; - - void takeOwnership(); - - static constexpr char const* const s_empty = ""; - - public: // construction/ assignment - StringRef() noexcept - : StringRef( s_empty, 0 ) - {} - - StringRef( StringRef const& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ) - {} - - StringRef( StringRef&& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ), - m_data( other.m_data ) - { - other.m_data = nullptr; - } - - StringRef( char const* rawChars ) noexcept; - - 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() ) - {} - - ~StringRef() noexcept { - delete[] m_data; - } - - auto operator = ( StringRef const &other ) noexcept -> StringRef& { - delete[] m_data; - m_data = nullptr; - m_start = other.m_start; - m_size = other.m_size; - return *this; - } - - operator std::string() const; - - void swap( StringRef& other ) noexcept; - - public: // operators - auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != ( StringRef const& other ) const noexcept -> bool; - - auto operator[] ( size_type index ) const noexcept -> char; - - public: // named queries - auto empty() const noexcept -> bool { - return m_size == 0; - } - auto size() const noexcept -> size_type { - return m_size; - } - - auto numberOfCharacters() const noexcept -> size_type; - auto c_str() const -> char const*; - - public: // substrings and searches - auto substr( size_type start, size_type size ) const noexcept -> StringRef; - - // Returns the current start pointer. - // Note that the pointer can change when if the StringRef is a substring - auto currentData() const noexcept -> char const*; - - private: // ownership queries - may not be consistent between calls - auto isOwned() const noexcept -> bool; - auto isSubstring() const noexcept -> bool; - }; - - auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; - auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; - auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; - - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; - auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - - inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); - } - -} // namespace Catch - -inline 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_type_traits.hpp - - -#include <type_traits> - -namespace Catch{ - -#ifdef CATCH_CPP17_OR_GREATER - template <typename...> - inline constexpr auto is_unique = std::true_type{}; - - template <typename T, typename... Rest> - inline constexpr auto is_unique<T, Rest...> = std::bool_constant< - (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...> - >{}; -#else - -template <typename...> -struct is_unique : std::true_type{}; - -template <typename T0, typename T1, typename... Rest> -struct is_unique<T0, T1, Rest...> : std::integral_constant -<bool, - !std::is_same<T0, T1>::value - && is_unique<T0, Rest...>::value - && is_unique<T1, Rest...>::value ->{}; - -#endif -} - -// end catch_type_traits.hpp -// 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, _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 L1, typename...E1, template<typename...> class L2, typename...E2> \ - constexpr auto append(L1<E1...>, L2<E2...>) noexcept -> L1<E1...,E2...> { return {}; }\ - template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\ - constexpr auto append(L1<E1...>, L2<E2...>, Rest...) noexcept -> decltype(append(L1<E1...,E2...>{}, Rest{}...)) { return {}; }\ - template< template<typename...> class L1, typename...E1, typename...Rest>\ - constexpr auto append(L1<E1...>, TypeList<mpl_::na>, Rest...) noexcept -> L1<E1...> { return {}; }\ - \ - template< template<typename...> class Container, template<typename...> class List, typename...elems>\ - constexpr auto rewrap(List<elems...>) noexcept -> TypeList<Container<elems...>> { return {}; }\ - template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\ - constexpr auto rewrap(List<Elems...>,Elements...) noexcept -> decltype(append(TypeList<Container<Elems...>>{}, rewrap<Container>(Elements{}...))) { return {}; }\ - \ - template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\ - constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }\ - template<template <typename...> class Final, template <typename...> class List, typename...Ts>\ - constexpr auto convert(List<Ts...>) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; } - -#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 Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\ - constexpr auto rewrap(List<__VA_ARGS__>) noexcept -> TypeList<Container<__VA_ARGS__>> { return {}; }\ - template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\ - constexpr auto rewrap(List<__VA_ARGS__>,Elements...elems) noexcept -> decltype(append(TypeList<Container<__VA_ARGS__>>{}, rewrap<Container>(elems...))) { return {}; }\ - template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\ - constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; } - -#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)) {}; - -} // 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_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_UNSUPPRESS_GLOBALS_WARNINGS \ - 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_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_UNSUPPRESS_GLOBALS_WARNINGS - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ - 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_UNSUPPRESS_GLOBALS_WARNINGS \ - 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_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_UNSUPPRESS_GLOBALS_WARNINGS - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_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++, 0)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ - TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\ - return 0;\ - }();\ - }\ - }\ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \ - 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_SUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_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++, 0)... };/* NOLINT */\ - } \ - }; \ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ - using TestInit = decltype(create<TestName, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{})); \ - TestInit t; \ - t.reg_tests(); \ - return 0; \ - }(); \ - } \ - } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \ - 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_SUPPRESS_GLOBALS_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++, 0)... };/* NOLINT */\ - } \ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ - using TestInit = decltype(convert<TestName>(TmplList {})); \ - TestInit t; \ - t.reg_tests(); \ - return 0; \ - }(); \ - }}\ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - 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_SUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_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++, 0)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ - TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\ - return 0;\ - }();\ - }\ - }\ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\ - CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\ - 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_SUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_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++, 0)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ - using TestInit = decltype(create<TestNameClass, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{}));\ - TestInit t;\ - t.reg_tests();\ - return 0;\ - }(); \ - }\ - }\ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \ - 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_SUPPRESS_GLOBALS_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++, 0)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ - using TestInit = decltype(convert<TestNameClass>(TmplList {}));\ - TestInit t;\ - t.reg_tests();\ - return 0;\ - }(); \ - }}\ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - 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 { - 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; } - }; -} - -// 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, std::string>> 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 ) { - std::vector<int> intValues; - intValues.reserve( values.size() ); - for( auto enumValue : values ) - intValues.push_back( static_cast<int>( enumValue ) ); - return registerEnum( enumName, allEnums, intValues ); - } - }; - -} // 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 SS, typename TT> - static auto test(int) - -> decltype(std::declval<SS&>() << std::declval<TT>(), 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) }); - } - }; - - 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> - std::string rangeToString(InputIterator first, InputIterator 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(); - } - } - -#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(); - } - }; -} -#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(); - } - }; -} -#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&) {} - }; - - } - - 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(); - } - }; -} -#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 - ); - } - } - }; -} -#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER - -namespace Catch { - struct not_this_one {}; // Tag type for detecting which begin/ end are being selected - - // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace - using std::begin; - using std::end; - - not_this_one begin( ... ); - not_this_one end( ... ); - - template <typename T> - struct is_range { - static const bool value = - !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value && - !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value; - }; - -#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); - } - }; -} -#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 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 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 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 LhsT> - class UnaryExpr : public ITransientExpression { - LhsT m_lhs; - - void streamReconstructedExpression( std::ostream &os ) const override { - os << Catch::Detail::stringify( m_lhs ); - } - - public: - explicit UnaryExpr( LhsT lhs ) - : ITransientExpression{ false, static_cast<bool>(lhs) }, - m_lhs( lhs ) - {} - }; - - // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int) - template<typename LhsT, typename RhsT> - auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); } - template<typename T> - auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } - template<typename T> - auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } - template<typename T> - auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } - template<typename T> - auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } - - template<typename LhsT, typename RhsT> - auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); } - template<typename T> - auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } - template<typename T> - auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } - template<typename T> - auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } - template<typename T> - auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } - - template<typename LhsT> - class ExprLhs { - LhsT m_lhs; - public: - explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {} - - template<typename RhsT> - auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { - return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs }; - } - auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const { - return { m_lhs == rhs, m_lhs, "==", rhs }; - } - - template<typename RhsT> - auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { - return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs }; - } - auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const { - return { m_lhs != rhs, m_lhs, "!=", rhs }; - } - - template<typename RhsT> - auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { - return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs }; - } - template<typename RhsT> - auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { - return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs }; - } - template<typename RhsT> - auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { - return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs }; - } - template<typename RhsT> - auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { - return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs }; - } - - template<typename RhsT> - auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const { - static_assert(always_false<RhsT>::value, - "operator&& is not supported inside assertions, " - "wrap the expression inside parentheses, or decompose it"); - } - - template<typename RhsT> - auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const { - static_assert(always_false<RhsT>::value, - "operator|| is not supported inside assertions, " - "wrap the expression inside parentheses, or decompose it"); - } - - auto makeUnaryExpr() const -> UnaryExpr<LhsT> { - return UnaryExpr<LhsT>{ m_lhs }; - } - }; - - void handleExpression( ITransientExpression const& expr ); - - template<typename T> - void handleExpression( ExprLhs<T> const& expr ) { - handleExpression( expr.makeUnaryExpr() ); - } - - struct Decomposer { - template<typename T> - auto operator <= ( T const& lhs ) -> ExprLhs<T const&> { - return ExprLhs<T const&>{ lhs }; - } - - auto operator <=( bool value ) -> ExprLhs<bool> { - return ExprLhs<bool>{ value }; - } - }; - -} // end namespace Catch - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -// end catch_decomposer.h -// start catch_interfaces_capture.h - -#include <string> -#include <chrono> - -namespace Catch { - - class AssertionResult; - struct AssertionInfo; - struct SectionInfo; - struct SectionEndInfo; - struct MessageInfo; - struct MessageBuilder; - struct Counts; - struct AssertionReaction; - struct SourceLineInfo; - - struct ITransientExpression; - struct IGeneratorTracker; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - struct BenchmarkInfo; - template <typename Duration = std::chrono::duration<double, std::nano>> - struct BenchmarkStats; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - struct IResultCapture { - - virtual ~IResultCapture(); - - virtual bool sectionStarted( SectionInfo const& sectionInfo, - Counts& assertions ) = 0; - virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; - virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; - - virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - virtual void benchmarkPreparing( std::string const& name ) = 0; - virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; - virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0; - virtual void benchmarkFailed( std::string const& error ) = 0; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - virtual void pushScopedMessage( MessageInfo const& message ) = 0; - virtual void popScopedMessage( MessageInfo const& message ) = 0; - - virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0; - - virtual void handleFatalErrorCondition( StringRef message ) = 0; - - virtual void handleExpr - ( AssertionInfo const& info, - ITransientExpression const& expr, - AssertionReaction& reaction ) = 0; - virtual void handleMessage - ( AssertionInfo const& info, - ResultWas::OfType resultType, - StringRef const& message, - AssertionReaction& reaction ) = 0; - virtual void handleUnexpectedExceptionNotThrown - ( AssertionInfo const& info, - AssertionReaction& reaction ) = 0; - virtual void handleUnexpectedInflightException - ( AssertionInfo const& info, - std::string const& message, - AssertionReaction& reaction ) = 0; - virtual void handleIncomplete - ( AssertionInfo const& info ) = 0; - virtual void handleNonExpr - ( AssertionInfo const &info, - ResultWas::OfType resultType, - AssertionReaction &reaction ) = 0; - - virtual bool lastAssertionPassed() = 0; - virtual void assertionPassed() = 0; - - // Deprecated, do not use: - virtual std::string getCurrentTestName() const = 0; - virtual const AssertionResult* getLastResult() const = 0; - virtual void exceptionEarlyReported() = 0; - }; - - IResultCapture& getResultCapture(); -} - -// end catch_interfaces_capture.h -namespace Catch { - - struct TestFailureException{}; - struct AssertionResultData; - struct IResultCapture; - class RunContext; - - class LazyExpression { - friend class AssertionHandler; - friend struct AssertionStats; - friend class RunContext; - - ITransientExpression const* m_transientExpression = nullptr; - bool m_isNegated; - public: - LazyExpression( bool isNegated ); - LazyExpression( LazyExpression const& other ); - LazyExpression& operator = ( LazyExpression const& ) = delete; - - explicit operator bool() const; - - friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&; - }; - - struct AssertionReaction { - bool shouldDebugBreak = false; - bool shouldThrow = false; - }; - - class AssertionHandler { - AssertionInfo m_assertionInfo; - AssertionReaction m_reaction; - bool m_completed = false; - IResultCapture& m_resultCapture; - - public: - AssertionHandler - ( StringRef const& macroName, - SourceLineInfo const& lineInfo, - StringRef capturedExpression, - ResultDisposition::Flags resultDisposition ); - ~AssertionHandler() { - if ( !m_completed ) { - m_resultCapture.handleIncomplete( m_assertionInfo ); - } - } - - template<typename T> - void handleExpr( ExprLhs<T> const& expr ) { - handleExpr( expr.makeUnaryExpr() ); - } - void handleExpr( ITransientExpression const& expr ); - - void handleMessage(ResultWas::OfType resultType, StringRef const& message); - - void handleExceptionThrownAsExpected(); - void handleUnexpectedExceptionNotThrown(); - void handleExceptionNotThrownAsExpected(); - void handleThrowingCallSkipped(); - void handleUnexpectedInflightException(); - - void complete(); - void setCompleted(); - - // query - auto allowThrows() const -> bool; - }; - - void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ); - -} // namespace Catch - -// end catch_assertionhandler.h -// start catch_message.h - -#include <string> -#include <vector> - -namespace Catch { - - struct MessageInfo { - MessageInfo( StringRef const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ); - - StringRef macroName; - std::string message; - SourceLineInfo lineInfo; - ResultWas::OfType type; - unsigned int sequence; - - bool operator == ( MessageInfo const& other ) const; - bool operator < ( MessageInfo const& other ) const; - private: - static unsigned int globalCount; - }; - - struct MessageStream { - - template<typename T> - MessageStream& operator << ( T const& value ) { - m_stream << value; - return *this; - } - - ReusableStringStream m_stream; - }; - - struct MessageBuilder : MessageStream { - MessageBuilder( StringRef const& macroName, - SourceLineInfo const& lineInfo, - ResultWas::OfType type ); - - template<typename T> - MessageBuilder& operator << ( T const& value ) { - m_stream << value; - return *this; - } - - MessageInfo m_info; - }; - - class ScopedMessage { - public: - explicit ScopedMessage( MessageBuilder const& builder ); - ScopedMessage( ScopedMessage& duplicate ) = delete; - ScopedMessage( ScopedMessage&& old ); - ~ScopedMessage(); - - MessageInfo m_info; - bool m_moved; - }; - - class Capturer { - std::vector<MessageInfo> m_messages; - IResultCapture& m_resultCapture = getResultCapture(); - size_t m_captured = 0; - public: - Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ); - ~Capturer(); - - void captureValue( size_t index, std::string const& value ); - - template<typename T> - void captureValues( size_t index, T const& value ) { - captureValue( index, Catch::Detail::stringify( value ) ); - } - - template<typename T, typename... Ts> - void captureValues( size_t index, T const& value, Ts const&... values ) { - captureValue( index, Catch::Detail::stringify(value) ); - captureValues( index+1, values... ); - } - }; - -} // end namespace Catch - -// end catch_message.h -#if !defined(CATCH_CONFIG_DISABLE) - -#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) - #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ -#else - #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" -#endif - -#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - -/////////////////////////////////////////////////////////////////////////////// -// Another way to speed-up compilation is to omit local try-catch for REQUIRE* -// macros. -#define INTERNAL_CATCH_TRY -#define INTERNAL_CATCH_CATCH( capturer ) - -#else // CATCH_CONFIG_FAST_COMPILE - -#define INTERNAL_CATCH_TRY try -#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); } - -#endif - -#define INTERNAL_CATCH_REACT( handler ) handler.complete(); - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ - INTERNAL_CATCH_TRY { \ - CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \ - CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look - // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ - INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ - if( Catch::getResultCapture().lastAssertionPassed() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ - INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ - if( !Catch::getResultCapture().lastAssertionPassed() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ - try { \ - static_cast<void>(__VA_ARGS__); \ - catchAssertionHandler.handleExceptionNotThrownAsExpected(); \ - } \ - catch( ... ) { \ - catchAssertionHandler.handleUnexpectedInflightException(); \ - } \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ - if( catchAssertionHandler.allowThrows() ) \ - try { \ - static_cast<void>(__VA_ARGS__); \ - catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ - } \ - catch( ... ) { \ - catchAssertionHandler.handleExceptionThrownAsExpected(); \ - } \ - else \ - catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ - if( catchAssertionHandler.allowThrows() ) \ - try { \ - static_cast<void>(expr); \ - catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ - } \ - catch( exceptionType const& ) { \ - catchAssertionHandler.handleExceptionThrownAsExpected(); \ - } \ - catch( ... ) { \ - catchAssertionHandler.handleUnexpectedInflightException(); \ - } \ - else \ - catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \ - catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \ - auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \ - varName.captureValues( 0, __VA_ARGS__ ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_INFO( macroName, log ) \ - Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \ - Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ) - -/////////////////////////////////////////////////////////////////////////////// -// Although this is matcher-based, it can be used with just a string -#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ - if( catchAssertionHandler.allowThrows() ) \ - try { \ - static_cast<void>(__VA_ARGS__); \ - catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ - } \ - catch( ... ) { \ - Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \ - } \ - else \ - catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -#endif // CATCH_CONFIG_DISABLE - -// end catch_capture.hpp -// start catch_section.h - -// start catch_section_info.h - -// start catch_totals.h - -#include <cstddef> - -namespace Catch { - - struct Counts { - Counts operator - ( Counts const& other ) const; - Counts& operator += ( Counts const& other ); - - std::size_t total() const; - bool allPassed() const; - bool allOk() const; - - std::size_t passed = 0; - std::size_t failed = 0; - std::size_t failedButOk = 0; - }; - - struct Totals { - - Totals operator - ( Totals const& other ) const; - Totals& operator += ( Totals const& other ); - - Totals delta( Totals const& prevTotals ) const; - - int error = 0; - Counts assertions; - Counts testCases; - }; -} - -// end catch_totals.h -#include <string> - -namespace Catch { - - struct SectionInfo { - SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name ); - - // Deprecated - SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& ) : SectionInfo( _lineInfo, _name ) {} - - std::string name; - std::string description; // !Deprecated: this will always be empty - SourceLineInfo lineInfo; - }; - - struct SectionEndInfo { - SectionInfo sectionInfo; - Counts prevAssertions; - double durationInSeconds; - }; - -} // end namespace Catch - -// end catch_section_info.h -// start catch_timer.h - -#include <cstdint> - -namespace Catch { - - auto getCurrentNanosecondsSinceEpoch() -> uint64_t; - auto getEstimatedClockResolution() -> uint64_t; - - class Timer { - uint64_t m_nanoseconds = 0; - public: - void start(); - auto getElapsedNanoseconds() const -> uint64_t; - auto getElapsedMicroseconds() const -> uint64_t; - auto getElapsedMilliseconds() const -> unsigned int; - auto getElapsedSeconds() const -> double; - }; - -} // namespace Catch - -// end catch_timer.h -#include <string> - -namespace Catch { - - class Section : NonCopyable { - public: - Section( SectionInfo const& info ); - ~Section(); - - // This indicates whether the section should be executed or not - explicit operator bool() const; - - private: - SectionInfo m_info; - - std::string m_name; - Counts m_assertions; - bool m_sectionIncluded; - Timer m_timer; - }; - -} // end namespace Catch - -#define INTERNAL_CATCH_SECTION( ... ) \ - CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \ - CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS - -#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \ - CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \ - CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS - -// end catch_section.h -// start catch_interfaces_exception.h - -// start catch_interfaces_registry_hub.h - -#include <string> -#include <memory> - -namespace Catch { - - class TestCase; - struct ITestCaseRegistry; - struct IExceptionTranslatorRegistry; - struct IExceptionTranslator; - struct IReporterRegistry; - struct IReporterFactory; - struct ITagAliasRegistry; - struct IMutableEnumValuesRegistry; - - class StartupExceptionRegistry; - - using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; - - struct IRegistryHub { - virtual ~IRegistryHub(); - - virtual IReporterRegistry const& getReporterRegistry() const = 0; - virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; - virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; - virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0; - - virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; - }; - - struct IMutableRegistryHub { - virtual ~IMutableRegistryHub(); - virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0; - virtual void registerListener( IReporterFactoryPtr const& factory ) = 0; - virtual void registerTest( TestCase const& testInfo ) = 0; - virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; - virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; - virtual void registerStartupException() noexcept = 0; - virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0; - }; - - IRegistryHub const& getRegistryHub(); - IMutableRegistryHub& getMutableRegistryHub(); - void cleanUp(); - std::string translateActiveException(); - -} - -// end catch_interfaces_registry_hub.h -#if defined(CATCH_CONFIG_DISABLE) - #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ - static std::string translatorName( signature ) -#endif - -#include <exception> -#include <string> -#include <vector> - -namespace Catch { - using exceptionTranslateFunction = std::string(*)(); - - struct IExceptionTranslator; - using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>; - - struct IExceptionTranslator { - virtual ~IExceptionTranslator(); - virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; - }; - - struct IExceptionTranslatorRegistry { - virtual ~IExceptionTranslatorRegistry(); - - virtual std::string translateActiveException() const = 0; - }; - - class ExceptionTranslatorRegistrar { - template<typename T> - class ExceptionTranslator : public IExceptionTranslator { - public: - - ExceptionTranslator( std::string(*translateFunction)( T& ) ) - : m_translateFunction( translateFunction ) - {} - - std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { - try { - if( it == itEnd ) - std::rethrow_exception(std::current_exception()); - else - return (*it)->translate( it+1, itEnd ); - } - catch( T& ex ) { - return m_translateFunction( ex ); - } - } - - protected: - std::string(*m_translateFunction)( T& ); - }; - - public: - template<typename T> - ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { - getMutableRegistryHub().registerTranslator - ( new ExceptionTranslator<T>( translateFunction ) ); - } - }; -} - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ - static std::string translatorName( signature ); \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - static std::string translatorName( signature ) - -#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) - -// end catch_interfaces_exception.h -// start catch_approx.h - -#include <type_traits> - -namespace Catch { -namespace Detail { - - class Approx { - private: - bool equalityComparisonImpl(double other) const; - // Validates the new margin (margin >= 0) - // out-of-line to avoid including stdexcept in the header - void setMargin(double margin); - // Validates the new epsilon (0 < epsilon < 1) - // out-of-line to avoid including stdexcept in the header - void setEpsilon(double epsilon); - - public: - explicit Approx ( double value ); - - static Approx custom(); - - Approx operator-() const; - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - Approx operator()( T const& value ) { - Approx approx( static_cast<double>(value) ); - approx.m_epsilon = m_epsilon; - approx.m_margin = m_margin; - approx.m_scale = m_scale; - return approx; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - explicit Approx( T const& value ): Approx(static_cast<double>(value)) - {} - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator == ( const T& lhs, Approx const& rhs ) { - auto lhs_v = static_cast<double>(lhs); - return rhs.equalityComparisonImpl(lhs_v); - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator == ( Approx const& lhs, const T& rhs ) { - return operator==( rhs, lhs ); - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator != ( T const& lhs, Approx const& rhs ) { - return !operator==( lhs, rhs ); - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator != ( Approx const& lhs, T const& rhs ) { - return !operator==( rhs, lhs ); - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator <= ( T const& lhs, Approx const& rhs ) { - return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator <= ( Approx const& lhs, T const& rhs ) { - return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator >= ( T const& lhs, Approx const& rhs ) { - return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - friend bool operator >= ( Approx const& lhs, T const& rhs ) { - return lhs.m_value > static_cast<double>(rhs) || lhs == rhs; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - Approx& epsilon( T const& newEpsilon ) { - double epsilonAsDouble = static_cast<double>(newEpsilon); - setEpsilon(epsilonAsDouble); - return *this; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - Approx& margin( T const& newMargin ) { - double marginAsDouble = static_cast<double>(newMargin); - setMargin(marginAsDouble); - return *this; - } - - template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - Approx& scale( T const& newScale ) { - m_scale = static_cast<double>(newScale); - return *this; - } - - std::string toString() const; - - private: - double m_epsilon; - double m_margin; - double m_scale; - double m_value; - }; -} // end namespace Detail - -namespace literals { - Detail::Approx operator "" _a(long double val); - Detail::Approx operator "" _a(unsigned long long val); -} // end namespace literals - -template<> -struct StringMaker<Catch::Detail::Approx> { - static std::string convert(Catch::Detail::Approx const& value); -}; - -} // end namespace Catch - -// end catch_approx.h -// start catch_string_manip.h - -#include <string> -#include <iosfwd> -#include <vector> - -namespace Catch { - - bool startsWith( std::string const& s, std::string const& prefix ); - bool startsWith( std::string const& s, char prefix ); - bool endsWith( std::string const& s, std::string const& suffix ); - bool endsWith( std::string const& s, char suffix ); - bool contains( std::string const& s, std::string const& infix ); - void toLowerInPlace( std::string& s ); - std::string toLower( std::string const& s ); - std::string trim( std::string const& str ); - - // !!! Be aware, returns refs into original string - make sure original string outlives them - std::vector<StringRef> splitStringRef( StringRef str, char delimiter ); - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); - - struct pluralise { - pluralise( std::size_t count, std::string const& label ); - - friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); - - std::size_t m_count; - std::string m_label; - }; -} - -// end catch_string_manip.h -#ifndef CATCH_CONFIG_DISABLE_MATCHERS -// start catch_capture_matchers.h - -// start catch_matchers.h - -#include <string> -#include <vector> - -namespace Catch { -namespace Matchers { - namespace Impl { - - template<typename ArgT> struct MatchAllOf; - template<typename ArgT> struct MatchAnyOf; - template<typename ArgT> struct MatchNotOf; - - class MatcherUntypedBase { - public: - MatcherUntypedBase() = default; - MatcherUntypedBase ( MatcherUntypedBase const& ) = default; - MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete; - std::string toString() const; - - protected: - virtual ~MatcherUntypedBase(); - virtual std::string describe() const = 0; - mutable std::string m_cachedToString; - }; - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#endif - - template<typename ObjectT> - struct MatcherMethod { - virtual bool match( ObjectT const& arg ) const = 0; - }; - -#ifdef __clang__ -# pragma clang diagnostic pop -#endif - - template<typename T> - struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> { - - MatchAllOf<T> operator && ( MatcherBase const& other ) const; - MatchAnyOf<T> operator || ( MatcherBase const& other ) const; - MatchNotOf<T> operator ! () const; - }; - - template<typename ArgT> - struct MatchAllOf : MatcherBase<ArgT> { - bool match( ArgT const& arg ) const override { - for( auto matcher : m_matchers ) { - if (!matcher->match(arg)) - return false; - } - return true; - } - std::string describe() const override { - std::string description; - description.reserve( 4 + m_matchers.size()*32 ); - description += "( "; - bool first = true; - for( auto matcher : m_matchers ) { - if( first ) - first = false; - else - description += " and "; - description += matcher->toString(); - } - description += " )"; - return description; - } - - MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) { - m_matchers.push_back( &other ); - return *this; - } - - std::vector<MatcherBase<ArgT> const*> m_matchers; - }; - template<typename ArgT> - struct MatchAnyOf : MatcherBase<ArgT> { - - bool match( ArgT const& arg ) const override { - for( auto matcher : m_matchers ) { - if (matcher->match(arg)) - return true; - } - return false; - } - std::string describe() const override { - std::string description; - description.reserve( 4 + m_matchers.size()*32 ); - description += "( "; - bool first = true; - for( auto matcher : m_matchers ) { - if( first ) - first = false; - else - description += " or "; - description += matcher->toString(); - } - description += " )"; - return description; - } - - MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) { - m_matchers.push_back( &other ); - return *this; - } - - std::vector<MatcherBase<ArgT> const*> m_matchers; - }; - - template<typename ArgT> - struct MatchNotOf : MatcherBase<ArgT> { - - MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} - - bool match( ArgT const& arg ) const override { - return !m_underlyingMatcher.match( arg ); - } - - std::string describe() const override { - return "not " + m_underlyingMatcher.toString(); - } - MatcherBase<ArgT> const& m_underlyingMatcher; - }; - - template<typename T> - MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const { - return MatchAllOf<T>() && *this && other; - } - template<typename T> - MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const { - return MatchAnyOf<T>() || *this || other; - } - template<typename T> - MatchNotOf<T> MatcherBase<T>::operator ! () const { - return MatchNotOf<T>( *this ); - } - - } // namespace Impl - -} // namespace Matchers - -using namespace Matchers; -using Matchers::Impl::MatcherBase; - -} // namespace Catch - -// end catch_matchers.h -// start catch_matchers_floating.h - -#include <type_traits> -#include <cmath> - -namespace Catch { -namespace Matchers { - - namespace Floating { - - enum class FloatingPointKind : uint8_t; - - struct WithinAbsMatcher : MatcherBase<double> { - WithinAbsMatcher(double target, double margin); - bool match(double const& matchee) const override; - std::string describe() const override; - private: - double m_target; - double m_margin; - }; - - struct WithinUlpsMatcher : MatcherBase<double> { - WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType); - bool match(double const& matchee) const override; - std::string describe() const override; - private: - double m_target; - int m_ulps; - FloatingPointKind m_type; - }; - - } // namespace Floating - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff); - Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff); - Floating::WithinAbsMatcher WithinAbs(double target, double margin); - -} // namespace Matchers -} // namespace Catch - -// end catch_matchers_floating.h -// start catch_matchers_generic.hpp - -#include <functional> -#include <string> - -namespace Catch { -namespace Matchers { -namespace Generic { - -namespace Detail { - std::string finalizeDescription(const std::string& desc); -} - -template <typename T> -class PredicateMatcher : public MatcherBase<T> { - std::function<bool(T const&)> m_predicate; - std::string m_description; -public: - - PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr) - :m_predicate(std::move(elem)), - m_description(Detail::finalizeDescription(descr)) - {} - - bool match( T const& item ) const override { - return m_predicate(item); - } - - std::string describe() const override { - return m_description; - } -}; - -} // namespace Generic - - // The following functions create the actual matcher objects. - // The user has to explicitly specify type to the function, because - // inferring std::function<bool(T const&)> is hard (but possible) and - // requires a lot of TMP. - template<typename T> - Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") { - return Generic::PredicateMatcher<T>(predicate, description); - } - -} // namespace Matchers -} // namespace Catch - -// end catch_matchers_generic.hpp -// start catch_matchers_string.h - -#include <string> - -namespace Catch { -namespace Matchers { - - namespace StdString { - - struct CasedString - { - CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); - std::string adjustString( std::string const& str ) const; - std::string caseSensitivitySuffix() const; - - CaseSensitive::Choice m_caseSensitivity; - std::string m_str; - }; - - struct StringMatcherBase : MatcherBase<std::string> { - StringMatcherBase( std::string const& operation, CasedString const& comparator ); - std::string describe() const override; - - CasedString m_comparator; - std::string m_operation; - }; - - struct EqualsMatcher : StringMatcherBase { - EqualsMatcher( CasedString const& comparator ); - bool match( std::string const& source ) const override; - }; - struct ContainsMatcher : StringMatcherBase { - ContainsMatcher( CasedString const& comparator ); - bool match( std::string const& source ) const override; - }; - struct StartsWithMatcher : StringMatcherBase { - StartsWithMatcher( CasedString const& comparator ); - bool match( std::string const& source ) const override; - }; - struct EndsWithMatcher : StringMatcherBase { - EndsWithMatcher( CasedString const& comparator ); - bool match( std::string const& source ) const override; - }; - - struct RegexMatcher : MatcherBase<std::string> { - RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity ); - bool match( std::string const& matchee ) const override; - std::string describe() const override; - - private: - std::string m_regex; - CaseSensitive::Choice m_caseSensitivity; - }; - - } // namespace StdString - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - - StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - -} // namespace Matchers -} // namespace Catch - -// end catch_matchers_string.h -// start catch_matchers_vector.h - -#include <algorithm> - -namespace Catch { -namespace Matchers { - - namespace Vector { - template<typename T> - struct ContainsElementMatcher : MatcherBase<std::vector<T>> { - - ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} - - bool match(std::vector<T> const &v) const override { - for (auto const& el : v) { - if (el == m_comparator) { - return true; - } - } - return false; - } - - std::string describe() const override { - return "Contains: " + ::Catch::Detail::stringify( m_comparator ); - } - - T const& m_comparator; - }; - - template<typename T> - struct ContainsMatcher : MatcherBase<std::vector<T>> { - - ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} - - bool match(std::vector<T> const &v) const override { - // !TBD: see note in EqualsMatcher - if (m_comparator.size() > v.size()) - return false; - for (auto const& comparator : m_comparator) { - auto present = false; - for (const auto& el : v) { - if (el == comparator) { - present = true; - break; - } - } - if (!present) { - return false; - } - } - return true; - } - std::string describe() const override { - return "Contains: " + ::Catch::Detail::stringify( m_comparator ); - } - - std::vector<T> const& m_comparator; - }; - - template<typename T> - struct EqualsMatcher : MatcherBase<std::vector<T>> { - - EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} - - bool match(std::vector<T> const &v) const override { - // !TBD: This currently works if all elements can be compared using != - // - a more general approach would be via a compare template that defaults - // to using !=. but could be specialised for, e.g. std::vector<T> etc - // - then just call that directly - if (m_comparator.size() != v.size()) - return false; - for (std::size_t i = 0; i < v.size(); ++i) - if (m_comparator[i] != v[i]) - return false; - return true; - } - std::string describe() const override { - return "Equals: " + ::Catch::Detail::stringify( m_comparator ); - } - std::vector<T> const& m_comparator; - }; - - template<typename T> - struct ApproxMatcher : MatcherBase<std::vector<T>> { - - ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {} - - bool match(std::vector<T> const &v) const override { - if (m_comparator.size() != v.size()) - return false; - for (std::size_t i = 0; i < v.size(); ++i) - if (m_comparator[i] != approx(v[i])) - return false; - return true; - } - std::string describe() const override { - return "is approx: " + ::Catch::Detail::stringify( m_comparator ); - } - template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - ApproxMatcher& epsilon( T const& newEpsilon ) { - approx.epsilon(newEpsilon); - return *this; - } - template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - ApproxMatcher& margin( T const& newMargin ) { - approx.margin(newMargin); - return *this; - } - template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> - ApproxMatcher& scale( T const& newScale ) { - approx.scale(newScale); - return *this; - } - - std::vector<T> const& m_comparator; - mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom(); - }; - - template<typename T> - struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> { - UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {} - bool match(std::vector<T> const& vec) const override { - // Note: This is a reimplementation of std::is_permutation, - // because I don't want to include <algorithm> inside the common path - if (m_target.size() != vec.size()) { - return false; - } - return std::is_permutation(m_target.begin(), m_target.end(), vec.begin()); - } - - std::string describe() const override { - return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); - } - private: - std::vector<T> const& m_target; - }; - - } // namespace Vector - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - - template<typename T> - Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) { - return Vector::ContainsMatcher<T>( comparator ); - } - - template<typename T> - Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) { - return Vector::ContainsElementMatcher<T>( comparator ); - } - - template<typename T> - Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) { - return Vector::EqualsMatcher<T>( comparator ); - } - - template<typename T> - Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) { - return Vector::ApproxMatcher<T>( comparator ); - } - - template<typename T> - Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) { - return Vector::UnorderedEqualsMatcher<T>(target); - } - -} // namespace Matchers -} // namespace Catch - -// end catch_matchers_vector.h -namespace Catch { - - template<typename ArgT, typename MatcherT> - class MatchExpr : public ITransientExpression { - ArgT const& m_arg; - MatcherT m_matcher; - StringRef m_matcherString; - public: - MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) - : ITransientExpression{ true, matcher.match( arg ) }, - m_arg( arg ), - m_matcher( matcher ), - m_matcherString( matcherString ) - {} - - void streamReconstructedExpression( std::ostream &os ) const override { - auto matcherAsString = m_matcher.toString(); - os << Catch::Detail::stringify( m_arg ) << ' '; - if( matcherAsString == Detail::unprintableString ) - os << m_matcherString; - else - os << matcherAsString; - } - }; - - using StringMatcher = Matchers::Impl::MatcherBase<std::string>; - - void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ); - - template<typename ArgT, typename MatcherT> - auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> { - return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString ); - } - -} // namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ - INTERNAL_CATCH_TRY { \ - catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \ - } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ - do { \ - Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ - if( catchAssertionHandler.allowThrows() ) \ - try { \ - static_cast<void>(__VA_ARGS__ ); \ - catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ - } \ - catch( exceptionType const& ex ) { \ - catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \ - } \ - catch( ... ) { \ - catchAssertionHandler.handleUnexpectedInflightException(); \ - } \ - else \ - catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ - } while( false ) - -// end catch_capture_matchers.h -#endif -// start catch_generators.hpp - -// start catch_interfaces_generatortracker.h - - -#include <memory> - -namespace Catch { - - namespace Generators { - class GeneratorUntypedBase { - public: - GeneratorUntypedBase() = default; - virtual ~GeneratorUntypedBase(); - // Attempts to move the generator to the next element - // - // Returns true iff the move succeeded (and a valid element - // can be retrieved). - virtual bool next() = 0; - }; - using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>; - - } // namespace Generators - - struct IGeneratorTracker { - virtual ~IGeneratorTracker(); - virtual auto hasGenerator() const -> bool = 0; - virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0; - virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0; - }; - -} // namespace Catch - -// end catch_interfaces_generatortracker.h -// start catch_enforce.h - -#include <exception> - -namespace Catch { -#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - template <typename Ex> - [[noreturn]] - void throw_exception(Ex const& e) { - throw e; - } -#else // ^^ Exceptions are enabled // Exceptions are disabled vv - [[noreturn]] - void throw_exception(std::exception const& e); -#endif - - [[noreturn]] - void throw_logic_error(std::string const& msg); - [[noreturn]] - void throw_domain_error(std::string const& msg); - [[noreturn]] - void throw_runtime_error(std::string const& msg); - -} // namespace Catch; - -#define CATCH_MAKE_MSG(...) \ - (Catch::ReusableStringStream() << __VA_ARGS__).str() - -#define CATCH_INTERNAL_ERROR(...) \ - Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__)); - -#define CATCH_ERROR(...) \ - Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ )); - -#define CATCH_RUNTIME_ERROR(...) \ - Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ )); - -#define CATCH_ENFORCE( condition, ... ) \ - do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false) - -// end catch_enforce.h -#include <memory> -#include <vector> -#include <cassert> - -#include <utility> -#include <exception> - -namespace Catch { - -class GeneratorException : public std::exception { - const char* const m_msg = ""; - -public: - GeneratorException(const char* msg): - m_msg(msg) - {} - - const char* what() const noexcept override final; -}; - -namespace Generators { - - // !TBD move this into its own location? - namespace pf{ - template<typename T, typename... Args> - std::unique_ptr<T> make_unique( Args&&... args ) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - } - } - - template<typename T> - struct IGenerator : GeneratorUntypedBase { - virtual ~IGenerator() = default; - - // Returns the current element of the generator - // - // \Precondition The generator is either freshly constructed, - // or the last call to `next()` returned true - virtual T const& get() const = 0; - using type = T; - }; - - template<typename T> - class SingleValueGenerator final : public IGenerator<T> { - T m_value; - public: - SingleValueGenerator(T const& value) : m_value( value ) {} - SingleValueGenerator(T&& value) : m_value(std::move(value)) {} - - T const& get() const override { - return m_value; - } - bool next() override { - return false; - } - }; - - template<typename T> - class FixedValuesGenerator final : public IGenerator<T> { - std::vector<T> m_values; - size_t m_idx = 0; - public: - FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {} - - T const& get() const override { - return m_values[m_idx]; - } - bool next() override { - ++m_idx; - return m_idx < m_values.size(); - } - }; - - template <typename T> - class GeneratorWrapper final { - std::unique_ptr<IGenerator<T>> m_generator; - public: - GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator): - m_generator(std::move(generator)) - {} - T const& get() const { - return m_generator->get(); - } - bool next() { - return m_generator->next(); - } - }; - - template <typename T> - GeneratorWrapper<T> value(T&& value) { - return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value))); - } - template <typename T> - GeneratorWrapper<T> values(std::initializer_list<T> values) { - return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values)); - } - - template<typename T> - class Generators : public IGenerator<T> { - std::vector<GeneratorWrapper<T>> m_generators; - size_t m_current = 0; - - void populate(GeneratorWrapper<T>&& generator) { - m_generators.emplace_back(std::move(generator)); - } - void populate(T&& val) { - m_generators.emplace_back(value(std::move(val))); - } - template<typename U> - void populate(U&& val) { - populate(T(std::move(val))); - } - template<typename U, typename... Gs> - void populate(U&& valueOrGenerator, Gs... moreGenerators) { - populate(std::forward<U>(valueOrGenerator)); - populate(std::forward<Gs>(moreGenerators)...); - } - - public: - template <typename... Gs> - Generators(Gs... moreGenerators) { - m_generators.reserve(sizeof...(Gs)); - populate(std::forward<Gs>(moreGenerators)...); - } - - T const& get() const override { - return m_generators[m_current].get(); - } - - bool next() override { - if (m_current >= m_generators.size()) { - return false; - } - const bool current_status = m_generators[m_current].next(); - if (!current_status) { - ++m_current; - } - return m_current < m_generators.size(); - } - }; - - template<typename... Ts> - GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) { - return values<std::tuple<Ts...>>( tuples ); - } - - // Tag type to signal that a generator sequence should convert arguments to a specific type - template <typename T> - struct as {}; - - template<typename T, typename... Gs> - auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> { - return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...); - } - template<typename T> - auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> { - return Generators<T>(std::move(generator)); - } - template<typename T, typename... Gs> - auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> { - return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... ); - } - template<typename T, typename U, typename... Gs> - auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> { - return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); - } - - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; - - template<typename L> - // Note: The type after -> is weird, because VS2015 cannot parse - // the expression used in the typedef inside, when it is in - // return type. Yeah. - auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) { - using UnderlyingType = typename decltype(generatorExpression())::type; - - IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); - if (!tracker.hasGenerator()) { - tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression())); - } - - auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() ); - return generator.get(); - } - -} // namespace Generators -} // namespace Catch - -#define GENERATE( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) -#define GENERATE_COPY( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) -#define GENERATE_REF( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) - -// end catch_generators.hpp -// start catch_generators_generic.hpp - -namespace Catch { -namespace Generators { - - template <typename T> - class TakeGenerator : public IGenerator<T> { - GeneratorWrapper<T> m_generator; - size_t m_returned = 0; - size_t m_target; - public: - TakeGenerator(size_t target, GeneratorWrapper<T>&& generator): - m_generator(std::move(generator)), - m_target(target) - { - assert(target != 0 && "Empty generators are not allowed"); - } - T const& get() const override { - return m_generator.get(); - } - bool next() override { - ++m_returned; - if (m_returned >= m_target) { - return false; - } - - const auto success = m_generator.next(); - // If the underlying generator does not contain enough values - // then we cut short as well - if (!success) { - m_returned = m_target; - } - return success; - } - }; - - template <typename T> - GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) { - return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator))); - } - - template <typename T, typename Predicate> - class FilterGenerator : public IGenerator<T> { - GeneratorWrapper<T> m_generator; - Predicate m_predicate; - public: - template <typename P = Predicate> - FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator): - m_generator(std::move(generator)), - m_predicate(std::forward<P>(pred)) - { - if (!m_predicate(m_generator.get())) { - // It might happen that there are no values that pass the - // filter. In that case we throw an exception. - auto has_initial_value = next(); - if (!has_initial_value) { - Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); - } - } - } - - T const& get() const override { - return m_generator.get(); - } - - bool next() override { - bool success = m_generator.next(); - if (!success) { - return false; - } - while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true); - return success; - } - }; - - template <typename T, typename Predicate> - GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) { - return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator)))); - } - - template <typename T> - class RepeatGenerator : public IGenerator<T> { - GeneratorWrapper<T> m_generator; - mutable std::vector<T> m_returned; - size_t m_target_repeats; - size_t m_current_repeat = 0; - size_t m_repeat_index = 0; - public: - RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator): - m_generator(std::move(generator)), - m_target_repeats(repeats) - { - assert(m_target_repeats > 0 && "Repeat generator must repeat at least once"); - } - - T const& get() const override { - if (m_current_repeat == 0) { - m_returned.push_back(m_generator.get()); - return m_returned.back(); - } - return m_returned[m_repeat_index]; - } - - bool next() override { - // There are 2 basic cases: - // 1) We are still reading the generator - // 2) We are reading our own cache - - // In the first case, we need to poke the underlying generator. - // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache - if (m_current_repeat == 0) { - const auto success = m_generator.next(); - if (!success) { - ++m_current_repeat; - } - return m_current_repeat < m_target_repeats; - } - - // In the second case, we need to move indices forward and check that we haven't run up against the end - ++m_repeat_index; - if (m_repeat_index == m_returned.size()) { - m_repeat_index = 0; - ++m_current_repeat; - } - return m_current_repeat < m_target_repeats; - } - }; - - template <typename T> - GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) { - return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator))); - } - - template <typename T, typename U, typename Func> - class MapGenerator : public IGenerator<T> { - // TBD: provide static assert for mapping function, for friendly error message - GeneratorWrapper<U> m_generator; - Func m_function; - // To avoid returning dangling reference, we have to save the values - T m_cache; - public: - template <typename F2 = Func> - MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) : - m_generator(std::move(generator)), - m_function(std::forward<F2>(function)), - m_cache(m_function(m_generator.get())) - {} - - T const& get() const override { - return m_cache; - } - bool next() override { - const auto success = m_generator.next(); - if (success) { - m_cache = m_function(m_generator.get()); - } - return success; - } - }; - -#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. Also *_t format is preferred over - // typename *::type format. - template <typename Func, typename U> - using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>; -#else - template <typename Func, typename U> - using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type; -#endif - - template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>> - GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) { - return GeneratorWrapper<T>( - pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)) - ); - } - - template <typename T, typename U, typename Func> - GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) { - return GeneratorWrapper<T>( - pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)) - ); - } - - template <typename T> - class ChunkGenerator final : public IGenerator<std::vector<T>> { - std::vector<T> m_chunk; - size_t m_chunk_size; - GeneratorWrapper<T> m_generator; - bool m_used_up = false; - public: - ChunkGenerator(size_t size, GeneratorWrapper<T> generator) : - m_chunk_size(size), m_generator(std::move(generator)) - { - m_chunk.reserve(m_chunk_size); - m_chunk.push_back(m_generator.get()); - for (size_t i = 1; i < m_chunk_size; ++i) { - if (!m_generator.next()) { - Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk")); - } - m_chunk.push_back(m_generator.get()); - } - } - std::vector<T> const& get() const override { - return m_chunk; - } - bool next() override { - m_chunk.clear(); - for (size_t idx = 0; idx < m_chunk_size; ++idx) { - if (!m_generator.next()) { - return false; - } - m_chunk.push_back(m_generator.get()); - } - return true; - } - }; - - template <typename T> - GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) { - return GeneratorWrapper<std::vector<T>>( - pf::make_unique<ChunkGenerator<T>>(size, std::move(generator)) - ); - } - -} // namespace Generators -} // namespace Catch - -// end catch_generators_generic.hpp -// start catch_generators_specific.hpp - -// start catch_context.h - -#include <memory> - -namespace Catch { - - struct IResultCapture; - struct IRunner; - struct IConfig; - struct IMutableContext; - - using IConfigPtr = std::shared_ptr<IConfig const>; - - struct IContext - { - virtual ~IContext(); - - virtual IResultCapture* getResultCapture() = 0; - virtual IRunner* getRunner() = 0; - virtual IConfigPtr const& getConfig() const = 0; - }; - - struct IMutableContext : IContext - { - virtual ~IMutableContext(); - virtual void setResultCapture( IResultCapture* resultCapture ) = 0; - virtual void setRunner( IRunner* runner ) = 0; - virtual void setConfig( IConfigPtr const& config ) = 0; - - private: - static IMutableContext *currentContext; - friend IMutableContext& getCurrentMutableContext(); - friend void cleanUpContext(); - static void createContext(); - }; - - inline IMutableContext& getCurrentMutableContext() - { - if( !IMutableContext::currentContext ) - IMutableContext::createContext(); - return *IMutableContext::currentContext; - } - - inline IContext& getCurrentContext() - { - return getCurrentMutableContext(); - } - - void cleanUpContext(); -} - -// end catch_context.h -// start catch_interfaces_config.h - -// start catch_option.hpp - -namespace Catch { - - // An optional type - template<typename T> - class Option { - public: - Option() : nullableValue( nullptr ) {} - Option( T const& _value ) - : nullableValue( new( storage ) T( _value ) ) - {} - Option( Option const& _other ) - : nullableValue( _other ? new( storage ) T( *_other ) : nullptr ) - {} - - ~Option() { - reset(); - } - - Option& operator= ( Option const& _other ) { - if( &_other != this ) { - reset(); - if( _other ) - nullableValue = new( storage ) T( *_other ); - } - return *this; - } - Option& operator = ( T const& _value ) { - reset(); - nullableValue = new( storage ) T( _value ); - return *this; - } - - void reset() { - if( nullableValue ) - nullableValue->~T(); - nullableValue = nullptr; - } - - T& operator*() { return *nullableValue; } - T const& operator*() const { return *nullableValue; } - T* operator->() { return nullableValue; } - const T* operator->() const { return nullableValue; } - - T valueOr( T const& defaultValue ) const { - return nullableValue ? *nullableValue : defaultValue; - } - - bool some() const { return nullableValue != nullptr; } - bool none() const { return nullableValue == nullptr; } - - bool operator !() const { return nullableValue == nullptr; } - explicit operator bool() const { - return some(); - } - - private: - T *nullableValue; - alignas(alignof(T)) char storage[sizeof(T)]; - }; - -} // end namespace Catch - -// end catch_option.hpp -#include <iosfwd> -#include <string> -#include <vector> -#include <memory> - -namespace Catch { - - enum class Verbosity { - Quiet = 0, - Normal, - High - }; - - struct WarnAbout { enum What { - Nothing = 0x00, - NoAssertions = 0x01, - NoTests = 0x02 - }; }; - - struct ShowDurations { enum OrNot { - DefaultForReporter, - Always, - Never - }; }; - struct RunTests { enum InWhatOrder { - InDeclarationOrder, - InLexicographicalOrder, - InRandomOrder - }; }; - struct UseColour { enum YesOrNo { - Auto, - Yes, - No - }; }; - struct WaitForKeypress { enum When { - Never, - BeforeStart = 1, - BeforeExit = 2, - BeforeStartAndExit = BeforeStart | BeforeExit - }; }; - - class TestSpec; - - struct IConfig : NonCopyable { - - virtual ~IConfig(); - - virtual bool allowThrows() const = 0; - virtual std::ostream& stream() const = 0; - virtual std::string name() const = 0; - virtual bool includeSuccessfulResults() const = 0; - virtual bool shouldDebugBreak() const = 0; - virtual bool warnAboutMissingAssertions() const = 0; - virtual bool warnAboutNoTests() const = 0; - virtual int abortAfter() const = 0; - virtual bool showInvisibles() const = 0; - virtual ShowDurations::OrNot showDurations() const = 0; - virtual TestSpec const& testSpec() const = 0; - virtual bool hasTestFilters() const = 0; - virtual std::vector<std::string> const& getTestsOrTags() const = 0; - virtual RunTests::InWhatOrder runOrder() const = 0; - virtual unsigned int rngSeed() const = 0; - virtual UseColour::YesOrNo useColour() const = 0; - virtual std::vector<std::string> const& getSectionsToRun() const = 0; - virtual Verbosity verbosity() const = 0; - - virtual bool benchmarkNoAnalysis() const = 0; - virtual int benchmarkSamples() const = 0; - virtual double benchmarkConfidenceInterval() const = 0; - virtual unsigned int benchmarkResamples() const = 0; - }; - - using IConfigPtr = std::shared_ptr<IConfig const>; -} - -// end catch_interfaces_config.h -#include <random> - -namespace Catch { -namespace Generators { - -template <typename Float> -class RandomFloatingGenerator final : public IGenerator<Float> { - // FIXME: What is the right seed? - std::minstd_rand m_rand; - std::uniform_real_distribution<Float> m_dist; - Float m_current_number; -public: - - RandomFloatingGenerator(Float a, Float b): - m_rand(getCurrentContext().getConfig()->rngSeed()), - m_dist(a, b) { - static_cast<void>(next()); - } - - Float const& get() const override { - return m_current_number; - } - bool next() override { - m_current_number = m_dist(m_rand); - return true; - } -}; - -template <typename Integer> -class RandomIntegerGenerator final : public IGenerator<Integer> { - std::minstd_rand m_rand; - std::uniform_int_distribution<Integer> m_dist; - Integer m_current_number; -public: - - RandomIntegerGenerator(Integer a, Integer b): - m_rand(getCurrentContext().getConfig()->rngSeed()), - m_dist(a, b) { - static_cast<void>(next()); - } - - Integer const& get() const override { - return m_current_number; - } - bool next() override { - m_current_number = m_dist(m_rand); - return true; - } -}; - -// TODO: Ideally this would be also constrained against the various char types, -// but I don't expect users to run into that in practice. -template <typename T> -typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, -GeneratorWrapper<T>>::type -random(T a, T b) { - return GeneratorWrapper<T>( - pf::make_unique<RandomIntegerGenerator<T>>(a, b) - ); -} - -template <typename T> -typename std::enable_if<std::is_floating_point<T>::value, -GeneratorWrapper<T>>::type -random(T a, T b) { - return GeneratorWrapper<T>( - pf::make_unique<RandomFloatingGenerator<T>>(a, b) - ); -} - -template <typename T> -class RangeGenerator final : public IGenerator<T> { - T m_current; - T m_end; - T m_step; - bool m_positive; - -public: - RangeGenerator(T const& start, T const& end, T const& step): - m_current(start), - m_end(end), - m_step(step), - m_positive(m_step > T(0)) - { - assert(m_current != m_end && "Range start and end cannot be equal"); - assert(m_step != T(0) && "Step size cannot be zero"); - assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end"); - } - - RangeGenerator(T const& start, T const& end): - RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) - {} - - T const& get() const override { - return m_current; - } - - bool next() override { - m_current += m_step; - return (m_positive) ? (m_current < m_end) : (m_current > m_end); - } -}; - -template <typename T> -GeneratorWrapper<T> range(T const& start, T const& end, T const& step) { - static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer"); - return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step)); -} - -template <typename T> -GeneratorWrapper<T> range(T const& start, T const& end) { - static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer"); - return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end)); -} - -} // namespace Generators -} // namespace Catch - -// end catch_generators_specific.hpp - -// These files are included here so the single_include script doesn't put them -// in the conditionally compiled sections -// start catch_test_case_info.h - -#include <string> -#include <vector> -#include <memory> - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - struct ITestInvoker; - - struct TestCaseInfo { - enum SpecialProperties{ - None = 0, - IsHidden = 1 << 1, - ShouldFail = 1 << 2, - MayFail = 1 << 3, - Throws = 1 << 4, - NonPortable = 1 << 5, - Benchmark = 1 << 6 - }; - - TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::vector<std::string> const& _tags, - SourceLineInfo const& _lineInfo ); - - friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ); - - bool isHidden() const; - bool throws() const; - bool okToFail() const; - bool expectedToFail() const; - - std::string tagsAsString() const; - - std::string name; - std::string className; - std::string description; - std::vector<std::string> tags; - std::vector<std::string> lcaseTags; - SourceLineInfo lineInfo; - SpecialProperties properties; - }; - - class TestCase : public TestCaseInfo { - public: - - TestCase( ITestInvoker* testCase, TestCaseInfo&& info ); - - TestCase withName( std::string const& _newName ) const; - - void invoke() const; - - TestCaseInfo const& getTestCaseInfo() const; - - bool operator == ( TestCase const& other ) const; - bool operator < ( TestCase const& other ) const; - - private: - std::shared_ptr<ITestInvoker> test; - }; - - TestCase makeTestCase( ITestInvoker* testCase, - std::string const& className, - NameAndTags const& nameAndTags, - SourceLineInfo const& lineInfo ); -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// end catch_test_case_info.h -// start catch_interfaces_runner.h - -namespace Catch { - - struct IRunner { - virtual ~IRunner(); - virtual bool aborting() const = 0; - }; -} - -// end catch_interfaces_runner.h - -#ifdef __OBJC__ -// start catch_objc.hpp - -#import <objc/runtime.h> - -#include <string> - -// NB. Any general catch headers included here must be included -// in catch.hpp first to make sure they are included by the single -// header for non obj-usage - -/////////////////////////////////////////////////////////////////////////////// -// This protocol is really only here for (self) documenting purposes, since -// all its methods are optional. -@protocol OcFixture - -@optional - --(void) setUp; --(void) tearDown; - -@end - -namespace Catch { - - class OcMethod : public ITestInvoker { - - public: - OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} - - virtual void invoke() const { - id obj = [[m_cls alloc] init]; - - performOptionalSelector( obj, @selector(setUp) ); - performOptionalSelector( obj, m_sel ); - performOptionalSelector( obj, @selector(tearDown) ); - - arcSafeRelease( obj ); - } - private: - virtual ~OcMethod() {} - - Class m_cls; - SEL m_sel; - }; - - namespace Detail{ - - inline std::string getAnnotation( Class cls, - std::string const& annotationName, - std::string const& testCaseName ) { - NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; - SEL sel = NSSelectorFromString( selStr ); - arcSafeRelease( selStr ); - id value = performOptionalSelector( cls, sel ); - if( value ) - return [(NSString*)value UTF8String]; - return ""; - } - } - - inline std::size_t registerTestMethods() { - std::size_t noTestMethods = 0; - int noClasses = objc_getClassList( nullptr, 0 ); - - Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); - objc_getClassList( classes, noClasses ); - - for( int c = 0; c < noClasses; c++ ) { - Class cls = classes[c]; - { - u_int count; - Method* methods = class_copyMethodList( cls, &count ); - for( u_int m = 0; m < count ; m++ ) { - SEL selector = method_getName(methods[m]); - std::string methodName = sel_getName(selector); - if( startsWith( methodName, "Catch_TestCase_" ) ) { - std::string testCaseName = methodName.substr( 15 ); - std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); - std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); - const char* className = class_getName( cls ); - - getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) ); - noTestMethods++; - } - } - free(methods); - } - } - return noTestMethods; - } - -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) - - namespace Matchers { - namespace Impl { - namespace NSStringMatchers { - - struct StringHolder : MatcherBase<NSString*>{ - StringHolder( NSString* substr ) : m_substr( [substr copy] ){} - StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} - StringHolder() { - arcSafeRelease( m_substr ); - } - - bool match( NSString* const& str ) const override { - return false; - } - - NSString* CATCH_ARC_STRONG m_substr; - }; - - struct Equals : StringHolder { - Equals( NSString* substr ) : StringHolder( substr ){} - - bool match( NSString* const& str ) const override { - return (str != nil || m_substr == nil ) && - [str isEqualToString:m_substr]; - } - - std::string describe() const override { - return "equals string: " + Catch::Detail::stringify( m_substr ); - } - }; - - struct Contains : StringHolder { - Contains( NSString* substr ) : StringHolder( substr ){} - - bool match( NSString* const& str ) const override { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location != NSNotFound; - } - - std::string describe() const override { - return "contains string: " + Catch::Detail::stringify( m_substr ); - } - }; - - struct StartsWith : StringHolder { - StartsWith( NSString* substr ) : StringHolder( substr ){} - - bool match( NSString* const& str ) const override { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == 0; - } - - std::string describe() const override { - return "starts with: " + Catch::Detail::stringify( m_substr ); - } - }; - struct EndsWith : StringHolder { - EndsWith( NSString* substr ) : StringHolder( substr ){} - - bool match( NSString* const& str ) const override { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == [str length] - [m_substr length]; - } - - std::string describe() const override { - return "ends with: " + Catch::Detail::stringify( m_substr ); - } - }; - - } // namespace NSStringMatchers - } // namespace Impl - - inline Impl::NSStringMatchers::Equals - Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } - - inline Impl::NSStringMatchers::Contains - Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } - - inline Impl::NSStringMatchers::StartsWith - StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } - - inline Impl::NSStringMatchers::EndsWith - EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } - - } // namespace Matchers - - using namespace Matchers; - -#endif // CATCH_CONFIG_DISABLE_MATCHERS - -} // namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix -#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ -+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ -{ \ -return @ name; \ -} \ -+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ -{ \ -return @ desc; \ -} \ --(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) - -#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) - -// end catch_objc.hpp -#endif - -// Benchmarking needs the externally-facing parts of reporters to work -#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING) -// start catch_external_interfaces.h - -// start catch_reporter_bases.hpp - -// start catch_interfaces_reporter.h - -// start catch_config.hpp - -// start catch_test_spec_parser.h - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -// start catch_test_spec.h - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -// start catch_wildcard_pattern.h - -namespace Catch -{ - class WildcardPattern { - enum WildcardPosition { - NoWildcard = 0, - WildcardAtStart = 1, - WildcardAtEnd = 2, - WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd - }; - - public: - - WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ); - virtual ~WildcardPattern() = default; - virtual bool matches( std::string const& str ) const; - - private: - std::string adjustCase( std::string const& str ) const; - CaseSensitive::Choice m_caseSensitivity; - WildcardPosition m_wildcard = NoWildcard; - std::string m_pattern; - }; -} - -// end catch_wildcard_pattern.h -#include <string> -#include <vector> -#include <memory> - -namespace Catch { - - class TestSpec { - struct Pattern { - virtual ~Pattern(); - virtual bool matches( TestCaseInfo const& testCase ) const = 0; - }; - using PatternPtr = std::shared_ptr<Pattern>; - - class NamePattern : public Pattern { - public: - NamePattern( std::string const& name ); - virtual ~NamePattern(); - bool matches( TestCaseInfo const& testCase ) const override; - private: - WildcardPattern m_wildcardPattern; - }; - - class TagPattern : public Pattern { - public: - TagPattern( std::string const& tag ); - virtual ~TagPattern(); - bool matches( TestCaseInfo const& testCase ) const override; - private: - std::string m_tag; - }; - - class ExcludedPattern : public Pattern { - public: - ExcludedPattern( PatternPtr const& underlyingPattern ); - virtual ~ExcludedPattern(); - bool matches( TestCaseInfo const& testCase ) const override; - private: - PatternPtr m_underlyingPattern; - }; - - struct Filter { - std::vector<PatternPtr> m_patterns; - - bool matches( TestCaseInfo const& testCase ) const; - }; - - public: - bool hasFilters() const; - bool matches( TestCaseInfo const& testCase ) const; - - private: - std::vector<Filter> m_filters; - - friend class TestSpecParser; - }; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// end catch_test_spec.h -// start catch_interfaces_tag_alias_registry.h - -#include <string> - -namespace Catch { - - struct TagAlias; - - struct ITagAliasRegistry { - virtual ~ITagAliasRegistry(); - // Nullptr if not present - virtual TagAlias const* find( std::string const& alias ) const = 0; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; - - static ITagAliasRegistry const& get(); - }; - -} // end namespace Catch - -// end catch_interfaces_tag_alias_registry.h -namespace Catch { - - class TestSpecParser { - enum Mode{ None, Name, QuotedName, Tag, EscapedName }; - Mode m_mode = None; - bool m_exclusion = false; - std::size_t m_start = std::string::npos, m_pos = 0; - std::string m_arg; - std::vector<std::size_t> m_escapeChars; - TestSpec::Filter m_currentFilter; - TestSpec m_testSpec; - ITagAliasRegistry const* m_tagAliases = nullptr; - - public: - TestSpecParser( ITagAliasRegistry const& tagAliases ); - - TestSpecParser& parse( std::string const& arg ); - TestSpec testSpec(); - - private: - void visitChar( char c ); - void startNewMode( Mode mode, std::size_t start ); - void escape(); - std::string subString() const; - - template<typename T> - void addPattern() { - std::string token = subString(); - for( std::size_t i = 0; i < m_escapeChars.size(); ++i ) - token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); - m_escapeChars.clear(); - if( startsWith( token, "exclude:" ) ) { - m_exclusion = true; - token = token.substr( 8 ); - } - if( !token.empty() ) { - TestSpec::PatternPtr pattern = std::make_shared<T>( token ); - if( m_exclusion ) - pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern ); - m_currentFilter.m_patterns.push_back( pattern ); - } - m_exclusion = false; - m_mode = None; - } - - void addFilter(); - }; - TestSpec parseTestSpec( std::string const& arg ); - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// end catch_test_spec_parser.h -// Libstdc++ doesn't like incomplete classes for unique_ptr - -#include <memory> -#include <vector> -#include <string> - -#ifndef CATCH_CONFIG_CONSOLE_WIDTH -#define CATCH_CONFIG_CONSOLE_WIDTH 80 -#endif - -namespace Catch { - - struct IStream; - - struct ConfigData { - bool listTests = false; - bool listTags = false; - bool listReporters = false; - bool listTestNamesOnly = false; - - bool showSuccessfulTests = false; - bool shouldDebugBreak = false; - bool noThrow = false; - bool showHelp = false; - bool showInvisibles = false; - bool filenamesAsTags = false; - bool libIdentify = false; - - int abortAfter = -1; - unsigned int rngSeed = 0; - - bool benchmarkNoAnalysis = false; - unsigned int benchmarkSamples = 100; - double benchmarkConfidenceInterval = 0.95; - unsigned int benchmarkResamples = 100000; - - Verbosity verbosity = Verbosity::Normal; - WarnAbout::What warnings = WarnAbout::Nothing; - ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; - RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; - UseColour::YesOrNo useColour = UseColour::Auto; - WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; - - std::string outputFilename; - std::string name; - std::string processName; -#ifndef CATCH_CONFIG_DEFAULT_REPORTER -#define CATCH_CONFIG_DEFAULT_REPORTER "console" -#endif - std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER; -#undef CATCH_CONFIG_DEFAULT_REPORTER - - std::vector<std::string> testsOrTags; - std::vector<std::string> sectionsToRun; - }; - - class Config : public IConfig { - public: - - Config() = default; - Config( ConfigData const& data ); - virtual ~Config() = default; - - std::string const& getFilename() const; - - bool listTests() const; - bool listTestNamesOnly() const; - bool listTags() const; - bool listReporters() const; - - std::string getProcessName() const; - std::string const& getReporterName() const; - - std::vector<std::string> const& getTestsOrTags() const override; - std::vector<std::string> const& getSectionsToRun() const override; - - TestSpec const& testSpec() const override; - bool hasTestFilters() const override; - - bool showHelp() const; - - // IConfig interface - bool allowThrows() const override; - std::ostream& stream() const override; - std::string name() const override; - bool includeSuccessfulResults() const override; - bool warnAboutMissingAssertions() const override; - bool warnAboutNoTests() const override; - ShowDurations::OrNot showDurations() const override; - RunTests::InWhatOrder runOrder() const override; - unsigned int rngSeed() const override; - UseColour::YesOrNo useColour() const override; - bool shouldDebugBreak() const override; - int abortAfter() const override; - bool showInvisibles() const override; - Verbosity verbosity() const override; - bool benchmarkNoAnalysis() const override; - int benchmarkSamples() const override; - double benchmarkConfidenceInterval() const override; - unsigned int benchmarkResamples() const override; - - private: - - IStream const* openStream(); - ConfigData m_data; - - std::unique_ptr<IStream const> m_stream; - TestSpec m_testSpec; - bool m_hasTestFilters = false; - }; - -} // end namespace Catch - -// end catch_config.hpp -// start catch_assertionresult.h - -#include <string> - -namespace Catch { - - struct AssertionResultData - { - AssertionResultData() = delete; - - AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ); - - std::string message; - mutable std::string reconstructedExpression; - LazyExpression lazyExpression; - ResultWas::OfType resultType; - - std::string reconstructExpression() const; - }; - - class AssertionResult { - public: - AssertionResult() = delete; - AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); - - bool isOk() const; - bool succeeded() const; - ResultWas::OfType getResultType() const; - bool hasExpression() const; - bool hasMessage() const; - std::string getExpression() const; - std::string getExpressionInMacro() const; - bool hasExpandedExpression() const; - std::string getExpandedExpression() const; - std::string getMessage() const; - SourceLineInfo getSourceInfo() const; - StringRef getTestMacroName() const; - - //protected: - AssertionInfo m_info; - AssertionResultData m_resultData; - }; - -} // end namespace Catch - -// end catch_assertionresult.h -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) -// start catch_estimate.hpp - - // Statistics estimates - - -namespace Catch { - namespace Benchmark { - template <typename Duration> - struct Estimate { - Duration point; - Duration lower_bound; - Duration upper_bound; - double confidence_interval; - - template <typename Duration2> - operator Estimate<Duration2>() const { - return { point, lower_bound, upper_bound, confidence_interval }; - } - }; - } // namespace Benchmark -} // namespace Catch - -// end catch_estimate.hpp -// start catch_outlier_classification.hpp - -// Outlier information - -namespace Catch { - namespace Benchmark { - struct OutlierClassification { - int samples_seen = 0; - int low_severe = 0; // more than 3 times IQR below Q1 - int low_mild = 0; // 1.5 to 3 times IQR below Q1 - int high_mild = 0; // 1.5 to 3 times IQR above Q3 - int high_severe = 0; // more than 3 times IQR above Q3 - - int total() const { - return low_severe + low_mild + high_mild + high_severe; - } - }; - } // namespace Benchmark -} // namespace Catch - -// end catch_outlier_classification.hpp -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - -#include <string> -#include <iosfwd> -#include <map> -#include <set> -#include <memory> -#include <algorithm> - -namespace Catch { - - struct ReporterConfig { - explicit ReporterConfig( IConfigPtr const& _fullConfig ); - - ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ); - - std::ostream& stream() const; - IConfigPtr fullConfig() const; - - private: - std::ostream* m_stream; - IConfigPtr m_fullConfig; - }; - - struct ReporterPreferences { - bool shouldRedirectStdOut = false; - bool shouldReportAllAssertions = false; - }; - - template<typename T> - struct LazyStat : Option<T> { - LazyStat& operator=( T const& _value ) { - Option<T>::operator=( _value ); - used = false; - return *this; - } - void reset() { - Option<T>::reset(); - used = false; - } - bool used = false; - }; - - struct TestRunInfo { - TestRunInfo( std::string const& _name ); - std::string name; - }; - struct GroupInfo { - GroupInfo( std::string const& _name, - std::size_t _groupIndex, - std::size_t _groupsCount ); - - std::string name; - std::size_t groupIndex; - std::size_t groupsCounts; - }; - - struct AssertionStats { - AssertionStats( AssertionResult const& _assertionResult, - std::vector<MessageInfo> const& _infoMessages, - Totals const& _totals ); - - AssertionStats( AssertionStats const& ) = default; - AssertionStats( AssertionStats && ) = default; - AssertionStats& operator = ( AssertionStats const& ) = delete; - AssertionStats& operator = ( AssertionStats && ) = delete; - virtual ~AssertionStats(); - - AssertionResult assertionResult; - std::vector<MessageInfo> infoMessages; - Totals totals; - }; - - struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, - Counts const& _assertions, - double _durationInSeconds, - bool _missingAssertions ); - SectionStats( SectionStats const& ) = default; - SectionStats( SectionStats && ) = default; - SectionStats& operator = ( SectionStats const& ) = default; - SectionStats& operator = ( SectionStats && ) = default; - virtual ~SectionStats(); - - SectionInfo sectionInfo; - Counts assertions; - double durationInSeconds; - bool missingAssertions; - }; - - struct TestCaseStats { - TestCaseStats( TestCaseInfo const& _testInfo, - Totals const& _totals, - std::string const& _stdOut, - std::string const& _stdErr, - bool _aborting ); - - TestCaseStats( TestCaseStats const& ) = default; - TestCaseStats( TestCaseStats && ) = default; - TestCaseStats& operator = ( TestCaseStats const& ) = default; - TestCaseStats& operator = ( TestCaseStats && ) = default; - virtual ~TestCaseStats(); - - TestCaseInfo testInfo; - Totals totals; - std::string stdOut; - std::string stdErr; - bool aborting; - }; - - struct TestGroupStats { - TestGroupStats( GroupInfo const& _groupInfo, - Totals const& _totals, - bool _aborting ); - TestGroupStats( GroupInfo const& _groupInfo ); - - TestGroupStats( TestGroupStats const& ) = default; - TestGroupStats( TestGroupStats && ) = default; - TestGroupStats& operator = ( TestGroupStats const& ) = default; - TestGroupStats& operator = ( TestGroupStats && ) = default; - virtual ~TestGroupStats(); - - GroupInfo groupInfo; - Totals totals; - bool aborting; - }; - - struct TestRunStats { - TestRunStats( TestRunInfo const& _runInfo, - Totals const& _totals, - bool _aborting ); - - TestRunStats( TestRunStats const& ) = default; - TestRunStats( TestRunStats && ) = default; - TestRunStats& operator = ( TestRunStats const& ) = default; - TestRunStats& operator = ( TestRunStats && ) = default; - virtual ~TestRunStats(); - - TestRunInfo runInfo; - Totals totals; - bool aborting; - }; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - struct BenchmarkInfo { - std::string name; - double estimatedDuration; - int iterations; - int samples; - unsigned int resamples; - double clockResolution; - double clockCost; - }; - - template <class Duration> - struct BenchmarkStats { - BenchmarkInfo info; - - std::vector<Duration> samples; - Benchmark::Estimate<Duration> mean; - Benchmark::Estimate<Duration> standardDeviation; - Benchmark::OutlierClassification outliers; - double outlierVariance; - - template <typename Duration2> - operator BenchmarkStats<Duration2>() const { - std::vector<Duration2> samples2; - samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); }); - return { - info, - std::move(samples2), - mean, - standardDeviation, - outliers, - outlierVariance, - }; - } - }; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - struct IStreamingReporter { - virtual ~IStreamingReporter() = default; - - // Implementing class must also provide the following static methods: - // static std::string getDescription(); - // static std::set<Verbosity> getSupportedVerbosities() - - virtual ReporterPreferences getPreferences() const = 0; - - virtual void noMatchingTestCases( std::string const& spec ) = 0; - - virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; - virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; - virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - virtual void benchmarkPreparing( std::string const& ) {} - virtual void benchmarkStarting( BenchmarkInfo const& ) {} - virtual void benchmarkEnded( BenchmarkStats<> const& ) {} - virtual void benchmarkFailed( std::string const& ) {} -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; - - // The return value indicates if the messages buffer should be cleared: - virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; - - virtual void sectionEnded( SectionStats const& sectionStats ) = 0; - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; - virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; - - virtual void skipTest( TestCaseInfo const& testInfo ) = 0; - - // Default empty implementation provided - virtual void fatalErrorEncountered( StringRef name ); - - virtual bool isMulti() const; - }; - using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>; - - struct IReporterFactory { - virtual ~IReporterFactory(); - virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0; - virtual std::string getDescription() const = 0; - }; - using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; - - struct IReporterRegistry { - using FactoryMap = std::map<std::string, IReporterFactoryPtr>; - using Listeners = std::vector<IReporterFactoryPtr>; - - virtual ~IReporterRegistry(); - virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0; - virtual FactoryMap const& getFactories() const = 0; - virtual Listeners const& getListeners() const = 0; - }; - -} // end namespace Catch - -// end catch_interfaces_reporter.h -#include <algorithm> -#include <cstring> -#include <cfloat> -#include <cstdio> -#include <cassert> -#include <memory> -#include <ostream> - -namespace Catch { - void prepareExpandedExpression(AssertionResult& result); - - // Returns double formatted as %.3f (format expected on output) - std::string getFormattedDuration( double duration ); - - std::string serializeFilters( std::vector<std::string> const& container ); - - template<typename DerivedT> - struct StreamingReporterBase : IStreamingReporter { - - StreamingReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - { - m_reporterPrefs.shouldRedirectStdOut = false; - if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) - CATCH_ERROR( "Verbosity level not supported by this reporter" ); - } - - ReporterPreferences getPreferences() const override { - return m_reporterPrefs; - } - - static std::set<Verbosity> getSupportedVerbosities() { - return { Verbosity::Normal }; - } - - ~StreamingReporterBase() override = default; - - void noMatchingTestCases(std::string const&) override {} - - void testRunStarting(TestRunInfo const& _testRunInfo) override { - currentTestRunInfo = _testRunInfo; - } - - void testGroupStarting(GroupInfo const& _groupInfo) override { - currentGroupInfo = _groupInfo; - } - - void testCaseStarting(TestCaseInfo const& _testInfo) override { - currentTestCaseInfo = _testInfo; - } - void sectionStarting(SectionInfo const& _sectionInfo) override { - m_sectionStack.push_back(_sectionInfo); - } - - void sectionEnded(SectionStats const& /* _sectionStats */) override { - m_sectionStack.pop_back(); - } - void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override { - currentTestCaseInfo.reset(); - } - void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override { - currentGroupInfo.reset(); - } - void testRunEnded(TestRunStats const& /* _testRunStats */) override { - currentTestCaseInfo.reset(); - currentGroupInfo.reset(); - currentTestRunInfo.reset(); - } - - void skipTest(TestCaseInfo const&) override { - // Don't do anything with this by default. - // It can optionally be overridden in the derived class. - } - - IConfigPtr m_config; - std::ostream& stream; - - LazyStat<TestRunInfo> currentTestRunInfo; - LazyStat<GroupInfo> currentGroupInfo; - LazyStat<TestCaseInfo> currentTestCaseInfo; - - std::vector<SectionInfo> m_sectionStack; - ReporterPreferences m_reporterPrefs; - }; - - template<typename DerivedT> - struct CumulativeReporterBase : IStreamingReporter { - template<typename T, typename ChildNodeT> - struct Node { - explicit Node( T const& _value ) : value( _value ) {} - virtual ~Node() {} - - using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>; - T value; - ChildNodes children; - }; - struct SectionNode { - explicit SectionNode(SectionStats const& _stats) : stats(_stats) {} - virtual ~SectionNode() = default; - - bool operator == (SectionNode const& other) const { - return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; - } - bool operator == (std::shared_ptr<SectionNode> const& other) const { - return operator==(*other); - } - - SectionStats stats; - using ChildSections = std::vector<std::shared_ptr<SectionNode>>; - using Assertions = std::vector<AssertionStats>; - ChildSections childSections; - Assertions assertions; - std::string stdOut; - std::string stdErr; - }; - - struct BySectionInfo { - BySectionInfo( SectionInfo const& other ) : m_other( other ) {} - BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} - bool operator() (std::shared_ptr<SectionNode> const& node) const { - return ((node->stats.sectionInfo.name == m_other.name) && - (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); - } - void operator=(BySectionInfo const&) = delete; - - private: - SectionInfo const& m_other; - }; - - using TestCaseNode = Node<TestCaseStats, SectionNode>; - using TestGroupNode = Node<TestGroupStats, TestCaseNode>; - using TestRunNode = Node<TestRunStats, TestGroupNode>; - - CumulativeReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - { - m_reporterPrefs.shouldRedirectStdOut = false; - if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) - CATCH_ERROR( "Verbosity level not supported by this reporter" ); - } - ~CumulativeReporterBase() override = default; - - ReporterPreferences getPreferences() const override { - return m_reporterPrefs; - } - - static std::set<Verbosity> getSupportedVerbosities() { - return { Verbosity::Normal }; - } - - void testRunStarting( TestRunInfo const& ) override {} - void testGroupStarting( GroupInfo const& ) override {} - - void testCaseStarting( TestCaseInfo const& ) override {} - - void sectionStarting( SectionInfo const& sectionInfo ) override { - SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); - std::shared_ptr<SectionNode> node; - if( m_sectionStack.empty() ) { - if( !m_rootSection ) - m_rootSection = std::make_shared<SectionNode>( incompleteStats ); - node = m_rootSection; - } - else { - SectionNode& parentNode = *m_sectionStack.back(); - auto it = - std::find_if( parentNode.childSections.begin(), - parentNode.childSections.end(), - BySectionInfo( sectionInfo ) ); - if( it == parentNode.childSections.end() ) { - node = std::make_shared<SectionNode>( incompleteStats ); - parentNode.childSections.push_back( node ); - } - else - node = *it; - } - m_sectionStack.push_back( node ); - m_deepestSection = std::move(node); - } - - void assertionStarting(AssertionInfo const&) override {} - - bool assertionEnded(AssertionStats const& assertionStats) override { - assert(!m_sectionStack.empty()); - // AssertionResult holds a pointer to a temporary DecomposedExpression, - // which getExpandedExpression() calls to build the expression string. - // Our section stack copy of the assertionResult will likely outlive the - // temporary, so it must be expanded or discarded now to avoid calling - // a destroyed object later. - prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) ); - SectionNode& sectionNode = *m_sectionStack.back(); - sectionNode.assertions.push_back(assertionStats); - return true; - } - void sectionEnded(SectionStats const& sectionStats) override { - assert(!m_sectionStack.empty()); - SectionNode& node = *m_sectionStack.back(); - node.stats = sectionStats; - m_sectionStack.pop_back(); - } - void testCaseEnded(TestCaseStats const& testCaseStats) override { - auto node = std::make_shared<TestCaseNode>(testCaseStats); - assert(m_sectionStack.size() == 0); - node->children.push_back(m_rootSection); - m_testCases.push_back(node); - m_rootSection.reset(); - - assert(m_deepestSection); - m_deepestSection->stdOut = testCaseStats.stdOut; - m_deepestSection->stdErr = testCaseStats.stdErr; - } - void testGroupEnded(TestGroupStats const& testGroupStats) override { - auto node = std::make_shared<TestGroupNode>(testGroupStats); - node->children.swap(m_testCases); - m_testGroups.push_back(node); - } - void testRunEnded(TestRunStats const& testRunStats) override { - auto node = std::make_shared<TestRunNode>(testRunStats); - node->children.swap(m_testGroups); - m_testRuns.push_back(node); - testRunEndedCumulative(); - } - virtual void testRunEndedCumulative() = 0; - - void skipTest(TestCaseInfo const&) override {} - - IConfigPtr m_config; - std::ostream& stream; - std::vector<AssertionStats> m_assertions; - std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections; - std::vector<std::shared_ptr<TestCaseNode>> m_testCases; - std::vector<std::shared_ptr<TestGroupNode>> m_testGroups; - - std::vector<std::shared_ptr<TestRunNode>> m_testRuns; - - std::shared_ptr<SectionNode> m_rootSection; - std::shared_ptr<SectionNode> m_deepestSection; - std::vector<std::shared_ptr<SectionNode>> m_sectionStack; - ReporterPreferences m_reporterPrefs; - }; - - template<char C> - char const* getLineOfChars() { - static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; - if( !*line ) { - std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); - line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; - } - return line; - } - - struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> { - TestEventListenerBase( ReporterConfig const& _config ); - - static std::set<Verbosity> getSupportedVerbosities(); - - void assertionStarting(AssertionInfo const&) override; - bool assertionEnded(AssertionStats const&) override; - }; - -} // end namespace Catch - -// end catch_reporter_bases.hpp -// start catch_console_colour.h - -namespace Catch { - - struct Colour { - enum Code { - None = 0, - - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White, - BrightYellow = Bright | Yellow, - - // By intention - FileName = LightGrey, - Warning = BrightYellow, - ResultError = BrightRed, - ResultSuccess = BrightGreen, - ResultExpectedFailure = Warning, - - Error = BrightRed, - Success = Green, - - OriginalExpression = Cyan, - ReconstructedExpression = BrightYellow, - - SecondaryText = LightGrey, - Headers = White - }; - - // Use constructed object for RAII guard - Colour( Code _colourCode ); - Colour( Colour&& other ) noexcept; - Colour& operator=( Colour&& other ) noexcept; - ~Colour(); - - // Use static method for one-shot changes - static void use( Code _colourCode ); - - private: - bool m_moved = false; - }; - - std::ostream& operator << ( std::ostream& os, Colour const& ); - -} // end namespace Catch - -// end catch_console_colour.h -// start catch_reporter_registrars.hpp - - -namespace Catch { - - template<typename T> - class ReporterRegistrar { - - class ReporterFactory : public IReporterFactory { - - IStreamingReporterPtr create( ReporterConfig const& config ) const override { - return std::unique_ptr<T>( new T( config ) ); - } - - std::string getDescription() const override { - return T::getDescription(); - } - }; - - public: - - explicit ReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() ); - } - }; - - template<typename T> - class ListenerRegistrar { - - class ListenerFactory : public IReporterFactory { - - IStreamingReporterPtr create( ReporterConfig const& config ) const override { - return std::unique_ptr<T>( new T( config ) ); - } - std::string getDescription() const override { - return std::string(); - } - }; - - public: - - ListenerRegistrar() { - getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() ); - } - }; -} - -#if !defined(CATCH_CONFIG_DISABLE) - -#define CATCH_REGISTER_REPORTER( name, reporterType ) \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS - -#define CATCH_REGISTER_LISTENER( listenerType ) \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -#else // CATCH_CONFIG_DISABLE - -#define CATCH_REGISTER_REPORTER(name, reporterType) -#define CATCH_REGISTER_LISTENER(listenerType) - -#endif // CATCH_CONFIG_DISABLE - -// end catch_reporter_registrars.hpp -// Allow users to base their work off existing reporters -// start catch_reporter_compact.h - -namespace Catch { - - struct CompactReporter : StreamingReporterBase<CompactReporter> { - - using StreamingReporterBase::StreamingReporterBase; - - ~CompactReporter() override; - - static std::string getDescription(); - - ReporterPreferences getPreferences() const override; - - void noMatchingTestCases(std::string const& spec) override; - - void assertionStarting(AssertionInfo const&) override; - - bool assertionEnded(AssertionStats const& _assertionStats) override; - - void sectionEnded(SectionStats const& _sectionStats) override; - - void testRunEnded(TestRunStats const& _testRunStats) override; - - }; - -} // end namespace Catch - -// end catch_reporter_compact.h -// start catch_reporter_console.h - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch - // Note that 4062 (not all labels are handled - // and default is missing) is enabled -#endif - -namespace Catch { - // Fwd decls - struct SummaryColumn; - class TablePrinter; - - struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> { - std::unique_ptr<TablePrinter> m_tablePrinter; - - ConsoleReporter(ReporterConfig const& config); - ~ConsoleReporter() override; - static std::string getDescription(); - - void noMatchingTestCases(std::string const& spec) override; - - void assertionStarting(AssertionInfo const&) override; - - bool assertionEnded(AssertionStats const& _assertionStats) override; - - void sectionStarting(SectionInfo const& _sectionInfo) override; - void sectionEnded(SectionStats const& _sectionStats) override; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void benchmarkPreparing(std::string const& name) override; - void benchmarkStarting(BenchmarkInfo const& info) override; - void benchmarkEnded(BenchmarkStats<> const& stats) override; - void benchmarkFailed(std::string const& error) override; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - void testCaseEnded(TestCaseStats const& _testCaseStats) override; - void testGroupEnded(TestGroupStats const& _testGroupStats) override; - void testRunEnded(TestRunStats const& _testRunStats) override; - void testRunStarting(TestRunInfo const& _testRunInfo) override; - private: - - void lazyPrint(); - - void lazyPrintWithoutClosingBenchmarkTable(); - void lazyPrintRunInfo(); - void lazyPrintGroupInfo(); - void printTestCaseAndSectionHeader(); - - void printClosedHeader(std::string const& _name); - void printOpenHeader(std::string const& _name); - - // if string has a : in first line will set indent to follow it on - // subsequent lines - void printHeaderString(std::string const& _string, std::size_t indent = 0); - - void printTotals(Totals const& totals); - void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row); - - void printTotalsDivider(Totals const& totals); - void printSummaryDivider(); - void printTestFilters(); - - private: - bool m_headerPrinted = false; - }; - -} // end namespace Catch - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -// end catch_reporter_console.h -// start catch_reporter_junit.h - -// start catch_xmlwriter.h - -#include <vector> - -namespace Catch { - - class XmlEncode { - public: - enum ForWhat { ForTextNodes, ForAttributes }; - - XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); - - void encodeTo( std::ostream& os ) const; - - friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); - - private: - std::string m_str; - ForWhat m_forWhat; - }; - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ); - - ScopedElement( ScopedElement&& other ) noexcept; - ScopedElement& operator=( ScopedElement&& other ) noexcept; - - ~ScopedElement(); - - ScopedElement& writeText( std::string const& text, bool indent = true ); - - template<typename T> - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer = nullptr; - }; - - XmlWriter( std::ostream& os = Catch::cout() ); - ~XmlWriter(); - - XmlWriter( XmlWriter const& ) = delete; - XmlWriter& operator=( XmlWriter const& ) = delete; - - XmlWriter& startElement( std::string const& name ); - - ScopedElement scopedElement( std::string const& name ); - - XmlWriter& endElement(); - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); - - XmlWriter& writeAttribute( std::string const& name, bool attribute ); - - template<typename T> - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - ReusableStringStream rss; - rss << attribute; - return writeAttribute( name, rss.str() ); - } - - XmlWriter& writeText( std::string const& text, bool indent = true ); - - XmlWriter& writeComment( std::string const& text ); - - void writeStylesheetRef( std::string const& url ); - - XmlWriter& writeBlankLine(); - - void ensureTagClosed(); - - private: - - void writeDeclaration(); - - void newlineIfNecessary(); - - bool m_tagIsOpen = false; - bool m_needsNewline = false; - std::vector<std::string> m_tags; - std::string m_indent; - std::ostream& m_os; - }; - -} - -// end catch_xmlwriter.h -namespace Catch { - - class JunitReporter : public CumulativeReporterBase<JunitReporter> { - public: - JunitReporter(ReporterConfig const& _config); - - ~JunitReporter() override; - - static std::string getDescription(); - - void noMatchingTestCases(std::string const& /*spec*/) override; - - void testRunStarting(TestRunInfo const& runInfo) override; - - void testGroupStarting(GroupInfo const& groupInfo) override; - - void testCaseStarting(TestCaseInfo const& testCaseInfo) override; - bool assertionEnded(AssertionStats const& assertionStats) override; - - void testCaseEnded(TestCaseStats const& testCaseStats) override; - - void testGroupEnded(TestGroupStats const& testGroupStats) override; - - void testRunEndedCumulative() override; - - void writeGroup(TestGroupNode const& groupNode, double suiteTime); - - void writeTestCase(TestCaseNode const& testCaseNode); - - void writeSection(std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode); - - void writeAssertions(SectionNode const& sectionNode); - void writeAssertion(AssertionStats const& stats); - - XmlWriter xml; - Timer suiteTimer; - std::string stdOutForSuite; - std::string stdErrForSuite; - unsigned int unexpectedExceptions = 0; - bool m_okToFail = false; - }; - -} // end namespace Catch - -// end catch_reporter_junit.h -// start catch_reporter_xml.h - -namespace Catch { - class XmlReporter : public StreamingReporterBase<XmlReporter> { - public: - XmlReporter(ReporterConfig const& _config); - - ~XmlReporter() override; - - static std::string getDescription(); - - virtual std::string getStylesheetRef() const; - - void writeSourceInfo(SourceLineInfo const& sourceInfo); - - public: // StreamingReporterBase - - void noMatchingTestCases(std::string const& s) override; - - void testRunStarting(TestRunInfo const& testInfo) override; - - void testGroupStarting(GroupInfo const& groupInfo) override; - - void testCaseStarting(TestCaseInfo const& testInfo) override; - - void sectionStarting(SectionInfo const& sectionInfo) override; - - void assertionStarting(AssertionInfo const&) override; - - bool assertionEnded(AssertionStats const& assertionStats) override; - - void sectionEnded(SectionStats const& sectionStats) override; - - void testCaseEnded(TestCaseStats const& testCaseStats) override; - - void testGroupEnded(TestGroupStats const& testGroupStats) override; - - void testRunEnded(TestRunStats const& testRunStats) override; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void benchmarkStarting(BenchmarkInfo const&) override; - void benchmarkEnded(BenchmarkStats<> const&) override; - void benchmarkFailed(std::string const&) override; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - private: - Timer m_testCaseTimer; - XmlWriter m_xml; - int m_sectionDepth = 0; - }; - -} // end namespace Catch - -// end catch_reporter_xml.h - -// end catch_external_interfaces.h -#endif - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) -// start catch_benchmark.hpp - - // Benchmark - -// start catch_chronometer.hpp - -// User-facing chronometer - - -// start catch_clock.hpp - -// Clocks - - -#include <chrono> -#include <ratio> - -namespace Catch { - namespace Benchmark { - template <typename Clock> - using ClockDuration = typename Clock::duration; - template <typename Clock> - using FloatDuration = std::chrono::duration<double, typename Clock::period>; - - template <typename Clock> - using TimePoint = typename Clock::time_point; - - using default_clock = std::chrono::steady_clock; - - template <typename Clock> - struct now { - TimePoint<Clock> operator()() const { - return Clock::now(); - } - }; - - using fp_seconds = std::chrono::duration<double, std::ratio<1>>; - } // namespace Benchmark -} // namespace Catch - -// end catch_clock.hpp -// start catch_optimizer.hpp - - // Hinting the optimizer - - -#if defined(_MSC_VER) -# include <atomic> // atomic_thread_fence -#endif - -namespace Catch { - namespace Benchmark { -#if defined(__GNUC__) || defined(__clang__) - template <typename T> - inline void keep_memory(T* p) { - asm volatile("" : : "g"(p) : "memory"); - } - inline void keep_memory() { - asm volatile("" : : : "memory"); - } - - namespace Detail { - inline void optimizer_barrier() { keep_memory(); } - } // namespace Detail -#elif defined(_MSC_VER) - -#pragma optimize("", off) - template <typename T> - inline void keep_memory(T* p) { - // thanks @milleniumbug - *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p); - } - // TODO equivalent keep_memory() -#pragma optimize("", on) - - namespace Detail { - inline void optimizer_barrier() { - std::atomic_thread_fence(std::memory_order_seq_cst); - } - } // namespace Detail - -#endif - - template <typename T> - inline void deoptimize_value(T&& x) { - keep_memory(&x); - } - - template <typename Fn, typename... Args> - inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type { - deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...))); - } - - template <typename Fn, typename... Args> - inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type { - std::forward<Fn>(fn) (std::forward<Args...>(args...)); - } - } // namespace Benchmark -} // namespace Catch - -// end catch_optimizer.hpp -// start catch_complete_invoke.hpp - -// Invoke with a special case for void - - -#include <type_traits> -#include <utility> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename T> - struct CompleteType { using type = T; }; - template <> - struct CompleteType<void> { struct type {}; }; - - template <typename T> - using CompleteType_t = typename CompleteType<T>::type; - - template <typename Result> - struct CompleteInvoker { - template <typename Fun, typename... Args> - static Result invoke(Fun&& fun, Args&&... args) { - return std::forward<Fun>(fun)(std::forward<Args>(args)...); - } - }; - template <> - struct CompleteInvoker<void> { - template <typename Fun, typename... Args> - static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) { - std::forward<Fun>(fun)(std::forward<Args>(args)...); - return {}; - } - }; - template <typename Sig> - using ResultOf_t = typename std::result_of<Sig>::type; - - // invoke and not return void :( - template <typename Fun, typename... Args> - CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) { - return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...); - } - - const std::string benchmarkErrorMsg = "a benchmark failed to run successfully"; - } // namespace Detail - - template <typename Fun> - Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) { - CATCH_TRY{ - return Detail::complete_invoke(std::forward<Fun>(fun)); - } CATCH_CATCH_ALL{ - getResultCapture().benchmarkFailed(translateActiveException()); - CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg); - } - } - } // namespace Benchmark -} // namespace Catch - -// end catch_complete_invoke.hpp -namespace Catch { - namespace Benchmark { - namespace Detail { - struct ChronometerConcept { - virtual void start() = 0; - virtual void finish() = 0; - virtual ~ChronometerConcept() = default; - }; - template <typename Clock> - struct ChronometerModel final : public ChronometerConcept { - void start() override { started = Clock::now(); } - void finish() override { finished = Clock::now(); } - - ClockDuration<Clock> elapsed() const { return finished - started; } - - TimePoint<Clock> started; - TimePoint<Clock> finished; - }; - } // namespace Detail - - struct Chronometer { - public: - template <typename Fun> - void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); } - - int runs() const { return k; } - - Chronometer(Detail::ChronometerConcept& meter, int k) - : impl(&meter) - , k(k) {} - - private: - template <typename Fun> - void measure(Fun&& fun, std::false_type) { - measure([&fun](int) { return fun(); }, std::true_type()); - } - - template <typename Fun> - void measure(Fun&& fun, std::true_type) { - Detail::optimizer_barrier(); - impl->start(); - for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i); - impl->finish(); - Detail::optimizer_barrier(); - } - - Detail::ChronometerConcept* impl; - int k; - }; - } // namespace Benchmark -} // namespace Catch - -// end catch_chronometer.hpp -// start catch_environment.hpp - -// Environment information - - -namespace Catch { - namespace Benchmark { - template <typename Duration> - struct EnvironmentEstimate { - Duration mean; - OutlierClassification outliers; - - template <typename Duration2> - operator EnvironmentEstimate<Duration2>() const { - return { mean, outliers }; - } - }; - template <typename Clock> - struct Environment { - using clock_type = Clock; - EnvironmentEstimate<FloatDuration<Clock>> clock_resolution; - EnvironmentEstimate<FloatDuration<Clock>> clock_cost; - }; - } // namespace Benchmark -} // namespace Catch - -// end catch_environment.hpp -// start catch_execution_plan.hpp - - // Execution plan - - -// start catch_benchmark_function.hpp - - // Dumb std::function implementation for consistent call overhead - - -#include <cassert> -#include <type_traits> -#include <utility> -#include <memory> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename T> - using Decay = typename std::decay<T>::type; - template <typename T, typename U> - struct is_related - : std::is_same<Decay<T>, Decay<U>> {}; - - /// We need to reinvent std::function because every piece of code that might add overhead - /// in a measurement context needs to have consistent performance characteristics so that we - /// can account for it in the measurement. - /// Implementations of std::function with optimizations that aren't always applicable, like - /// small buffer optimizations, are not uncommon. - /// This is effectively an implementation of std::function without any such optimizations; - /// it may be slow, but it is consistently slow. - struct BenchmarkFunction { - private: - struct callable { - virtual void call(Chronometer meter) const = 0; - virtual callable* clone() const = 0; - virtual ~callable() = default; - }; - template <typename Fun> - struct model : public callable { - model(Fun&& fun) : fun(std::move(fun)) {} - model(Fun const& fun) : fun(fun) {} - - model<Fun>* clone() const override { return new model<Fun>(*this); } - - void call(Chronometer meter) const override { - call(meter, is_callable<Fun(Chronometer)>()); - } - void call(Chronometer meter, std::true_type) const { - fun(meter); - } - void call(Chronometer meter, std::false_type) const { - meter.measure(fun); - } - - Fun fun; - }; - - struct do_nothing { void operator()() const {} }; - - template <typename T> - BenchmarkFunction(model<T>* c) : f(c) {} - - public: - BenchmarkFunction() - : f(new model<do_nothing>{ {} }) {} - - template <typename Fun, - typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0> - BenchmarkFunction(Fun&& fun) - : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {} - - BenchmarkFunction(BenchmarkFunction&& that) - : f(std::move(that.f)) {} - - BenchmarkFunction(BenchmarkFunction const& that) - : f(that.f->clone()) {} - - BenchmarkFunction& operator=(BenchmarkFunction&& that) { - f = std::move(that.f); - return *this; - } - - BenchmarkFunction& operator=(BenchmarkFunction const& that) { - f.reset(that.f->clone()); - return *this; - } - - void operator()(Chronometer meter) const { f->call(meter); } - - private: - std::unique_ptr<callable> f; - }; - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_benchmark_function.hpp -// start catch_repeat.hpp - -// repeat algorithm - - -#include <type_traits> -#include <utility> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename Fun> - struct repeater { - void operator()(int k) const { - for (int i = 0; i < k; ++i) { - fun(); - } - } - Fun fun; - }; - template <typename Fun> - repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) { - return { std::forward<Fun>(fun) }; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_repeat.hpp -// start catch_run_for_at_least.hpp - -// Run a function for a minimum amount of time - - -// start catch_measure.hpp - -// Measure - - -// start catch_timing.hpp - -// Timing - - -#include <tuple> -#include <type_traits> - -namespace Catch { - namespace Benchmark { - template <typename Duration, typename Result> - struct Timing { - Duration elapsed; - Result result; - int iterations; - }; - template <typename Clock, typename Sig> - using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>; - } // namespace Benchmark -} // namespace Catch - -// end catch_timing.hpp -#include <utility> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename Clock, typename Fun, typename... Args> - TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) { - auto start = Clock::now(); - auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...); - auto end = Clock::now(); - auto delta = end - start; - return { delta, std::forward<decltype(r)>(r), 1 }; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_measure.hpp -#include <utility> -#include <type_traits> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename Clock, typename Fun> - TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) { - return Detail::measure<Clock>(fun, iters); - } - template <typename Clock, typename Fun> - TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) { - Detail::ChronometerModel<Clock> meter; - auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); - - return { meter.elapsed(), std::move(result), iters }; - } - - template <typename Clock, typename Fun> - using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type; - - struct optimized_away_error : std::exception { - const char* what() const noexcept override { - return "could not measure benchmark, maybe it was optimized away"; - } - }; - - template <typename Clock, typename Fun> - TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) { - auto iters = seed; - while (iters < (1 << 30)) { - auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>()); - - if (Timing.elapsed >= how_long) { - return { Timing.elapsed, std::move(Timing.result), iters }; - } - iters *= 2; - } - throw optimized_away_error{}; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_run_for_at_least.hpp -#include <algorithm> - -namespace Catch { - namespace Benchmark { - template <typename Duration> - struct ExecutionPlan { - int iterations_per_sample; - Duration estimated_duration; - Detail::BenchmarkFunction benchmark; - Duration warmup_time; - int warmup_iterations; - - template <typename Duration2> - operator ExecutionPlan<Duration2>() const { - return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations }; - } - - template <typename Clock> - std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { - // warmup a bit - Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{})); - - std::vector<FloatDuration<Clock>> times; - times.reserve(cfg.benchmarkSamples()); - std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] { - Detail::ChronometerModel<Clock> model; - this->benchmark(Chronometer(model, iterations_per_sample)); - auto sample_time = model.elapsed() - env.clock_cost.mean; - if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero(); - return sample_time / iterations_per_sample; - }); - return times; - } - }; - } // namespace Benchmark -} // namespace Catch - -// end catch_execution_plan.hpp -// start catch_estimate_clock.hpp - - // Environment measurement - - -// start catch_stats.hpp - -// Statistical analysis tools - - -#include <algorithm> -#include <functional> -#include <vector> -#include <numeric> -#include <tuple> -#include <cmath> -#include <utility> -#include <cstddef> - -namespace Catch { - namespace Benchmark { - namespace Detail { - using sample = std::vector<double>; - - double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last); - - template <typename Iterator> - OutlierClassification classify_outliers(Iterator first, Iterator last) { - std::vector<double> copy(first, last); - - auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end()); - auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end()); - auto iqr = q3 - q1; - auto los = q1 - (iqr * 3.); - auto lom = q1 - (iqr * 1.5); - auto him = q3 + (iqr * 1.5); - auto his = q3 + (iqr * 3.); - - OutlierClassification o; - for (; first != last; ++first) { - auto&& t = *first; - if (t < los) ++o.low_severe; - else if (t < lom) ++o.low_mild; - else if (t > his) ++o.high_severe; - else if (t > him) ++o.high_mild; - ++o.samples_seen; - } - return o; - } - - template <typename Iterator> - double mean(Iterator first, Iterator last) { - auto count = last - first; - double sum = std::accumulate(first, last, 0.); - return sum / count; - } - - template <typename URng, typename Iterator, typename Estimator> - sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) { - auto n = last - first; - std::uniform_int_distribution<decltype(n)> dist(0, n - 1); - - sample out; - out.reserve(resamples); - std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] { - std::vector<double> resampled; - resampled.reserve(n); - std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; }); - return estimator(resampled.begin(), resampled.end()); - }); - std::sort(out.begin(), out.end()); - return out; - } - - template <typename Estimator, typename Iterator> - sample jackknife(Estimator&& estimator, Iterator first, Iterator last) { - auto n = last - first; - auto second = std::next(first); - sample results; - results.reserve(n); - - for (auto it = first; it != last; ++it) { - std::iter_swap(it, first); - results.push_back(estimator(second, last)); - } - - return results; - } - - inline double normal_cdf(double x) { - return std::erfc(-x / std::sqrt(2.0)) / 2.0; - } - - double erfc_inv(double x); - - double normal_quantile(double p); - - template <typename Iterator, typename Estimator> - Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) { - auto n_samples = last - first; - - double point = estimator(first, last); - // Degenerate case with a single sample - if (n_samples == 1) return { point, point, point, confidence_level }; - - sample jack = jackknife(estimator, first, last); - double jack_mean = mean(jack.begin(), jack.end()); - double sum_squares, sum_cubes; - std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> { - auto d = jack_mean - x; - auto d2 = d * d; - auto d3 = d2 * d; - return { sqcb.first + d2, sqcb.second + d3 }; - }); - - double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5)); - int n = static_cast<int>(resample.size()); - double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n; - // degenerate case with uniform samples - if (prob_n == 0) return { point, point, point, confidence_level }; - - double bias = normal_quantile(prob_n); - double z1 = normal_quantile((1. - confidence_level) / 2.); - - auto cumn = [n](double x) -> int { - return std::lround(normal_cdf(x) * n); }; - auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); }; - double b1 = bias + z1; - double b2 = bias - z1; - double a1 = a(b1); - double a2 = a(b2); - auto lo = std::max(cumn(a1), 0); - auto hi = std::min(cumn(a2), n - 1); - - return { point, resample[lo], resample[hi], confidence_level }; - } - - double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n); - - struct bootstrap_analysis { - Estimate<double> mean; - Estimate<double> standard_deviation; - double outlier_variance; - }; - - bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last); - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_stats.hpp -#include <algorithm> -#include <iterator> -#include <tuple> -#include <vector> -#include <cmath> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename Clock> - std::vector<double> resolution(int k) { - std::vector<TimePoint<Clock>> times; - times.reserve(k + 1); - std::generate_n(std::back_inserter(times), k + 1, now<Clock>{}); - - std::vector<double> deltas; - deltas.reserve(k); - std::transform(std::next(times.begin()), times.end(), times.begin(), - std::back_inserter(deltas), - [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); }); - - return deltas; - } - - const auto warmup_iterations = 10000; - const auto warmup_time = std::chrono::milliseconds(100); - const auto minimum_ticks = 1000; - const auto warmup_seed = 10000; - const auto clock_resolution_estimation_time = std::chrono::milliseconds(500); - const auto clock_cost_estimation_time_limit = std::chrono::seconds(1); - const auto clock_cost_estimation_tick_limit = 100000; - const auto clock_cost_estimation_time = std::chrono::milliseconds(10); - const auto clock_cost_estimation_iterations = 10000; - - template <typename Clock> - int warmup() { - return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>) - .iterations; - } - template <typename Clock> - EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) { - auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>) - .result; - return { - FloatDuration<Clock>(mean(r.begin(), r.end())), - classify_outliers(r.begin(), r.end()), - }; - } - template <typename Clock> - EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) { - auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit)); - auto time_clock = [](int k) { - return Detail::measure<Clock>([k] { - for (int i = 0; i < k; ++i) { - volatile auto ignored = Clock::now(); - (void)ignored; - } - }).elapsed; - }; - time_clock(1); - int iters = clock_cost_estimation_iterations; - auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock); - std::vector<double> times; - int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed)); - times.reserve(nsamples); - std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] { - return static_cast<double>((time_clock(r.iterations) / r.iterations).count()); - }); - return { - FloatDuration<Clock>(mean(times.begin(), times.end())), - classify_outliers(times.begin(), times.end()), - }; - } - - template <typename Clock> - Environment<FloatDuration<Clock>> measure_environment() { - static Environment<FloatDuration<Clock>>* env = nullptr; - if (env) { - return *env; - } - - auto iters = Detail::warmup<Clock>(); - auto resolution = Detail::estimate_clock_resolution<Clock>(iters); - auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean); - - env = new Environment<FloatDuration<Clock>>{ resolution, cost }; - return *env; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_estimate_clock.hpp -// start catch_analyse.hpp - - // Run and analyse one benchmark - - -// start catch_sample_analysis.hpp - -// Benchmark results - - -#include <algorithm> -#include <vector> -#include <string> -#include <iterator> - -namespace Catch { - namespace Benchmark { - template <typename Duration> - struct SampleAnalysis { - std::vector<Duration> samples; - Estimate<Duration> mean; - Estimate<Duration> standard_deviation; - OutlierClassification outliers; - double outlier_variance; - - template <typename Duration2> - operator SampleAnalysis<Duration2>() const { - std::vector<Duration2> samples2; - samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); }); - return { - std::move(samples2), - mean, - standard_deviation, - outliers, - outlier_variance, - }; - } - }; - } // namespace Benchmark -} // namespace Catch - -// end catch_sample_analysis.hpp -#include <algorithm> -#include <iterator> -#include <vector> - -namespace Catch { - namespace Benchmark { - namespace Detail { - template <typename Duration, typename Iterator> - SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) { - if (!cfg.benchmarkNoAnalysis()) { - std::vector<double> samples; - samples.reserve(last - first); - std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); }); - - auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end()); - auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end()); - - auto wrap_estimate = [](Estimate<double> e) { - return Estimate<Duration> { - Duration(e.point), - Duration(e.lower_bound), - Duration(e.upper_bound), - e.confidence_interval, - }; - }; - std::vector<Duration> samples2; - samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); }); - return { - std::move(samples2), - wrap_estimate(analysis.mean), - wrap_estimate(analysis.standard_deviation), - outliers, - analysis.outlier_variance, - }; - } else { - std::vector<Duration> samples; - samples.reserve(last - first); - - Duration mean = Duration(0); - int i = 0; - for (auto it = first; it < last; ++it, ++i) { - samples.push_back(Duration(*it)); - mean += Duration(*it); - } - mean /= i; - - return { - std::move(samples), - Estimate<Duration>{mean, mean, mean, 0.0}, - Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0}, - OutlierClassification{}, - 0.0 - }; - } - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -// end catch_analyse.hpp -#include <algorithm> -#include <functional> -#include <string> -#include <vector> -#include <cmath> - -namespace Catch { - namespace Benchmark { - struct Benchmark { - Benchmark(std::string &&name) - : name(std::move(name)) {} - - template <class FUN> - Benchmark(std::string &&name, FUN &&func) - : fun(std::move(func)), name(std::move(name)) {} - - template <typename Clock> - ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { - auto min_time = env.clock_resolution.mean * Detail::minimum_ticks; - auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time)); - auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun); - int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); - return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations }; - } - - template <typename Clock = default_clock> - void run() { - IConfigPtr cfg = getCurrentContext().getConfig(); - - auto env = Detail::measure_environment<Clock>(); - - getResultCapture().benchmarkPreparing(name); - CATCH_TRY{ - auto plan = user_code([&] { - return prepare<Clock>(*cfg, env); - }); - - BenchmarkInfo info { - name, - plan.estimated_duration.count(), - plan.iterations_per_sample, - cfg->benchmarkSamples(), - cfg->benchmarkResamples(), - env.clock_resolution.mean.count(), - env.clock_cost.mean.count() - }; - - getResultCapture().benchmarkStarting(info); - - auto samples = user_code([&] { - return plan.template run<Clock>(*cfg, env); - }); - - auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); - BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; - getResultCapture().benchmarkEnded(stats); - - } CATCH_CATCH_ALL{ - if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow. - std::rethrow_exception(std::current_exception()); - } - } - - // sets lambda to be used in fun *and* executes benchmark! - template <typename Fun, - typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0> - Benchmark & operator=(Fun func) { - fun = Detail::BenchmarkFunction(func); - run(); - return *this; - } - - explicit operator bool() { - return true; - } - - private: - Detail::BenchmarkFunction fun; - std::string name; - }; - } -} // namespace Catch - -#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1 -#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2 - -#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\ - if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \ - BenchmarkName = [&](int benchmarkIndex) - -#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\ - if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \ - BenchmarkName = [&] - -// end catch_benchmark.hpp -#endif - -#endif // ! CATCH_CONFIG_IMPL_ONLY - -#ifdef CATCH_IMPL -// start catch_impl.hpp - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -// Keep these here for external reporters -// start catch_test_case_tracker.h - -#include <string> -#include <vector> -#include <memory> - -namespace Catch { -namespace TestCaseTracking { - - struct NameAndLocation { - std::string name; - SourceLineInfo location; - - NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); - }; - - struct ITracker; - - using ITrackerPtr = std::shared_ptr<ITracker>; - - struct ITracker { - virtual ~ITracker(); - - // static queries - virtual NameAndLocation const& nameAndLocation() const = 0; - - // dynamic queries - virtual bool isComplete() const = 0; // Successfully completed or failed - virtual bool isSuccessfullyCompleted() const = 0; - virtual bool isOpen() const = 0; // Started but not complete - virtual bool hasChildren() const = 0; - - virtual ITracker& parent() = 0; - - // actions - virtual void close() = 0; // Successfully complete - virtual void fail() = 0; - virtual void markAsNeedingAnotherRun() = 0; - - virtual void addChild( ITrackerPtr const& child ) = 0; - virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; - virtual void openChild() = 0; - - // Debug/ checking - virtual bool isSectionTracker() const = 0; - virtual bool isGeneratorTracker() const = 0; - }; - - class TrackerContext { - - enum RunState { - NotStarted, - Executing, - CompletedCycle - }; - - ITrackerPtr m_rootTracker; - ITracker* m_currentTracker = nullptr; - RunState m_runState = NotStarted; - - public: - - ITracker& startRun(); - void endRun(); - - void startCycle(); - void completeCycle(); - - bool completedCycle() const; - ITracker& currentTracker(); - void setCurrentTracker( ITracker* tracker ); - }; - - class TrackerBase : public ITracker { - protected: - enum CycleState { - NotStarted, - Executing, - ExecutingChildren, - NeedsAnotherRun, - CompletedSuccessfully, - Failed - }; - - using Children = std::vector<ITrackerPtr>; - NameAndLocation m_nameAndLocation; - TrackerContext& m_ctx; - ITracker* m_parent; - Children m_children; - CycleState m_runState = NotStarted; - - public: - TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); - - NameAndLocation const& nameAndLocation() const override; - bool isComplete() const override; - bool isSuccessfullyCompleted() const override; - bool isOpen() const override; - bool hasChildren() const override; - - void addChild( ITrackerPtr const& child ) override; - - ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; - ITracker& parent() override; - - void openChild() override; - - bool isSectionTracker() const override; - bool isGeneratorTracker() const override; - - void open(); - - void close() override; - void fail() override; - void markAsNeedingAnotherRun() override; - - private: - void moveToParent(); - void moveToThis(); - }; - - class SectionTracker : public TrackerBase { - std::vector<std::string> m_filters; - public: - SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); - - bool isSectionTracker() const override; - - bool isComplete() const override; - - static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); - - void tryOpen(); - - void addInitialFilters( std::vector<std::string> const& filters ); - void addNextFilters( std::vector<std::string> const& filters ); - }; - -} // namespace TestCaseTracking - -using TestCaseTracking::ITracker; -using TestCaseTracking::TrackerContext; -using TestCaseTracking::SectionTracker; - -} // namespace Catch - -// end catch_test_case_tracker.h - -// start catch_leak_detector.h - -namespace Catch { - - struct LeakDetector { - LeakDetector(); - ~LeakDetector(); - }; - -} -// end catch_leak_detector.h -// Cpp files will be included in the single-header file here -// start catch_stats.cpp - -// Statistical analysis tools - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - -#include <cassert> -#include <random> - -#if defined(CATCH_CONFIG_USE_ASYNC) -#include <future> -#endif - -namespace { - double erf_inv(double x) { - // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2 - double w, p; - - w = -log((1.0 - x) * (1.0 + x)); - - if (w < 6.250000) { - w = w - 3.125000; - p = -3.6444120640178196996e-21; - p = -1.685059138182016589e-19 + p * w; - p = 1.2858480715256400167e-18 + p * w; - p = 1.115787767802518096e-17 + p * w; - p = -1.333171662854620906e-16 + p * w; - p = 2.0972767875968561637e-17 + p * w; - p = 6.6376381343583238325e-15 + p * w; - p = -4.0545662729752068639e-14 + p * w; - p = -8.1519341976054721522e-14 + p * w; - p = 2.6335093153082322977e-12 + p * w; - p = -1.2975133253453532498e-11 + p * w; - p = -5.4154120542946279317e-11 + p * w; - p = 1.051212273321532285e-09 + p * w; - p = -4.1126339803469836976e-09 + p * w; - p = -2.9070369957882005086e-08 + p * w; - p = 4.2347877827932403518e-07 + p * w; - p = -1.3654692000834678645e-06 + p * w; - p = -1.3882523362786468719e-05 + p * w; - p = 0.0001867342080340571352 + p * w; - p = -0.00074070253416626697512 + p * w; - p = -0.0060336708714301490533 + p * w; - p = 0.24015818242558961693 + p * w; - p = 1.6536545626831027356 + p * w; - } else if (w < 16.000000) { - w = sqrt(w) - 3.250000; - p = 2.2137376921775787049e-09; - p = 9.0756561938885390979e-08 + p * w; - p = -2.7517406297064545428e-07 + p * w; - p = 1.8239629214389227755e-08 + p * w; - p = 1.5027403968909827627e-06 + p * w; - p = -4.013867526981545969e-06 + p * w; - p = 2.9234449089955446044e-06 + p * w; - p = 1.2475304481671778723e-05 + p * w; - p = -4.7318229009055733981e-05 + p * w; - p = 6.8284851459573175448e-05 + p * w; - p = 2.4031110387097893999e-05 + p * w; - p = -0.0003550375203628474796 + p * w; - p = 0.00095328937973738049703 + p * w; - p = -0.0016882755560235047313 + p * w; - p = 0.0024914420961078508066 + p * w; - p = -0.0037512085075692412107 + p * w; - p = 0.005370914553590063617 + p * w; - p = 1.0052589676941592334 + p * w; - p = 3.0838856104922207635 + p * w; - } else { - w = sqrt(w) - 5.000000; - p = -2.7109920616438573243e-11; - p = -2.5556418169965252055e-10 + p * w; - p = 1.5076572693500548083e-09 + p * w; - p = -3.7894654401267369937e-09 + p * w; - p = 7.6157012080783393804e-09 + p * w; - p = -1.4960026627149240478e-08 + p * w; - p = 2.9147953450901080826e-08 + p * w; - p = -6.7711997758452339498e-08 + p * w; - p = 2.2900482228026654717e-07 + p * w; - p = -9.9298272942317002539e-07 + p * w; - p = 4.5260625972231537039e-06 + p * w; - p = -1.9681778105531670567e-05 + p * w; - p = 7.5995277030017761139e-05 + p * w; - p = -0.00021503011930044477347 + p * w; - p = -0.00013871931833623122026 + p * w; - p = 1.0103004648645343977 + p * w; - p = 4.8499064014085844221 + p * w; - } - return p * x; - } - - double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) { - auto m = Catch::Benchmark::Detail::mean(first, last); - double variance = std::accumulate(first, last, 0., [m](double a, double b) { - double diff = b - m; - return a + diff * diff; - }) / (last - first); - return std::sqrt(variance); - } - -} - -namespace Catch { - namespace Benchmark { - namespace Detail { - - double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) { - auto count = last - first; - double idx = (count - 1) * k / static_cast<double>(q); - int j = static_cast<int>(idx); - double g = idx - j; - std::nth_element(first, first + j, last); - auto xj = first[j]; - if (g == 0) return xj; - - auto xj1 = *std::min_element(first + (j + 1), last); - return xj + g * (xj1 - xj); - } - - double erfc_inv(double x) { - return erf_inv(1.0 - x); - } - - double normal_quantile(double p) { - static const double ROOT_TWO = std::sqrt(2.0); - - double result = 0.0; - assert(p >= 0 && p <= 1); - if (p < 0 || p > 1) { - return result; - } - - result = -erfc_inv(2.0 * p); - // result *= normal distribution standard deviation (1.0) * sqrt(2) - result *= /*sd * */ ROOT_TWO; - // result += normal disttribution mean (0) - return result; - } - - double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) { - double sb = stddev.point; - double mn = mean.point / n; - double mg_min = mn / 2.; - double sg = std::min(mg_min / 4., sb / std::sqrt(n)); - double sg2 = sg * sg; - double sb2 = sb * sb; - - auto c_max = [n, mn, sb2, sg2](double x) -> double { - double k = mn - x; - double d = k * k; - double nd = n * d; - double k0 = -n * nd; - double k1 = sb2 - n * sg2 + nd; - double det = k1 * k1 - 4 * sg2 * k0; - return (int)(-2. * k0 / (k1 + std::sqrt(det))); - }; - - auto var_out = [n, sb2, sg2](double c) { - double nc = n - c; - return (nc / n) * (sb2 - nc * sg2); - }; - - return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2; - } - - bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) { - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS - static std::random_device entropy; - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS - - auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++ - - auto mean = &Detail::mean<std::vector<double>::iterator>; - auto stddev = &standard_deviation; - -#if defined(CATCH_CONFIG_USE_ASYNC) - auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) { - auto seed = entropy(); - return std::async(std::launch::async, [=] { - std::mt19937 rng(seed); - auto resampled = resample(rng, n_resamples, first, last, f); - return bootstrap(confidence_level, first, last, resampled, f); - }); - }; - - auto mean_future = Estimate(mean); - auto stddev_future = Estimate(stddev); - - auto mean_estimate = mean_future.get(); - auto stddev_estimate = stddev_future.get(); -#else - auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) { - auto seed = entropy(); - std::mt19937 rng(seed); - auto resampled = resample(rng, n_resamples, first, last, f); - return bootstrap(confidence_level, first, last, resampled, f); - }; - - auto mean_estimate = Estimate(mean); - auto stddev_estimate = Estimate(stddev); -#endif // CATCH_USE_ASYNC - - double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n); - - return { mean_estimate, stddev_estimate, outlier_variance }; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING -// end catch_stats.cpp -// start catch_approx.cpp - -#include <cmath> -#include <limits> - -namespace { - -// Performs equivalent check of std::fabs(lhs - rhs) <= margin -// But without the subtraction to allow for INFINITY in comparison -bool marginComparison(double lhs, double rhs, double margin) { - return (lhs + margin >= rhs) && (rhs + margin >= lhs); -} - -} - -namespace Catch { -namespace Detail { - - Approx::Approx ( double value ) - : m_epsilon( std::numeric_limits<float>::epsilon()*100 ), - m_margin( 0.0 ), - m_scale( 0.0 ), - m_value( value ) - {} - - Approx Approx::custom() { - return Approx( 0 ); - } - - Approx Approx::operator-() const { - auto temp(*this); - temp.m_value = -temp.m_value; - return temp; - } - - std::string Approx::toString() const { - ReusableStringStream rss; - rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )"; - return rss.str(); - } - - bool Approx::equalityComparisonImpl(const double other) const { - // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value - // Thanks to Richard Harris for his help refining the scaled margin value - return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value))); - } - - void Approx::setMargin(double newMargin) { - CATCH_ENFORCE(newMargin >= 0, - "Invalid Approx::margin: " << newMargin << '.' - << " Approx::Margin has to be non-negative."); - m_margin = newMargin; - } - - void Approx::setEpsilon(double newEpsilon) { - CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0, - "Invalid Approx::epsilon: " << newEpsilon << '.' - << " Approx::epsilon has to be in [0, 1]"); - m_epsilon = newEpsilon; - } - -} // end namespace Detail - -namespace literals { - Detail::Approx operator "" _a(long double val) { - return Detail::Approx(val); - } - Detail::Approx operator "" _a(unsigned long long val) { - return Detail::Approx(val); - } -} // end namespace literals - -std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) { - return value.toString(); -} - -} // end namespace Catch -// end catch_approx.cpp -// start catch_assertionhandler.cpp - -// start catch_debugger.h - -namespace Catch { - bool isDebuggerActive(); -} - -#ifdef CATCH_PLATFORM_MAC - - #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ - -#elif defined(CATCH_PLATFORM_LINUX) - // If we can use inline assembler, do it because this allows us to break - // directly at the location of the failing check instead of breaking inside - // raise() called from it, i.e. one stack frame below. - #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) - #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ - #else // Fall back to the generic way. - #include <signal.h> - - #define CATCH_TRAP() raise(SIGTRAP) - #endif -#elif defined(_MSC_VER) - #define CATCH_TRAP() __debugbreak() -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) void __stdcall DebugBreak(); - #define CATCH_TRAP() DebugBreak() -#endif - -#ifdef CATCH_TRAP - #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() -#else - #define CATCH_BREAK_INTO_DEBUGGER() []{}() -#endif - -// end catch_debugger.h -// start catch_run_context.h - -// start catch_fatal_condition.h - -// start catch_windows_h_proxy.h - - -#if defined(CATCH_PLATFORM_WINDOWS) - -#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) -# define CATCH_DEFINED_NOMINMAX -# define NOMINMAX -#endif -#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) -# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif - -#ifdef __AFXDLL -#include <AfxWin.h> -#else -#include <windows.h> -#endif - -#ifdef CATCH_DEFINED_NOMINMAX -# undef NOMINMAX -#endif -#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN -# undef WIN32_LEAN_AND_MEAN -#endif - -#endif // defined(CATCH_PLATFORM_WINDOWS) - -// end catch_windows_h_proxy.h -#if defined( CATCH_CONFIG_WINDOWS_SEH ) - -namespace Catch { - - struct FatalConditionHandler { - - static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); - FatalConditionHandler(); - static void reset(); - ~FatalConditionHandler(); - - private: - static bool isSet; - static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; - }; - -} // namespace Catch - -#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) - -#include <signal.h> - -namespace Catch { - - struct FatalConditionHandler { - - static bool isSet; - static struct sigaction oldSigActions[]; - static stack_t oldSigStack; - static char altStackMem[]; - - static void handleSignal( int sig ); - - FatalConditionHandler(); - ~FatalConditionHandler(); - static void reset(); - }; - -} // namespace Catch - -#else - -namespace Catch { - struct FatalConditionHandler { - void reset(); - }; -} - -#endif - -// end catch_fatal_condition.h -#include <string> - -namespace Catch { - - struct IMutableContext; - - /////////////////////////////////////////////////////////////////////////// - - class RunContext : public IResultCapture, public IRunner { - - public: - RunContext( RunContext const& ) = delete; - RunContext& operator =( RunContext const& ) = delete; - - explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter ); - - ~RunContext() override; - - void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ); - void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ); - - Totals runTest(TestCase const& testCase); - - IConfigPtr config() const; - IStreamingReporter& reporter() const; - - public: // IResultCapture - - // Assertion handlers - void handleExpr - ( AssertionInfo const& info, - ITransientExpression const& expr, - AssertionReaction& reaction ) override; - void handleMessage - ( AssertionInfo const& info, - ResultWas::OfType resultType, - StringRef const& message, - AssertionReaction& reaction ) override; - void handleUnexpectedExceptionNotThrown - ( AssertionInfo const& info, - AssertionReaction& reaction ) override; - void handleUnexpectedInflightException - ( AssertionInfo const& info, - std::string const& message, - AssertionReaction& reaction ) override; - void handleIncomplete - ( AssertionInfo const& info ) override; - void handleNonExpr - ( AssertionInfo const &info, - ResultWas::OfType resultType, - AssertionReaction &reaction ) override; - - bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override; - - void sectionEnded( SectionEndInfo const& endInfo ) override; - void sectionEndedEarly( SectionEndInfo const& endInfo ) override; - - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void benchmarkPreparing( std::string const& name ) override; - void benchmarkStarting( BenchmarkInfo const& info ) override; - void benchmarkEnded( BenchmarkStats<> const& stats ) override; - void benchmarkFailed( std::string const& error ) override; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - void pushScopedMessage( MessageInfo const& message ) override; - void popScopedMessage( MessageInfo const& message ) override; - - void emplaceUnscopedMessage( MessageBuilder const& builder ) override; - - std::string getCurrentTestName() const override; - - const AssertionResult* getLastResult() const override; - - void exceptionEarlyReported() override; - - void handleFatalErrorCondition( StringRef message ) override; - - bool lastAssertionPassed() override; - - void assertionPassed() override; - - public: - // !TBD We need to do this another way! - bool aborting() const final; - - private: - - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ); - void invokeActiveTestCase(); - - void resetAssertionInfo(); - bool testForMissingAssertions( Counts& assertions ); - - void assertionEnded( AssertionResult const& result ); - void reportExpr - ( AssertionInfo const &info, - ResultWas::OfType resultType, - ITransientExpression const *expr, - bool negated ); - - void populateReaction( AssertionReaction& reaction ); - - private: - - void handleUnfinishedSections(); - - TestRunInfo m_runInfo; - IMutableContext& m_context; - TestCase const* m_activeTestCase = nullptr; - ITracker* m_testCaseTracker = nullptr; - Option<AssertionResult> m_lastResult; - - IConfigPtr m_config; - Totals m_totals; - IStreamingReporterPtr m_reporter; - std::vector<MessageInfo> m_messages; - std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */ - AssertionInfo m_lastAssertionInfo; - std::vector<SectionEndInfo> m_unfinishedSections; - std::vector<ITracker*> m_activeSections; - TrackerContext m_trackerContext; - bool m_lastAssertionPassed = false; - bool m_shouldReportUnexpected = true; - bool m_includeSuccessfulResults; - }; - -} // end namespace Catch - -// end catch_run_context.h -namespace Catch { - - namespace { - auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { - expr.streamReconstructedExpression( os ); - return os; - } - } - - LazyExpression::LazyExpression( bool isNegated ) - : m_isNegated( isNegated ) - {} - - LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} - - LazyExpression::operator bool() const { - return m_transientExpression != nullptr; - } - - auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { - if( lazyExpr.m_isNegated ) - os << "!"; - - if( lazyExpr ) { - if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) - os << "(" << *lazyExpr.m_transientExpression << ")"; - else - os << *lazyExpr.m_transientExpression; - } - else { - os << "{** error - unchecked empty expression requested **}"; - } - return os; - } - - AssertionHandler::AssertionHandler - ( StringRef const& macroName, - SourceLineInfo const& lineInfo, - StringRef capturedExpression, - ResultDisposition::Flags resultDisposition ) - : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, - m_resultCapture( getResultCapture() ) - {} - - void AssertionHandler::handleExpr( ITransientExpression const& expr ) { - m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); - } - void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) { - m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); - } - - auto AssertionHandler::allowThrows() const -> bool { - return getCurrentContext().getConfig()->allowThrows(); - } - - void AssertionHandler::complete() { - setCompleted(); - if( m_reaction.shouldDebugBreak ) { - - // If you find your debugger stopping you here then go one level up on the - // call-stack for the code that caused it (typically a failed assertion) - - // (To go back to the test and change execution, jump over the throw, next) - CATCH_BREAK_INTO_DEBUGGER(); - } - if (m_reaction.shouldThrow) { -#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - throw Catch::TestFailureException(); -#else - CATCH_ERROR( "Test failure requires aborting test!" ); -#endif - } - } - void AssertionHandler::setCompleted() { - m_completed = true; - } - - void AssertionHandler::handleUnexpectedInflightException() { - m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction ); - } - - void AssertionHandler::handleExceptionThrownAsExpected() { - m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); - } - void AssertionHandler::handleExceptionNotThrownAsExpected() { - m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); - } - - void AssertionHandler::handleUnexpectedExceptionNotThrown() { - m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction ); - } - - void AssertionHandler::handleThrowingCallSkipped() { - m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); - } - - // This is the overload that takes a string and infers the Equals matcher from it - // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp - void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) { - handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); - } - -} // namespace Catch -// end catch_assertionhandler.cpp -// start catch_assertionresult.cpp - -namespace Catch { - AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression): - lazyExpression(_lazyExpression), - resultType(_resultType) {} - - std::string AssertionResultData::reconstructExpression() const { - - if( reconstructedExpression.empty() ) { - if( lazyExpression ) { - ReusableStringStream rss; - rss << lazyExpression; - reconstructedExpression = rss.str(); - } - } - return reconstructedExpression; - } - - AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) - : m_info( info ), - m_resultData( data ) - {} - - // Result was a success - bool AssertionResult::succeeded() const { - return Catch::isOk( m_resultData.resultType ); - } - - // Result was a success, or failure is suppressed - bool AssertionResult::isOk() const { - return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); - } - - ResultWas::OfType AssertionResult::getResultType() const { - return m_resultData.resultType; - } - - bool AssertionResult::hasExpression() const { - return m_info.capturedExpression[0] != 0; - } - - bool AssertionResult::hasMessage() const { - return !m_resultData.message.empty(); - } - - std::string AssertionResult::getExpression() const { - if( isFalseTest( m_info.resultDisposition ) ) - return "!(" + m_info.capturedExpression + ")"; - else - return m_info.capturedExpression; - } - - std::string AssertionResult::getExpressionInMacro() const { - std::string expr; - if( m_info.macroName[0] == 0 ) - expr = m_info.capturedExpression; - else { - expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 ); - expr += m_info.macroName; - expr += "( "; - expr += m_info.capturedExpression; - expr += " )"; - } - return expr; - } - - bool AssertionResult::hasExpandedExpression() const { - return hasExpression() && getExpandedExpression() != getExpression(); - } - - std::string AssertionResult::getExpandedExpression() const { - std::string expr = m_resultData.reconstructExpression(); - return expr.empty() - ? getExpression() - : expr; - } - - std::string AssertionResult::getMessage() const { - return m_resultData.message; - } - SourceLineInfo AssertionResult::getSourceInfo() const { - return m_info.lineInfo; - } - - StringRef AssertionResult::getTestMacroName() const { - return m_info.macroName; - } - -} // end namespace Catch -// end catch_assertionresult.cpp -// start catch_capture_matchers.cpp - -namespace Catch { - - using StringMatcher = Matchers::Impl::MatcherBase<std::string>; - - // This is the general overload that takes a any string matcher - // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers - // the Equals matcher (so the header does not mention matchers) - void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) { - std::string exceptionMessage = Catch::translateActiveException(); - MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString ); - handler.handleExpr( expr ); - } - -} // namespace Catch -// end catch_capture_matchers.cpp -// start catch_commandline.cpp - -// start catch_commandline.h - -// start catch_clara.h - -// Use Catch's value for console width (store Clara's off to the side, if present) -#ifdef CLARA_CONFIG_CONSOLE_WIDTH -#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH -#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH -#endif -#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" -#pragma clang diagnostic ignored "-Wexit-time-destructors" -#pragma clang diagnostic ignored "-Wshadow" -#endif - -// start clara.hpp -// Copyright 2017 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) -// -// See https://github.com/philsquared/Clara for more details - -// Clara v1.1.5 - - -#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH -#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 -#endif - -#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH -#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH -#endif - -#ifndef CLARA_CONFIG_OPTIONAL_TYPE -#ifdef __has_include -#if __has_include(<optional>) && __cplusplus >= 201703L -#include <optional> -#define CLARA_CONFIG_OPTIONAL_TYPE std::optional -#endif -#endif -#endif - -// ----------- #included from clara_textflow.hpp ----------- - -// TextFlowCpp -// -// A single-header library for wrapping and laying out basic text, by Phil Nash -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// This project is hosted at https://github.com/philsquared/textflowcpp - - -#include <cassert> -#include <ostream> -#include <sstream> -#include <vector> - -#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH -#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 -#endif - -namespace Catch { -namespace clara { -namespace TextFlow { - -inline auto isWhitespace(char c) -> bool { - static std::string chars = " \t\n\r"; - return chars.find(c) != std::string::npos; -} -inline auto isBreakableBefore(char c) -> bool { - static std::string chars = "[({<|"; - return chars.find(c) != std::string::npos; -} -inline auto isBreakableAfter(char c) -> bool { - static std::string chars = "])}>.,:;*+-=&/\\"; - return chars.find(c) != std::string::npos; -} - -class Columns; - -class Column { - std::vector<std::string> m_strings; - size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; - size_t m_indent = 0; - size_t m_initialIndent = std::string::npos; - -public: - class iterator { - friend Column; - - Column const& m_column; - size_t m_stringIndex = 0; - size_t m_pos = 0; - - size_t m_len = 0; - size_t m_end = 0; - bool m_suffix = false; - - iterator(Column const& column, size_t stringIndex) - : m_column(column), - m_stringIndex(stringIndex) {} - - auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; } - - auto isBoundary(size_t at) const -> bool { - assert(at > 0); - assert(at <= line().size()); - - return at == line().size() || - (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) || - isBreakableBefore(line()[at]) || - isBreakableAfter(line()[at - 1]); - } - - void calcLength() { - assert(m_stringIndex < m_column.m_strings.size()); - - m_suffix = false; - auto width = m_column.m_width - indent(); - m_end = m_pos; - if (line()[m_pos] == '\n') { - ++m_end; - } - while (m_end < line().size() && line()[m_end] != '\n') - ++m_end; - - if (m_end < m_pos + width) { - m_len = m_end - m_pos; - } else { - size_t len = width; - while (len > 0 && !isBoundary(m_pos + len)) - --len; - while (len > 0 && isWhitespace(line()[m_pos + len - 1])) - --len; - - if (len > 0) { - m_len = len; - } else { - m_suffix = true; - m_len = width - 1; - } - } - } - - auto indent() const -> size_t { - auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; - return initial == std::string::npos ? m_column.m_indent : initial; - } - - auto addIndentAndSuffix(std::string const &plain) const -> std::string { - return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain); - } - - public: - using difference_type = std::ptrdiff_t; - using value_type = std::string; - using pointer = value_type * ; - using reference = value_type & ; - using iterator_category = std::forward_iterator_tag; - - explicit iterator(Column const& column) : m_column(column) { - assert(m_column.m_width > m_column.m_indent); - assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent); - calcLength(); - if (m_len == 0) - m_stringIndex++; // Empty string - } - - auto operator *() const -> std::string { - assert(m_stringIndex < m_column.m_strings.size()); - assert(m_pos <= m_end); - return addIndentAndSuffix(line().substr(m_pos, m_len)); - } - - auto operator ++() -> iterator& { - m_pos += m_len; - if (m_pos < line().size() && line()[m_pos] == '\n') - m_pos += 1; - else - while (m_pos < line().size() && isWhitespace(line()[m_pos])) - ++m_pos; - - if (m_pos == line().size()) { - m_pos = 0; - ++m_stringIndex; - } - if (m_stringIndex < m_column.m_strings.size()) - calcLength(); - return *this; - } - auto operator ++(int) -> iterator { - iterator prev(*this); - operator++(); - return prev; - } - - auto operator ==(iterator const& other) const -> bool { - return - m_pos == other.m_pos && - m_stringIndex == other.m_stringIndex && - &m_column == &other.m_column; - } - auto operator !=(iterator const& other) const -> bool { - return !operator==(other); - } - }; - using const_iterator = iterator; - - explicit Column(std::string const& text) { m_strings.push_back(text); } - - auto width(size_t newWidth) -> Column& { - assert(newWidth > 0); - m_width = newWidth; - return *this; - } - auto indent(size_t newIndent) -> Column& { - m_indent = newIndent; - return *this; - } - auto initialIndent(size_t newIndent) -> Column& { - m_initialIndent = newIndent; - return *this; - } - - auto width() const -> size_t { return m_width; } - auto begin() const -> iterator { return iterator(*this); } - auto end() const -> iterator { return { *this, m_strings.size() }; } - - inline friend std::ostream& operator << (std::ostream& os, Column const& col) { - bool first = true; - for (auto line : col) { - if (first) - first = false; - else - os << "\n"; - os << line; - } - return os; - } - - auto operator + (Column const& other)->Columns; - - auto toString() const -> std::string { - std::ostringstream oss; - oss << *this; - return oss.str(); - } -}; - -class Spacer : public Column { - -public: - explicit Spacer(size_t spaceWidth) : Column("") { - width(spaceWidth); - } -}; - -class Columns { - std::vector<Column> m_columns; - -public: - - class iterator { - friend Columns; - struct EndTag {}; - - std::vector<Column> const& m_columns; - std::vector<Column::iterator> m_iterators; - size_t m_activeIterators; - - iterator(Columns const& columns, EndTag) - : m_columns(columns.m_columns), - m_activeIterators(0) { - m_iterators.reserve(m_columns.size()); - - for (auto const& col : m_columns) - m_iterators.push_back(col.end()); - } - - public: - using difference_type = std::ptrdiff_t; - using value_type = std::string; - using pointer = value_type * ; - using reference = value_type & ; - using iterator_category = std::forward_iterator_tag; - - explicit iterator(Columns const& columns) - : m_columns(columns.m_columns), - m_activeIterators(m_columns.size()) { - m_iterators.reserve(m_columns.size()); - - for (auto const& col : m_columns) - m_iterators.push_back(col.begin()); - } - - auto operator ==(iterator const& other) const -> bool { - return m_iterators == other.m_iterators; - } - auto operator !=(iterator const& other) const -> bool { - return m_iterators != other.m_iterators; - } - auto operator *() const -> std::string { - std::string row, padding; - - for (size_t i = 0; i < m_columns.size(); ++i) { - auto width = m_columns[i].width(); - if (m_iterators[i] != m_columns[i].end()) { - std::string col = *m_iterators[i]; - row += padding + col; - if (col.size() < width) - padding = std::string(width - col.size(), ' '); - else - padding = ""; - } else { - padding += std::string(width, ' '); - } - } - return row; - } - auto operator ++() -> iterator& { - for (size_t i = 0; i < m_columns.size(); ++i) { - if (m_iterators[i] != m_columns[i].end()) - ++m_iterators[i]; - } - return *this; - } - auto operator ++(int) -> iterator { - iterator prev(*this); - operator++(); - return prev; - } - }; - using const_iterator = iterator; - - auto begin() const -> iterator { return iterator(*this); } - auto end() const -> iterator { return { *this, iterator::EndTag() }; } - - auto operator += (Column const& col) -> Columns& { - m_columns.push_back(col); - return *this; - } - auto operator + (Column const& col) -> Columns { - Columns combined = *this; - combined += col; - return combined; - } - - inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) { - - bool first = true; - for (auto line : cols) { - if (first) - first = false; - else - os << "\n"; - os << line; - } - return os; - } - - auto toString() const -> std::string { - std::ostringstream oss; - oss << *this; - return oss.str(); - } -}; - -inline auto Column::operator + (Column const& other) -> Columns { - Columns cols; - cols += *this; - cols += other; - return cols; -} -} - -} -} - -// ----------- end of #include from clara_textflow.hpp ----------- -// ........... back in clara.hpp - -#include <cctype> -#include <string> -#include <memory> -#include <set> -#include <algorithm> - -#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) ) -#define CATCH_PLATFORM_WINDOWS -#endif - -namespace Catch { namespace clara { -namespace detail { - - // Traits for extracting arg and return type of lambdas (for single argument lambdas) - template<typename L> - struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {}; - - template<typename ClassT, typename ReturnT, typename... Args> - struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> { - static const bool isValid = false; - }; - - template<typename ClassT, typename ReturnT, typename ArgT> - struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> { - static const bool isValid = true; - using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type; - using ReturnType = ReturnT; - }; - - class TokenStream; - - // Transport for raw args (copied from main args, or supplied via init list for testing) - class Args { - friend TokenStream; - std::string m_exeName; - std::vector<std::string> m_args; - - public: - Args( int argc, char const* const* argv ) - : m_exeName(argv[0]), - m_args(argv + 1, argv + argc) {} - - Args( std::initializer_list<std::string> args ) - : m_exeName( *args.begin() ), - m_args( args.begin()+1, args.end() ) - {} - - auto exeName() const -> std::string { - return m_exeName; - } - }; - - // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string - // may encode an option + its argument if the : or = form is used - enum class TokenType { - Option, Argument - }; - struct Token { - TokenType type; - std::string token; - }; - - inline auto isOptPrefix( char c ) -> bool { - return c == '-' -#ifdef CATCH_PLATFORM_WINDOWS - || c == '/' -#endif - ; - } - - // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled - class TokenStream { - using Iterator = std::vector<std::string>::const_iterator; - Iterator it; - Iterator itEnd; - std::vector<Token> m_tokenBuffer; - - void loadBuffer() { - m_tokenBuffer.resize( 0 ); - - // Skip any empty strings - while( it != itEnd && it->empty() ) - ++it; - - if( it != itEnd ) { - auto const &next = *it; - if( isOptPrefix( next[0] ) ) { - auto delimiterPos = next.find_first_of( " :=" ); - if( delimiterPos != std::string::npos ) { - m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } ); - m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } ); - } else { - if( next[1] != '-' && next.size() > 2 ) { - std::string opt = "- "; - for( size_t i = 1; i < next.size(); ++i ) { - opt[1] = next[i]; - m_tokenBuffer.push_back( { TokenType::Option, opt } ); - } - } else { - m_tokenBuffer.push_back( { TokenType::Option, next } ); - } - } - } else { - m_tokenBuffer.push_back( { TokenType::Argument, next } ); - } - } - } - - public: - explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {} - - TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) { - loadBuffer(); - } - - explicit operator bool() const { - return !m_tokenBuffer.empty() || it != itEnd; - } - - auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); } - - auto operator*() const -> Token { - assert( !m_tokenBuffer.empty() ); - return m_tokenBuffer.front(); - } - - auto operator->() const -> Token const * { - assert( !m_tokenBuffer.empty() ); - return &m_tokenBuffer.front(); - } - - auto operator++() -> TokenStream & { - if( m_tokenBuffer.size() >= 2 ) { - m_tokenBuffer.erase( m_tokenBuffer.begin() ); - } else { - if( it != itEnd ) - ++it; - loadBuffer(); - } - return *this; - } - }; - - class ResultBase { - public: - enum Type { - Ok, LogicError, RuntimeError - }; - - protected: - ResultBase( Type type ) : m_type( type ) {} - virtual ~ResultBase() = default; - - virtual void enforceOk() const = 0; - - Type m_type; - }; - - template<typename T> - class ResultValueBase : public ResultBase { - public: - auto value() const -> T const & { - enforceOk(); - return m_value; - } - - protected: - ResultValueBase( Type type ) : ResultBase( type ) {} - - ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) { - if( m_type == ResultBase::Ok ) - new( &m_value ) T( other.m_value ); - } - - ResultValueBase( Type, T const &value ) : ResultBase( Ok ) { - new( &m_value ) T( value ); - } - - auto operator=( ResultValueBase const &other ) -> ResultValueBase & { - if( m_type == ResultBase::Ok ) - m_value.~T(); - ResultBase::operator=(other); - if( m_type == ResultBase::Ok ) - new( &m_value ) T( other.m_value ); - return *this; - } - - ~ResultValueBase() override { - if( m_type == Ok ) - m_value.~T(); - } - - union { - T m_value; - }; - }; - - template<> - class ResultValueBase<void> : public ResultBase { - protected: - using ResultBase::ResultBase; - }; - - template<typename T = void> - class BasicResult : public ResultValueBase<T> { - public: - template<typename U> - explicit BasicResult( BasicResult<U> const &other ) - : ResultValueBase<T>( other.type() ), - m_errorMessage( other.errorMessage() ) - { - assert( type() != ResultBase::Ok ); - } - - template<typename U> - static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; } - static auto ok() -> BasicResult { return { ResultBase::Ok }; } - static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; } - static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; } - - explicit operator bool() const { return m_type == ResultBase::Ok; } - auto type() const -> ResultBase::Type { return m_type; } - auto errorMessage() const -> std::string { return m_errorMessage; } - - protected: - void enforceOk() const override { - - // Errors shouldn't reach this point, but if they do - // the actual error message will be in m_errorMessage - assert( m_type != ResultBase::LogicError ); - assert( m_type != ResultBase::RuntimeError ); - if( m_type != ResultBase::Ok ) - std::abort(); - } - - std::string m_errorMessage; // Only populated if resultType is an error - - BasicResult( ResultBase::Type type, std::string const &message ) - : ResultValueBase<T>(type), - m_errorMessage(message) - { - assert( m_type != ResultBase::Ok ); - } - - using ResultValueBase<T>::ResultValueBase; - using ResultBase::m_type; - }; - - enum class ParseResultType { - Matched, NoMatch, ShortCircuitAll, ShortCircuitSame - }; - - class ParseState { - public: - - ParseState( ParseResultType type, TokenStream const &remainingTokens ) - : m_type(type), - m_remainingTokens( remainingTokens ) - {} - - auto type() const -> ParseResultType { return m_type; } - auto remainingTokens() const -> TokenStream { return m_remainingTokens; } - - private: - ParseResultType m_type; - TokenStream m_remainingTokens; - }; - - using Result = BasicResult<void>; - using ParserResult = BasicResult<ParseResultType>; - using InternalParseResult = BasicResult<ParseState>; - - struct HelpColumns { - std::string left; - std::string right; - }; - - template<typename T> - inline auto convertInto( std::string const &source, T& target ) -> ParserResult { - std::stringstream ss; - ss << source; - ss >> target; - if( ss.fail() ) - return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" ); - else - return ParserResult::ok( ParseResultType::Matched ); - } - inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult { - target = source; - return ParserResult::ok( ParseResultType::Matched ); - } - inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { - std::string srcLC = source; - std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } ); - if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") - target = true; - else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") - target = false; - else - return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); - return ParserResult::ok( ParseResultType::Matched ); - } -#ifdef CLARA_CONFIG_OPTIONAL_TYPE - template<typename T> - inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult { - T temp; - auto result = convertInto( source, temp ); - if( result ) - target = std::move(temp); - return result; - } -#endif // CLARA_CONFIG_OPTIONAL_TYPE - - struct NonCopyable { - NonCopyable() = default; - NonCopyable( NonCopyable const & ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable &operator=( NonCopyable const & ) = delete; - NonCopyable &operator=( NonCopyable && ) = delete; - }; - - struct BoundRef : NonCopyable { - virtual ~BoundRef() = default; - virtual auto isContainer() const -> bool { return false; } - virtual auto isFlag() const -> bool { return false; } - }; - struct BoundValueRefBase : BoundRef { - virtual auto setValue( std::string const &arg ) -> ParserResult = 0; - }; - struct BoundFlagRefBase : BoundRef { - virtual auto setFlag( bool flag ) -> ParserResult = 0; - virtual auto isFlag() const -> bool { return true; } - }; - - template<typename T> - struct BoundValueRef : BoundValueRefBase { - T &m_ref; - - explicit BoundValueRef( T &ref ) : m_ref( ref ) {} - - auto setValue( std::string const &arg ) -> ParserResult override { - return convertInto( arg, m_ref ); - } - }; - - template<typename T> - struct BoundValueRef<std::vector<T>> : BoundValueRefBase { - std::vector<T> &m_ref; - - explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {} - - auto isContainer() const -> bool override { return true; } - - auto setValue( std::string const &arg ) -> ParserResult override { - T temp; - auto result = convertInto( arg, temp ); - if( result ) - m_ref.push_back( temp ); - return result; - } - }; - - struct BoundFlagRef : BoundFlagRefBase { - bool &m_ref; - - explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {} - - auto setFlag( bool flag ) -> ParserResult override { - m_ref = flag; - return ParserResult::ok( ParseResultType::Matched ); - } - }; - - template<typename ReturnType> - struct LambdaInvoker { - static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" ); - - template<typename L, typename ArgType> - static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { - return lambda( arg ); - } - }; - - template<> - struct LambdaInvoker<void> { - template<typename L, typename ArgType> - static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { - lambda( arg ); - return ParserResult::ok( ParseResultType::Matched ); - } - }; - - template<typename ArgType, typename L> - inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult { - ArgType temp{}; - auto result = convertInto( arg, temp ); - return !result - ? result - : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp ); - } - - template<typename L> - struct BoundLambda : BoundValueRefBase { - L m_lambda; - - static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" ); - explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {} - - auto setValue( std::string const &arg ) -> ParserResult override { - return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg ); - } - }; - - template<typename L> - struct BoundFlagLambda : BoundFlagRefBase { - L m_lambda; - - static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" ); - static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" ); - - explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {} - - auto setFlag( bool flag ) -> ParserResult override { - return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag ); - } - }; - - enum class Optionality { Optional, Required }; - - struct Parser; - - class ParserBase { - public: - virtual ~ParserBase() = default; - virtual auto validate() const -> Result { return Result::ok(); } - virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0; - virtual auto cardinality() const -> size_t { return 1; } - - auto parse( Args const &args ) const -> InternalParseResult { - return parse( args.exeName(), TokenStream( args ) ); - } - }; - - template<typename DerivedT> - class ComposableParserImpl : public ParserBase { - public: - template<typename T> - auto operator|( T const &other ) const -> Parser; - - template<typename T> - auto operator+( T const &other ) const -> Parser; - }; - - // Common code and state for Args and Opts - template<typename DerivedT> - class ParserRefImpl : public ComposableParserImpl<DerivedT> { - protected: - Optionality m_optionality = Optionality::Optional; - std::shared_ptr<BoundRef> m_ref; - std::string m_hint; - std::string m_description; - - explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {} - - public: - template<typename T> - ParserRefImpl( T &ref, std::string const &hint ) - : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ), - m_hint( hint ) - {} - - template<typename LambdaT> - ParserRefImpl( LambdaT const &ref, std::string const &hint ) - : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ), - m_hint(hint) - {} - - auto operator()( std::string const &description ) -> DerivedT & { - m_description = description; - return static_cast<DerivedT &>( *this ); - } - - auto optional() -> DerivedT & { - m_optionality = Optionality::Optional; - return static_cast<DerivedT &>( *this ); - }; - - auto required() -> DerivedT & { - m_optionality = Optionality::Required; - return static_cast<DerivedT &>( *this ); - }; - - auto isOptional() const -> bool { - return m_optionality == Optionality::Optional; - } - - auto cardinality() const -> size_t override { - if( m_ref->isContainer() ) - return 0; - else - return 1; - } - - auto hint() const -> std::string { return m_hint; } - }; - - class ExeName : public ComposableParserImpl<ExeName> { - std::shared_ptr<std::string> m_name; - std::shared_ptr<BoundValueRefBase> m_ref; - - template<typename LambdaT> - static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> { - return std::make_shared<BoundLambda<LambdaT>>( lambda) ; - } - - public: - ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {} - - explicit ExeName( std::string &ref ) : ExeName() { - m_ref = std::make_shared<BoundValueRef<std::string>>( ref ); - } - - template<typename LambdaT> - explicit ExeName( LambdaT const& lambda ) : ExeName() { - m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda ); - } - - // The exe name is not parsed out of the normal tokens, but is handled specially - auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { - return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); - } - - auto name() const -> std::string { return *m_name; } - auto set( std::string const& newName ) -> ParserResult { - - auto lastSlash = newName.find_last_of( "\\/" ); - auto filename = ( lastSlash == std::string::npos ) - ? newName - : newName.substr( lastSlash+1 ); - - *m_name = filename; - if( m_ref ) - return m_ref->setValue( filename ); - else - return ParserResult::ok( ParseResultType::Matched ); - } - }; - - class Arg : public ParserRefImpl<Arg> { - public: - using ParserRefImpl::ParserRefImpl; - - auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override { - auto validationResult = validate(); - if( !validationResult ) - return InternalParseResult( validationResult ); - - auto remainingTokens = tokens; - auto const &token = *remainingTokens; - if( token.type != TokenType::Argument ) - return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); - - assert( !m_ref->isFlag() ); - auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); - - auto result = valueRef->setValue( remainingTokens->token ); - if( !result ) - return InternalParseResult( result ); - else - return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); - } - }; - - inline auto normaliseOpt( std::string const &optName ) -> std::string { -#ifdef CATCH_PLATFORM_WINDOWS - if( optName[0] == '/' ) - return "-" + optName.substr( 1 ); - else -#endif - return optName; - } - - class Opt : public ParserRefImpl<Opt> { - protected: - std::vector<std::string> m_optNames; - - public: - template<typename LambdaT> - explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {} - - explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {} - - template<typename LambdaT> - Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} - - template<typename T> - Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} - - auto operator[]( std::string const &optName ) -> Opt & { - m_optNames.push_back( optName ); - return *this; - } - - auto getHelpColumns() const -> std::vector<HelpColumns> { - std::ostringstream oss; - bool first = true; - for( auto const &opt : m_optNames ) { - if (first) - first = false; - else - oss << ", "; - oss << opt; - } - if( !m_hint.empty() ) - oss << " <" << m_hint << ">"; - return { { oss.str(), m_description } }; - } - - auto isMatch( std::string const &optToken ) const -> bool { - auto normalisedToken = normaliseOpt( optToken ); - for( auto const &name : m_optNames ) { - if( normaliseOpt( name ) == normalisedToken ) - return true; - } - return false; - } - - using ParserBase::parse; - - auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { - auto validationResult = validate(); - if( !validationResult ) - return InternalParseResult( validationResult ); - - auto remainingTokens = tokens; - if( remainingTokens && remainingTokens->type == TokenType::Option ) { - auto const &token = *remainingTokens; - if( isMatch(token.token ) ) { - if( m_ref->isFlag() ) { - auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() ); - auto result = flagRef->setFlag( true ); - if( !result ) - return InternalParseResult( result ); - if( result.value() == ParseResultType::ShortCircuitAll ) - return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); - } else { - auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); - ++remainingTokens; - if( !remainingTokens ) - return InternalParseResult::runtimeError( "Expected argument following " + token.token ); - auto const &argToken = *remainingTokens; - if( argToken.type != TokenType::Argument ) - return InternalParseResult::runtimeError( "Expected argument following " + token.token ); - auto result = valueRef->setValue( argToken.token ); - if( !result ) - return InternalParseResult( result ); - if( result.value() == ParseResultType::ShortCircuitAll ) - return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); - } - return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); - } - } - return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); - } - - auto validate() const -> Result override { - if( m_optNames.empty() ) - return Result::logicError( "No options supplied to Opt" ); - for( auto const &name : m_optNames ) { - if( name.empty() ) - return Result::logicError( "Option name cannot be empty" ); -#ifdef CATCH_PLATFORM_WINDOWS - if( name[0] != '-' && name[0] != '/' ) - return Result::logicError( "Option name must begin with '-' or '/'" ); -#else - if( name[0] != '-' ) - return Result::logicError( "Option name must begin with '-'" ); -#endif - } - return ParserRefImpl::validate(); - } - }; - - struct Help : Opt { - Help( bool &showHelpFlag ) - : Opt([&]( bool flag ) { - showHelpFlag = flag; - return ParserResult::ok( ParseResultType::ShortCircuitAll ); - }) - { - static_cast<Opt &>( *this ) - ("display usage information") - ["-?"]["-h"]["--help"] - .optional(); - } - }; - - struct Parser : ParserBase { - - mutable ExeName m_exeName; - std::vector<Opt> m_options; - std::vector<Arg> m_args; - - auto operator|=( ExeName const &exeName ) -> Parser & { - m_exeName = exeName; - return *this; - } - - auto operator|=( Arg const &arg ) -> Parser & { - m_args.push_back(arg); - return *this; - } - - auto operator|=( Opt const &opt ) -> Parser & { - m_options.push_back(opt); - return *this; - } - - auto operator|=( Parser const &other ) -> Parser & { - m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end()); - m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end()); - return *this; - } - - template<typename T> - auto operator|( T const &other ) const -> Parser { - return Parser( *this ) |= other; - } - - // Forward deprecated interface with '+' instead of '|' - template<typename T> - auto operator+=( T const &other ) -> Parser & { return operator|=( other ); } - template<typename T> - auto operator+( T const &other ) const -> Parser { return operator|( other ); } - - auto getHelpColumns() const -> std::vector<HelpColumns> { - std::vector<HelpColumns> cols; - for (auto const &o : m_options) { - auto childCols = o.getHelpColumns(); - cols.insert( cols.end(), childCols.begin(), childCols.end() ); - } - return cols; - } - - void writeToStream( std::ostream &os ) const { - if (!m_exeName.name().empty()) { - os << "usage:\n" << " " << m_exeName.name() << " "; - bool required = true, first = true; - for( auto const &arg : m_args ) { - if (first) - first = false; - else - os << " "; - if( arg.isOptional() && required ) { - os << "["; - required = false; - } - os << "<" << arg.hint() << ">"; - if( arg.cardinality() == 0 ) - os << " ... "; - } - if( !required ) - os << "]"; - if( !m_options.empty() ) - os << " options"; - os << "\n\nwhere options are:" << std::endl; - } - - auto rows = getHelpColumns(); - size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH; - size_t optWidth = 0; - for( auto const &cols : rows ) - optWidth = (std::max)(optWidth, cols.left.size() + 2); - - optWidth = (std::min)(optWidth, consoleWidth/2); - - for( auto const &cols : rows ) { - auto row = - TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) + - TextFlow::Spacer(4) + - TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth ); - os << row << std::endl; - } - } - - friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& { - parser.writeToStream( os ); - return os; - } - - auto validate() const -> Result override { - for( auto const &opt : m_options ) { - auto result = opt.validate(); - if( !result ) - return result; - } - for( auto const &arg : m_args ) { - auto result = arg.validate(); - if( !result ) - return result; - } - return Result::ok(); - } - - using ParserBase::parse; - - auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override { - - struct ParserInfo { - ParserBase const* parser = nullptr; - size_t count = 0; - }; - const size_t totalParsers = m_options.size() + m_args.size(); - assert( totalParsers < 512 ); - // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do - ParserInfo parseInfos[512]; - - { - size_t i = 0; - for (auto const &opt : m_options) parseInfos[i++].parser = &opt; - for (auto const &arg : m_args) parseInfos[i++].parser = &arg; - } - - m_exeName.set( exeName ); - - auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); - while( result.value().remainingTokens() ) { - bool tokenParsed = false; - - for( size_t i = 0; i < totalParsers; ++i ) { - auto& parseInfo = parseInfos[i]; - if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) { - result = parseInfo.parser->parse(exeName, result.value().remainingTokens()); - if (!result) - return result; - if (result.value().type() != ParseResultType::NoMatch) { - tokenParsed = true; - ++parseInfo.count; - break; - } - } - } - - if( result.value().type() == ParseResultType::ShortCircuitAll ) - return result; - if( !tokenParsed ) - return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token ); - } - // !TBD Check missing required options - return result; - } - }; - - template<typename DerivedT> - template<typename T> - auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser { - return Parser() | static_cast<DerivedT const &>( *this ) | other; - } -} // namespace detail - -// A Combined parser -using detail::Parser; - -// A parser for options -using detail::Opt; - -// A parser for arguments -using detail::Arg; - -// Wrapper for argc, argv from main() -using detail::Args; - -// Specifies the name of the executable -using detail::ExeName; - -// Convenience wrapper for option parser that specifies the help option -using detail::Help; - -// enum of result types from a parse -using detail::ParseResultType; - -// Result type for parser operation -using detail::ParserResult; - -}} // namespace Catch::clara - -// end clara.hpp -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// Restore Clara's value for console width, if present -#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#endif - -// end catch_clara.h -namespace Catch { - - clara::Parser makeCommandLineParser( ConfigData& config ); - -} // end namespace Catch - -// end catch_commandline.h -#include <fstream> -#include <ctime> - -namespace Catch { - - clara::Parser makeCommandLineParser( ConfigData& config ) { - - using namespace clara; - - auto const setWarning = [&]( std::string const& warning ) { - auto warningSet = [&]() { - if( warning == "NoAssertions" ) - return WarnAbout::NoAssertions; - - if ( warning == "NoTests" ) - return WarnAbout::NoTests; - - return WarnAbout::Nothing; - }(); - - if (warningSet == WarnAbout::Nothing) - return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" ); - config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet ); - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const loadTestNamesFromFile = [&]( std::string const& filename ) { - std::ifstream f( filename.c_str() ); - if( !f.is_open() ) - return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" ); - - std::string line; - while( std::getline( f, line ) ) { - line = trim(line); - if( !line.empty() && !startsWith( line, '#' ) ) { - if( !startsWith( line, '"' ) ) - line = '"' + line + '"'; - config.testsOrTags.push_back( line + ',' ); - } - } - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const setTestOrder = [&]( std::string const& order ) { - if( startsWith( "declared", order ) ) - config.runOrder = RunTests::InDeclarationOrder; - else if( startsWith( "lexical", order ) ) - config.runOrder = RunTests::InLexicographicalOrder; - else if( startsWith( "random", order ) ) - config.runOrder = RunTests::InRandomOrder; - else - return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" ); - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const setRngSeed = [&]( std::string const& seed ) { - if( seed != "time" ) - return clara::detail::convertInto( seed, config.rngSeed ); - config.rngSeed = static_cast<unsigned int>( std::time(nullptr) ); - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const setColourUsage = [&]( std::string const& useColour ) { - auto mode = toLower( useColour ); - - if( mode == "yes" ) - config.useColour = UseColour::Yes; - else if( mode == "no" ) - config.useColour = UseColour::No; - else if( mode == "auto" ) - config.useColour = UseColour::Auto; - else - return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" ); - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const setWaitForKeypress = [&]( std::string const& keypress ) { - auto keypressLc = toLower( keypress ); - if( keypressLc == "start" ) - config.waitForKeypress = WaitForKeypress::BeforeStart; - else if( keypressLc == "exit" ) - config.waitForKeypress = WaitForKeypress::BeforeExit; - else if( keypressLc == "both" ) - config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; - else - return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const setVerbosity = [&]( std::string const& verbosity ) { - auto lcVerbosity = toLower( verbosity ); - if( lcVerbosity == "quiet" ) - config.verbosity = Verbosity::Quiet; - else if( lcVerbosity == "normal" ) - config.verbosity = Verbosity::Normal; - else if( lcVerbosity == "high" ) - config.verbosity = Verbosity::High; - else - return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); - return ParserResult::ok( ParseResultType::Matched ); - }; - auto const setReporter = [&]( std::string const& reporter ) { - IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); - - auto lcReporter = toLower( reporter ); - auto result = factories.find( lcReporter ); - - if( factories.end() != result ) - config.reporterName = lcReporter; - else - return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" ); - return ParserResult::ok( ParseResultType::Matched ); - }; - - auto cli - = ExeName( config.processName ) - | Help( config.showHelp ) - | Opt( config.listTests ) - ["-l"]["--list-tests"] - ( "list all/matching test cases" ) - | Opt( config.listTags ) - ["-t"]["--list-tags"] - ( "list all/matching tags" ) - | Opt( config.showSuccessfulTests ) - ["-s"]["--success"] - ( "include successful tests in output" ) - | Opt( config.shouldDebugBreak ) - ["-b"]["--break"] - ( "break into debugger on failure" ) - | Opt( config.noThrow ) - ["-e"]["--nothrow"] - ( "skip exception tests" ) - | Opt( config.showInvisibles ) - ["-i"]["--invisibles"] - ( "show invisibles (tabs, newlines)" ) - | Opt( config.outputFilename, "filename" ) - ["-o"]["--out"] - ( "output filename" ) - | Opt( setReporter, "name" ) - ["-r"]["--reporter"] - ( "reporter to use (defaults to console)" ) - | Opt( config.name, "name" ) - ["-n"]["--name"] - ( "suite name" ) - | Opt( [&]( bool ){ config.abortAfter = 1; } ) - ["-a"]["--abort"] - ( "abort at first failure" ) - | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" ) - ["-x"]["--abortx"] - ( "abort after x failures" ) - | Opt( setWarning, "warning name" ) - ["-w"]["--warn"] - ( "enable warnings" ) - | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) - ["-d"]["--durations"] - ( "show test durations" ) - | Opt( loadTestNamesFromFile, "filename" ) - ["-f"]["--input-file"] - ( "load test names to run from a file" ) - | Opt( config.filenamesAsTags ) - ["-#"]["--filenames-as-tags"] - ( "adds a tag for the filename" ) - | Opt( config.sectionsToRun, "section name" ) - ["-c"]["--section"] - ( "specify section to run" ) - | Opt( setVerbosity, "quiet|normal|high" ) - ["-v"]["--verbosity"] - ( "set output verbosity" ) - | Opt( config.listTestNamesOnly ) - ["--list-test-names-only"] - ( "list all/matching test cases names only" ) - | Opt( config.listReporters ) - ["--list-reporters"] - ( "list all reporters" ) - | Opt( setTestOrder, "decl|lex|rand" ) - ["--order"] - ( "test case order (defaults to decl)" ) - | Opt( setRngSeed, "'time'|number" ) - ["--rng-seed"] - ( "set a specific seed for random numbers" ) - | Opt( setColourUsage, "yes|no" ) - ["--use-colour"] - ( "should output be colourised" ) - | Opt( config.libIdentify ) - ["--libidentify"] - ( "report name and version according to libidentify standard" ) - | Opt( setWaitForKeypress, "start|exit|both" ) - ["--wait-for-keypress"] - ( "waits for a keypress before exiting" ) - | Opt( config.benchmarkSamples, "samples" ) - ["--benchmark-samples"] - ( "number of samples to collect (default: 100)" ) - | Opt( config.benchmarkResamples, "resamples" ) - ["--benchmark-resamples"] - ( "number of resamples for the bootstrap (default: 100000)" ) - | Opt( config.benchmarkConfidenceInterval, "confidence interval" ) - ["--benchmark-confidence-interval"] - ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" ) - | Opt( config.benchmarkNoAnalysis ) - ["--benchmark-no-analysis"] - ( "perform only measurements; do not perform any analysis" ) - | Arg( config.testsOrTags, "test name|pattern|tags" ) - ( "which test or tests to use" ); - - return cli; - } - -} // end namespace Catch -// end catch_commandline.cpp -// start catch_common.cpp - -#include <cstring> -#include <ostream> - -namespace Catch { - - bool SourceLineInfo::empty() const noexcept { - return file[0] == '\0'; - } - bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept { - return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); - } - bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept { - // We can assume that the same file will usually have the same pointer. - // Thus, if the pointers are the same, there is no point in calling the strcmp - return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0)); - } - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { -#ifndef __GNUG__ - os << info.file << '(' << info.line << ')'; -#else - os << info.file << ':' << info.line; -#endif - return os; - } - - std::string StreamEndStop::operator+() const { - return std::string(); - } - - NonCopyable::NonCopyable() = default; - NonCopyable::~NonCopyable() = default; - -} -// end catch_common.cpp -// start catch_config.cpp - -namespace Catch { - - Config::Config( ConfigData const& data ) - : m_data( data ), - m_stream( openStream() ) - { - TestSpecParser parser(ITagAliasRegistry::get()); - if (!data.testsOrTags.empty()) { - m_hasTestFilters = true; - for( auto const& testOrTags : data.testsOrTags ) - parser.parse( testOrTags ); - } - m_testSpec = parser.testSpec(); - } - - std::string const& Config::getFilename() const { - return m_data.outputFilename ; - } - - bool Config::listTests() const { return m_data.listTests; } - bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; } - bool Config::listTags() const { return m_data.listTags; } - bool Config::listReporters() const { return m_data.listReporters; } - - std::string Config::getProcessName() const { return m_data.processName; } - std::string const& Config::getReporterName() const { return m_data.reporterName; } - - std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; } - std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } - - TestSpec const& Config::testSpec() const { return m_testSpec; } - bool Config::hasTestFilters() const { return m_hasTestFilters; } - - bool Config::showHelp() const { return m_data.showHelp; } - - // IConfig interface - bool Config::allowThrows() const { return !m_data.noThrow; } - std::ostream& Config::stream() const { return m_stream->stream(); } - std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } - bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; } - bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } - bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } - ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } - RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } - unsigned int Config::rngSeed() const { return m_data.rngSeed; } - UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } - bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; } - int Config::abortAfter() const { return m_data.abortAfter; } - bool Config::showInvisibles() const { return m_data.showInvisibles; } - Verbosity Config::verbosity() const { return m_data.verbosity; } - - bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; } - int Config::benchmarkSamples() const { return m_data.benchmarkSamples; } - double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; } - unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; } - - IStream const* Config::openStream() { - return Catch::makeStream(m_data.outputFilename); - } - -} // end namespace Catch -// end catch_config.cpp -// start catch_console_colour.cpp - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wexit-time-destructors" -#endif - -// start catch_errno_guard.h - -namespace Catch { - - class ErrnoGuard { - public: - ErrnoGuard(); - ~ErrnoGuard(); - private: - int m_oldErrno; - }; - -} - -// end catch_errno_guard.h -#include <sstream> - -namespace Catch { - namespace { - - struct IColourImpl { - virtual ~IColourImpl() = default; - virtual void use( Colour::Code _colourCode ) = 0; - }; - - struct NoColourImpl : IColourImpl { - void use( Colour::Code ) {} - - static IColourImpl* instance() { - static NoColourImpl s_instance; - return &s_instance; - } - }; - - } // anon namespace -} // namespace Catch - -#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) -# ifdef CATCH_PLATFORM_WINDOWS -# define CATCH_CONFIG_COLOUR_WINDOWS -# else -# define CATCH_CONFIG_COLOUR_ANSI -# endif -#endif - -#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// - -namespace Catch { -namespace { - - class Win32ColourImpl : public IColourImpl { - public: - Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) - { - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); - originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); - originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); - } - - void use( Colour::Code _colourCode ) override { - switch( _colourCode ) { - case Colour::None: return setTextAttribute( originalForegroundAttributes ); - case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - case Colour::Red: return setTextAttribute( FOREGROUND_RED ); - case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); - case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); - case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); - case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); - case Colour::Grey: return setTextAttribute( 0 ); - - case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); - case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); - case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); - case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN ); - - case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); - - default: - CATCH_ERROR( "Unknown colour requested" ); - } - } - - private: - void setTextAttribute( WORD _textAttribute ) { - SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); - } - HANDLE stdoutHandle; - WORD originalForegroundAttributes; - WORD originalBackgroundAttributes; - }; - - IColourImpl* platformColourInstance() { - static Win32ColourImpl s_instance; - - IConfigPtr config = getCurrentContext().getConfig(); - UseColour::YesOrNo colourMode = config - ? config->useColour() - : UseColour::Auto; - if( colourMode == UseColour::Auto ) - colourMode = UseColour::Yes; - return colourMode == UseColour::Yes - ? &s_instance - : NoColourImpl::instance(); - } - -} // end anon namespace -} // end namespace Catch - -#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// - -#include <unistd.h> - -namespace Catch { -namespace { - - // use POSIX/ ANSI console terminal codes - // Thanks to Adam Strzelecki for original contribution - // (http://github.com/nanoant) - // https://github.com/philsquared/Catch/pull/131 - class PosixColourImpl : public IColourImpl { - public: - void use( Colour::Code _colourCode ) override { - switch( _colourCode ) { - case Colour::None: - case Colour::White: return setColour( "[0m" ); - case Colour::Red: return setColour( "[0;31m" ); - case Colour::Green: return setColour( "[0;32m" ); - case Colour::Blue: return setColour( "[0;34m" ); - case Colour::Cyan: return setColour( "[0;36m" ); - case Colour::Yellow: return setColour( "[0;33m" ); - case Colour::Grey: return setColour( "[1;30m" ); - - case Colour::LightGrey: return setColour( "[0;37m" ); - case Colour::BrightRed: return setColour( "[1;31m" ); - case Colour::BrightGreen: return setColour( "[1;32m" ); - case Colour::BrightWhite: return setColour( "[1;37m" ); - case Colour::BrightYellow: return setColour( "[1;33m" ); - - case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); - default: CATCH_INTERNAL_ERROR( "Unknown colour requested" ); - } - } - static IColourImpl* instance() { - static PosixColourImpl s_instance; - return &s_instance; - } - - private: - void setColour( const char* _escapeCode ) { - getCurrentContext().getConfig()->stream() - << '\033' << _escapeCode; - } - }; - - bool useColourOnPlatform() { - return -#ifdef CATCH_PLATFORM_MAC - !isDebuggerActive() && -#endif -#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) - isatty(STDOUT_FILENO) -#else - false -#endif - ; - } - IColourImpl* platformColourInstance() { - ErrnoGuard guard; - IConfigPtr config = getCurrentContext().getConfig(); - UseColour::YesOrNo colourMode = config - ? config->useColour() - : UseColour::Auto; - if( colourMode == UseColour::Auto ) - colourMode = useColourOnPlatform() - ? UseColour::Yes - : UseColour::No; - return colourMode == UseColour::Yes - ? PosixColourImpl::instance() - : NoColourImpl::instance(); - } - -} // end anon namespace -} // end namespace Catch - -#else // not Windows or ANSI /////////////////////////////////////////////// - -namespace Catch { - - static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } - -} // end namespace Catch - -#endif // Windows/ ANSI/ None - -namespace Catch { - - Colour::Colour( Code _colourCode ) { use( _colourCode ); } - Colour::Colour( Colour&& rhs ) noexcept { - m_moved = rhs.m_moved; - rhs.m_moved = true; - } - Colour& Colour::operator=( Colour&& rhs ) noexcept { - m_moved = rhs.m_moved; - rhs.m_moved = true; - return *this; - } - - Colour::~Colour(){ if( !m_moved ) use( None ); } - - void Colour::use( Code _colourCode ) { - static IColourImpl* impl = platformColourInstance(); - // Strictly speaking, this cannot possibly happen. - // However, under some conditions it does happen (see #1626), - // and this change is small enough that we can let practicality - // triumph over purity in this case. - if (impl != NULL) { - impl->use( _colourCode ); - } - } - - std::ostream& operator << ( std::ostream& os, Colour const& ) { - return os; - } - -} // end namespace Catch - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -// end catch_console_colour.cpp -// start catch_context.cpp - -namespace Catch { - - class Context : public IMutableContext, NonCopyable { - - public: // IContext - IResultCapture* getResultCapture() override { - return m_resultCapture; - } - IRunner* getRunner() override { - return m_runner; - } - - IConfigPtr const& getConfig() const override { - return m_config; - } - - ~Context() override; - - public: // IMutableContext - void setResultCapture( IResultCapture* resultCapture ) override { - m_resultCapture = resultCapture; - } - void setRunner( IRunner* runner ) override { - m_runner = runner; - } - void setConfig( IConfigPtr const& config ) override { - m_config = config; - } - - friend IMutableContext& getCurrentMutableContext(); - - private: - IConfigPtr m_config; - IRunner* m_runner = nullptr; - IResultCapture* m_resultCapture = nullptr; - }; - - IMutableContext *IMutableContext::currentContext = nullptr; - - void IMutableContext::createContext() - { - currentContext = new Context(); - } - - void cleanUpContext() { - delete IMutableContext::currentContext; - IMutableContext::currentContext = nullptr; - } - IContext::~IContext() = default; - IMutableContext::~IMutableContext() = default; - Context::~Context() = default; -} -// end catch_context.cpp -// start catch_debug_console.cpp - -// start catch_debug_console.h - -#include <string> - -namespace Catch { - void writeToDebugConsole( std::string const& text ); -} - -// end catch_debug_console.h -#ifdef CATCH_PLATFORM_WINDOWS - - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - ::OutputDebugStringA( text.c_str() ); - } - } - -#else - - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - // !TBD: Need a version for Mac/ XCode and other IDEs - Catch::cout() << text; - } - } - -#endif // Platform -// end catch_debug_console.cpp -// start catch_debugger.cpp - -#ifdef CATCH_PLATFORM_MAC - -# include <assert.h> -# include <stdbool.h> -# include <sys/types.h> -# include <unistd.h> -# include <cstddef> -# include <ostream> - -#ifdef __apple_build_version__ - // These headers will only compile with AppleClang (XCode) - // For other compilers (Clang, GCC, ... ) we need to exclude them -# include <sys/sysctl.h> -#endif - - namespace Catch { - #ifdef __apple_build_version__ - // The following function is taken directly from the following technical note: - // https://developer.apple.com/library/archive/qa/qa1361/_index.html - - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive(){ - int mib[4]; - struct kinfo_proc info; - std::size_t size; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - // Call sysctl. - - size = sizeof(info); - if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) { - Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; - return false; - } - - // We're being debugged if the P_TRACED flag is set. - - return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); - } - #else - bool isDebuggerActive() { - // We need to find another way to determine this for non-appleclang compilers on macOS - return false; - } - #endif - } // namespace Catch - -#elif defined(CATCH_PLATFORM_LINUX) - #include <fstream> - #include <string> - - namespace Catch{ - // The standard POSIX way of detecting a debugger is to attempt to - // ptrace() the process, but this needs to be done from a child and not - // this process itself to still allow attaching to this process later - // if wanted, so is rather heavy. Under Linux we have the PID of the - // "debugger" (which doesn't need to be gdb, of course, it could also - // be strace, for example) in /proc/$PID/status, so just get it from - // there instead. - bool isDebuggerActive(){ - // Libstdc++ has a bug, where std::ifstream sets errno to 0 - // This way our users can properly assert over errno values - ErrnoGuard guard; - std::ifstream in("/proc/self/status"); - for( std::string line; std::getline(in, line); ) { - static const int PREFIX_LEN = 11; - if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { - // We're traced if the PID is not 0 and no other PID starts - // with 0 digit, so it's enough to check for just a single - // character. - return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; - } - } - - return false; - } - } // namespace Catch -#elif defined(_MSC_VER) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#else - namespace Catch { - bool isDebuggerActive() { return false; } - } -#endif // Platform -// end catch_debugger.cpp -// start catch_decomposer.cpp - -namespace Catch { - - ITransientExpression::~ITransientExpression() = default; - - void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { - if( lhs.size() + rhs.size() < 40 && - lhs.find('\n') == std::string::npos && - rhs.find('\n') == std::string::npos ) - os << lhs << " " << op << " " << rhs; - else - os << lhs << "\n" << op << "\n" << rhs; - } -} -// end catch_decomposer.cpp -// start catch_enforce.cpp - -#include <stdexcept> - -namespace Catch { -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER) - [[noreturn]] - void throw_exception(std::exception const& e) { - Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n" - << "The message was: " << e.what() << '\n'; - std::terminate(); - } -#endif - - [[noreturn]] - void throw_logic_error(std::string const& msg) { - throw_exception(std::logic_error(msg)); - } - - [[noreturn]] - void throw_domain_error(std::string const& msg) { - throw_exception(std::domain_error(msg)); - } - - [[noreturn]] - void throw_runtime_error(std::string const& msg) { - throw_exception(std::runtime_error(msg)); - } - -} // namespace Catch; -// end catch_enforce.cpp -// start catch_enum_values_registry.cpp -// start catch_enum_values_registry.h - -#include <vector> -#include <memory> - -namespace Catch { - - namespace Detail { - - std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ); - - class EnumValuesRegistry : public IMutableEnumValuesRegistry { - - std::vector<std::unique_ptr<EnumInfo>> m_enumInfos; - - EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override; - }; - - std::vector<std::string> parseEnums( StringRef enums ); - - } // Detail - -} // Catch - -// end catch_enum_values_registry.h - -#include <map> -#include <cassert> - -namespace Catch { - - IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {} - - namespace Detail { - - std::vector<std::string> parseEnums( StringRef enums ) { - auto enumValues = splitStringRef( enums, ',' ); - std::vector<std::string> parsed; - parsed.reserve( enumValues.size() ); - for( auto const& enumValue : enumValues ) { - auto identifiers = splitStringRef( enumValue, ':' ); - parsed.push_back( Catch::trim( identifiers.back() ) ); - } - return parsed; - } - - EnumInfo::~EnumInfo() {} - - StringRef EnumInfo::lookup( int value ) const { - for( auto const& valueToName : m_values ) { - if( valueToName.first == value ) - return valueToName.second; - } - return "{** unexpected enum value **}"; - } - - std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { - std::unique_ptr<EnumInfo> enumInfo( new EnumInfo ); - enumInfo->m_name = enumName; - enumInfo->m_values.reserve( values.size() ); - - const auto valueNames = Catch::Detail::parseEnums( allValueNames ); - assert( valueNames.size() == values.size() ); - std::size_t i = 0; - for( auto value : values ) - enumInfo->m_values.push_back({ value, valueNames[i++] }); - - return enumInfo; - } - - EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { - auto enumInfo = makeEnumInfo( enumName, allValueNames, values ); - EnumInfo* raw = enumInfo.get(); - m_enumInfos.push_back( std::move( enumInfo ) ); - return *raw; - } - - } // Detail -} // Catch - -// end catch_enum_values_registry.cpp -// start catch_errno_guard.cpp - -#include <cerrno> - -namespace Catch { - ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} - ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } -} -// end catch_errno_guard.cpp -// start catch_exception_translator_registry.cpp - -// start catch_exception_translator_registry.h - -#include <vector> -#include <string> -#include <memory> - -namespace Catch { - - class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { - public: - ~ExceptionTranslatorRegistry(); - virtual void registerTranslator( const IExceptionTranslator* translator ); - std::string translateActiveException() const override; - std::string tryTranslators() const; - - private: - std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators; - }; -} - -// end catch_exception_translator_registry.h -#ifdef __OBJC__ -#import "Foundation/Foundation.h" -#endif - -namespace Catch { - - ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { - } - - void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) { - m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) ); - } - -#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - std::string ExceptionTranslatorRegistry::translateActiveException() const { - try { -#ifdef __OBJC__ - // In Objective-C try objective-c exceptions first - @try { - return tryTranslators(); - } - @catch (NSException *exception) { - return Catch::Detail::stringify( [exception description] ); - } -#else - // Compiling a mixed mode project with MSVC means that CLR - // exceptions will be caught in (...) as well. However, these - // do not fill-in std::current_exception and thus lead to crash - // when attempting rethrow. - // /EHa switch also causes structured exceptions to be caught - // here, but they fill-in current_exception properly, so - // at worst the output should be a little weird, instead of - // causing a crash. - if (std::current_exception() == nullptr) { - return "Non C++ exception. Possibly a CLR exception."; - } - return tryTranslators(); -#endif - } - catch( TestFailureException& ) { - std::rethrow_exception(std::current_exception()); - } - catch( std::exception& ex ) { - return ex.what(); - } - catch( std::string& msg ) { - return msg; - } - catch( const char* msg ) { - return msg; - } - catch(...) { - return "Unknown exception"; - } - } - - std::string ExceptionTranslatorRegistry::tryTranslators() const { - if (m_translators.empty()) { - std::rethrow_exception(std::current_exception()); - } else { - return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end()); - } - } - -#else // ^^ Exceptions are enabled // Exceptions are disabled vv - std::string ExceptionTranslatorRegistry::translateActiveException() const { - CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); - } - - std::string ExceptionTranslatorRegistry::tryTranslators() const { - CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); - } -#endif - -} -// end catch_exception_translator_registry.cpp -// start catch_fatal_condition.cpp - -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif - -#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) - -namespace { - // Report the error condition - void reportFatal( char const * const message ) { - Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); - } -} - -#endif // signals/SEH handling - -#if defined( CATCH_CONFIG_WINDOWS_SEH ) - -namespace Catch { - struct SignalDefs { DWORD id; const char* name; }; - - // There is no 1-1 mapping between signals and windows exceptions. - // Windows can easily distinguish between SO and SigSegV, - // but SigInt, SigTerm, etc are handled differently. - static SignalDefs signalDefs[] = { - { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" }, - { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" }, - { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" }, - { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" }, - }; - - LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { - for (auto const& def : signalDefs) { - if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { - reportFatal(def.name); - } - } - // If its not an exception we care about, pass it along. - // This stops us from eating debugger breaks etc. - return EXCEPTION_CONTINUE_SEARCH; - } - - FatalConditionHandler::FatalConditionHandler() { - isSet = true; - // 32k seems enough for Catch to handle stack overflow, - // but the value was found experimentally, so there is no strong guarantee - guaranteeSize = 32 * 1024; - exceptionHandlerHandle = nullptr; - // Register as first handler in current chain - exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - } - - void FatalConditionHandler::reset() { - if (isSet) { - RemoveVectoredExceptionHandler(exceptionHandlerHandle); - SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = nullptr; - isSet = false; - } - } - - FatalConditionHandler::~FatalConditionHandler() { - reset(); - } - -bool FatalConditionHandler::isSet = false; -ULONG FatalConditionHandler::guaranteeSize = 0; -PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; - -} // namespace Catch - -#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) - -namespace Catch { - - struct SignalDefs { - int id; - const char* name; - }; - - // 32kb for the alternate stack seems to be sufficient. However, this value - // is experimentally determined, so that's not guaranteed. - constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; - - static SignalDefs signalDefs[] = { - { SIGINT, "SIGINT - Terminal interrupt signal" }, - { SIGILL, "SIGILL - Illegal instruction signal" }, - { SIGFPE, "SIGFPE - Floating point error signal" }, - { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, - { SIGTERM, "SIGTERM - Termination request signal" }, - { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } - }; - - void FatalConditionHandler::handleSignal( int sig ) { - char const * name = "<unknown signal>"; - for (auto const& def : signalDefs) { - if (sig == def.id) { - name = def.name; - break; - } - } - reset(); - reportFatal(name); - raise( sig ); - } - - FatalConditionHandler::FatalConditionHandler() { - isSet = true; - stack_t sigStack; - sigStack.ss_sp = altStackMem; - sigStack.ss_size = sigStackSize; - sigStack.ss_flags = 0; - sigaltstack(&sigStack, &oldSigStack); - struct sigaction sa = { }; - - sa.sa_handler = handleSignal; - sa.sa_flags = SA_ONSTACK; - for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { - sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); - } - } - - FatalConditionHandler::~FatalConditionHandler() { - reset(); - } - - void FatalConditionHandler::reset() { - if( isSet ) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { - sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); - } - // Return the old stack - sigaltstack(&oldSigStack, nullptr); - isSet = false; - } - } - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[sigStackSize] = {}; - -} // namespace Catch - -#else - -namespace Catch { - void FatalConditionHandler::reset() {} -} - -#endif // signals/SEH handling - -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif -// end catch_fatal_condition.cpp -// start catch_generators.cpp - -// start catch_random_number_generator.h - -#include <algorithm> -#include <random> - -namespace Catch { - - struct IConfig; - - std::mt19937& rng(); - void seedRng( IConfig const& config ); - unsigned int rngSeed(); - -} - -// end catch_random_number_generator.h -#include <limits> -#include <set> - -namespace Catch { - -IGeneratorTracker::~IGeneratorTracker() {} - -const char* GeneratorException::what() const noexcept { - return m_msg; -} - -namespace Generators { - - GeneratorUntypedBase::~GeneratorUntypedBase() {} - - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { - return getResultCapture().acquireGeneratorTracker( lineInfo ); - } - -} // namespace Generators -} // namespace Catch -// end catch_generators.cpp -// start catch_interfaces_capture.cpp - -namespace Catch { - IResultCapture::~IResultCapture() = default; -} -// end catch_interfaces_capture.cpp -// start catch_interfaces_config.cpp - -namespace Catch { - IConfig::~IConfig() = default; -} -// end catch_interfaces_config.cpp -// start catch_interfaces_exception.cpp - -namespace Catch { - IExceptionTranslator::~IExceptionTranslator() = default; - IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; -} -// end catch_interfaces_exception.cpp -// start catch_interfaces_registry_hub.cpp - -namespace Catch { - IRegistryHub::~IRegistryHub() = default; - IMutableRegistryHub::~IMutableRegistryHub() = default; -} -// end catch_interfaces_registry_hub.cpp -// start catch_interfaces_reporter.cpp - -// start catch_reporter_listening.h - -namespace Catch { - - class ListeningReporter : public IStreamingReporter { - using Reporters = std::vector<IStreamingReporterPtr>; - Reporters m_listeners; - IStreamingReporterPtr m_reporter = nullptr; - ReporterPreferences m_preferences; - - public: - ListeningReporter(); - - void addListener( IStreamingReporterPtr&& listener ); - void addReporter( IStreamingReporterPtr&& reporter ); - - public: // IStreamingReporter - - ReporterPreferences getPreferences() const override; - - void noMatchingTestCases( std::string const& spec ) override; - - static std::set<Verbosity> getSupportedVerbosities(); - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void benchmarkPreparing(std::string const& name) override; - void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override; - void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override; - void benchmarkFailed(std::string const&) override; -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - void testRunStarting( TestRunInfo const& testRunInfo ) override; - void testGroupStarting( GroupInfo const& groupInfo ) override; - void testCaseStarting( TestCaseInfo const& testInfo ) override; - void sectionStarting( SectionInfo const& sectionInfo ) override; - void assertionStarting( AssertionInfo const& assertionInfo ) override; - - // The return value indicates if the messages buffer should be cleared: - bool assertionEnded( AssertionStats const& assertionStats ) override; - void sectionEnded( SectionStats const& sectionStats ) override; - void testCaseEnded( TestCaseStats const& testCaseStats ) override; - void testGroupEnded( TestGroupStats const& testGroupStats ) override; - void testRunEnded( TestRunStats const& testRunStats ) override; - - void skipTest( TestCaseInfo const& testInfo ) override; - bool isMulti() const override; - - }; - -} // end namespace Catch - -// end catch_reporter_listening.h -namespace Catch { - - ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig ) - : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} - - ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ) - : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} - - std::ostream& ReporterConfig::stream() const { return *m_stream; } - IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; } - - TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {} - - GroupInfo::GroupInfo( std::string const& _name, - std::size_t _groupIndex, - std::size_t _groupsCount ) - : name( _name ), - groupIndex( _groupIndex ), - groupsCounts( _groupsCount ) - {} - - AssertionStats::AssertionStats( AssertionResult const& _assertionResult, - std::vector<MessageInfo> const& _infoMessages, - Totals const& _totals ) - : assertionResult( _assertionResult ), - infoMessages( _infoMessages ), - totals( _totals ) - { - assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression; - - if( assertionResult.hasMessage() ) { - // Copy message into messages list. - // !TBD This should have been done earlier, somewhere - MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); - builder << assertionResult.getMessage(); - builder.m_info.message = builder.m_stream.str(); - - infoMessages.push_back( builder.m_info ); - } - } - - AssertionStats::~AssertionStats() = default; - - SectionStats::SectionStats( SectionInfo const& _sectionInfo, - Counts const& _assertions, - double _durationInSeconds, - bool _missingAssertions ) - : sectionInfo( _sectionInfo ), - assertions( _assertions ), - durationInSeconds( _durationInSeconds ), - missingAssertions( _missingAssertions ) - {} - - SectionStats::~SectionStats() = default; - - TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo, - Totals const& _totals, - std::string const& _stdOut, - std::string const& _stdErr, - bool _aborting ) - : testInfo( _testInfo ), - totals( _totals ), - stdOut( _stdOut ), - stdErr( _stdErr ), - aborting( _aborting ) - {} - - TestCaseStats::~TestCaseStats() = default; - - TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo, - Totals const& _totals, - bool _aborting ) - : groupInfo( _groupInfo ), - totals( _totals ), - aborting( _aborting ) - {} - - TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo ) - : groupInfo( _groupInfo ), - aborting( false ) - {} - - TestGroupStats::~TestGroupStats() = default; - - TestRunStats::TestRunStats( TestRunInfo const& _runInfo, - Totals const& _totals, - bool _aborting ) - : runInfo( _runInfo ), - totals( _totals ), - aborting( _aborting ) - {} - - TestRunStats::~TestRunStats() = default; - - void IStreamingReporter::fatalErrorEncountered( StringRef ) {} - bool IStreamingReporter::isMulti() const { return false; } - - IReporterFactory::~IReporterFactory() = default; - IReporterRegistry::~IReporterRegistry() = default; - -} // end namespace Catch -// end catch_interfaces_reporter.cpp -// start catch_interfaces_runner.cpp - -namespace Catch { - IRunner::~IRunner() = default; -} -// end catch_interfaces_runner.cpp -// start catch_interfaces_testcase.cpp - -namespace Catch { - ITestInvoker::~ITestInvoker() = default; - ITestCaseRegistry::~ITestCaseRegistry() = default; -} -// end catch_interfaces_testcase.cpp -// start catch_leak_detector.cpp - -#ifdef CATCH_CONFIG_WINDOWS_CRTDBG -#include <crtdbg.h> - -namespace Catch { - - LeakDetector::LeakDetector() { - int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - flag |= _CRTDBG_LEAK_CHECK_DF; - flag |= _CRTDBG_ALLOC_MEM_DF; - _CrtSetDbgFlag(flag); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - // Change this to leaking allocation's number to break there - _CrtSetBreakAlloc(-1); - } -} - -#else - - Catch::LeakDetector::LeakDetector() {} - -#endif - -Catch::LeakDetector::~LeakDetector() { - Catch::cleanUp(); -} -// end catch_leak_detector.cpp -// start catch_list.cpp - -// start catch_list.h - -#include <set> - -namespace Catch { - - std::size_t listTests( Config const& config ); - - std::size_t listTestsNamesOnly( Config const& config ); - - struct TagInfo { - void add( std::string const& spelling ); - std::string all() const; - - std::set<std::string> spellings; - std::size_t count = 0; - }; - - std::size_t listTags( Config const& config ); - - std::size_t listReporters(); - - Option<std::size_t> list( std::shared_ptr<Config> const& config ); - -} // end namespace Catch - -// end catch_list.h -// start catch_text.h - -namespace Catch { - using namespace clara::TextFlow; -} - -// end catch_text.h -#include <limits> -#include <algorithm> -#include <iomanip> - -namespace Catch { - - std::size_t listTests( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( config.hasTestFilters() ) - Catch::cout() << "Matching test cases:\n"; - else { - Catch::cout() << "All available test cases:\n"; - } - - auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); - for( auto const& testCaseInfo : matchedTestCases ) { - Colour::Code colour = testCaseInfo.isHidden() - ? Colour::SecondaryText - : Colour::None; - Colour colourGuard( colour ); - - Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n"; - if( config.verbosity() >= Verbosity::High ) { - Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl; - std::string description = testCaseInfo.description; - if( description.empty() ) - description = "(NO DESCRIPTION)"; - Catch::cout() << Column( description ).indent(4) << std::endl; - } - if( !testCaseInfo.tags.empty() ) - Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n"; - } - - if( !config.hasTestFilters() ) - Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl; - else - Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl; - return matchedTestCases.size(); - } - - std::size_t listTestsNamesOnly( Config const& config ) { - TestSpec testSpec = config.testSpec(); - std::size_t matchedTests = 0; - std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); - for( auto const& testCaseInfo : matchedTestCases ) { - matchedTests++; - if( startsWith( testCaseInfo.name, '#' ) ) - Catch::cout() << '"' << testCaseInfo.name << '"'; - else - Catch::cout() << testCaseInfo.name; - if ( config.verbosity() >= Verbosity::High ) - Catch::cout() << "\t@" << testCaseInfo.lineInfo; - Catch::cout() << std::endl; - } - return matchedTests; - } - - void TagInfo::add( std::string const& spelling ) { - ++count; - spellings.insert( spelling ); - } - - std::string TagInfo::all() const { - std::string out; - for( auto const& spelling : spellings ) - out += "[" + spelling + "]"; - return out; - } - - std::size_t listTags( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( config.hasTestFilters() ) - Catch::cout() << "Tags for matching test cases:\n"; - else { - Catch::cout() << "All available tags:\n"; - } - - std::map<std::string, TagInfo> tagCounts; - - std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); - for( auto const& testCase : matchedTestCases ) { - for( auto const& tagName : testCase.getTestCaseInfo().tags ) { - std::string lcaseTagName = toLower( tagName ); - auto countIt = tagCounts.find( lcaseTagName ); - if( countIt == tagCounts.end() ) - countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; - countIt->second.add( tagName ); - } - } - - for( auto const& tagCount : tagCounts ) { - ReusableStringStream rss; - rss << " " << std::setw(2) << tagCount.second.count << " "; - auto str = rss.str(); - auto wrapper = Column( tagCount.second.all() ) - .initialIndent( 0 ) - .indent( str.size() ) - .width( CATCH_CONFIG_CONSOLE_WIDTH-10 ); - Catch::cout() << str << wrapper << '\n'; - } - Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; - return tagCounts.size(); - } - - std::size_t listReporters() { - Catch::cout() << "Available reporters:\n"; - IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); - std::size_t maxNameLen = 0; - for( auto const& factoryKvp : factories ) - maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() ); - - for( auto const& factoryKvp : factories ) { - Catch::cout() - << Column( factoryKvp.first + ":" ) - .indent(2) - .width( 5+maxNameLen ) - + Column( factoryKvp.second->getDescription() ) - .initialIndent(0) - .indent(2) - .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) - << "\n"; - } - Catch::cout() << std::endl; - return factories.size(); - } - - Option<std::size_t> list( std::shared_ptr<Config> const& config ) { - Option<std::size_t> listedCount; - getCurrentMutableContext().setConfig( config ); - if( config->listTests() ) - listedCount = listedCount.valueOr(0) + listTests( *config ); - if( config->listTestNamesOnly() ) - listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config ); - if( config->listTags() ) - listedCount = listedCount.valueOr(0) + listTags( *config ); - if( config->listReporters() ) - listedCount = listedCount.valueOr(0) + listReporters(); - return listedCount; - } - -} // end namespace Catch -// end catch_list.cpp -// start catch_matchers.cpp - -namespace Catch { -namespace Matchers { - namespace Impl { - - std::string MatcherUntypedBase::toString() const { - if( m_cachedToString.empty() ) - m_cachedToString = describe(); - return m_cachedToString; - } - - MatcherUntypedBase::~MatcherUntypedBase() = default; - - } // namespace Impl -} // namespace Matchers - -using namespace Matchers; -using Matchers::Impl::MatcherBase; - -} // namespace Catch -// end catch_matchers.cpp -// start catch_matchers_floating.cpp - -// start catch_polyfills.hpp - -namespace Catch { - bool isnan(float f); - bool isnan(double d); -} - -// end catch_polyfills.hpp -// start catch_to_string.hpp - -#include <string> - -namespace Catch { - template <typename T> - std::string to_string(T const& t) { -#if defined(CATCH_CONFIG_CPP11_TO_STRING) - return std::to_string(t); -#else - ReusableStringStream rss; - rss << t; - return rss.str(); -#endif - } -} // end namespace Catch - -// end catch_to_string.hpp -#include <cstdlib> -#include <cstdint> -#include <cstring> -#include <sstream> -#include <iomanip> -#include <limits> - -namespace Catch { -namespace Matchers { -namespace Floating { -enum class FloatingPointKind : uint8_t { - Float, - Double -}; -} -} -} - -namespace { - -template <typename T> -struct Converter; - -template <> -struct Converter<float> { - static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated"); - Converter(float f) { - std::memcpy(&i, &f, sizeof(f)); - } - int32_t i; -}; - -template <> -struct Converter<double> { - static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated"); - Converter(double d) { - std::memcpy(&i, &d, sizeof(d)); - } - int64_t i; -}; - -template <typename T> -auto convert(T t) -> Converter<T> { - return Converter<T>(t); -} - -template <typename FP> -bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) { - // Comparison with NaN should always be false. - // This way we can rule it out before getting into the ugly details - if (Catch::isnan(lhs) || Catch::isnan(rhs)) { - return false; - } - - auto lc = convert(lhs); - auto rc = convert(rhs); - - if ((lc.i < 0) != (rc.i < 0)) { - // Potentially we can have +0 and -0 - return lhs == rhs; - } - - auto ulpDiff = std::abs(lc.i - rc.i); - return ulpDiff <= maxUlpDiff; -} - -template <typename FP> -FP step(FP start, FP direction, int steps) { - for (int i = 0; i < steps; ++i) { - start = std::nextafter(start, direction); - } - return start; -} - -} // end anonymous namespace - -namespace Catch { -namespace Matchers { -namespace Floating { - WithinAbsMatcher::WithinAbsMatcher(double target, double margin) - :m_target{ target }, m_margin{ margin } { - CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.' - << " Margin has to be non-negative."); - } - - // Performs equivalent check of std::fabs(lhs - rhs) <= margin - // But without the subtraction to allow for INFINITY in comparison - bool WithinAbsMatcher::match(double const& matchee) const { - return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee); - } - - std::string WithinAbsMatcher::describe() const { - return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target); - } - - WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType) - :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } { - CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.' - << " ULPs have to be non-negative."); - } - -#if defined(__clang__) -#pragma clang diagnostic push -// Clang <3.5 reports on the default branch in the switch below -#pragma clang diagnostic ignored "-Wunreachable-code" -#endif - - bool WithinUlpsMatcher::match(double const& matchee) const { - switch (m_type) { - case FloatingPointKind::Float: - return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps); - case FloatingPointKind::Double: - return almostEqualUlps<double>(matchee, m_target, m_ulps); - default: - CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" ); - } - } - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - - std::string WithinUlpsMatcher::describe() const { - std::stringstream ret; - - ret << "is within " << m_ulps << " ULPs of " << ::Catch::Detail::stringify(m_target); - - if (m_type == FloatingPointKind::Float) { - ret << 'f'; - } - - ret << " (["; - ret << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10); - if (m_type == FloatingPointKind::Double) { - ret << step(m_target, static_cast<double>(-INFINITY), m_ulps) - << ", " - << step(m_target, static_cast<double>(INFINITY), m_ulps); - } else { - ret << step<float>(static_cast<float>(m_target), -INFINITY, m_ulps) - << ", " - << step<float>(static_cast<float>(m_target), INFINITY, m_ulps); - } - ret << "])"; - - return ret.str(); - //return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); - } - -}// namespace Floating - -Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) { - return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double); -} - -Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) { - return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float); -} - -Floating::WithinAbsMatcher WithinAbs(double target, double margin) { - return Floating::WithinAbsMatcher(target, margin); -} - -} // namespace Matchers -} // namespace Catch - -// end catch_matchers_floating.cpp -// start catch_matchers_generic.cpp - -std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) { - if (desc.empty()) { - return "matches undescribed predicate"; - } else { - return "matches predicate: \"" + desc + '"'; - } -} -// end catch_matchers_generic.cpp -// start catch_matchers_string.cpp - -#include <regex> - -namespace Catch { -namespace Matchers { - - namespace StdString { - - CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) - : m_caseSensitivity( caseSensitivity ), - m_str( adjustString( str ) ) - {} - std::string CasedString::adjustString( std::string const& str ) const { - return m_caseSensitivity == CaseSensitive::No - ? toLower( str ) - : str; - } - std::string CasedString::caseSensitivitySuffix() const { - return m_caseSensitivity == CaseSensitive::No - ? " (case insensitive)" - : std::string(); - } - - StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) - : m_comparator( comparator ), - m_operation( operation ) { - } - - std::string StringMatcherBase::describe() const { - std::string description; - description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + - m_comparator.caseSensitivitySuffix().size()); - description += m_operation; - description += ": \""; - description += m_comparator.m_str; - description += "\""; - description += m_comparator.caseSensitivitySuffix(); - return description; - } - - EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} - - bool EqualsMatcher::match( std::string const& source ) const { - return m_comparator.adjustString( source ) == m_comparator.m_str; - } - - ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} - - bool ContainsMatcher::match( std::string const& source ) const { - return contains( m_comparator.adjustString( source ), m_comparator.m_str ); - } - - StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} - - bool StartsWithMatcher::match( std::string const& source ) const { - return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); - } - - EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} - - bool EndsWithMatcher::match( std::string const& source ) const { - return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); - } - - RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {} - - bool RegexMatcher::match(std::string const& matchee) const { - auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway - if (m_caseSensitivity == CaseSensitive::Choice::No) { - flags |= std::regex::icase; - } - auto reg = std::regex(m_regex, flags); - return std::regex_match(matchee, reg); - } - - std::string RegexMatcher::describe() const { - return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively"); - } - - } // namespace StdString - - StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); - } - StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); - } - StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); - } - StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); - } - - StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) { - return StdString::RegexMatcher(regex, caseSensitivity); - } - -} // namespace Matchers -} // namespace Catch -// end catch_matchers_string.cpp -// start catch_message.cpp - -// start catch_uncaught_exceptions.h - -namespace Catch { - bool uncaught_exceptions(); -} // end namespace Catch - -// end catch_uncaught_exceptions.h -#include <cassert> -#include <stack> - -namespace Catch { - - MessageInfo::MessageInfo( StringRef const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - type( _type ), - sequence( ++globalCount ) - {} - - bool MessageInfo::operator==( MessageInfo const& other ) const { - return sequence == other.sequence; - } - - bool MessageInfo::operator<( MessageInfo const& other ) const { - return sequence < other.sequence; - } - - // This may need protecting if threading support is added - unsigned int MessageInfo::globalCount = 0; - - //////////////////////////////////////////////////////////////////////////// - - Catch::MessageBuilder::MessageBuilder( StringRef const& macroName, - SourceLineInfo const& lineInfo, - ResultWas::OfType type ) - :m_info(macroName, lineInfo, type) {} - - //////////////////////////////////////////////////////////////////////////// - - ScopedMessage::ScopedMessage( MessageBuilder const& builder ) - : m_info( builder.m_info ), m_moved() - { - m_info.message = builder.m_stream.str(); - getResultCapture().pushScopedMessage( m_info ); - } - - ScopedMessage::ScopedMessage( ScopedMessage&& old ) - : m_info( old.m_info ), m_moved() - { - old.m_moved = true; - } - - ScopedMessage::~ScopedMessage() { - if ( !uncaught_exceptions() && !m_moved ){ - getResultCapture().popScopedMessage(m_info); - } - } - - Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) { - auto trimmed = [&] (size_t start, size_t end) { - while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) { - ++start; - } - while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) { - --end; - } - return names.substr(start, end - start + 1); - }; - auto skipq = [&] (size_t start, char quote) { - for (auto i = start + 1; i < names.size() ; ++i) { - if (names[i] == quote) - return i; - if (names[i] == '\\') - ++i; - } - CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote"); - }; - - size_t start = 0; - std::stack<char> openings; - for (size_t pos = 0; pos < names.size(); ++pos) { - char c = names[pos]; - switch (c) { - case '[': - case '{': - case '(': - // It is basically impossible to disambiguate between - // comparison and start of template args in this context -// case '<': - openings.push(c); - break; - case ']': - case '}': - case ')': -// case '>': - openings.pop(); - break; - case '"': - case '\'': - pos = skipq(pos, c); - break; - case ',': - if (start != pos && openings.size() == 0) { - m_messages.emplace_back(macroName, lineInfo, resultType); - m_messages.back().message = trimmed(start, pos); - m_messages.back().message += " := "; - start = pos; - } - } - } - assert(openings.size() == 0 && "Mismatched openings"); - m_messages.emplace_back(macroName, lineInfo, resultType); - m_messages.back().message = trimmed(start, names.size() - 1); - m_messages.back().message += " := "; - } - Capturer::~Capturer() { - if ( !uncaught_exceptions() ){ - assert( m_captured == m_messages.size() ); - for( size_t i = 0; i < m_captured; ++i ) - m_resultCapture.popScopedMessage( m_messages[i] ); - } - } - - void Capturer::captureValue( size_t index, std::string const& value ) { - assert( index < m_messages.size() ); - m_messages[index].message += value; - m_resultCapture.pushScopedMessage( m_messages[index] ); - m_captured++; - } - -} // end namespace Catch -// end catch_message.cpp -// start catch_output_redirect.cpp - -// start catch_output_redirect.h -#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H -#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H - -#include <cstdio> -#include <iosfwd> -#include <string> - -namespace Catch { - - class RedirectedStream { - std::ostream& m_originalStream; - std::ostream& m_redirectionStream; - std::streambuf* m_prevBuf; - - public: - RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ); - ~RedirectedStream(); - }; - - class RedirectedStdOut { - ReusableStringStream m_rss; - RedirectedStream m_cout; - public: - RedirectedStdOut(); - auto str() const -> std::string; - }; - - // StdErr has two constituent streams in C++, std::cerr and std::clog - // This means that we need to redirect 2 streams into 1 to keep proper - // order of writes - class RedirectedStdErr { - ReusableStringStream m_rss; - RedirectedStream m_cerr; - RedirectedStream m_clog; - public: - RedirectedStdErr(); - auto str() const -> std::string; - }; - - class RedirectedStreams { - public: - RedirectedStreams(RedirectedStreams const&) = delete; - RedirectedStreams& operator=(RedirectedStreams const&) = delete; - RedirectedStreams(RedirectedStreams&&) = delete; - RedirectedStreams& operator=(RedirectedStreams&&) = delete; - - RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr); - ~RedirectedStreams(); - private: - std::string& m_redirectedCout; - std::string& m_redirectedCerr; - RedirectedStdOut m_redirectedStdOut; - RedirectedStdErr m_redirectedStdErr; - }; - -#if defined(CATCH_CONFIG_NEW_CAPTURE) - - // Windows's implementation of std::tmpfile is terrible (it tries - // to create a file inside system folder, thus requiring elevated - // privileges for the binary), so we have to use tmpnam(_s) and - // create the file ourselves there. - class TempFile { - public: - TempFile(TempFile const&) = delete; - TempFile& operator=(TempFile const&) = delete; - TempFile(TempFile&&) = delete; - TempFile& operator=(TempFile&&) = delete; - - TempFile(); - ~TempFile(); - - std::FILE* getFile(); - std::string getContents(); - - private: - std::FILE* m_file = nullptr; - #if defined(_MSC_VER) - char m_buffer[L_tmpnam] = { 0 }; - #endif - }; - - class OutputRedirect { - public: - OutputRedirect(OutputRedirect const&) = delete; - OutputRedirect& operator=(OutputRedirect const&) = delete; - OutputRedirect(OutputRedirect&&) = delete; - OutputRedirect& operator=(OutputRedirect&&) = delete; - - OutputRedirect(std::string& stdout_dest, std::string& stderr_dest); - ~OutputRedirect(); - - private: - int m_originalStdout = -1; - int m_originalStderr = -1; - TempFile m_stdoutFile; - TempFile m_stderrFile; - std::string& m_stdoutDest; - std::string& m_stderrDest; - }; - -#endif - -} // end namespace Catch - -#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H -// end catch_output_redirect.h -#include <cstdio> -#include <cstring> -#include <fstream> -#include <sstream> -#include <stdexcept> - -#if defined(CATCH_CONFIG_NEW_CAPTURE) - #if defined(_MSC_VER) - #include <io.h> //_dup and _dup2 - #define dup _dup - #define dup2 _dup2 - #define fileno _fileno - #else - #include <unistd.h> // dup and dup2 - #endif -#endif - -namespace Catch { - - RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) - : m_originalStream( originalStream ), - m_redirectionStream( redirectionStream ), - m_prevBuf( m_originalStream.rdbuf() ) - { - m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); - } - - RedirectedStream::~RedirectedStream() { - m_originalStream.rdbuf( m_prevBuf ); - } - - RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} - auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); } - - RedirectedStdErr::RedirectedStdErr() - : m_cerr( Catch::cerr(), m_rss.get() ), - m_clog( Catch::clog(), m_rss.get() ) - {} - auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } - - RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr) - : m_redirectedCout(redirectedCout), - m_redirectedCerr(redirectedCerr) - {} - - RedirectedStreams::~RedirectedStreams() { - m_redirectedCout += m_redirectedStdOut.str(); - m_redirectedCerr += m_redirectedStdErr.str(); - } - -#if defined(CATCH_CONFIG_NEW_CAPTURE) - -#if defined(_MSC_VER) - TempFile::TempFile() { - if (tmpnam_s(m_buffer)) { - CATCH_RUNTIME_ERROR("Could not get a temp filename"); - } - if (fopen_s(&m_file, m_buffer, "w")) { - char buffer[100]; - if (strerror_s(buffer, errno)) { - CATCH_RUNTIME_ERROR("Could not translate errno to a string"); - } - CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer); - } - } -#else - TempFile::TempFile() { - m_file = std::tmpfile(); - if (!m_file) { - CATCH_RUNTIME_ERROR("Could not create a temp file."); - } - } - -#endif - - TempFile::~TempFile() { - // TBD: What to do about errors here? - std::fclose(m_file); - // We manually create the file on Windows only, on Linux - // it will be autodeleted -#if defined(_MSC_VER) - std::remove(m_buffer); -#endif - } - - FILE* TempFile::getFile() { - return m_file; - } - - std::string TempFile::getContents() { - std::stringstream sstr; - char buffer[100] = {}; - std::rewind(m_file); - while (std::fgets(buffer, sizeof(buffer), m_file)) { - sstr << buffer; - } - return sstr.str(); - } - - OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) : - m_originalStdout(dup(1)), - m_originalStderr(dup(2)), - m_stdoutDest(stdout_dest), - m_stderrDest(stderr_dest) { - dup2(fileno(m_stdoutFile.getFile()), 1); - dup2(fileno(m_stderrFile.getFile()), 2); - } - - OutputRedirect::~OutputRedirect() { - Catch::cout() << std::flush; - fflush(stdout); - // Since we support overriding these streams, we flush cerr - // even though std::cerr is unbuffered - Catch::cerr() << std::flush; - Catch::clog() << std::flush; - fflush(stderr); - - dup2(m_originalStdout, 1); - dup2(m_originalStderr, 2); - - m_stdoutDest += m_stdoutFile.getContents(); - m_stderrDest += m_stderrFile.getContents(); - } - -#endif // CATCH_CONFIG_NEW_CAPTURE - -} // namespace Catch - -#if defined(CATCH_CONFIG_NEW_CAPTURE) - #if defined(_MSC_VER) - #undef dup - #undef dup2 - #undef fileno - #endif -#endif -// end catch_output_redirect.cpp -// start catch_polyfills.cpp - -#include <cmath> - -namespace Catch { - -#if !defined(CATCH_CONFIG_POLYFILL_ISNAN) - bool isnan(float f) { - return std::isnan(f); - } - bool isnan(double d) { - return std::isnan(d); - } -#else - // For now we only use this for embarcadero - bool isnan(float f) { - return std::_isnan(f); - } - bool isnan(double d) { - return std::_isnan(d); - } -#endif - -} // end namespace Catch -// end catch_polyfills.cpp -// start catch_random_number_generator.cpp - -namespace Catch { - - std::mt19937& rng() { - static std::mt19937 s_rng; - return s_rng; - } - - void seedRng( IConfig const& config ) { - if( config.rngSeed() != 0 ) { - std::srand( config.rngSeed() ); - rng().seed( config.rngSeed() ); - } - } - - unsigned int rngSeed() { - return getCurrentContext().getConfig()->rngSeed(); - } -} -// end catch_random_number_generator.cpp -// start catch_registry_hub.cpp - -// start catch_test_case_registry_impl.h - -#include <vector> -#include <set> -#include <algorithm> -#include <ios> - -namespace Catch { - - class TestCase; - struct IConfig; - - std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ); - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - - void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ); - - std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ); - - class TestRegistry : public ITestCaseRegistry { - public: - virtual ~TestRegistry() = default; - - virtual void registerTest( TestCase const& testCase ); - - std::vector<TestCase> const& getAllTests() const override; - std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override; - - private: - std::vector<TestCase> m_functions; - mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder; - mutable std::vector<TestCase> m_sortedFunctions; - std::size_t m_unnamedCount = 0; - std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised - }; - - /////////////////////////////////////////////////////////////////////////// - - class TestInvokerAsFunction : public ITestInvoker { - void(*m_testAsFunction)(); - public: - TestInvokerAsFunction( void(*testAsFunction)() ) noexcept; - - void invoke() const override; - }; - - std::string extractClassName( StringRef const& classOrQualifiedMethodName ); - - /////////////////////////////////////////////////////////////////////////// - -} // end namespace Catch - -// end catch_test_case_registry_impl.h -// start catch_reporter_registry.h - -#include <map> - -namespace Catch { - - class ReporterRegistry : public IReporterRegistry { - - public: - - ~ReporterRegistry() override; - - IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override; - - void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ); - void registerListener( IReporterFactoryPtr const& factory ); - - FactoryMap const& getFactories() const override; - Listeners const& getListeners() const override; - - private: - FactoryMap m_factories; - Listeners m_listeners; - }; -} - -// end catch_reporter_registry.h -// start catch_tag_alias_registry.h - -// start catch_tag_alias.h - -#include <string> - -namespace Catch { - - struct TagAlias { - TagAlias(std::string const& _tag, SourceLineInfo _lineInfo); - - std::string tag; - SourceLineInfo lineInfo; - }; - -} // end namespace Catch - -// end catch_tag_alias.h -#include <map> - -namespace Catch { - - class TagAliasRegistry : public ITagAliasRegistry { - public: - ~TagAliasRegistry() override; - TagAlias const* find( std::string const& alias ) const override; - std::string expandAliases( std::string const& unexpandedTestSpec ) const override; - void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); - - private: - std::map<std::string, TagAlias> m_registry; - }; - -} // end namespace Catch - -// end catch_tag_alias_registry.h -// start catch_startup_exception_registry.h - -#include <vector> -#include <exception> - -namespace Catch { - - class StartupExceptionRegistry { - public: - void add(std::exception_ptr const& exception) noexcept; - std::vector<std::exception_ptr> const& getExceptions() const noexcept; - private: - std::vector<std::exception_ptr> m_exceptions; - }; - -} // end namespace Catch - -// end catch_startup_exception_registry.h -// start catch_singletons.hpp - -namespace Catch { - - struct ISingleton { - virtual ~ISingleton(); - }; - - void addSingleton( ISingleton* singleton ); - void cleanupSingletons(); - - template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT> - class Singleton : SingletonImplT, public ISingleton { - - static auto getInternal() -> Singleton* { - static Singleton* s_instance = nullptr; - if( !s_instance ) { - s_instance = new Singleton; - addSingleton( s_instance ); - } - return s_instance; - } - - public: - static auto get() -> InterfaceT const& { - return *getInternal(); - } - static auto getMutable() -> MutableInterfaceT& { - return *getInternal(); - } - }; - -} // namespace Catch - -// end catch_singletons.hpp -namespace Catch { - - namespace { - - class RegistryHub : public IRegistryHub, public IMutableRegistryHub, - private NonCopyable { - - public: // IRegistryHub - RegistryHub() = default; - IReporterRegistry const& getReporterRegistry() const override { - return m_reporterRegistry; - } - ITestCaseRegistry const& getTestCaseRegistry() const override { - return m_testCaseRegistry; - } - IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override { - return m_exceptionTranslatorRegistry; - } - ITagAliasRegistry const& getTagAliasRegistry() const override { - return m_tagAliasRegistry; - } - StartupExceptionRegistry const& getStartupExceptionRegistry() const override { - return m_exceptionRegistry; - } - - public: // IMutableRegistryHub - void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override { - m_reporterRegistry.registerReporter( name, factory ); - } - void registerListener( IReporterFactoryPtr const& factory ) override { - m_reporterRegistry.registerListener( factory ); - } - void registerTest( TestCase const& testInfo ) override { - m_testCaseRegistry.registerTest( testInfo ); - } - void registerTranslator( const IExceptionTranslator* translator ) override { - m_exceptionTranslatorRegistry.registerTranslator( translator ); - } - void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override { - m_tagAliasRegistry.add( alias, tag, lineInfo ); - } - void registerStartupException() noexcept override { - m_exceptionRegistry.add(std::current_exception()); - } - IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { - return m_enumValuesRegistry; - } - - private: - TestRegistry m_testCaseRegistry; - ReporterRegistry m_reporterRegistry; - ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; - TagAliasRegistry m_tagAliasRegistry; - StartupExceptionRegistry m_exceptionRegistry; - Detail::EnumValuesRegistry m_enumValuesRegistry; - }; - } - - using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>; - - IRegistryHub const& getRegistryHub() { - return RegistryHubSingleton::get(); - } - IMutableRegistryHub& getMutableRegistryHub() { - return RegistryHubSingleton::getMutable(); - } - void cleanUp() { - cleanupSingletons(); - cleanUpContext(); - } - std::string translateActiveException() { - return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); - } - -} // end namespace Catch -// end catch_registry_hub.cpp -// start catch_reporter_registry.cpp - -namespace Catch { - - ReporterRegistry::~ReporterRegistry() = default; - - IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const { - auto it = m_factories.find( name ); - if( it == m_factories.end() ) - return nullptr; - return it->second->create( ReporterConfig( config ) ); - } - - void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) { - m_factories.emplace(name, factory); - } - void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) { - m_listeners.push_back( factory ); - } - - IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const { - return m_factories; - } - IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const { - return m_listeners; - } - -} -// end catch_reporter_registry.cpp -// start catch_result_type.cpp - -namespace Catch { - - bool isOk( ResultWas::OfType resultType ) { - return ( resultType & ResultWas::FailureBit ) == 0; - } - bool isJustInfo( int flags ) { - return flags == ResultWas::Info; - } - - ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { - return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); - } - - bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } - bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } - -} // end namespace Catch -// end catch_result_type.cpp -// start catch_run_context.cpp - -#include <cassert> -#include <algorithm> -#include <sstream> - -namespace Catch { - - namespace Generators { - struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker { - GeneratorBasePtr m_generator; - - GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : TrackerBase( nameAndLocation, ctx, parent ) - {} - ~GeneratorTracker(); - - static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) { - std::shared_ptr<GeneratorTracker> tracker; - - ITracker& currentTracker = ctx.currentTracker(); - if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { - assert( childTracker ); - assert( childTracker->isGeneratorTracker() ); - tracker = std::static_pointer_cast<GeneratorTracker>( childTracker ); - } - else { - tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, ¤tTracker ); - currentTracker.addChild( tracker ); - } - - if( !ctx.completedCycle() && !tracker->isComplete() ) { - tracker->open(); - } - - return *tracker; - } - - // TrackerBase interface - bool isGeneratorTracker() const override { return true; } - auto hasGenerator() const -> bool override { - return !!m_generator; - } - void close() override { - TrackerBase::close(); - // Generator interface only finds out if it has another item on atual move - if (m_runState == CompletedSuccessfully && m_generator->next()) { - m_children.clear(); - m_runState = Executing; - } - } - - // IGeneratorTracker interface - auto getGenerator() const -> GeneratorBasePtr const& override { - return m_generator; - } - void setGenerator( GeneratorBasePtr&& generator ) override { - m_generator = std::move( generator ); - } - }; - GeneratorTracker::~GeneratorTracker() {} - } - - RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) - : m_runInfo(_config->name()), - m_context(getCurrentMutableContext()), - m_config(_config), - m_reporter(std::move(reporter)), - m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal }, - m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions ) - { - m_context.setRunner(this); - m_context.setConfig(m_config); - m_context.setResultCapture(this); - m_reporter->testRunStarting(m_runInfo); - } - - RunContext::~RunContext() { - m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting())); - } - - void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) { - m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount)); - } - - void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) { - m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting())); - } - - Totals RunContext::runTest(TestCase const& testCase) { - Totals prevTotals = m_totals; - - std::string redirectedCout; - std::string redirectedCerr; - - auto const& testInfo = testCase.getTestCaseInfo(); - - m_reporter->testCaseStarting(testInfo); - - m_activeTestCase = &testCase; - - ITracker& rootTracker = m_trackerContext.startRun(); - assert(rootTracker.isSectionTracker()); - static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun()); - do { - m_trackerContext.startCycle(); - m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); - runCurrentTest(redirectedCout, redirectedCerr); - } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting()); - - Totals deltaTotals = m_totals.delta(prevTotals); - if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) { - deltaTotals.assertions.failed++; - deltaTotals.testCases.passed--; - deltaTotals.testCases.failed++; - } - m_totals.testCases += deltaTotals.testCases; - m_reporter->testCaseEnded(TestCaseStats(testInfo, - deltaTotals, - redirectedCout, - redirectedCerr, - aborting())); - - m_activeTestCase = nullptr; - m_testCaseTracker = nullptr; - - return deltaTotals; - } - - IConfigPtr RunContext::config() const { - return m_config; - } - - IStreamingReporter& RunContext::reporter() const { - return *m_reporter; - } - - void RunContext::assertionEnded(AssertionResult const & result) { - if (result.getResultType() == ResultWas::Ok) { - m_totals.assertions.passed++; - m_lastAssertionPassed = true; - } else if (!result.isOk()) { - m_lastAssertionPassed = false; - if( m_activeTestCase->getTestCaseInfo().okToFail() ) - m_totals.assertions.failedButOk++; - else - m_totals.assertions.failed++; - } - else { - m_lastAssertionPassed = true; - } - - // We have no use for the return value (whether messages should be cleared), because messages were made scoped - // and should be let to clear themselves out. - static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); - - if (result.getResultType() != ResultWas::Warning) - m_messageScopes.clear(); - - // Reset working state - resetAssertionInfo(); - m_lastResult = result; - } - void RunContext::resetAssertionInfo() { - m_lastAssertionInfo.macroName = StringRef(); - m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; - } - - bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { - ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); - if (!sectionTracker.isOpen()) - return false; - m_activeSections.push_back(§ionTracker); - - m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; - - m_reporter->sectionStarting(sectionInfo); - - assertions = m_totals.assertions; - - return true; - } - auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { - using namespace Generators; - GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) ); - assert( tracker.isOpen() ); - m_lastAssertionInfo.lineInfo = lineInfo; - return tracker; - } - - bool RunContext::testForMissingAssertions(Counts& assertions) { - if (assertions.total() != 0) - return false; - if (!m_config->warnAboutMissingAssertions()) - return false; - if (m_trackerContext.currentTracker().hasChildren()) - return false; - m_totals.assertions.failed++; - assertions.failed++; - return true; - } - - void RunContext::sectionEnded(SectionEndInfo const & endInfo) { - Counts assertions = m_totals.assertions - endInfo.prevAssertions; - bool missingAssertions = testForMissingAssertions(assertions); - - if (!m_activeSections.empty()) { - m_activeSections.back()->close(); - m_activeSections.pop_back(); - } - - m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); - m_messages.clear(); - m_messageScopes.clear(); - } - - void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { - if (m_unfinishedSections.empty()) - m_activeSections.back()->fail(); - else - m_activeSections.back()->close(); - m_activeSections.pop_back(); - - m_unfinishedSections.push_back(endInfo); - } - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void RunContext::benchmarkPreparing(std::string const& name) { - m_reporter->benchmarkPreparing(name); - } - void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { - m_reporter->benchmarkStarting( info ); - } - void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) { - m_reporter->benchmarkEnded( stats ); - } - void RunContext::benchmarkFailed(std::string const & error) { - m_reporter->benchmarkFailed(error); - } -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - void RunContext::pushScopedMessage(MessageInfo const & message) { - m_messages.push_back(message); - } - - void RunContext::popScopedMessage(MessageInfo const & message) { - m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); - } - - void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) { - m_messageScopes.emplace_back( builder ); - } - - std::string RunContext::getCurrentTestName() const { - return m_activeTestCase - ? m_activeTestCase->getTestCaseInfo().name - : std::string(); - } - - const AssertionResult * RunContext::getLastResult() const { - return &(*m_lastResult); - } - - void RunContext::exceptionEarlyReported() { - m_shouldReportUnexpected = false; - } - - void RunContext::handleFatalErrorCondition( StringRef message ) { - // First notify reporter that bad things happened - m_reporter->fatalErrorEncountered(message); - - // Don't rebuild the result -- the stringification itself can cause more fatal errors - // Instead, fake a result data. - AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); - tempResult.message = message; - AssertionResult result(m_lastAssertionInfo, tempResult); - - assertionEnded(result); - - handleUnfinishedSections(); - - // Recreate section for test case (as we will lose the one that was in scope) - auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name); - - Counts assertions; - assertions.failed = 1; - SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); - m_reporter->sectionEnded(testCaseSectionStats); - - auto const& testInfo = m_activeTestCase->getTestCaseInfo(); - - Totals deltaTotals; - deltaTotals.testCases.failed = 1; - deltaTotals.assertions.failed = 1; - m_reporter->testCaseEnded(TestCaseStats(testInfo, - deltaTotals, - std::string(), - std::string(), - false)); - m_totals.testCases.failed++; - testGroupEnded(std::string(), m_totals, 1, 1); - m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); - } - - bool RunContext::lastAssertionPassed() { - return m_lastAssertionPassed; - } - - void RunContext::assertionPassed() { - m_lastAssertionPassed = true; - ++m_totals.assertions.passed; - resetAssertionInfo(); - m_messageScopes.clear(); - } - - bool RunContext::aborting() const { - return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter()); - } - - void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) { - auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name); - m_reporter->sectionStarting(testCaseSection); - Counts prevAssertions = m_totals.assertions; - double duration = 0; - m_shouldReportUnexpected = true; - m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal }; - - seedRng(*m_config); - - Timer timer; - CATCH_TRY { - if (m_reporter->getPreferences().shouldRedirectStdOut) { -#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) - RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr); - - timer.start(); - invokeActiveTestCase(); -#else - OutputRedirect r(redirectedCout, redirectedCerr); - timer.start(); - invokeActiveTestCase(); -#endif - } else { - timer.start(); - invokeActiveTestCase(); - } - duration = timer.getElapsedSeconds(); - } CATCH_CATCH_ANON (TestFailureException&) { - // This just means the test was aborted due to failure - } CATCH_CATCH_ALL { - // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions - // are reported without translation at the point of origin. - if( m_shouldReportUnexpected ) { - AssertionReaction dummyReaction; - handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction ); - } - } - Counts assertions = m_totals.assertions - prevAssertions; - bool missingAssertions = testForMissingAssertions(assertions); - - m_testCaseTracker->close(); - handleUnfinishedSections(); - m_messages.clear(); - m_messageScopes.clear(); - - SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); - m_reporter->sectionEnded(testCaseSectionStats); - } - - void RunContext::invokeActiveTestCase() { - FatalConditionHandler fatalConditionHandler; // Handle signals - m_activeTestCase->invoke(); - fatalConditionHandler.reset(); - } - - void RunContext::handleUnfinishedSections() { - // If sections ended prematurely due to an exception we stored their - // infos here so we can tear them down outside the unwind process. - for (auto it = m_unfinishedSections.rbegin(), - itEnd = m_unfinishedSections.rend(); - it != itEnd; - ++it) - sectionEnded(*it); - m_unfinishedSections.clear(); - } - - void RunContext::handleExpr( - AssertionInfo const& info, - ITransientExpression const& expr, - AssertionReaction& reaction - ) { - m_reporter->assertionStarting( info ); - - bool negated = isFalseTest( info.resultDisposition ); - bool result = expr.getResult() != negated; - - if( result ) { - if (!m_includeSuccessfulResults) { - assertionPassed(); - } - else { - reportExpr(info, ResultWas::Ok, &expr, negated); - } - } - else { - reportExpr(info, ResultWas::ExpressionFailed, &expr, negated ); - populateReaction( reaction ); - } - } - void RunContext::reportExpr( - AssertionInfo const &info, - ResultWas::OfType resultType, - ITransientExpression const *expr, - bool negated ) { - - m_lastAssertionInfo = info; - AssertionResultData data( resultType, LazyExpression( negated ) ); - - AssertionResult assertionResult{ info, data }; - assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; - - assertionEnded( assertionResult ); - } - - void RunContext::handleMessage( - AssertionInfo const& info, - ResultWas::OfType resultType, - StringRef const& message, - AssertionReaction& reaction - ) { - m_reporter->assertionStarting( info ); - - m_lastAssertionInfo = info; - - AssertionResultData data( resultType, LazyExpression( false ) ); - data.message = message; - AssertionResult assertionResult{ m_lastAssertionInfo, data }; - assertionEnded( assertionResult ); - if( !assertionResult.isOk() ) - populateReaction( reaction ); - } - void RunContext::handleUnexpectedExceptionNotThrown( - AssertionInfo const& info, - AssertionReaction& reaction - ) { - handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction); - } - - void RunContext::handleUnexpectedInflightException( - AssertionInfo const& info, - std::string const& message, - AssertionReaction& reaction - ) { - m_lastAssertionInfo = info; - - AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); - data.message = message; - AssertionResult assertionResult{ info, data }; - assertionEnded( assertionResult ); - populateReaction( reaction ); - } - - void RunContext::populateReaction( AssertionReaction& reaction ) { - reaction.shouldDebugBreak = m_config->shouldDebugBreak(); - reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal); - } - - void RunContext::handleIncomplete( - AssertionInfo const& info - ) { - m_lastAssertionInfo = info; - - AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); - data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; - AssertionResult assertionResult{ info, data }; - assertionEnded( assertionResult ); - } - void RunContext::handleNonExpr( - AssertionInfo const &info, - ResultWas::OfType resultType, - AssertionReaction &reaction - ) { - m_lastAssertionInfo = info; - - AssertionResultData data( resultType, LazyExpression( false ) ); - AssertionResult assertionResult{ info, data }; - assertionEnded( assertionResult ); - - if( !assertionResult.isOk() ) - populateReaction( reaction ); - } - - IResultCapture& getResultCapture() { - if (auto* capture = getCurrentContext().getResultCapture()) - return *capture; - else - CATCH_INTERNAL_ERROR("No result capture instance"); - } -} -// end catch_run_context.cpp -// start catch_section.cpp - -namespace Catch { - - Section::Section( SectionInfo const& info ) - : m_info( info ), - m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) - { - m_timer.start(); - } - - Section::~Section() { - if( m_sectionIncluded ) { - SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() }; - if( uncaught_exceptions() ) - getResultCapture().sectionEndedEarly( endInfo ); - else - getResultCapture().sectionEnded( endInfo ); - } - } - - // This indicates whether the section should be executed or not - Section::operator bool() const { - return m_sectionIncluded; - } - -} // end namespace Catch -// end catch_section.cpp -// start catch_section_info.cpp - -namespace Catch { - - SectionInfo::SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name ) - : name( _name ), - lineInfo( _lineInfo ) - {} - -} // end namespace Catch -// end catch_section_info.cpp -// start catch_session.cpp - -// start catch_session.h - -#include <memory> - -namespace Catch { - - class Session : NonCopyable { - public: - - Session(); - ~Session() override; - - void showHelp() const; - void libIdentify(); - - int applyCommandLine( int argc, char const * const * argv ); - #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) - int applyCommandLine( int argc, wchar_t const * const * argv ); - #endif - - void useConfigData( ConfigData const& configData ); - - template<typename CharT> - int run(int argc, CharT const * const argv[]) { - if (m_startupExceptions) - return 1; - int returnCode = applyCommandLine(argc, argv); - if (returnCode == 0) - returnCode = run(); - return returnCode; - } - - int run(); - - clara::Parser const& cli() const; - void cli( clara::Parser const& newParser ); - ConfigData& configData(); - Config& config(); - private: - int runInternal(); - - clara::Parser m_cli; - ConfigData m_configData; - std::shared_ptr<Config> m_config; - bool m_startupExceptions = false; - }; - -} // end namespace Catch - -// end catch_session.h -// start catch_version.h - -#include <iosfwd> - -namespace Catch { - - // Versioning information - struct Version { - Version( Version const& ) = delete; - Version& operator=( Version const& ) = delete; - Version( unsigned int _majorVersion, - unsigned int _minorVersion, - unsigned int _patchNumber, - char const * const _branchName, - unsigned int _buildNumber ); - - unsigned int const majorVersion; - unsigned int const minorVersion; - unsigned int const patchNumber; - - // buildNumber is only used if branchName is not null - char const * const branchName; - unsigned int const buildNumber; - - friend std::ostream& operator << ( std::ostream& os, Version const& version ); - }; - - Version const& libraryVersion(); -} - -// end catch_version.h -#include <cstdlib> -#include <iomanip> - -namespace Catch { - - namespace { - const int MaxExitCode = 255; - - IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) { - auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config); - CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'"); - - return reporter; - } - - IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) { - if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) { - return createReporter(config->getReporterName(), config); - } - - // On older platforms, returning std::unique_ptr<ListeningReporter> - // when the return type is std::unique_ptr<IStreamingReporter> - // doesn't compile without a std::move call. However, this causes - // a warning on newer platforms. Thus, we have to work around - // it a bit and downcast the pointer manually. - auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter); - auto& multi = static_cast<ListeningReporter&>(*ret); - auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); - for (auto const& listener : listeners) { - multi.addListener(listener->create(Catch::ReporterConfig(config))); - } - multi.addReporter(createReporter(config->getReporterName(), config)); - return ret; - } - - Catch::Totals runTests(std::shared_ptr<Config> const& config) { - auto reporter = makeReporter(config); - - RunContext context(config, std::move(reporter)); - - Totals totals; - - context.testGroupStarting(config->name(), 1, 1); - - TestSpec testSpec = config->testSpec(); - - auto const& allTestCases = getAllTestCasesSorted(*config); - for (auto const& testCase : allTestCases) { - bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) || - (testSpec.hasFilters() && matchTest(testCase, testSpec, *config)); - - if (!context.aborting() && matching) - totals += context.runTest(testCase); - else - context.reporter().skipTest(testCase); - } - - if (config->warnAboutNoTests() && totals.testCases.total() == 0) { - ReusableStringStream testConfig; - - bool first = true; - for (const auto& input : config->getTestsOrTags()) { - if (!first) { testConfig << ' '; } - first = false; - testConfig << input; - } - - context.reporter().noMatchingTestCases(testConfig.str()); - totals.error = -1; - } - - context.testGroupEnded(config->name(), totals, 1, 1); - return totals; - } - - void applyFilenamesAsTags(Catch::IConfig const& config) { - auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config)); - for (auto& testCase : tests) { - auto tags = testCase.tags; - - std::string filename = testCase.lineInfo.file; - auto lastSlash = filename.find_last_of("\\/"); - if (lastSlash != std::string::npos) { - filename.erase(0, lastSlash); - filename[0] = '#'; - } - - auto lastDot = filename.find_last_of('.'); - if (lastDot != std::string::npos) { - filename.erase(lastDot); - } - - tags.push_back(std::move(filename)); - setTags(testCase, tags); - } - } - - } // anon namespace - - Session::Session() { - static bool alreadyInstantiated = false; - if( alreadyInstantiated ) { - CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); } - CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); } - } - - // There cannot be exceptions at startup in no-exception mode. -#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions(); - if ( !exceptions.empty() ) { - config(); - getCurrentMutableContext().setConfig(m_config); - - m_startupExceptions = true; - Colour colourGuard( Colour::Red ); - Catch::cerr() << "Errors occurred during startup!" << '\n'; - // iterate over all exceptions and notify user - for ( const auto& ex_ptr : exceptions ) { - try { - std::rethrow_exception(ex_ptr); - } catch ( std::exception const& ex ) { - Catch::cerr() << Column( ex.what() ).indent(2) << '\n'; - } - } - } -#endif - - alreadyInstantiated = true; - m_cli = makeCommandLineParser( m_configData ); - } - Session::~Session() { - Catch::cleanUp(); - } - - void Session::showHelp() const { - Catch::cout() - << "\nCatch v" << libraryVersion() << "\n" - << m_cli << std::endl - << "For more detailed usage please see the project docs\n" << std::endl; - } - void Session::libIdentify() { - Catch::cout() - << std::left << std::setw(16) << "description: " << "A Catch test executable\n" - << std::left << std::setw(16) << "category: " << "testframework\n" - << std::left << std::setw(16) << "framework: " << "Catch Test\n" - << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; - } - - int Session::applyCommandLine( int argc, char const * const * argv ) { - if( m_startupExceptions ) - return 1; - - auto result = m_cli.parse( clara::Args( argc, argv ) ); - if( !result ) { - config(); - getCurrentMutableContext().setConfig(m_config); - Catch::cerr() - << Colour( Colour::Red ) - << "\nError(s) in input:\n" - << Column( result.errorMessage() ).indent( 2 ) - << "\n\n"; - Catch::cerr() << "Run with -? for usage\n" << std::endl; - return MaxExitCode; - } - - if( m_configData.showHelp ) - showHelp(); - if( m_configData.libIdentify ) - libIdentify(); - m_config.reset(); - return 0; - } - -#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) - int Session::applyCommandLine( int argc, wchar_t const * const * argv ) { - - char **utf8Argv = new char *[ argc ]; - - for ( int i = 0; i < argc; ++i ) { - int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); - - utf8Argv[ i ] = new char[ bufSize ]; - - WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); - } - - int returnCode = applyCommandLine( argc, utf8Argv ); - - for ( int i = 0; i < argc; ++i ) - delete [] utf8Argv[ i ]; - - delete [] utf8Argv; - - return returnCode; - } -#endif - - void Session::useConfigData( ConfigData const& configData ) { - m_configData = configData; - m_config.reset(); - } - - int Session::run() { - if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { - Catch::cout() << "...waiting for enter/ return before starting" << std::endl; - static_cast<void>(std::getchar()); - } - int exitCode = runInternal(); - if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { - Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; - static_cast<void>(std::getchar()); - } - return exitCode; - } - - clara::Parser const& Session::cli() const { - return m_cli; - } - void Session::cli( clara::Parser const& newParser ) { - m_cli = newParser; - } - ConfigData& Session::configData() { - return m_configData; - } - Config& Session::config() { - if( !m_config ) - m_config = std::make_shared<Config>( m_configData ); - return *m_config; - } - - int Session::runInternal() { - if( m_startupExceptions ) - return 1; - - if (m_configData.showHelp || m_configData.libIdentify) { - return 0; - } - - CATCH_TRY { - config(); // Force config to be constructed - - seedRng( *m_config ); - - if( m_configData.filenamesAsTags ) - applyFilenamesAsTags( *m_config ); - - // Handle list request - if( Option<std::size_t> listed = list( m_config ) ) - return static_cast<int>( *listed ); - - auto totals = runTests( m_config ); - // Note that on unices only the lower 8 bits are usually used, clamping - // the return value to 255 prevents false negative when some multiple - // of 256 tests has failed - return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed))); - } -#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - catch( std::exception& ex ) { - Catch::cerr() << ex.what() << std::endl; - return MaxExitCode; - } -#endif - } - -} // end namespace Catch -// end catch_session.cpp -// start catch_singletons.cpp - -#include <vector> - -namespace Catch { - - namespace { - static auto getSingletons() -> std::vector<ISingleton*>*& { - static std::vector<ISingleton*>* g_singletons = nullptr; - if( !g_singletons ) - g_singletons = new std::vector<ISingleton*>(); - return g_singletons; - } - } - - ISingleton::~ISingleton() {} - - void addSingleton(ISingleton* singleton ) { - getSingletons()->push_back( singleton ); - } - void cleanupSingletons() { - auto& singletons = getSingletons(); - for( auto singleton : *singletons ) - delete singleton; - delete singletons; - singletons = nullptr; - } - -} // namespace Catch -// end catch_singletons.cpp -// start catch_startup_exception_registry.cpp - -namespace Catch { -void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { - CATCH_TRY { - m_exceptions.push_back(exception); - } CATCH_CATCH_ALL { - // If we run out of memory during start-up there's really not a lot more we can do about it - std::terminate(); - } - } - - std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept { - return m_exceptions; - } - -} // end namespace Catch -// end catch_startup_exception_registry.cpp -// start catch_stream.cpp - -#include <cstdio> -#include <iostream> -#include <fstream> -#include <sstream> -#include <vector> -#include <memory> - -namespace Catch { - - Catch::IStream::~IStream() = default; - - namespace Detail { namespace { - template<typename WriterF, std::size_t bufferSize=256> - class StreamBufImpl : public std::streambuf { - char data[bufferSize]; - WriterF m_writer; - - public: - StreamBufImpl() { - setp( data, data + sizeof(data) ); - } - - ~StreamBufImpl() noexcept { - StreamBufImpl::sync(); - } - - private: - int overflow( int c ) override { - sync(); - - if( c != EOF ) { - if( pbase() == epptr() ) - m_writer( std::string( 1, static_cast<char>( c ) ) ); - else - sputc( static_cast<char>( c ) ); - } - return 0; - } - - int sync() override { - if( pbase() != pptr() ) { - m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); - setp( pbase(), epptr() ); - } - return 0; - } - }; - - /////////////////////////////////////////////////////////////////////////// - - struct OutputDebugWriter { - - void operator()( std::string const&str ) { - writeToDebugConsole( str ); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - class FileStream : public IStream { - mutable std::ofstream m_ofs; - public: - FileStream( StringRef filename ) { - m_ofs.open( filename.c_str() ); - CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" ); - } - ~FileStream() override = default; - public: // IStream - std::ostream& stream() const override { - return m_ofs; - } - }; - - /////////////////////////////////////////////////////////////////////////// - - class CoutStream : public IStream { - mutable std::ostream m_os; - public: - // Store the streambuf from cout up-front because - // cout may get redirected when running tests - CoutStream() : m_os( Catch::cout().rdbuf() ) {} - ~CoutStream() override = default; - - public: // IStream - std::ostream& stream() const override { return m_os; } - }; - - /////////////////////////////////////////////////////////////////////////// - - class DebugOutStream : public IStream { - std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf; - mutable std::ostream m_os; - public: - DebugOutStream() - : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ), - m_os( m_streamBuf.get() ) - {} - - ~DebugOutStream() override = default; - - public: // IStream - std::ostream& stream() const override { return m_os; } - }; - - }} // namespace anon::detail - - /////////////////////////////////////////////////////////////////////////// - - auto makeStream( StringRef const &filename ) -> IStream const* { - if( filename.empty() ) - return new Detail::CoutStream(); - else if( filename[0] == '%' ) { - if( filename == "%debug" ) - return new Detail::DebugOutStream(); - else - CATCH_ERROR( "Unrecognised stream: '" << filename << "'" ); - } - else - return new Detail::FileStream( filename ); - } - - // This class encapsulates the idea of a pool of ostringstreams that can be reused. - struct StringStreams { - std::vector<std::unique_ptr<std::ostringstream>> m_streams; - std::vector<std::size_t> m_unused; - std::ostringstream m_referenceStream; // Used for copy state/ flags from - - auto add() -> std::size_t { - if( m_unused.empty() ) { - m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) ); - return m_streams.size()-1; - } - else { - auto index = m_unused.back(); - m_unused.pop_back(); - return index; - } - } - - void release( std::size_t index ) { - m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state - m_unused.push_back(index); - } - }; - - ReusableStringStream::ReusableStringStream() - : m_index( Singleton<StringStreams>::getMutable().add() ), - m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() ) - {} - - ReusableStringStream::~ReusableStringStream() { - static_cast<std::ostringstream*>( m_oss )->str(""); - m_oss->clear(); - Singleton<StringStreams>::getMutable().release( m_index ); - } - - auto ReusableStringStream::str() const -> std::string { - return static_cast<std::ostringstream*>( m_oss )->str(); - } - - /////////////////////////////////////////////////////////////////////////// - -#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions - std::ostream& cout() { return std::cout; } - std::ostream& cerr() { return std::cerr; } - std::ostream& clog() { return std::clog; } -#endif -} -// end catch_stream.cpp -// start catch_string_manip.cpp - -#include <algorithm> -#include <ostream> -#include <cstring> -#include <cctype> -#include <vector> - -namespace Catch { - - namespace { - char toLowerCh(char c) { - return static_cast<char>( std::tolower( c ) ); - } - } - - bool startsWith( std::string const& s, std::string const& prefix ) { - return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); - } - bool startsWith( std::string const& s, char prefix ) { - return !s.empty() && s[0] == prefix; - } - bool endsWith( std::string const& s, std::string const& suffix ) { - return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); - } - bool endsWith( std::string const& s, char suffix ) { - return !s.empty() && s[s.size()-1] == suffix; - } - bool contains( std::string const& s, std::string const& infix ) { - return s.find( infix ) != std::string::npos; - } - void toLowerInPlace( std::string& s ) { - std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); - } - std::string toLower( std::string const& s ) { - std::string lc = s; - toLowerInPlace( lc ); - return lc; - } - std::string trim( std::string const& str ) { - static char const* whitespaceChars = "\n\r\t "; - std::string::size_type start = str.find_first_not_of( whitespaceChars ); - std::string::size_type end = str.find_last_not_of( whitespaceChars ); - - return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); - } - - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { - bool replaced = false; - std::size_t i = str.find( replaceThis ); - while( i != std::string::npos ) { - replaced = true; - str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); - if( i < str.size()-withThis.size() ) - i = str.find( replaceThis, i+withThis.size() ); - else - i = std::string::npos; - } - return replaced; - } - - std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) { - std::vector<StringRef> subStrings; - std::size_t start = 0; - for(std::size_t pos = 0; pos < str.size(); ++pos ) { - if( str[pos] == delimiter ) { - if( pos - start > 1 ) - subStrings.push_back( str.substr( start, pos-start ) ); - start = pos+1; - } - } - if( start < str.size() ) - subStrings.push_back( str.substr( start, str.size()-start ) ); - return subStrings; - } - - pluralise::pluralise( std::size_t count, std::string const& label ) - : m_count( count ), - m_label( label ) - {} - - std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { - os << pluraliser.m_count << ' ' << pluraliser.m_label; - if( pluraliser.m_count != 1 ) - os << 's'; - return os; - } - -} -// end catch_string_manip.cpp -// start catch_stringref.cpp - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wexit-time-destructors" -#endif - -#include <ostream> -#include <cstring> -#include <cstdint> - -namespace { - const uint32_t byte_2_lead = 0xC0; - const uint32_t byte_3_lead = 0xE0; - const uint32_t byte_4_lead = 0xF0; -} - -namespace Catch { - StringRef::StringRef( char const* rawChars ) noexcept - : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) ) - {} - - StringRef::operator std::string() const { - return std::string( m_start, m_size ); - } - - void StringRef::swap( StringRef& other ) noexcept { - std::swap( m_start, other.m_start ); - std::swap( m_size, other.m_size ); - std::swap( m_data, other.m_data ); - } - - auto StringRef::c_str() const -> char const* { - if( !isSubstring() ) - return m_start; - - const_cast<StringRef *>( this )->takeOwnership(); - return m_data; - } - auto StringRef::currentData() const noexcept -> char const* { - return m_start; - } - - auto StringRef::isOwned() const noexcept -> bool { - return m_data != nullptr; - } - auto StringRef::isSubstring() const noexcept -> bool { - return m_start[m_size] != '\0'; - } - - void StringRef::takeOwnership() { - if( !isOwned() ) { - m_data = new char[m_size+1]; - memcpy( m_data, m_start, m_size ); - m_data[m_size] = '\0'; - } - } - auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef { - if( start < m_size ) - return StringRef( m_start+start, size ); - else - return StringRef(); - } - auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool { - return - size() == other.size() && - (std::strncmp( m_start, other.m_start, size() ) == 0); - } - auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool { - return !operator==( other ); - } - - auto StringRef::operator[](size_type index) const noexcept -> char { - return m_start[index]; - } - - auto StringRef::numberOfCharacters() const noexcept -> size_type { - size_type noChars = m_size; - // Make adjustments for uft encodings - for( size_type i=0; i < m_size; ++i ) { - char c = m_start[i]; - if( ( c & byte_2_lead ) == byte_2_lead ) { - noChars--; - if (( c & byte_3_lead ) == byte_3_lead ) - noChars--; - if( ( c & byte_4_lead ) == byte_4_lead ) - noChars--; - } - } - return noChars; - } - - auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string { - std::string str; - str.reserve( lhs.size() + rhs.size() ); - str += lhs; - str += rhs; - return str; - } - auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string { - return std::string( lhs ) + std::string( rhs ); - } - auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string { - return std::string( lhs ) + std::string( rhs ); - } - - auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& { - return os.write(str.currentData(), str.size()); - } - - auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& { - lhs.append(rhs.currentData(), rhs.size()); - return lhs; - } - -} // namespace Catch - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif -// end catch_stringref.cpp -// start catch_tag_alias.cpp - -namespace Catch { - TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {} -} -// end catch_tag_alias.cpp -// start catch_tag_alias_autoregistrar.cpp - -namespace Catch { - - RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) { - CATCH_TRY { - getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); - } CATCH_CATCH_ALL { - // Do not throw when constructing global objects, instead register the exception to be processed later - getMutableRegistryHub().registerStartupException(); - } - } - -} -// end catch_tag_alias_autoregistrar.cpp -// start catch_tag_alias_registry.cpp - -#include <sstream> - -namespace Catch { - - TagAliasRegistry::~TagAliasRegistry() {} - - TagAlias const* TagAliasRegistry::find( std::string const& alias ) const { - auto it = m_registry.find( alias ); - if( it != m_registry.end() ) - return &(it->second); - else - return nullptr; - } - - std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { - std::string expandedTestSpec = unexpandedTestSpec; - for( auto const& registryKvp : m_registry ) { - std::size_t pos = expandedTestSpec.find( registryKvp.first ); - if( pos != std::string::npos ) { - expandedTestSpec = expandedTestSpec.substr( 0, pos ) + - registryKvp.second.tag + - expandedTestSpec.substr( pos + registryKvp.first.size() ); - } - } - return expandedTestSpec; - } - - void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { - CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'), - "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo ); - - CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second, - "error: tag alias, '" << alias << "' already registered.\n" - << "\tFirst seen at: " << find(alias)->lineInfo << "\n" - << "\tRedefined at: " << lineInfo ); - } - - ITagAliasRegistry::~ITagAliasRegistry() {} - - ITagAliasRegistry const& ITagAliasRegistry::get() { - return getRegistryHub().getTagAliasRegistry(); - } - -} // end namespace Catch -// end catch_tag_alias_registry.cpp -// start catch_test_case_info.cpp - -#include <cctype> -#include <exception> -#include <algorithm> -#include <sstream> - -namespace Catch { - - namespace { - TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { - if( startsWith( tag, '.' ) || - tag == "!hide" ) - return TestCaseInfo::IsHidden; - else if( tag == "!throws" ) - return TestCaseInfo::Throws; - else if( tag == "!shouldfail" ) - return TestCaseInfo::ShouldFail; - else if( tag == "!mayfail" ) - return TestCaseInfo::MayFail; - else if( tag == "!nonportable" ) - return TestCaseInfo::NonPortable; - else if( tag == "!benchmark" ) - return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); - else - return TestCaseInfo::None; - } - bool isReservedTag( std::string const& tag ) { - return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) ); - } - void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { - CATCH_ENFORCE( !isReservedTag(tag), - "Tag name: [" << tag << "] is not allowed.\n" - << "Tag names starting with non alphanumeric characters are reserved\n" - << _lineInfo ); - } - } - - TestCase makeTestCase( ITestInvoker* _testCase, - std::string const& _className, - NameAndTags const& nameAndTags, - SourceLineInfo const& _lineInfo ) - { - bool isHidden = false; - - // Parse out tags - std::vector<std::string> tags; - std::string desc, tag; - bool inTag = false; - std::string _descOrTags = nameAndTags.tags; - for (char c : _descOrTags) { - if( !inTag ) { - if( c == '[' ) - inTag = true; - else - desc += c; - } - else { - if( c == ']' ) { - TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); - if( ( prop & TestCaseInfo::IsHidden ) != 0 ) - isHidden = true; - else if( prop == TestCaseInfo::None ) - enforceNotReservedTag( tag, _lineInfo ); - - // Merged hide tags like `[.approvals]` should be added as - // `[.][approvals]`. The `[.]` is added at later point, so - // we only strip the prefix - if (startsWith(tag, '.') && tag.size() > 1) { - tag.erase(0, 1); - } - tags.push_back( tag ); - tag.clear(); - inTag = false; - } - else - tag += c; - } - } - if( isHidden ) { - tags.push_back( "." ); - } - - TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo ); - return TestCase( _testCase, std::move(info) ); - } - - void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) { - std::sort(begin(tags), end(tags)); - tags.erase(std::unique(begin(tags), end(tags)), end(tags)); - testCaseInfo.lcaseTags.clear(); - - for( auto const& tag : tags ) { - std::string lcaseTag = toLower( tag ); - testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); - testCaseInfo.lcaseTags.push_back( lcaseTag ); - } - testCaseInfo.tags = std::move(tags); - } - - TestCaseInfo::TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::vector<std::string> const& _tags, - SourceLineInfo const& _lineInfo ) - : name( _name ), - className( _className ), - description( _description ), - lineInfo( _lineInfo ), - properties( None ) - { - setTags( *this, _tags ); - } - - bool TestCaseInfo::isHidden() const { - return ( properties & IsHidden ) != 0; - } - bool TestCaseInfo::throws() const { - return ( properties & Throws ) != 0; - } - bool TestCaseInfo::okToFail() const { - return ( properties & (ShouldFail | MayFail ) ) != 0; - } - bool TestCaseInfo::expectedToFail() const { - return ( properties & (ShouldFail ) ) != 0; - } - - std::string TestCaseInfo::tagsAsString() const { - std::string ret; - // '[' and ']' per tag - std::size_t full_size = 2 * tags.size(); - for (const auto& tag : tags) { - full_size += tag.size(); - } - ret.reserve(full_size); - for (const auto& tag : tags) { - ret.push_back('['); - ret.append(tag); - ret.push_back(']'); - } - - return ret; - } - - TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {} - - TestCase TestCase::withName( std::string const& _newName ) const { - TestCase other( *this ); - other.name = _newName; - return other; - } - - void TestCase::invoke() const { - test->invoke(); - } - - bool TestCase::operator == ( TestCase const& other ) const { - return test.get() == other.test.get() && - name == other.name && - className == other.className; - } - - bool TestCase::operator < ( TestCase const& other ) const { - return name < other.name; - } - - TestCaseInfo const& TestCase::getTestCaseInfo() const - { - return *this; - } - -} // end namespace Catch -// end catch_test_case_info.cpp -// start catch_test_case_registry_impl.cpp - -#include <sstream> - -namespace Catch { - - std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) { - - std::vector<TestCase> sorted = unsortedTestCases; - - switch( config.runOrder() ) { - case RunTests::InLexicographicalOrder: - std::sort( sorted.begin(), sorted.end() ); - break; - case RunTests::InRandomOrder: - seedRng( config ); - std::shuffle( sorted.begin(), sorted.end(), rng() ); - break; - case RunTests::InDeclarationOrder: - // already in declaration order - break; - } - return sorted; - } - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { - return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); - } - - void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) { - std::set<TestCase> seenFunctions; - for( auto const& function : functions ) { - auto prev = seenFunctions.insert( function ); - CATCH_ENFORCE( prev.second, - "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n" - << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" - << "\tRedefined at " << function.getTestCaseInfo().lineInfo ); - } - } - - std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) { - std::vector<TestCase> filtered; - filtered.reserve( testCases.size() ); - for (auto const& testCase : testCases) { - if ((!testSpec.hasFilters() && !testCase.isHidden()) || - (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) { - filtered.push_back(testCase); - } - } - return filtered; - } - std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) { - return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); - } - - void TestRegistry::registerTest( TestCase const& testCase ) { - std::string name = testCase.getTestCaseInfo().name; - if( name.empty() ) { - ReusableStringStream rss; - rss << "Anonymous test case " << ++m_unnamedCount; - return registerTest( testCase.withName( rss.str() ) ); - } - m_functions.push_back( testCase ); - } - - std::vector<TestCase> const& TestRegistry::getAllTests() const { - return m_functions; - } - std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const { - if( m_sortedFunctions.empty() ) - enforceNoDuplicateTestCases( m_functions ); - - if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { - m_sortedFunctions = sortTests( config, m_functions ); - m_currentSortOrder = config.runOrder(); - } - return m_sortedFunctions; - } - - /////////////////////////////////////////////////////////////////////////// - TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {} - - void TestInvokerAsFunction::invoke() const { - m_testAsFunction(); - } - - std::string extractClassName( StringRef const& classOrQualifiedMethodName ) { - std::string className = classOrQualifiedMethodName; - if( startsWith( className, '&' ) ) - { - std::size_t lastColons = className.rfind( "::" ); - std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); - if( penultimateColons == std::string::npos ) - penultimateColons = 1; - className = className.substr( penultimateColons, lastColons-penultimateColons ); - } - return className; - } - -} // end namespace Catch -// end catch_test_case_registry_impl.cpp -// start catch_test_case_tracker.cpp - -#include <algorithm> -#include <cassert> -#include <stdexcept> -#include <memory> -#include <sstream> - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wexit-time-destructors" -#endif - -namespace Catch { -namespace TestCaseTracking { - - NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) - : name( _name ), - location( _location ) - {} - - ITracker::~ITracker() = default; - - ITracker& TrackerContext::startRun() { - m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr ); - m_currentTracker = nullptr; - m_runState = Executing; - return *m_rootTracker; - } - - void TrackerContext::endRun() { - m_rootTracker.reset(); - m_currentTracker = nullptr; - m_runState = NotStarted; - } - - void TrackerContext::startCycle() { - m_currentTracker = m_rootTracker.get(); - m_runState = Executing; - } - void TrackerContext::completeCycle() { - m_runState = CompletedCycle; - } - - bool TrackerContext::completedCycle() const { - return m_runState == CompletedCycle; - } - ITracker& TrackerContext::currentTracker() { - return *m_currentTracker; - } - void TrackerContext::setCurrentTracker( ITracker* tracker ) { - m_currentTracker = tracker; - } - - TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : m_nameAndLocation( nameAndLocation ), - m_ctx( ctx ), - m_parent( parent ) - {} - - NameAndLocation const& TrackerBase::nameAndLocation() const { - return m_nameAndLocation; - } - bool TrackerBase::isComplete() const { - return m_runState == CompletedSuccessfully || m_runState == Failed; - } - bool TrackerBase::isSuccessfullyCompleted() const { - return m_runState == CompletedSuccessfully; - } - bool TrackerBase::isOpen() const { - return m_runState != NotStarted && !isComplete(); - } - bool TrackerBase::hasChildren() const { - return !m_children.empty(); - } - - void TrackerBase::addChild( ITrackerPtr const& child ) { - m_children.push_back( child ); - } - - ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) { - auto it = std::find_if( m_children.begin(), m_children.end(), - [&nameAndLocation]( ITrackerPtr const& tracker ){ - return - tracker->nameAndLocation().location == nameAndLocation.location && - tracker->nameAndLocation().name == nameAndLocation.name; - } ); - return( it != m_children.end() ) - ? *it - : nullptr; - } - ITracker& TrackerBase::parent() { - assert( m_parent ); // Should always be non-null except for root - return *m_parent; - } - - void TrackerBase::openChild() { - if( m_runState != ExecutingChildren ) { - m_runState = ExecutingChildren; - if( m_parent ) - m_parent->openChild(); - } - } - - bool TrackerBase::isSectionTracker() const { return false; } - bool TrackerBase::isGeneratorTracker() const { return false; } - - void TrackerBase::open() { - m_runState = Executing; - moveToThis(); - if( m_parent ) - m_parent->openChild(); - } - - void TrackerBase::close() { - - // Close any still open children (e.g. generators) - while( &m_ctx.currentTracker() != this ) - m_ctx.currentTracker().close(); - - switch( m_runState ) { - case NeedsAnotherRun: - break; - - case Executing: - m_runState = CompletedSuccessfully; - break; - case ExecutingChildren: - if( m_children.empty() || m_children.back()->isComplete() ) - m_runState = CompletedSuccessfully; - break; - - case NotStarted: - case CompletedSuccessfully: - case Failed: - CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState ); - - default: - CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState ); - } - moveToParent(); - m_ctx.completeCycle(); - } - void TrackerBase::fail() { - m_runState = Failed; - if( m_parent ) - m_parent->markAsNeedingAnotherRun(); - moveToParent(); - m_ctx.completeCycle(); - } - void TrackerBase::markAsNeedingAnotherRun() { - m_runState = NeedsAnotherRun; - } - - void TrackerBase::moveToParent() { - assert( m_parent ); - m_ctx.setCurrentTracker( m_parent ); - } - void TrackerBase::moveToThis() { - m_ctx.setCurrentTracker( this ); - } - - SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : TrackerBase( nameAndLocation, ctx, parent ) - { - if( parent ) { - while( !parent->isSectionTracker() ) - parent = &parent->parent(); - - SectionTracker& parentSection = static_cast<SectionTracker&>( *parent ); - addNextFilters( parentSection.m_filters ); - } - } - - bool SectionTracker::isComplete() const { - bool complete = true; - - if ((m_filters.empty() || m_filters[0] == "") || - std::find(m_filters.begin(), m_filters.end(), - m_nameAndLocation.name) != m_filters.end()) - complete = TrackerBase::isComplete(); - return complete; - - } - - bool SectionTracker::isSectionTracker() const { return true; } - - SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { - std::shared_ptr<SectionTracker> section; - - ITracker& currentTracker = ctx.currentTracker(); - if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { - assert( childTracker ); - assert( childTracker->isSectionTracker() ); - section = std::static_pointer_cast<SectionTracker>( childTracker ); - } - else { - section = std::make_shared<SectionTracker>( nameAndLocation, ctx, ¤tTracker ); - currentTracker.addChild( section ); - } - if( !ctx.completedCycle() ) - section->tryOpen(); - return *section; - } - - void SectionTracker::tryOpen() { - if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) - open(); - } - - void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) { - if( !filters.empty() ) { - m_filters.push_back(""); // Root - should never be consulted - m_filters.push_back(""); // Test Case - not a section filter - m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); - } - } - void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) { - if( filters.size() > 1 ) - m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); - } - -} // namespace TestCaseTracking - -using TestCaseTracking::ITracker; -using TestCaseTracking::TrackerContext; -using TestCaseTracking::SectionTracker; - -} // namespace Catch - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif -// end catch_test_case_tracker.cpp -// start catch_test_registry.cpp - -namespace Catch { - - auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* { - return new(std::nothrow) TestInvokerAsFunction( testAsFunction ); - } - - NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {} - - AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept { - CATCH_TRY { - getMutableRegistryHub() - .registerTest( - makeTestCase( - invoker, - extractClassName( classOrMethod ), - nameAndTags, - lineInfo)); - } CATCH_CATCH_ALL { - // Do not throw when constructing global objects, instead register the exception to be processed later - getMutableRegistryHub().registerStartupException(); - } - } - - AutoReg::~AutoReg() = default; -} -// end catch_test_registry.cpp -// start catch_test_spec.cpp - -#include <algorithm> -#include <string> -#include <vector> -#include <memory> - -namespace Catch { - - TestSpec::Pattern::~Pattern() = default; - TestSpec::NamePattern::~NamePattern() = default; - TestSpec::TagPattern::~TagPattern() = default; - TestSpec::ExcludedPattern::~ExcludedPattern() = default; - - TestSpec::NamePattern::NamePattern( std::string const& name ) - : m_wildcardPattern( toLower( name ), CaseSensitive::No ) - {} - bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const { - return m_wildcardPattern.matches( toLower( testCase.name ) ); - } - - TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} - bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const { - return std::find(begin(testCase.lcaseTags), - end(testCase.lcaseTags), - m_tag) != end(testCase.lcaseTags); - } - - TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} - bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } - - bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const { - // All patterns in a filter must match for the filter to be a match - for( auto const& pattern : m_patterns ) { - if( !pattern->matches( testCase ) ) - return false; - } - return true; - } - - bool TestSpec::hasFilters() const { - return !m_filters.empty(); - } - bool TestSpec::matches( TestCaseInfo const& testCase ) const { - // A TestSpec matches if any filter matches - for( auto const& filter : m_filters ) - if( filter.matches( testCase ) ) - return true; - return false; - } -} -// end catch_test_spec.cpp -// start catch_test_spec_parser.cpp - -namespace Catch { - - TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} - - TestSpecParser& TestSpecParser::parse( std::string const& arg ) { - m_mode = None; - m_exclusion = false; - m_start = std::string::npos; - m_arg = m_tagAliases->expandAliases( arg ); - m_escapeChars.clear(); - for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) - visitChar( m_arg[m_pos] ); - if( m_mode == Name ) - addPattern<TestSpec::NamePattern>(); - return *this; - } - TestSpec TestSpecParser::testSpec() { - addFilter(); - return m_testSpec; - } - - void TestSpecParser::visitChar( char c ) { - if( m_mode == None ) { - switch( c ) { - case ' ': return; - case '~': m_exclusion = true; return; - case '[': return startNewMode( Tag, ++m_pos ); - case '"': return startNewMode( QuotedName, ++m_pos ); - case '\\': return escape(); - default: startNewMode( Name, m_pos ); break; - } - } - if( m_mode == Name ) { - if( c == ',' ) { - addPattern<TestSpec::NamePattern>(); - addFilter(); - } - else if( c == '[' ) { - if( subString() == "exclude:" ) - m_exclusion = true; - else - addPattern<TestSpec::NamePattern>(); - startNewMode( Tag, ++m_pos ); - } - else if( c == '\\' ) - escape(); - } - else if( m_mode == EscapedName ) - m_mode = Name; - else if( m_mode == QuotedName && c == '"' ) - addPattern<TestSpec::NamePattern>(); - else if( m_mode == Tag && c == ']' ) - addPattern<TestSpec::TagPattern>(); - } - void TestSpecParser::startNewMode( Mode mode, std::size_t start ) { - m_mode = mode; - m_start = start; - } - void TestSpecParser::escape() { - if( m_mode == None ) - m_start = m_pos; - m_mode = EscapedName; - m_escapeChars.push_back( m_pos ); - } - std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); } - - void TestSpecParser::addFilter() { - if( !m_currentFilter.m_patterns.empty() ) { - m_testSpec.m_filters.push_back( m_currentFilter ); - m_currentFilter = TestSpec::Filter(); - } - } - - TestSpec parseTestSpec( std::string const& arg ) { - return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); - } - -} // namespace Catch -// end catch_test_spec_parser.cpp -// start catch_timer.cpp - -#include <chrono> - -static const uint64_t nanosecondsInSecond = 1000000000; - -namespace Catch { - - auto getCurrentNanosecondsSinceEpoch() -> uint64_t { - return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); - } - - namespace { - auto estimateClockResolution() -> uint64_t { - uint64_t sum = 0; - static const uint64_t iterations = 1000000; - - auto startTime = getCurrentNanosecondsSinceEpoch(); - - for( std::size_t i = 0; i < iterations; ++i ) { - - uint64_t ticks; - uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); - do { - ticks = getCurrentNanosecondsSinceEpoch(); - } while( ticks == baseTicks ); - - auto delta = ticks - baseTicks; - sum += delta; - - // If we have been calibrating for over 3 seconds -- the clock - // is terrible and we should move on. - // TBD: How to signal that the measured resolution is probably wrong? - if (ticks > startTime + 3 * nanosecondsInSecond) { - return sum / ( i + 1u ); - } - } - - // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers - // - and potentially do more iterations if there's a high variance. - return sum/iterations; - } - } - auto getEstimatedClockResolution() -> uint64_t { - static auto s_resolution = estimateClockResolution(); - return s_resolution; - } - - void Timer::start() { - m_nanoseconds = getCurrentNanosecondsSinceEpoch(); - } - auto Timer::getElapsedNanoseconds() const -> uint64_t { - return getCurrentNanosecondsSinceEpoch() - m_nanoseconds; - } - auto Timer::getElapsedMicroseconds() const -> uint64_t { - return getElapsedNanoseconds()/1000; - } - auto Timer::getElapsedMilliseconds() const -> unsigned int { - return static_cast<unsigned int>(getElapsedMicroseconds()/1000); - } - auto Timer::getElapsedSeconds() const -> double { - return getElapsedMicroseconds()/1000000.0; - } - -} // namespace Catch -// end catch_timer.cpp -// start catch_tostring.cpp - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wexit-time-destructors" -# pragma clang diagnostic ignored "-Wglobal-constructors" -#endif - -// Enable specific decls locally -#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -#endif - -#include <cmath> -#include <iomanip> - -namespace Catch { - -namespace Detail { - - const std::string unprintableString = "{?}"; - - namespace { - const int hexThreshold = 255; - - struct Endianness { - enum Arch { Big, Little }; - - static Arch which() { - union _{ - int asInt; - char asChar[sizeof (int)]; - } u; - - u.asInt = 1; - return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; - } - }; - } - - std::string rawMemoryToString( const void *object, std::size_t size ) { - // Reverse order for little endian architectures - int i = 0, end = static_cast<int>( size ), inc = 1; - if( Endianness::which() == Endianness::Little ) { - i = end-1; - end = inc = -1; - } - - unsigned char const *bytes = static_cast<unsigned char const *>(object); - ReusableStringStream rss; - rss << "0x" << std::setfill('0') << std::hex; - for( ; i != end; i += inc ) - rss << std::setw(2) << static_cast<unsigned>(bytes[i]); - return rss.str(); - } -} - -template<typename T> -std::string fpToString( T value, int precision ) { - if (Catch::isnan(value)) { - return "nan"; - } - - ReusableStringStream rss; - rss << std::setprecision( precision ) - << std::fixed - << value; - std::string d = rss.str(); - std::size_t i = d.find_last_not_of( '0' ); - if( i != std::string::npos && i != d.size()-1 ) { - if( d[i] == '.' ) - i++; - d = d.substr( 0, i+1 ); - } - return d; -} - -//// ======================================================= //// -// -// Out-of-line defs for full specialization of StringMaker -// -//// ======================================================= //// - -std::string StringMaker<std::string>::convert(const std::string& str) { - if (!getCurrentContext().getConfig()->showInvisibles()) { - return '"' + str + '"'; - } - - std::string s("\""); - for (char c : str) { - switch (c) { - case '\n': - s.append("\\n"); - break; - case '\t': - s.append("\\t"); - break; - default: - s.push_back(c); - break; - } - } - s.append("\""); - return s; -} - -#ifdef CATCH_CONFIG_CPP17_STRING_VIEW -std::string StringMaker<std::string_view>::convert(std::string_view str) { - return ::Catch::Detail::stringify(std::string{ str }); -} -#endif - -std::string StringMaker<char const*>::convert(char const* str) { - if (str) { - return ::Catch::Detail::stringify(std::string{ str }); - } else { - return{ "{null string}" }; - } -} -std::string StringMaker<char*>::convert(char* str) { - if (str) { - return ::Catch::Detail::stringify(std::string{ str }); - } else { - return{ "{null string}" }; - } -} - -#ifdef CATCH_CONFIG_WCHAR -std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) { - std::string s; - s.reserve(wstr.size()); - for (auto c : wstr) { - s += (c <= 0xff) ? static_cast<char>(c) : '?'; - } - return ::Catch::Detail::stringify(s); -} - -# ifdef CATCH_CONFIG_CPP17_STRING_VIEW -std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) { - return StringMaker<std::wstring>::convert(std::wstring(str)); -} -# endif - -std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) { - if (str) { - return ::Catch::Detail::stringify(std::wstring{ str }); - } else { - return{ "{null string}" }; - } -} -std::string StringMaker<wchar_t *>::convert(wchar_t * str) { - if (str) { - return ::Catch::Detail::stringify(std::wstring{ str }); - } else { - return{ "{null string}" }; - } -} -#endif - -std::string StringMaker<int>::convert(int value) { - return ::Catch::Detail::stringify(static_cast<long long>(value)); -} -std::string StringMaker<long>::convert(long value) { - return ::Catch::Detail::stringify(static_cast<long long>(value)); -} -std::string StringMaker<long long>::convert(long long value) { - ReusableStringStream rss; - rss << value; - if (value > Detail::hexThreshold) { - rss << " (0x" << std::hex << value << ')'; - } - return rss.str(); -} - -std::string StringMaker<unsigned int>::convert(unsigned int value) { - return ::Catch::Detail::stringify(static_cast<unsigned long long>(value)); -} -std::string StringMaker<unsigned long>::convert(unsigned long value) { - return ::Catch::Detail::stringify(static_cast<unsigned long long>(value)); -} -std::string StringMaker<unsigned long long>::convert(unsigned long long value) { - ReusableStringStream rss; - rss << value; - if (value > Detail::hexThreshold) { - rss << " (0x" << std::hex << value << ')'; - } - return rss.str(); -} - -std::string StringMaker<bool>::convert(bool b) { - return b ? "true" : "false"; -} - -std::string StringMaker<signed char>::convert(signed char value) { - if (value == '\r') { - return "'\\r'"; - } else if (value == '\f') { - return "'\\f'"; - } else if (value == '\n') { - return "'\\n'"; - } else if (value == '\t') { - return "'\\t'"; - } else if ('\0' <= value && value < ' ') { - return ::Catch::Detail::stringify(static_cast<unsigned int>(value)); - } else { - char chstr[] = "' '"; - chstr[1] = value; - return chstr; - } -} -std::string StringMaker<char>::convert(char c) { - return ::Catch::Detail::stringify(static_cast<signed char>(c)); -} -std::string StringMaker<unsigned char>::convert(unsigned char c) { - return ::Catch::Detail::stringify(static_cast<char>(c)); -} - -std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) { - return "nullptr"; -} - -int StringMaker<float>::precision = 5; - -std::string StringMaker<float>::convert(float value) { - return fpToString(value, precision) + 'f'; -} - -int StringMaker<double>::precision = 10; - -std::string StringMaker<double>::convert(double value) { - return fpToString(value, precision); -} - -std::string ratio_string<std::atto>::symbol() { return "a"; } -std::string ratio_string<std::femto>::symbol() { return "f"; } -std::string ratio_string<std::pico>::symbol() { return "p"; } -std::string ratio_string<std::nano>::symbol() { return "n"; } -std::string ratio_string<std::micro>::symbol() { return "u"; } -std::string ratio_string<std::milli>::symbol() { return "m"; } - -} // end namespace Catch - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -// end catch_tostring.cpp -// start catch_totals.cpp - -namespace Catch { - - Counts Counts::operator - ( Counts const& other ) const { - Counts diff; - diff.passed = passed - other.passed; - diff.failed = failed - other.failed; - diff.failedButOk = failedButOk - other.failedButOk; - return diff; - } - - Counts& Counts::operator += ( Counts const& other ) { - passed += other.passed; - failed += other.failed; - failedButOk += other.failedButOk; - return *this; - } - - std::size_t Counts::total() const { - return passed + failed + failedButOk; - } - bool Counts::allPassed() const { - return failed == 0 && failedButOk == 0; - } - bool Counts::allOk() const { - return failed == 0; - } - - Totals Totals::operator - ( Totals const& other ) const { - Totals diff; - diff.assertions = assertions - other.assertions; - diff.testCases = testCases - other.testCases; - return diff; - } - - Totals& Totals::operator += ( Totals const& other ) { - assertions += other.assertions; - testCases += other.testCases; - return *this; - } - - Totals Totals::delta( Totals const& prevTotals ) const { - Totals diff = *this - prevTotals; - if( diff.assertions.failed > 0 ) - ++diff.testCases.failed; - else if( diff.assertions.failedButOk > 0 ) - ++diff.testCases.failedButOk; - else - ++diff.testCases.passed; - return diff; - } - -} -// end catch_totals.cpp -// start catch_uncaught_exceptions.cpp - -#include <exception> - -namespace Catch { - bool uncaught_exceptions() { -#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) - return std::uncaught_exceptions() > 0; -#else - return std::uncaught_exception(); -#endif - } -} // end namespace Catch -// end catch_uncaught_exceptions.cpp -// start catch_version.cpp - -#include <ostream> - -namespace Catch { - - Version::Version - ( unsigned int _majorVersion, - unsigned int _minorVersion, - unsigned int _patchNumber, - char const * const _branchName, - unsigned int _buildNumber ) - : majorVersion( _majorVersion ), - minorVersion( _minorVersion ), - patchNumber( _patchNumber ), - branchName( _branchName ), - buildNumber( _buildNumber ) - {} - - std::ostream& operator << ( std::ostream& os, Version const& version ) { - os << version.majorVersion << '.' - << version.minorVersion << '.' - << version.patchNumber; - // branchName is never null -> 0th char is \0 if it is empty - if (version.branchName[0]) { - os << '-' << version.branchName - << '.' << version.buildNumber; - } - return os; - } - - Version const& libraryVersion() { - static Version version( 2, 9, 1, "", 0 ); - return version; - } - -} -// end catch_version.cpp -// start catch_wildcard_pattern.cpp - -#include <sstream> - -namespace Catch { - - WildcardPattern::WildcardPattern( std::string const& pattern, - CaseSensitive::Choice caseSensitivity ) - : m_caseSensitivity( caseSensitivity ), - m_pattern( adjustCase( pattern ) ) - { - if( startsWith( m_pattern, '*' ) ) { - m_pattern = m_pattern.substr( 1 ); - m_wildcard = WildcardAtStart; - } - if( endsWith( m_pattern, '*' ) ) { - m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); - m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd ); - } - } - - bool WildcardPattern::matches( std::string const& str ) const { - switch( m_wildcard ) { - case NoWildcard: - return m_pattern == adjustCase( str ); - case WildcardAtStart: - return endsWith( adjustCase( str ), m_pattern ); - case WildcardAtEnd: - return startsWith( adjustCase( str ), m_pattern ); - case WildcardAtBothEnds: - return contains( adjustCase( str ), m_pattern ); - default: - CATCH_INTERNAL_ERROR( "Unknown enum" ); - } - } - - std::string WildcardPattern::adjustCase( std::string const& str ) const { - return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; - } -} -// end catch_wildcard_pattern.cpp -// start catch_xmlwriter.cpp - -#include <iomanip> - -using uchar = unsigned char; - -namespace Catch { - -namespace { - - size_t trailingBytes(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return 2; - } - if ((c & 0xF0) == 0xE0) { - return 3; - } - if ((c & 0xF8) == 0xF0) { - return 4; - } - CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - uint32_t headerValue(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return c & 0x1F; - } - if ((c & 0xF0) == 0xE0) { - return c & 0x0F; - } - if ((c & 0xF8) == 0xF0) { - return c & 0x07; - } - CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - void hexEscapeChar(std::ostream& os, unsigned char c) { - std::ios_base::fmtflags f(os.flags()); - os << "\\x" - << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast<int>(c); - os.flags(f); - } - -} // anonymous namespace - - XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) - : m_str( str ), - m_forWhat( forWhat ) - {} - - void XmlEncode::encodeTo( std::ostream& os ) const { - // Apostrophe escaping not necessary if we always use " to write attributes - // (see: http://www.w3.org/TR/xml/#syntax) - - for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { - uchar c = m_str[idx]; - switch (c) { - case '<': os << "<"; break; - case '&': os << "&"; break; - - case '>': - // See: http://www.w3.org/TR/xml/#syntax - if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') - os << ">"; - else - os << c; - break; - - case '\"': - if (m_forWhat == ForAttributes) - os << """; - else - os << c; - break; - - default: - // Check for control characters and invalid utf-8 - - // Escape control characters in standard ascii - // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 - if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { - hexEscapeChar(os, c); - break; - } - - // Plain ASCII: Write it to stream - if (c < 0x7F) { - os << c; - break; - } - - // UTF-8 territory - // Check if the encoding is valid and if it is not, hex escape bytes. - // Important: We do not check the exact decoded values for validity, only the encoding format - // First check that this bytes is a valid lead byte: - // This means that it is not encoded as 1111 1XXX - // Or as 10XX XXXX - if (c < 0xC0 || - c >= 0xF8) { - hexEscapeChar(os, c); - break; - } - - auto encBytes = trailingBytes(c); - // Are there enough bytes left to avoid accessing out-of-bounds memory? - if (idx + encBytes - 1 >= m_str.size()) { - hexEscapeChar(os, c); - break; - } - // The header is valid, check data - // The next encBytes bytes must together be a valid utf-8 - // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) - bool valid = true; - uint32_t value = headerValue(c); - for (std::size_t n = 1; n < encBytes; ++n) { - uchar nc = m_str[idx + n]; - valid &= ((nc & 0xC0) == 0x80); - value = (value << 6) | (nc & 0x3F); - } - - if ( - // Wrong bit pattern of following bytes - (!valid) || - // Overlong encodings - (value < 0x80) || - (0x80 <= value && value < 0x800 && encBytes > 2) || - (0x800 < value && value < 0x10000 && encBytes > 3) || - // Encoded value out of range - (value >= 0x110000) - ) { - hexEscapeChar(os, c); - break; - } - - // If we got here, this is in fact a valid(ish) utf-8 sequence - for (std::size_t n = 0; n < encBytes; ++n) { - os << m_str[idx + n]; - } - idx += encBytes - 1; - break; - } - } - } - - std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { - xmlEncode.encodeTo( os ); - return os; - } - - XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept - : m_writer( other.m_writer ){ - other.m_writer = nullptr; - } - XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept { - if ( m_writer ) { - m_writer->endElement(); - } - m_writer = other.m_writer; - other.m_writer = nullptr; - return *this; - } - - XmlWriter::ScopedElement::~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { - m_writer->writeText( text, indent ); - return *this; - } - - XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) - { - writeDeclaration(); - } - - XmlWriter::~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - - XmlWriter& XmlWriter::startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - m_os << m_indent << '<' << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& XmlWriter::endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - m_os << "/>"; - m_tagIsOpen = false; - } - else { - m_os << m_indent << "</" << m_tags.back() << ">"; - } - m_os << std::endl; - m_tags.pop_back(); - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { - m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - m_os << m_indent; - m_os << XmlEncode( text ); - m_needsNewline = true; - } - return *this; - } - - XmlWriter& XmlWriter::writeComment( std::string const& text ) { - ensureTagClosed(); - m_os << m_indent << "<!--" << text << "-->"; - m_needsNewline = true; - return *this; - } - - void XmlWriter::writeStylesheetRef( std::string const& url ) { - m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n"; - } - - XmlWriter& XmlWriter::writeBlankLine() { - ensureTagClosed(); - m_os << '\n'; - return *this; - } - - void XmlWriter::ensureTagClosed() { - if( m_tagIsOpen ) { - m_os << ">" << std::endl; - m_tagIsOpen = false; - } - } - - void XmlWriter::writeDeclaration() { - m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; - } - - void XmlWriter::newlineIfNecessary() { - if( m_needsNewline ) { - m_os << std::endl; - m_needsNewline = false; - } - } -} -// end catch_xmlwriter.cpp -// start catch_reporter_bases.cpp - -#include <cstring> -#include <cfloat> -#include <cstdio> -#include <cassert> -#include <memory> - -namespace Catch { - void prepareExpandedExpression(AssertionResult& result) { - result.getExpandedExpression(); - } - - // Because formatting using c++ streams is stateful, drop down to C is required - // Alternatively we could use stringstream, but its performance is... not good. - std::string getFormattedDuration( double duration ) { - // Max exponent + 1 is required to represent the whole part - // + 1 for decimal point - // + 3 for the 3 decimal places - // + 1 for null terminator - const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; - char buffer[maxDoubleSize]; - - // Save previous errno, to prevent sprintf from overwriting it - ErrnoGuard guard; -#ifdef _MSC_VER - sprintf_s(buffer, "%.3f", duration); -#else - std::sprintf(buffer, "%.3f", duration); -#endif - return std::string(buffer); - } - - std::string serializeFilters( std::vector<std::string> const& container ) { - ReusableStringStream oss; - bool first = true; - for (auto&& filter : container) - { - if (!first) - oss << ' '; - else - first = false; - - oss << filter; - } - return oss.str(); - } - - TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config) - :StreamingReporterBase(_config) {} - - std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() { - return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High }; - } - - void TestEventListenerBase::assertionStarting(AssertionInfo const &) {} - - bool TestEventListenerBase::assertionEnded(AssertionStats const &) { - return false; - } - -} // end namespace Catch -// end catch_reporter_bases.cpp -// start catch_reporter_compact.cpp - -namespace { - -#ifdef CATCH_PLATFORM_MAC - const char* failedString() { return "FAILED"; } - const char* passedString() { return "PASSED"; } -#else - const char* failedString() { return "failed"; } - const char* passedString() { return "passed"; } -#endif - - // Colour::LightGrey - Catch::Colour::Code dimColour() { return Catch::Colour::FileName; } - - std::string bothOrAll( std::size_t count ) { - return count == 1 ? std::string() : - count == 2 ? "both " : "all " ; - } - -} // anon namespace - -namespace Catch { -namespace { -// Colour, message variants: -// - white: No tests ran. -// - red: Failed [both/all] N test cases, failed [both/all] M assertions. -// - white: Passed [both/all] N test cases (no assertions). -// - red: Failed N tests cases, failed M assertions. -// - green: Passed [both/all] N tests cases with M assertions. -void printTotals(std::ostream& out, const Totals& totals) { - if (totals.testCases.total() == 0) { - out << "No tests ran."; - } else if (totals.testCases.failed == totals.testCases.total()) { - Colour colour(Colour::ResultError); - const std::string qualify_assertions_failed = - totals.assertions.failed == totals.assertions.total() ? - bothOrAll(totals.assertions.failed) : std::string(); - out << - "Failed " << bothOrAll(totals.testCases.failed) - << pluralise(totals.testCases.failed, "test case") << ", " - "failed " << qualify_assertions_failed << - pluralise(totals.assertions.failed, "assertion") << '.'; - } else if (totals.assertions.total() == 0) { - out << - "Passed " << bothOrAll(totals.testCases.total()) - << pluralise(totals.testCases.total(), "test case") - << " (no assertions)."; - } else if (totals.assertions.failed) { - Colour colour(Colour::ResultError); - out << - "Failed " << pluralise(totals.testCases.failed, "test case") << ", " - "failed " << pluralise(totals.assertions.failed, "assertion") << '.'; - } else { - Colour colour(Colour::ResultSuccess); - out << - "Passed " << bothOrAll(totals.testCases.passed) - << pluralise(totals.testCases.passed, "test case") << - " with " << pluralise(totals.assertions.passed, "assertion") << '.'; - } -} - -// Implementation of CompactReporter formatting -class AssertionPrinter { -public: - AssertionPrinter& operator= (AssertionPrinter const&) = delete; - AssertionPrinter(AssertionPrinter const&) = delete; - AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) - : stream(_stream) - , result(_stats.assertionResult) - , messages(_stats.infoMessages) - , itMessage(_stats.infoMessages.begin()) - , printInfoMessages(_printInfoMessages) {} - - void print() { - printSourceInfo(); - - itMessage = messages.begin(); - - switch (result.getResultType()) { - case ResultWas::Ok: - printResultType(Colour::ResultSuccess, passedString()); - printOriginalExpression(); - printReconstructedExpression(); - if (!result.hasExpression()) - printRemainingMessages(Colour::None); - else - printRemainingMessages(); - break; - case ResultWas::ExpressionFailed: - if (result.isOk()) - printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok")); - else - printResultType(Colour::Error, failedString()); - printOriginalExpression(); - printReconstructedExpression(); - printRemainingMessages(); - break; - case ResultWas::ThrewException: - printResultType(Colour::Error, failedString()); - printIssue("unexpected exception with message:"); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::FatalErrorCondition: - printResultType(Colour::Error, failedString()); - printIssue("fatal error condition with message:"); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::DidntThrowException: - printResultType(Colour::Error, failedString()); - printIssue("expected exception, got none"); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::Info: - printResultType(Colour::None, "info"); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::Warning: - printResultType(Colour::None, "warning"); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::ExplicitFailure: - printResultType(Colour::Error, failedString()); - printIssue("explicitly"); - printRemainingMessages(Colour::None); - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - printResultType(Colour::Error, "** internal error **"); - break; - } - } - -private: - void printSourceInfo() const { - Colour colourGuard(Colour::FileName); - stream << result.getSourceInfo() << ':'; - } - - void printResultType(Colour::Code colour, std::string const& passOrFail) const { - if (!passOrFail.empty()) { - { - Colour colourGuard(colour); - stream << ' ' << passOrFail; - } - stream << ':'; - } - } - - void printIssue(std::string const& issue) const { - stream << ' ' << issue; - } - - void printExpressionWas() { - if (result.hasExpression()) { - stream << ';'; - { - Colour colour(dimColour()); - stream << " expression was:"; - } - printOriginalExpression(); - } - } - - void printOriginalExpression() const { - if (result.hasExpression()) { - stream << ' ' << result.getExpression(); - } - } - - void printReconstructedExpression() const { - if (result.hasExpandedExpression()) { - { - Colour colour(dimColour()); - stream << " for: "; - } - stream << result.getExpandedExpression(); - } - } - - void printMessage() { - if (itMessage != messages.end()) { - stream << " '" << itMessage->message << '\''; - ++itMessage; - } - } - - void printRemainingMessages(Colour::Code colour = dimColour()) { - if (itMessage == messages.end()) - return; - - // using messages.end() directly yields (or auto) compilation error: - std::vector<MessageInfo>::const_iterator itEnd = messages.end(); - const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd)); - - { - Colour colourGuard(colour); - stream << " with " << pluralise(N, "message") << ':'; - } - - for (; itMessage != itEnd; ) { - // If this assertion is a warning ignore any INFO messages - if (printInfoMessages || itMessage->type != ResultWas::Info) { - stream << " '" << itMessage->message << '\''; - if (++itMessage != itEnd) { - Colour colourGuard(dimColour()); - stream << " and"; - } - } - } - } - -private: - std::ostream& stream; - AssertionResult const& result; - std::vector<MessageInfo> messages; - std::vector<MessageInfo>::const_iterator itMessage; - bool printInfoMessages; -}; - -} // anon namespace - - std::string CompactReporter::getDescription() { - return "Reports test results on a single line, suitable for IDEs"; - } - - ReporterPreferences CompactReporter::getPreferences() const { - return m_reporterPrefs; - } - - void CompactReporter::noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << '\'' << std::endl; - } - - void CompactReporter::assertionStarting( AssertionInfo const& ) {} - - bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool printInfoMessages = true; - - // Drop out if result was successful and we're not printing those - if( !m_config->includeSuccessfulResults() && result.isOk() ) { - if( result.getResultType() != ResultWas::Warning ) - return false; - printInfoMessages = false; - } - - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); - printer.print(); - - stream << std::endl; - return true; - } - - void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; - } - } - - void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) { - printTotals( stream, _testRunStats.totals ); - stream << '\n' << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - CompactReporter::~CompactReporter() {} - - CATCH_REGISTER_REPORTER( "compact", CompactReporter ) - -} // end namespace Catch -// end catch_reporter_compact.cpp -// start catch_reporter_console.cpp - -#include <cfloat> -#include <cstdio> - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch - // Note that 4062 (not all labels are handled and default is missing) is enabled -#endif - -#if defined(__clang__) -# pragma clang diagnostic push -// For simplicity, benchmarking-only helpers are always enabled -# pragma clang diagnostic ignored "-Wunused-function" -#endif - -namespace Catch { - -namespace { - -// Formatter impl for ConsoleReporter -class ConsoleAssertionPrinter { -public: - ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete; - ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete; - ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) - : stream(_stream), - stats(_stats), - result(_stats.assertionResult), - colour(Colour::None), - message(result.getMessage()), - messages(_stats.infoMessages), - printInfoMessages(_printInfoMessages) { - switch (result.getResultType()) { - case ResultWas::Ok: - colour = Colour::Success; - passOrFail = "PASSED"; - //if( result.hasMessage() ) - if (_stats.infoMessages.size() == 1) - messageLabel = "with message"; - if (_stats.infoMessages.size() > 1) - messageLabel = "with messages"; - break; - case ResultWas::ExpressionFailed: - if (result.isOk()) { - colour = Colour::Success; - passOrFail = "FAILED - but was ok"; - } else { - colour = Colour::Error; - passOrFail = "FAILED"; - } - if (_stats.infoMessages.size() == 1) - messageLabel = "with message"; - if (_stats.infoMessages.size() > 1) - messageLabel = "with messages"; - break; - case ResultWas::ThrewException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to unexpected exception with "; - if (_stats.infoMessages.size() == 1) - messageLabel += "message"; - if (_stats.infoMessages.size() > 1) - messageLabel += "messages"; - break; - case ResultWas::FatalErrorCondition: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to a fatal error condition"; - break; - case ResultWas::DidntThrowException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "because no exception was thrown where one was expected"; - break; - case ResultWas::Info: - messageLabel = "info"; - break; - case ResultWas::Warning: - messageLabel = "warning"; - break; - case ResultWas::ExplicitFailure: - passOrFail = "FAILED"; - colour = Colour::Error; - if (_stats.infoMessages.size() == 1) - messageLabel = "explicitly with message"; - if (_stats.infoMessages.size() > 1) - messageLabel = "explicitly with messages"; - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - passOrFail = "** internal error **"; - colour = Colour::Error; - break; - } - } - - void print() const { - printSourceInfo(); - if (stats.totals.assertions.total() > 0) { - printResultType(); - printOriginalExpression(); - printReconstructedExpression(); - } else { - stream << '\n'; - } - printMessage(); - } - -private: - void printResultType() const { - if (!passOrFail.empty()) { - Colour colourGuard(colour); - stream << passOrFail << ":\n"; - } - } - void printOriginalExpression() const { - if (result.hasExpression()) { - Colour colourGuard(Colour::OriginalExpression); - stream << " "; - stream << result.getExpressionInMacro(); - stream << '\n'; - } - } - void printReconstructedExpression() const { - if (result.hasExpandedExpression()) { - stream << "with expansion:\n"; - Colour colourGuard(Colour::ReconstructedExpression); - stream << Column(result.getExpandedExpression()).indent(2) << '\n'; - } - } - void printMessage() const { - if (!messageLabel.empty()) - stream << messageLabel << ':' << '\n'; - for (auto const& msg : messages) { - // If this assertion is a warning ignore any INFO messages - if (printInfoMessages || msg.type != ResultWas::Info) - stream << Column(msg.message).indent(2) << '\n'; - } - } - void printSourceInfo() const { - Colour colourGuard(Colour::FileName); - stream << result.getSourceInfo() << ": "; - } - - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - Colour::Code colour; - std::string passOrFail; - std::string messageLabel; - std::string message; - std::vector<MessageInfo> messages; - bool printInfoMessages; -}; - -std::size_t makeRatio(std::size_t number, std::size_t total) { - std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0; - return (ratio == 0 && number > 0) ? 1 : ratio; -} - -std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) { - if (i > j && i > k) - return i; - else if (j > k) - return j; - else - return k; -} - -struct ColumnInfo { - enum Justification { Left, Right }; - std::string name; - int width; - Justification justification; -}; -struct ColumnBreak {}; -struct RowBreak {}; - -class Duration { - enum class Unit { - Auto, - Nanoseconds, - Microseconds, - Milliseconds, - Seconds, - Minutes - }; - static const uint64_t s_nanosecondsInAMicrosecond = 1000; - static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond; - static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond; - static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond; - - uint64_t m_inNanoseconds; - Unit m_units; - -public: - explicit Duration(double inNanoseconds, Unit units = Unit::Auto) - : Duration(static_cast<uint64_t>(inNanoseconds), units) { - } - - explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto) - : m_inNanoseconds(inNanoseconds), - m_units(units) { - if (m_units == Unit::Auto) { - if (m_inNanoseconds < s_nanosecondsInAMicrosecond) - m_units = Unit::Nanoseconds; - else if (m_inNanoseconds < s_nanosecondsInAMillisecond) - m_units = Unit::Microseconds; - else if (m_inNanoseconds < s_nanosecondsInASecond) - m_units = Unit::Milliseconds; - else if (m_inNanoseconds < s_nanosecondsInAMinute) - m_units = Unit::Seconds; - else - m_units = Unit::Minutes; - } - - } - - auto value() const -> double { - switch (m_units) { - case Unit::Microseconds: - return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond); - case Unit::Milliseconds: - return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond); - case Unit::Seconds: - return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond); - case Unit::Minutes: - return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute); - default: - return static_cast<double>(m_inNanoseconds); - } - } - auto unitsAsString() const -> std::string { - switch (m_units) { - case Unit::Nanoseconds: - return "ns"; - case Unit::Microseconds: - return "us"; - case Unit::Milliseconds: - return "ms"; - case Unit::Seconds: - return "s"; - case Unit::Minutes: - return "m"; - default: - return "** internal error **"; - } - - } - friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& { - return os << duration.value() << " " << duration.unitsAsString(); - } -}; -} // end anon namespace - -class TablePrinter { - std::ostream& m_os; - std::vector<ColumnInfo> m_columnInfos; - std::ostringstream m_oss; - int m_currentColumn = -1; - bool m_isOpen = false; - -public: - TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos ) - : m_os( os ), - m_columnInfos( std::move( columnInfos ) ) {} - - auto columnInfos() const -> std::vector<ColumnInfo> const& { - return m_columnInfos; - } - - void open() { - if (!m_isOpen) { - m_isOpen = true; - *this << RowBreak(); - - Columns headerCols; - Spacer spacer(2); - for (auto const& info : m_columnInfos) { - headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2)); - headerCols += spacer; - } - m_os << headerCols << "\n"; - - m_os << Catch::getLineOfChars<'-'>() << "\n"; - } - } - void close() { - if (m_isOpen) { - *this << RowBreak(); - m_os << std::endl; - m_isOpen = false; - } - } - - template<typename T> - friend TablePrinter& operator << (TablePrinter& tp, T const& value) { - tp.m_oss << value; - return tp; - } - - friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) { - auto colStr = tp.m_oss.str(); - // This takes account of utf8 encodings - auto strSize = Catch::StringRef(colStr).numberOfCharacters(); - tp.m_oss.str(""); - tp.open(); - if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) { - tp.m_currentColumn = -1; - tp.m_os << "\n"; - } - tp.m_currentColumn++; - - auto colInfo = tp.m_columnInfos[tp.m_currentColumn]; - auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width)) - ? std::string(colInfo.width - (strSize + 2), ' ') - : std::string(); - if (colInfo.justification == ColumnInfo::Left) - tp.m_os << colStr << padding << " "; - else - tp.m_os << padding << colStr << " "; - return tp; - } - - friend TablePrinter& operator << (TablePrinter& tp, RowBreak) { - if (tp.m_currentColumn > 0) { - tp.m_os << "\n"; - tp.m_currentColumn = -1; - } - return tp; - } -}; - -ConsoleReporter::ConsoleReporter(ReporterConfig const& config) - : StreamingReporterBase(config), - m_tablePrinter(new TablePrinter(config.stream(), - { - { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left }, - { "samples mean std dev", 14, ColumnInfo::Right }, - { "iterations low mean low std dev", 14, ColumnInfo::Right }, - { "estimated high mean high std dev", 14, ColumnInfo::Right } - })) {} -ConsoleReporter::~ConsoleReporter() = default; - -std::string ConsoleReporter::getDescription() { - return "Reports test results as plain lines of text"; -} - -void ConsoleReporter::noMatchingTestCases(std::string const& spec) { - stream << "No test cases matched '" << spec << '\'' << std::endl; -} - -void ConsoleReporter::assertionStarting(AssertionInfo const&) {} - -bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); - - // Drop out if result was successful but we're not printing them. - if (!includeResults && result.getResultType() != ResultWas::Warning) - return false; - - lazyPrint(); - - ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults); - printer.print(); - stream << std::endl; - return true; -} - -void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) { - m_tablePrinter->close(); - m_headerPrinted = false; - StreamingReporterBase::sectionStarting(_sectionInfo); -} -void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) { - m_tablePrinter->close(); - if (_sectionStats.missingAssertions) { - lazyPrint(); - Colour colour(Colour::ResultError); - if (m_sectionStack.size() > 1) - stream << "\nNo assertions in section"; - else - stream << "\nNo assertions in test case"; - stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; - } - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; - } - if (m_headerPrinted) { - m_headerPrinted = false; - } - StreamingReporterBase::sectionEnded(_sectionStats); -} - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) -void ConsoleReporter::benchmarkPreparing(std::string const& name) { - lazyPrintWithoutClosingBenchmarkTable(); - - auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2)); - - bool firstLine = true; - for (auto line : nameCol) { - if (!firstLine) - (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak(); - else - firstLine = false; - - (*m_tablePrinter) << line << ColumnBreak(); - } -} - -void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) { - (*m_tablePrinter) << info.samples << ColumnBreak() - << info.iterations << ColumnBreak() - << Duration(info.estimatedDuration) << ColumnBreak(); -} -void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) { - (*m_tablePrinter) << ColumnBreak() - << Duration(stats.mean.point.count()) << ColumnBreak() - << Duration(stats.mean.lower_bound.count()) << ColumnBreak() - << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak() - << Duration(stats.standardDeviation.point.count()) << ColumnBreak() - << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak() - << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak(); -} - -void ConsoleReporter::benchmarkFailed(std::string const& error) { - Colour colour(Colour::Red); - (*m_tablePrinter) - << "Benchmark failed (" << error << ")" - << ColumnBreak() << RowBreak(); -} -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - -void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) { - m_tablePrinter->close(); - StreamingReporterBase::testCaseEnded(_testCaseStats); - m_headerPrinted = false; -} -void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) { - if (currentGroupInfo.used) { - printSummaryDivider(); - stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; - printTotals(_testGroupStats.totals); - stream << '\n' << std::endl; - } - StreamingReporterBase::testGroupEnded(_testGroupStats); -} -void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) { - printTotalsDivider(_testRunStats.totals); - printTotals(_testRunStats.totals); - stream << std::endl; - StreamingReporterBase::testRunEnded(_testRunStats); -} -void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) { - StreamingReporterBase::testRunStarting(_testInfo); - printTestFilters(); -} - -void ConsoleReporter::lazyPrint() { - - m_tablePrinter->close(); - lazyPrintWithoutClosingBenchmarkTable(); -} - -void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { - - if (!currentTestRunInfo.used) - lazyPrintRunInfo(); - if (!currentGroupInfo.used) - lazyPrintGroupInfo(); - - if (!m_headerPrinted) { - printTestCaseAndSectionHeader(); - m_headerPrinted = true; - } -} -void ConsoleReporter::lazyPrintRunInfo() { - stream << '\n' << getLineOfChars<'~'>() << '\n'; - Colour colour(Colour::SecondaryText); - stream << currentTestRunInfo->name - << " is a Catch v" << libraryVersion() << " host application.\n" - << "Run with -? for options\n\n"; - - if (m_config->rngSeed() != 0) - stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; - - currentTestRunInfo.used = true; -} -void ConsoleReporter::lazyPrintGroupInfo() { - if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) { - printClosedHeader("Group: " + currentGroupInfo->name); - currentGroupInfo.used = true; - } -} -void ConsoleReporter::printTestCaseAndSectionHeader() { - assert(!m_sectionStack.empty()); - printOpenHeader(currentTestCaseInfo->name); - - if (m_sectionStack.size() > 1) { - Colour colourGuard(Colour::Headers); - - auto - it = m_sectionStack.begin() + 1, // Skip first section (test case) - itEnd = m_sectionStack.end(); - for (; it != itEnd; ++it) - printHeaderString(it->name, 2); - } - - SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; - - if (!lineInfo.empty()) { - stream << getLineOfChars<'-'>() << '\n'; - Colour colourGuard(Colour::FileName); - stream << lineInfo << '\n'; - } - stream << getLineOfChars<'.'>() << '\n' << std::endl; -} - -void ConsoleReporter::printClosedHeader(std::string const& _name) { - printOpenHeader(_name); - stream << getLineOfChars<'.'>() << '\n'; -} -void ConsoleReporter::printOpenHeader(std::string const& _name) { - stream << getLineOfChars<'-'>() << '\n'; - { - Colour colourGuard(Colour::Headers); - printHeaderString(_name); - } -} - -// if string has a : in first line will set indent to follow it on -// subsequent lines -void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) { - std::size_t i = _string.find(": "); - if (i != std::string::npos) - i += 2; - else - i = 0; - stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n'; -} - -struct SummaryColumn { - - SummaryColumn( std::string _label, Colour::Code _colour ) - : label( std::move( _label ) ), - colour( _colour ) {} - SummaryColumn addRow( std::size_t count ) { - ReusableStringStream rss; - rss << count; - std::string row = rss.str(); - for (auto& oldRow : rows) { - while (oldRow.size() < row.size()) - oldRow = ' ' + oldRow; - while (oldRow.size() > row.size()) - row = ' ' + row; - } - rows.push_back(row); - return *this; - } - - std::string label; - Colour::Code colour; - std::vector<std::string> rows; - -}; - -void ConsoleReporter::printTotals( Totals const& totals ) { - if (totals.testCases.total() == 0) { - stream << Colour(Colour::Warning) << "No tests ran\n"; - } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) { - stream << Colour(Colour::ResultSuccess) << "All tests passed"; - stream << " (" - << pluralise(totals.assertions.passed, "assertion") << " in " - << pluralise(totals.testCases.passed, "test case") << ')' - << '\n'; - } else { - - std::vector<SummaryColumn> columns; - columns.push_back(SummaryColumn("", Colour::None) - .addRow(totals.testCases.total()) - .addRow(totals.assertions.total())); - columns.push_back(SummaryColumn("passed", Colour::Success) - .addRow(totals.testCases.passed) - .addRow(totals.assertions.passed)); - columns.push_back(SummaryColumn("failed", Colour::ResultError) - .addRow(totals.testCases.failed) - .addRow(totals.assertions.failed)); - columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure) - .addRow(totals.testCases.failedButOk) - .addRow(totals.assertions.failedButOk)); - - printSummaryRow("test cases", columns, 0); - printSummaryRow("assertions", columns, 1); - } -} -void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) { - for (auto col : cols) { - std::string value = col.rows[row]; - if (col.label.empty()) { - stream << label << ": "; - if (value != "0") - stream << value; - else - stream << Colour(Colour::Warning) << "- none -"; - } else if (value != "0") { - stream << Colour(Colour::LightGrey) << " | "; - stream << Colour(col.colour) - << value << ' ' << col.label; - } - } - stream << '\n'; -} - -void ConsoleReporter::printTotalsDivider(Totals const& totals) { - if (totals.testCases.total() > 0) { - std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total()); - std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total()); - std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total()); - while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1) - findMax(failedRatio, failedButOkRatio, passedRatio)++; - while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1) - findMax(failedRatio, failedButOkRatio, passedRatio)--; - - stream << Colour(Colour::Error) << std::string(failedRatio, '='); - stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); - if (totals.testCases.allPassed()) - stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); - else - stream << Colour(Colour::Success) << std::string(passedRatio, '='); - } else { - stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); - } - stream << '\n'; -} -void ConsoleReporter::printSummaryDivider() { - stream << getLineOfChars<'-'>() << '\n'; -} - -void ConsoleReporter::printTestFilters() { - if (m_config->testSpec().hasFilters()) - stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n'; -} - -CATCH_REGISTER_REPORTER("console", ConsoleReporter) - -} // end namespace Catch - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif -// end catch_reporter_console.cpp -// start catch_reporter_junit.cpp - -#include <cassert> -#include <sstream> -#include <ctime> -#include <algorithm> - -namespace Catch { - - namespace { - std::string getCurrentTimestamp() { - // Beware, this is not reentrant because of backward compatibility issues - // Also, UTC only, again because of backward compatibility (%z is C++11) - time_t rawtime; - std::time(&rawtime); - auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); - -#ifdef _MSC_VER - std::tm timeInfo = {}; - gmtime_s(&timeInfo, &rawtime); -#else - std::tm* timeInfo; - timeInfo = std::gmtime(&rawtime); -#endif - - 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); - } - - std::string fileNameTag(const std::vector<std::string> &tags) { - auto it = std::find_if(begin(tags), - end(tags), - [] (std::string const& tag) {return tag.front() == '#'; }); - if (it != tags.end()) - return it->substr(1); - return std::string(); - } - } // anonymous namespace - - JunitReporter::JunitReporter( ReporterConfig const& _config ) - : CumulativeReporterBase( _config ), - xml( _config.stream() ) - { - m_reporterPrefs.shouldRedirectStdOut = true; - m_reporterPrefs.shouldReportAllAssertions = true; - } - - JunitReporter::~JunitReporter() {} - - std::string JunitReporter::getDescription() { - return "Reports test results in an XML format that looks like Ant's junitreport target"; - } - - void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {} - - void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) { - CumulativeReporterBase::testRunStarting( runInfo ); - xml.startElement( "testsuites" ); - } - - void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) { - suiteTimer.start(); - stdOutForSuite.clear(); - stdErrForSuite.clear(); - unexpectedExceptions = 0; - CumulativeReporterBase::testGroupStarting( groupInfo ); - } - - void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) { - m_okToFail = testCaseInfo.okToFail(); - } - - bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) { - if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) - unexpectedExceptions++; - return CumulativeReporterBase::assertionEnded( assertionStats ); - } - - void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { - stdOutForSuite += testCaseStats.stdOut; - stdErrForSuite += testCaseStats.stdErr; - CumulativeReporterBase::testCaseEnded( testCaseStats ); - } - - void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { - double suiteTime = suiteTimer.getElapsedSeconds(); - CumulativeReporterBase::testGroupEnded( testGroupStats ); - writeGroup( *m_testGroups.back(), suiteTime ); - } - - void JunitReporter::testRunEndedCumulative() { - xml.endElement(); - } - - void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); - - TestGroupStats const& stats = groupNode.value; - xml.writeAttribute( "name", stats.groupInfo.name ); - xml.writeAttribute( "errors", unexpectedExceptions ); - xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); - xml.writeAttribute( "tests", stats.totals.assertions.total() ); - xml.writeAttribute( "hostname", "tbd" ); // !TBD - if( m_config->showDurations() == ShowDurations::Never ) - xml.writeAttribute( "time", "" ); - else - xml.writeAttribute( "time", suiteTime ); - xml.writeAttribute( "timestamp", getCurrentTimestamp() ); - - // Write properties if there are any - if (m_config->hasTestFilters() || m_config->rngSeed() != 0) { - auto properties = xml.scopedElement("properties"); - if (m_config->hasTestFilters()) { - xml.scopedElement("property") - .writeAttribute("name", "filters") - .writeAttribute("value", serializeFilters(m_config->getTestsOrTags())); - } - if (m_config->rngSeed() != 0) { - xml.scopedElement("property") - .writeAttribute("name", "random-seed") - .writeAttribute("value", m_config->rngSeed()); - } - } - - // Write test cases - for( auto const& child : groupNode.children ) - writeTestCase( *child ); - - xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false ); - xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false ); - } - - void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) { - TestCaseStats const& stats = testCaseNode.value; - - // All test cases have exactly one section - which represents the - // test case itself. That section may have 0-n nested sections - assert( testCaseNode.children.size() == 1 ); - SectionNode const& rootSection = *testCaseNode.children.front(); - - std::string className = stats.testInfo.className; - - if( className.empty() ) { - className = fileNameTag(stats.testInfo.tags); - if ( className.empty() ) - className = "global"; - } - - if ( !m_config->name().empty() ) - className = m_config->name() + "." + className; - - writeSection( className, "", rootSection ); - } - - void JunitReporter::writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { - std::string name = trim( sectionNode.stats.sectionInfo.name ); - if( !rootName.empty() ) - name = rootName + '/' + name; - - if( !sectionNode.assertions.empty() || - !sectionNode.stdOut.empty() || - !sectionNode.stdErr.empty() ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); - if( className.empty() ) { - xml.writeAttribute( "classname", name ); - xml.writeAttribute( "name", "root" ); - } - else { - xml.writeAttribute( "classname", className ); - xml.writeAttribute( "name", name ); - } - xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); - - writeAssertions( sectionNode ); - - if( !sectionNode.stdOut.empty() ) - xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); - if( !sectionNode.stdErr.empty() ) - xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); - } - for( auto const& childNode : sectionNode.childSections ) - if( className.empty() ) - writeSection( name, "", *childNode ); - else - writeSection( className, name, *childNode ); - } - - void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { - for( auto const& assertion : sectionNode.assertions ) - writeAssertion( assertion ); - } - - void JunitReporter::writeAssertion( AssertionStats const& stats ) { - AssertionResult const& result = stats.assertionResult; - if( !result.isOk() ) { - std::string elementName; - switch( result.getResultType() ) { - case ResultWas::ThrewException: - case ResultWas::FatalErrorCondition: - elementName = "error"; - break; - case ResultWas::ExplicitFailure: - elementName = "failure"; - break; - case ResultWas::ExpressionFailed: - elementName = "failure"; - break; - case ResultWas::DidntThrowException: - elementName = "failure"; - break; - - // We should never see these here: - case ResultWas::Info: - case ResultWas::Warning: - case ResultWas::Ok: - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - elementName = "internalError"; - break; - } - - XmlWriter::ScopedElement e = xml.scopedElement( elementName ); - - xml.writeAttribute( "message", result.getExpandedExpression() ); - xml.writeAttribute( "type", result.getTestMacroName() ); - - ReusableStringStream rss; - if( !result.getMessage().empty() ) - rss << result.getMessage() << '\n'; - for( auto const& msg : stats.infoMessages ) - if( msg.type == ResultWas::Info ) - rss << msg.message << '\n'; - - rss << "at " << result.getSourceInfo(); - xml.writeText( rss.str(), false ); - } - } - - CATCH_REGISTER_REPORTER( "junit", JunitReporter ) - -} // end namespace Catch -// end catch_reporter_junit.cpp -// start catch_reporter_listening.cpp - -#include <cassert> - -namespace Catch { - - ListeningReporter::ListeningReporter() { - // We will assume that listeners will always want all assertions - m_preferences.shouldReportAllAssertions = true; - } - - void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) { - m_listeners.push_back( std::move( listener ) ); - } - - void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) { - assert(!m_reporter && "Listening reporter can wrap only 1 real reporter"); - m_reporter = std::move( reporter ); - m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut; - } - - ReporterPreferences ListeningReporter::getPreferences() const { - return m_preferences; - } - - std::set<Verbosity> ListeningReporter::getSupportedVerbosities() { - return std::set<Verbosity>{ }; - } - - void ListeningReporter::noMatchingTestCases( std::string const& spec ) { - for ( auto const& listener : m_listeners ) { - listener->noMatchingTestCases( spec ); - } - m_reporter->noMatchingTestCases( spec ); - } - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void ListeningReporter::benchmarkPreparing( std::string const& name ) { - for (auto const& listener : m_listeners) { - listener->benchmarkPreparing(name); - } - m_reporter->benchmarkPreparing(name); - } - void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) { - for ( auto const& listener : m_listeners ) { - listener->benchmarkStarting( benchmarkInfo ); - } - m_reporter->benchmarkStarting( benchmarkInfo ); - } - void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) { - for ( auto const& listener : m_listeners ) { - listener->benchmarkEnded( benchmarkStats ); - } - m_reporter->benchmarkEnded( benchmarkStats ); - } - - void ListeningReporter::benchmarkFailed( std::string const& error ) { - for (auto const& listener : m_listeners) { - listener->benchmarkFailed(error); - } - m_reporter->benchmarkFailed(error); - } -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) { - for ( auto const& listener : m_listeners ) { - listener->testRunStarting( testRunInfo ); - } - m_reporter->testRunStarting( testRunInfo ); - } - - void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) { - for ( auto const& listener : m_listeners ) { - listener->testGroupStarting( groupInfo ); - } - m_reporter->testGroupStarting( groupInfo ); - } - - void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) { - for ( auto const& listener : m_listeners ) { - listener->testCaseStarting( testInfo ); - } - m_reporter->testCaseStarting( testInfo ); - } - - void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) { - for ( auto const& listener : m_listeners ) { - listener->sectionStarting( sectionInfo ); - } - m_reporter->sectionStarting( sectionInfo ); - } - - void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) { - for ( auto const& listener : m_listeners ) { - listener->assertionStarting( assertionInfo ); - } - m_reporter->assertionStarting( assertionInfo ); - } - - // The return value indicates if the messages buffer should be cleared: - bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) { - for( auto const& listener : m_listeners ) { - static_cast<void>( listener->assertionEnded( assertionStats ) ); - } - return m_reporter->assertionEnded( assertionStats ); - } - - void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) { - for ( auto const& listener : m_listeners ) { - listener->sectionEnded( sectionStats ); - } - m_reporter->sectionEnded( sectionStats ); - } - - void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { - for ( auto const& listener : m_listeners ) { - listener->testCaseEnded( testCaseStats ); - } - m_reporter->testCaseEnded( testCaseStats ); - } - - void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { - for ( auto const& listener : m_listeners ) { - listener->testGroupEnded( testGroupStats ); - } - m_reporter->testGroupEnded( testGroupStats ); - } - - void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) { - for ( auto const& listener : m_listeners ) { - listener->testRunEnded( testRunStats ); - } - m_reporter->testRunEnded( testRunStats ); - } - - void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) { - for ( auto const& listener : m_listeners ) { - listener->skipTest( testInfo ); - } - m_reporter->skipTest( testInfo ); - } - - bool ListeningReporter::isMulti() const { - return true; - } - -} // end namespace Catch -// end catch_reporter_listening.cpp -// start catch_reporter_xml.cpp - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch - // Note that 4062 (not all labels are handled - // and default is missing) is enabled -#endif - -namespace Catch { - XmlReporter::XmlReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_xml(_config.stream()) - { - m_reporterPrefs.shouldRedirectStdOut = true; - m_reporterPrefs.shouldReportAllAssertions = true; - } - - XmlReporter::~XmlReporter() = default; - - std::string XmlReporter::getDescription() { - return "Reports test results as an XML document"; - } - - std::string XmlReporter::getStylesheetRef() const { - return std::string(); - } - - void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) { - m_xml - .writeAttribute( "filename", sourceInfo.file ) - .writeAttribute( "line", sourceInfo.line ); - } - - void XmlReporter::noMatchingTestCases( std::string const& s ) { - StreamingReporterBase::noMatchingTestCases( s ); - } - - void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) { - StreamingReporterBase::testRunStarting( testInfo ); - std::string stylesheetRef = getStylesheetRef(); - if( !stylesheetRef.empty() ) - m_xml.writeStylesheetRef( stylesheetRef ); - m_xml.startElement( "Catch" ); - if( !m_config->name().empty() ) - m_xml.writeAttribute( "name", m_config->name() ); - if (m_config->testSpec().hasFilters()) - m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) ); - if( m_config->rngSeed() != 0 ) - m_xml.scopedElement( "Randomness" ) - .writeAttribute( "seed", m_config->rngSeed() ); - } - - void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) { - StreamingReporterBase::testGroupStarting( groupInfo ); - m_xml.startElement( "Group" ) - .writeAttribute( "name", groupInfo.name ); - } - - void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) { - StreamingReporterBase::testCaseStarting(testInfo); - m_xml.startElement( "TestCase" ) - .writeAttribute( "name", trim( testInfo.name ) ) - .writeAttribute( "description", testInfo.description ) - .writeAttribute( "tags", testInfo.tagsAsString() ); - - writeSourceInfo( testInfo.lineInfo ); - - if ( m_config->showDurations() == ShowDurations::Always ) - m_testCaseTimer.start(); - m_xml.ensureTagClosed(); - } - - void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) { - StreamingReporterBase::sectionStarting( sectionInfo ); - if( m_sectionDepth++ > 0 ) { - m_xml.startElement( "Section" ) - .writeAttribute( "name", trim( sectionInfo.name ) ); - writeSourceInfo( sectionInfo.lineInfo ); - m_xml.ensureTagClosed(); - } - } - - void XmlReporter::assertionStarting( AssertionInfo const& ) { } - - bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) { - - AssertionResult const& result = assertionStats.assertionResult; - - bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); - - if( includeResults || result.getResultType() == ResultWas::Warning ) { - // Print any info messages in <Info> tags. - for( auto const& msg : assertionStats.infoMessages ) { - if( msg.type == ResultWas::Info && includeResults ) { - m_xml.scopedElement( "Info" ) - .writeText( msg.message ); - } else if ( msg.type == ResultWas::Warning ) { - m_xml.scopedElement( "Warning" ) - .writeText( msg.message ); - } - } - } - - // Drop out if result was successful but we're not printing them. - if( !includeResults && result.getResultType() != ResultWas::Warning ) - return true; - - // Print the expression if there is one. - if( result.hasExpression() ) { - m_xml.startElement( "Expression" ) - .writeAttribute( "success", result.succeeded() ) - .writeAttribute( "type", result.getTestMacroName() ); - - writeSourceInfo( result.getSourceInfo() ); - - m_xml.scopedElement( "Original" ) - .writeText( result.getExpression() ); - m_xml.scopedElement( "Expanded" ) - .writeText( result.getExpandedExpression() ); - } - - // And... Print a result applicable to each result type. - switch( result.getResultType() ) { - case ResultWas::ThrewException: - m_xml.startElement( "Exception" ); - writeSourceInfo( result.getSourceInfo() ); - m_xml.writeText( result.getMessage() ); - m_xml.endElement(); - break; - case ResultWas::FatalErrorCondition: - m_xml.startElement( "FatalErrorCondition" ); - writeSourceInfo( result.getSourceInfo() ); - m_xml.writeText( result.getMessage() ); - m_xml.endElement(); - break; - case ResultWas::Info: - m_xml.scopedElement( "Info" ) - .writeText( result.getMessage() ); - break; - case ResultWas::Warning: - // Warning will already have been written - break; - case ResultWas::ExplicitFailure: - m_xml.startElement( "Failure" ); - writeSourceInfo( result.getSourceInfo() ); - m_xml.writeText( result.getMessage() ); - m_xml.endElement(); - break; - default: - break; - } - - if( result.hasExpression() ) - m_xml.endElement(); - - return true; - } - - void XmlReporter::sectionEnded( SectionStats const& sectionStats ) { - StreamingReporterBase::sectionEnded( sectionStats ); - if( --m_sectionDepth > 0 ) { - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); - e.writeAttribute( "successes", sectionStats.assertions.passed ); - e.writeAttribute( "failures", sectionStats.assertions.failed ); - e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); - - m_xml.endElement(); - } - } - - void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { - StreamingReporterBase::testCaseEnded( testCaseStats ); - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); - e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); - - if( !testCaseStats.stdOut.empty() ) - m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); - if( !testCaseStats.stdErr.empty() ) - m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); - - m_xml.endElement(); - } - - void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { - StreamingReporterBase::testGroupEnded( testGroupStats ); - // TODO: Check testGroupStats.aborting and act accordingly. - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) - .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) { - StreamingReporterBase::testRunEnded( testRunStats ); - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testRunStats.totals.assertions.passed ) - .writeAttribute( "failures", testRunStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) { - m_xml.startElement("BenchmarkResults") - .writeAttribute("name", info.name) - .writeAttribute("samples", info.samples) - .writeAttribute("resamples", info.resamples) - .writeAttribute("iterations", info.iterations) - .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution)) - .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration)) - .writeComment("All values in nano seconds"); - } - - void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) { - m_xml.startElement("mean") - .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count())) - .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count())) - .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count())) - .writeAttribute("ci", benchmarkStats.mean.confidence_interval); - m_xml.endElement(); - m_xml.startElement("standardDeviation") - .writeAttribute("value", benchmarkStats.standardDeviation.point.count()) - .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count()) - .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count()) - .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval); - m_xml.endElement(); - m_xml.startElement("outliers") - .writeAttribute("variance", benchmarkStats.outlierVariance) - .writeAttribute("lowMild", benchmarkStats.outliers.low_mild) - .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe) - .writeAttribute("highMild", benchmarkStats.outliers.high_mild) - .writeAttribute("highSevere", benchmarkStats.outliers.high_severe); - m_xml.endElement(); - m_xml.endElement(); - } - - void XmlReporter::benchmarkFailed(std::string const &error) { - m_xml.scopedElement("failed"). - writeAttribute("message", error); - m_xml.endElement(); - } -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - CATCH_REGISTER_REPORTER( "xml", XmlReporter ) - -} // end namespace Catch - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif -// end catch_reporter_xml.cpp - -namespace Catch { - LeakDetector leakDetector; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// end catch_impl.hpp -#endif - -#ifdef CATCH_CONFIG_MAIN -// start catch_default_main.hpp - -#ifndef __OBJC__ - -#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) -// Standard C/C++ Win32 Unicode wmain entry point -extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { -#else -// Standard C/C++ main entry point -int main (int argc, char * argv[]) { -#endif - - return Catch::Session().run( argc, argv ); -} - -#else // __OBJC__ - -// Objective-C entry point -int main (int argc, char * const argv[]) { -#if !CATCH_ARC_ENABLED - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; -#endif - - Catch::registerTestMethods(); - int result = Catch::Session().run( argc, (char**)argv ); - -#if !CATCH_ARC_ENABLED - [pool drain]; -#endif - - return result; -} - -#endif // __OBJC__ - -// end catch_default_main.hpp -#endif - -#if !defined(CATCH_CONFIG_IMPL_ONLY) - -#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED -# undef CLARA_CONFIG_MAIN -#endif - -#if !defined(CATCH_CONFIG_DISABLE) -////// -// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ -#ifdef CATCH_CONFIG_PREFIX_ALL - -#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) - -#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) -#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) -#endif// CATCH_CONFIG_DISABLE_MATCHERS -#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) - -#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) -#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) - -#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) -#endif // CATCH_CONFIG_DISABLE_MATCHERS -#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) - -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) - -#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) -#endif // CATCH_CONFIG_DISABLE_MATCHERS - -#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) -#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg ) -#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) -#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ ) - -#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) -#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) -#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) -#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) -#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) -#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) - -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) -#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) -#else -#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) -#endif - -#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) -#define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ ) -#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ ) -#else -#define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ ) -#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ ) -#endif - -// "BDD-style" convenience wrappers -#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc ) -#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc ) -#define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc ) -#define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc ) -#define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc ) -#define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc ) - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) -#define CATCH_BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) -#define CATCH_BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - -// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required -#else - -#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) - -#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) -#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) -#endif // CATCH_CONFIG_DISABLE_MATCHERS -#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) - -#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) -#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) - -#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) -#endif // CATCH_CONFIG_DISABLE_MATCHERS -#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) - -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) - -#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) -#endif // CATCH_CONFIG_DISABLE_MATCHERS - -#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) -#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg ) -#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) -#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ ) - -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) -#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) -#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) -#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) -#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) -#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) -#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__) -#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#else -#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) -#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) ) -#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) -#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) -#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) ) -#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) -#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) ) -#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) -#endif - -#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) -#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ ) -#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" ) -#else -#define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ ) -#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ ) -#endif - -#endif - -#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) - -// "BDD-style" convenience wrappers -#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) - -#define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc ) -#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc ) -#define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc ) -#define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc ) -#define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc ) -#define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc ) - -#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) -#define BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) -#define BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) -#endif // CATCH_CONFIG_ENABLE_BENCHMARKING - -using Catch::Detail::Approx; - -#else // CATCH_CONFIG_DISABLE - -////// -// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ -#ifdef CATCH_CONFIG_PREFIX_ALL - -#define CATCH_REQUIRE( ... ) (void)(0) -#define CATCH_REQUIRE_FALSE( ... ) (void)(0) - -#define CATCH_REQUIRE_THROWS( ... ) (void)(0) -#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) -#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) -#endif// CATCH_CONFIG_DISABLE_MATCHERS -#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0) - -#define CATCH_CHECK( ... ) (void)(0) -#define CATCH_CHECK_FALSE( ... ) (void)(0) -#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__) -#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) -#define CATCH_CHECK_NOFAIL( ... ) (void)(0) - -#define CATCH_CHECK_THROWS( ... ) (void)(0) -#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0) -#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) -#endif // CATCH_CONFIG_DISABLE_MATCHERS -#define CATCH_CHECK_NOTHROW( ... ) (void)(0) - -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CATCH_CHECK_THAT( arg, matcher ) (void)(0) - -#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0) -#endif // CATCH_CONFIG_DISABLE_MATCHERS - -#define CATCH_INFO( msg ) (void)(0) -#define CATCH_UNSCOPED_INFO( msg ) (void)(0) -#define CATCH_WARN( msg ) (void)(0) -#define CATCH_CAPTURE( msg ) (void)(0) - -#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_METHOD_AS_TEST_CASE( method, ... ) -#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) -#define CATCH_SECTION( ... ) -#define CATCH_DYNAMIC_SECTION( ... ) -#define CATCH_FAIL( ... ) (void)(0) -#define CATCH_FAIL_CHECK( ... ) (void)(0) -#define CATCH_SUCCEED( ... ) (void)(0) - -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) -#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) -#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__) -#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#else -#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) ) -#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) ) -#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#endif - -// "BDD-style" convenience wrappers -#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) -#define CATCH_GIVEN( desc ) -#define CATCH_AND_GIVEN( desc ) -#define CATCH_WHEN( desc ) -#define CATCH_AND_WHEN( desc ) -#define CATCH_THEN( desc ) -#define CATCH_AND_THEN( desc ) - -#define CATCH_STATIC_REQUIRE( ... ) (void)(0) -#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0) - -// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required -#else - -#define REQUIRE( ... ) (void)(0) -#define REQUIRE_FALSE( ... ) (void)(0) - -#define REQUIRE_THROWS( ... ) (void)(0) -#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) -#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) -#endif // CATCH_CONFIG_DISABLE_MATCHERS -#define REQUIRE_NOTHROW( ... ) (void)(0) - -#define CHECK( ... ) (void)(0) -#define CHECK_FALSE( ... ) (void)(0) -#define CHECKED_IF( ... ) if (__VA_ARGS__) -#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) -#define CHECK_NOFAIL( ... ) (void)(0) - -#define CHECK_THROWS( ... ) (void)(0) -#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0) -#define CHECK_THROWS_WITH( expr, matcher ) (void)(0) -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) -#endif // CATCH_CONFIG_DISABLE_MATCHERS -#define CHECK_NOTHROW( ... ) (void)(0) - -#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) -#define CHECK_THAT( arg, matcher ) (void)(0) - -#define REQUIRE_THAT( arg, matcher ) (void)(0) -#endif // CATCH_CONFIG_DISABLE_MATCHERS - -#define INFO( msg ) (void)(0) -#define UNSCOPED_INFO( msg ) (void)(0) -#define WARN( msg ) (void)(0) -#define CAPTURE( msg ) (void)(0) - -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define METHOD_AS_TEST_CASE( method, ... ) -#define REGISTER_TEST_CASE( Function, ... ) (void)(0) -#define SECTION( ... ) -#define DYNAMIC_SECTION( ... ) -#define FAIL( ... ) (void)(0) -#define FAIL_CHECK( ... ) (void)(0) -#define SUCCEED( ... ) (void)(0) -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) -#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) -#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__) -#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#else -#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) ) -#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) ) -#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) ) -#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) ) -#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#endif - -#define STATIC_REQUIRE( ... ) (void)(0) -#define STATIC_REQUIRE_FALSE( ... ) (void)(0) - -#endif - -#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) - -// "BDD-style" convenience wrappers -#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) - -#define GIVEN( desc ) -#define AND_GIVEN( desc ) -#define WHEN( desc ) -#define AND_WHEN( desc ) -#define THEN( desc ) -#define AND_THEN( desc ) - -using Catch::Detail::Approx; - -#endif - -#endif // ! CATCH_CONFIG_IMPL_ONLY - -// start catch_reenable_warnings.h - - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(pop) -# else -# pragma clang diagnostic pop -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic pop -#endif - -// end catch_reenable_warnings.h -// end catch.hpp -#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h deleted file mode 100644 index b22c0a140..000000000 --- a/toolsrc/include/pch.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include <vcpkg/base/system_headers.h> - -#include <vcpkg/base/files.h> -#include <vcpkg/base/pragmas.h> - -#if defined(_WIN32) -#include <process.h> -#include <shellapi.h> -#include <winhttp.h> -#endif - -#include <math.h> -#include <stdarg.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#include <algorithm> -#include <array> -#include <atomic> -#include <cassert> -#include <cctype> -#include <chrono> -#include <codecvt> -#include <fstream> -#include <functional> -#include <iomanip> -#include <iostream> -#include <iterator> -#include <limits> -#include <map> -#include <memory> -#include <mutex> -#include <random> -#include <regex> -#include <set> -#include <stdexcept> -#include <string> -#if defined(_WIN32) -#include <sys/timeb.h> -#else -#include <sys/time.h> -#endif - -#include <time.h> - -#include <system_error> -#include <thread> -#include <type_traits> -#include <unordered_map> -#include <unordered_set> -#include <utility> -#include <vector> diff --git a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h deleted file mode 100644 index 6017457b6..000000000 --- a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include <vcpkg/cmakevars.h> - -namespace vcpkg::Test -{ - struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider - { - using SMap = std::unordered_map<std::string, std::string>; - void load_generic_triplet_vars(Triplet triplet) const override - { - generic_triplet_vars.emplace(triplet, SMap{}); - } - - void load_dep_info_vars(Span<const PackageSpec> specs) const override - { - for (auto&& spec : specs) - dep_info_vars.emplace(spec, SMap{}); - } - - void load_tag_vars(Span<const FullPackageSpec> specs, - const PortFileProvider::PortFileProvider& port_provider) const override - { - for (auto&& spec : specs) - tag_vars.emplace(spec.package_spec, SMap{}); - (void)(port_provider); - } - - Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars( - Triplet triplet) const override; - - Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars( - const PackageSpec& spec) const override; - - Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars( - const PackageSpec& spec) const override; - - mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_info_vars; - mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars; - mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars; - }; -} diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h deleted file mode 100644 index 1e20531fc..000000000 --- a/toolsrc/include/vcpkg-test/util.h +++ /dev/null @@ -1,132 +0,0 @@ -#include <vcpkg/base/system_headers.h> - -#include <catch2/catch.hpp> - -#include <vcpkg/base/files.h> -#include <vcpkg/base/pragmas.h> - -#include <vcpkg/statusparagraph.h> - -#include <memory> - -#define CHECK_EC(ec) \ - do \ - { \ - if (ec) \ - { \ - FAIL(ec.message()); \ - } \ - } while (0) - -namespace Catch -{ - template<> - struct StringMaker<vcpkg::FullPackageSpec> - { - static std::string convert(vcpkg::FullPackageSpec const& value) - { - return vcpkg::Strings::concat(value.package_spec.name(), - '[', - vcpkg::Strings::join(",", value.features), - "]:", - value.package_spec.triplet()); - } - }; - - template<> - struct StringMaker<vcpkg::Triplet> - { - static const std::string& convert(const vcpkg::Triplet& triplet) { return triplet.canonical_name(); } - }; -} - -namespace vcpkg::Test -{ - std::unique_ptr<SourceControlFile> make_control_file( - const char* name, - const char* depends, - const std::vector<std::pair<const char*, const char*>>& features = {}, - const std::vector<const char*>& default_features = {}); - - inline auto test_parse_control_file(const std::vector<std::unordered_map<std::string, std::string>>& v) - { - std::vector<vcpkg::Parse::Paragraph> pghs; - for (auto&& p : v) - { - pghs.emplace_back(); - for (auto&& kv : p) - pghs.back().emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); - } - return vcpkg::SourceControlFile::parse_control_file("", std::move(pghs)); - } - - std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name, - const char* depends = "", - const char* default_features = "", - const char* triplet = "x86-windows"); - - std::unique_ptr<vcpkg::StatusParagraph> make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "", - const char* triplet = "x86-windows"); - - extern const Triplet X86_WINDOWS; - extern const Triplet X64_WINDOWS; - extern const Triplet X86_UWP; - extern const Triplet ARM_UWP; - extern const Triplet X64_ANDROID; - - /// <summary> - /// Map of source control files by their package name. - /// </summary> - struct PackageSpecMap - { - std::unordered_map<std::string, SourceControlFileLocation> map; - Triplet triplet; - PackageSpecMap(Triplet t = X86_WINDOWS) noexcept : triplet(t) { } - - PackageSpec emplace(const char* name, - const char* depends = "", - const std::vector<std::pair<const char*, const char*>>& features = {}, - const std::vector<const char*>& default_features = {}); - - PackageSpec emplace(vcpkg::SourceControlFileLocation&& scfl); - }; - - template<class T, class S> - T&& unwrap(vcpkg::ExpectedT<T, S>&& p) - { - REQUIRE(p.has_value()); - return std::move(*p.get()); - } - - template<class T> - T&& unwrap(vcpkg::Optional<T>&& opt) - { - REQUIRE(opt.has_value()); - return std::move(*opt.get()); - } - - struct AllowSymlinks - { - enum Tag : bool - { - No = false, - Yes = true, - } tag; - - constexpr AllowSymlinks(Tag tag) noexcept : tag(tag) { } - - constexpr explicit AllowSymlinks(bool b) noexcept : tag(b ? Yes : No) { } - - constexpr operator bool() const noexcept { return tag == Yes; } - }; - - AllowSymlinks can_create_symlinks() noexcept; - - const fs::path& base_temporary_directory() noexcept; - - void create_symlink(const fs::path& file, const fs::path& target, std::error_code& ec); - - void create_directory_symlink(const fs::path& file, const fs::path& target, std::error_code& ec); -} diff --git a/toolsrc/include/vcpkg/archives.h b/toolsrc/include/vcpkg/archives.h deleted file mode 100644 index be2523dfb..000000000 --- a/toolsrc/include/vcpkg/archives.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/files.h> - -namespace vcpkg::Archives -{ - void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path); -} diff --git a/toolsrc/include/vcpkg/base/basic_checks.h b/toolsrc/include/vcpkg/base/basic_checks.h deleted file mode 100644 index 2ea714599..000000000 --- a/toolsrc/include/vcpkg/base/basic_checks.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include <vcpkg/base/lineinfo.h> -#include <vcpkg/base/stringview.h> - -namespace vcpkg::Checks -{ - void register_global_shutdown_handler(void (*func)()); - - // Note: for internal use - [[noreturn]] void final_cleanup_and_exit(const int exit_code); - - // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been - // broken. - [[noreturn]] void unreachable(const LineInfo& line_info); - - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); - - // Exit the tool without an error message. - [[noreturn]] void exit_fail(const LineInfo& line_info); - - // Exit the tool successfully. - [[noreturn]] void exit_success(const LineInfo& line_info); - - // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, StringView error_message); - - // If expression is false, call exit_fail. - void check_exit(const LineInfo& line_info, bool expression); - - // if expression is false, call exit_with_message. - void check_exit(const LineInfo& line_info, bool expression, StringView error_message); - - // Display a message indicating that vcpkg should be upgraded and exit. - [[noreturn]] void exit_maybe_upgrade(const LineInfo& line_info); - [[noreturn]] void exit_maybe_upgrade(const LineInfo& line_info, StringView error_message); - - // Check the indicated condition and call exit_maybe_upgrade if it is false. - void check_maybe_upgrade(const LineInfo& line_info, bool condition); - void check_maybe_upgrade(const LineInfo& line_info, bool condition, StringView error_message); -} diff --git a/toolsrc/include/vcpkg/base/cache.h b/toolsrc/include/vcpkg/base/cache.h deleted file mode 100644 index 7efae1361..000000000 --- a/toolsrc/include/vcpkg/base/cache.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include <map> - -namespace vcpkg -{ - template<class Key, class Value, class Less = std::less<Key>> - struct Cache - { - template<class F> - Value const& get_lazy(const Key& k, const F& f) const - { - auto it = m_cache.find(k); - if (it != m_cache.end()) return it->second; - return m_cache.emplace(k, f()).first->second; - } - - private: - mutable std::map<Key, Value, Less> m_cache; - }; -} diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h deleted file mode 100644 index f360fcb36..000000000 --- a/toolsrc/include/vcpkg/base/checks.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include <vcpkg/base/basic_checks.h> -#include <vcpkg/base/strings.h> - -namespace vcpkg::Checks -{ - // Additional convenience overloads on top of basic_checks.h that do formatting. - - template<class Arg1, class... Args> - // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, - const char* error_message_template, - const Arg1& error_message_arg1, - const Args&... error_message_args) - { - exit_with_message(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - - template<class Conditional, class Arg1, class... Args> - void check_exit(const LineInfo& line_info, - Conditional&& expression, - const char* error_message_template, - const Arg1& error_message_arg1, - const Args&... error_message_args) - { - if (!expression) - { - // Only create the string if the expression is false - exit_with_message(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - } - - template<class Arg1, class... Args> - [[noreturn]] void exit_maybe_upgrade(const LineInfo& line_info, - const char* error_message_template, - const Arg1& error_message_arg1, - const Args&... error_message_args) - { - exit_maybe_upgrade(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - - template<class Conditional, class Arg1, class... Args> - void check_maybe_upgrade(const LineInfo& line_info, - Conditional&& expression, - const char* error_message_template, - const Arg1& error_message_arg1, - const Args&... error_message_args) - { - if (!expression) - { - // Only create the string if the expression is false - exit_maybe_upgrade(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - } -} diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h deleted file mode 100644 index 0505192a0..000000000 --- a/toolsrc/include/vcpkg/base/chrono.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include <vcpkg/base/cstringview.h> -#include <vcpkg/base/optional.h> - -#include <chrono> -#include <string> - -namespace vcpkg::Chrono -{ - class ElapsedTime - { - using duration = std::chrono::high_resolution_clock::time_point::duration; - - public: - constexpr ElapsedTime() noexcept : m_duration() { } - constexpr ElapsedTime(duration d) noexcept : m_duration(d) { } - - template<class TimeUnit> - TimeUnit as() const - { - return std::chrono::duration_cast<TimeUnit>(m_duration); - } - - std::string to_string() const; - void to_string(std::string& into) const; - - private: - std::chrono::high_resolution_clock::time_point::duration m_duration; - }; - - class ElapsedTimer - { - public: - static ElapsedTimer create_started(); - - constexpr ElapsedTimer() noexcept : m_start_tick() { } - - ElapsedTime elapsed() const - { - return ElapsedTime(std::chrono::high_resolution_clock::now() - this->m_start_tick); - } - - double microseconds() const { return elapsed().as<std::chrono::duration<double, std::micro>>().count(); } - - std::string to_string() const; - void to_string(std::string& into) const; - - private: - std::chrono::high_resolution_clock::time_point m_start_tick; - }; - - class CTime - { - public: - static Optional<CTime> get_current_date_time(); - static Optional<CTime> parse(CStringView str); - - constexpr CTime() noexcept : m_tm{} { } - explicit constexpr CTime(tm t) noexcept : m_tm{t} { } - - CTime add_hours(const int hours) const; - - std::string to_string() const; - - std::chrono::system_clock::time_point to_time_point() const; - - private: - mutable tm m_tm; - }; - - tm get_current_date_time(); - - tm get_current_date_time_local(); -} diff --git a/toolsrc/include/vcpkg/base/cofffilereader.h b/toolsrc/include/vcpkg/base/cofffilereader.h deleted file mode 100644 index e0ad69b33..000000000 --- a/toolsrc/include/vcpkg/base/cofffilereader.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> -#include <vcpkg/base/machinetype.h> - -#include <vector> - -namespace vcpkg::CoffFileReader -{ - struct DllInfo - { - MachineType machine_type; - }; - - struct LibInfo - { - std::vector<MachineType> machine_types; - }; - -#if defined(_WIN32) - DllInfo read_dll(const fs::path& path); - - LibInfo read_lib(const fs::path& path); -#endif -} diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h deleted file mode 100644 index 94c806ae4..000000000 --- a/toolsrc/include/vcpkg/base/cstringview.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include <cstring> -#include <string> - -namespace vcpkg -{ - struct CStringView - { - constexpr CStringView() noexcept : cstr(nullptr) { } - constexpr CStringView(const char* cstr) : cstr(cstr) { } - constexpr CStringView(const CStringView&) = default; - CStringView(const std::string& str) : cstr(str.c_str()) { } - - constexpr const char* c_str() const { return cstr; } - - void to_string(std::string& str) const { str.append(cstr); } - - private: - const char* cstr; - }; - - namespace details - { - inline bool strequal(const char* l, const char* r) { return strcmp(l, r) == 0; } - } - - inline bool operator==(const CStringView& l, const CStringView& r) - { - return details::strequal(l.c_str(), r.c_str()); - } - - inline bool operator==(const char* l, const CStringView& r) { return details::strequal(l, r.c_str()); } - - inline bool operator==(const CStringView& r, const char* l) { return details::strequal(l, r.c_str()); } - - inline bool operator==(const std::string& l, const CStringView& r) { return l == r.c_str(); } - - inline bool operator==(const CStringView& r, const std::string& l) { return l == r.c_str(); } - - // notequals - inline bool operator!=(const CStringView& l, const CStringView& r) - { - return !details::strequal(l.c_str(), r.c_str()); - } - - inline bool operator!=(const char* l, const CStringView& r) { return !details::strequal(l, r.c_str()); } - - inline bool operator!=(const CStringView& r, const char* l) { return !details::strequal(l, r.c_str()); } - - inline bool operator!=(const CStringView& r, const std::string& l) { return l != r.c_str(); } - - inline bool operator!=(const std::string& l, const CStringView& r) { return l != r.c_str(); } - - inline std::string operator+(std::string&& l, const CStringView& r) { return std::move(l) + r.c_str(); } - - inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } - - static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); -} diff --git a/toolsrc/include/vcpkg/base/delayed_init.h b/toolsrc/include/vcpkg/base/delayed_init.h deleted file mode 100644 index a3257f54e..000000000 --- a/toolsrc/include/vcpkg/base/delayed_init.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include <vcpkg/base/optional.h> - -#include <memory> -#include <mutex> - -namespace vcpkg -{ - // implements the equivalent of function static initialization for an object - template<class T> - struct DelayedInit - { - template<class F> - const T& get(F&& f) const - { - std::call_once(underlying_->flag_, [&f, this]() { underlying_->storage_ = std::forward<F>(f)(); }); - return *underlying_->storage_.get(); - } - - private: - struct Storage - { - std::once_flag flag_; - Optional<T> storage_; - }; - std::unique_ptr<Storage> underlying_ = std::make_unique<Storage>(); - }; -} diff --git a/toolsrc/include/vcpkg/base/downloads.h b/toolsrc/include/vcpkg/base/downloads.h deleted file mode 100644 index bf97c0650..000000000 --- a/toolsrc/include/vcpkg/base/downloads.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/view.h> - -namespace vcpkg::Downloads -{ - namespace details - { - struct SplitURIView - { - StringView scheme; - Optional<StringView> authority; - StringView path_query_fragment; - }; - - // e.g. {"https","//example.org", "/index.html"} - Optional<SplitURIView> split_uri_view(StringView uri); - } - - void verify_downloaded_file_hash(const Files::Filesystem& fs, - const std::string& url, - const fs::path& path, - const std::string& sha512); - - // Returns url that was successfully downloaded from - std::string download_file(Files::Filesystem& fs, - View<std::string> urls, - const fs::path& download_path, - const std::string& sha512); - - void download_file(Files::Filesystem& fs, - const std::string& url, - const fs::path& download_path, - const std::string& sha512); - - std::vector<int> download_files(Files::Filesystem& fs, View<std::pair<std::string, fs::path>> url_pairs); - int put_file(const Files::Filesystem&, StringView url, const fs::path& file); - std::vector<int> url_heads(View<std::string> urls); -} diff --git a/toolsrc/include/vcpkg/base/enums.h b/toolsrc/include/vcpkg/base/enums.h deleted file mode 100644 index 1edd6dd8f..000000000 --- a/toolsrc/include/vcpkg/base/enums.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include <vcpkg/base/cstringview.h> -#include <vcpkg/base/lineinfo.h> - -namespace vcpkg::Enums -{ - std::string nullvalue_to_string(const CStringView enum_name); - - [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name); -} diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h deleted file mode 100644 index f24366c4a..000000000 --- a/toolsrc/include/vcpkg/base/expected.h +++ /dev/null @@ -1,245 +0,0 @@ -#pragma once - -#include <vcpkg/base/checks.h> -#include <vcpkg/base/lineinfo.h> -#include <vcpkg/base/stringliteral.h> -#include <vcpkg/base/system.print.h> - -#include <system_error> -#include <type_traits> - -namespace vcpkg -{ - template<class Err> - struct ErrorHolder - { - ErrorHolder() : m_is_error(false), m_err{} { } - template<class U> - ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err)) - { - } - - constexpr bool has_error() const { return m_is_error; } - - const Err& error() const { return m_err; } - Err& error() { return m_err; } - - StringLiteral to_string() const { return "value was error"; } - - private: - bool m_is_error; - Err m_err; - }; - - template<> - struct ErrorHolder<std::string> - { - ErrorHolder() : m_is_error(false) { } - template<class U> - ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err)) - { - } - - bool has_error() const { return m_is_error; } - - const std::string& error() const { return m_err; } - std::string& error() { return m_err; } - - const std::string& to_string() const { return m_err; } - - private: - bool m_is_error; - std::string m_err; - }; - - template<> - struct ErrorHolder<std::error_code> - { - ErrorHolder() = default; - ErrorHolder(const std::error_code& err) : m_err(err) { } - - bool has_error() const { return bool(m_err); } - - const std::error_code& error() const { return m_err; } - std::error_code& error() { return m_err; } - - std::string to_string() const { return m_err.message(); } - - private: - std::error_code m_err; - }; - - struct ExpectedLeftTag - { - }; - struct ExpectedRightTag - { - }; - constexpr ExpectedLeftTag expected_left_tag; - constexpr ExpectedRightTag expected_right_tag; - - template<class T> - struct ExpectedHolder - { - ExpectedHolder() = default; - ExpectedHolder(const T& t) : t(t) { } - ExpectedHolder(T&& t) : t(std::move(t)) { } - using pointer = T*; - using const_pointer = const T*; - T* get() { return &t; } - const T* get() const { return &t; } - T t; - }; - template<class T> - struct ExpectedHolder<T&> - { - ExpectedHolder(T& t) : t(&t) { } - ExpectedHolder() : t(nullptr) { } - using pointer = T*; - using const_pointer = T*; - T* get() { return t; } - T* get() const { return t; } - T* t; - }; - - template<class T, class S> - class ExpectedT - { - public: - constexpr ExpectedT() = default; - - // Constructors are intentionally implicit - - ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) { } - template<class = std::enable_if<!std::is_reference<S>::value>> - ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) - { - } - - ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) { } - template<class = std::enable_if<!std::is_reference<T>::value>> - ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t)) - { - } - - ExpectedT(const ExpectedT&) = default; - ExpectedT(ExpectedT&&) = default; - ExpectedT& operator=(const ExpectedT&) = default; - ExpectedT& operator=(ExpectedT&&) = default; - - explicit constexpr operator bool() const noexcept { return !m_s.has_error(); } - constexpr bool has_value() const noexcept { return !m_s.has_error(); } - - T&& value_or_exit(const LineInfo& line_info) && - { - exit_if_error(line_info); - return std::move(*this->m_t.get()); - } - - const T& value_or_exit(const LineInfo& line_info) const& - { - exit_if_error(line_info); - return *this->m_t.get(); - } - - const S& error() const& { return this->m_s.error(); } - - S&& error() && { return std::move(this->m_s.error()); } - - typename ExpectedHolder<T>::const_pointer get() const - { - if (!this->has_value()) - { - return nullptr; - } - return this->m_t.get(); - } - - typename ExpectedHolder<T>::pointer get() - { - if (!this->has_value()) - { - return nullptr; - } - return this->m_t.get(); - } - - template<class F> - using map_t = decltype(std::declval<F&>()(*std::declval<typename ExpectedHolder<T>::const_pointer>())); - - template<class F, class U = map_t<F>> - ExpectedT<U, S> map(F f) const& - { - if (has_value()) - { - return {f(*m_t.get()), expected_left_tag}; - } - else - { - return {error(), expected_right_tag}; - } - } - - template<class F> - using move_map_t = - decltype(std::declval<F&>()(std::move(*std::declval<typename ExpectedHolder<T>::pointer>()))); - - template<class F, class U = move_map_t<F>> - ExpectedT<U, S> map(F f) && - { - if (has_value()) - { - return {f(std::move(*m_t.get())), expected_left_tag}; - } - else - { - return {std::move(*this).error(), expected_right_tag}; - } - } - - template<class F, class U = map_t<F>> - U then(F f) const& - { - if (has_value()) - { - return f(*m_t.get()); - } - else - { - return U{error(), expected_right_tag}; - } - } - - template<class F, class U = move_map_t<F>> - U then(F f) && - { - if (has_value()) - { - return f(std::move(*m_t.get())); - } - else - { - return U{std::move(*this).error(), expected_right_tag}; - } - } - - private: - void exit_if_error(const LineInfo& line_info) const - { - if (m_s.has_error()) - { - System::print2(System::Color::error, m_s.to_string(), "\n"); - Checks::exit_fail(line_info); - } - } - - ErrorHolder<S> m_s; - ExpectedHolder<T> m_t; - }; - - template<class T> - using Expected = ExpectedT<T, std::error_code>; - - template<class T> - using ExpectedS = ExpectedT<T, std::string>; -} diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h deleted file mode 100644 index 5f2e96e91..000000000 --- a/toolsrc/include/vcpkg/base/files.h +++ /dev/null @@ -1,315 +0,0 @@ -#pragma once - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/ignore_errors.h> -#include <vcpkg/base/pragmas.h> - -#include <string.h> - -#if !defined(VCPKG_USE_STD_FILESYSTEM) -#error The build system must set VCPKG_USE_STD_FILESYSTEM. -#endif // !defined(VCPKG_USE_STD_FILESYSTEM) - -#if VCPKG_USE_STD_FILESYSTEM -#include <filesystem> -#else -#include <experimental/filesystem> -#endif - -namespace fs -{ -#if defined(_WIN32) - struct IsSlash - { - bool operator()(const wchar_t c) const noexcept { return c == L'/' || c == L'\\'; } - }; -#else - struct IsSlash - { - bool operator()(const char c) const noexcept { return c == '/'; } - }; -#endif - - constexpr IsSlash is_slash; - -#if VCPKG_USE_STD_FILESYSTEM - namespace stdfs = std::filesystem; -#else - namespace stdfs = std::experimental::filesystem; -#endif - - using stdfs::copy_options; - using stdfs::directory_iterator; - using stdfs::path; - using stdfs::perms; - - path u8path(vcpkg::StringView s); - inline path u8path(const char* first, const char* last) { return u8path(vcpkg::StringView{first, last}); } - inline path u8path(std::initializer_list<char> il) { return u8path(vcpkg::StringView{il.begin(), il.end()}); } - inline path u8path(const char* s) { return u8path(vcpkg::StringView{s, s + ::strlen(s)}); } - - inline path u8path(std::string::const_iterator first, std::string::const_iterator last) - { - auto firstp = &*first; - return u8path(vcpkg::StringView{firstp, firstp + (last - first)}); - } - - std::string u8string(const path& p); - std::string generic_u8string(const path& p); - - // equivalent to p.lexically_normal() - path lexically_normal(const path& p); - -#if defined(_WIN32) - enum class file_type - { - none = 0, - not_found = -1, - regular = 1, - directory = 2, - symlink = 3, - block = 4, - character = 5, - fifo = 6, - socket = 7, - unknown = 8, - // also stands for a junction - directory_symlink = 42 - }; - - struct file_status - { - explicit file_status(file_type type = file_type::none, perms permissions = perms::unknown) noexcept - : m_type(type), m_permissions(permissions) - { - } - - file_type type() const noexcept { return m_type; } - void type(file_type type) noexcept { m_type = type; } - - perms permissions() const noexcept { return m_permissions; } - void permissions(perms perm) noexcept { m_permissions = perm; } - - private: - file_type m_type; - perms m_permissions; - }; - - struct SystemHandle - { - using type = intptr_t; // HANDLE - type system_handle = -1; - - bool is_valid() const { return system_handle != -1; } - }; - -#else - - using stdfs::file_type; - // to set up ADL correctly on `file_status` objects, we are defining - // this in our own namespace - struct file_status : private stdfs::file_status - { - using stdfs::file_status::file_status; - using stdfs::file_status::permissions; - using stdfs::file_status::type; - }; - - struct SystemHandle - { - using type = int; // file descriptor - type system_handle = -1; - - bool is_valid() const { return system_handle != -1; } - }; - -#endif - - inline bool operator==(SystemHandle lhs, SystemHandle rhs) noexcept - { - return lhs.system_handle == rhs.system_handle; - } - inline bool operator!=(SystemHandle lhs, SystemHandle rhs) noexcept { return !(lhs == rhs); } - - inline bool is_symlink(file_status s) noexcept - { -#if defined(_WIN32) - if (s.type() == file_type::directory_symlink) return true; -#endif - return s.type() == file_type::symlink; - } - inline bool is_regular_file(file_status s) { return s.type() == file_type::regular; } - inline bool is_directory(file_status s) { return s.type() == file_type::directory; } - inline bool exists(file_status s) { return s.type() != file_type::not_found && s.type() != file_type::none; } -} - -/* - if someone attempts to use unqualified `symlink_status` or `is_symlink`, - they might get the ADL version, which is broken. - Therefore, put `(symlink_)?status` as deleted in the global namespace, so - that they get an error. - - We also want to poison the ADL on the other functions, because - we don't want people calling these functions on paths -*/ -void status(const fs::path& p) = delete; -void status(const fs::path& p, std::error_code& ec) = delete; -void symlink_status(const fs::path& p) = delete; -void symlink_status(const fs::path& p, std::error_code& ec) = delete; -void is_symlink(const fs::path& p) = delete; -void is_symlink(const fs::path& p, std::error_code& ec) = delete; -void is_regular_file(const fs::path& p) = delete; -void is_regular_file(const fs::path& p, std::error_code& ec) = delete; -void is_directory(const fs::path& p) = delete; -void is_directory(const fs::path& p, std::error_code& ec) = delete; - -namespace vcpkg::Files -{ - struct Filesystem - { - std::string read_contents(const fs::path& file_path, LineInfo linfo) const; - virtual Expected<std::string> read_contents(const fs::path& file_path) const = 0; - /// <summary>Read text lines from a file</summary> - /// <remarks>Lines will have up to one trailing carriage-return character stripped (CRLF)</remarks> - virtual Expected<std::vector<std::string>> read_lines(const fs::path& file_path) const = 0; - virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const fs::path& filename) const = 0; - virtual std::vector<fs::path> get_files_recursive(const fs::path& dir) const = 0; - virtual std::vector<fs::path> get_files_non_recursive(const fs::path& dir) const = 0; - void write_lines(const fs::path& file_path, const std::vector<std::string>& lines, LineInfo linfo); - virtual void write_lines(const fs::path& file_path, - const std::vector<std::string>& lines, - std::error_code& ec) = 0; - void write_contents(const fs::path& path, const std::string& data, LineInfo linfo); - virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) = 0; - void write_contents_and_dirs(const fs::path& path, const std::string& data, LineInfo linfo); - virtual void write_contents_and_dirs(const fs::path& file_path, - const std::string& data, - std::error_code& ec) = 0; - void rename(const fs::path& oldpath, const fs::path& newpath, LineInfo linfo); - virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) = 0; - virtual void rename_or_copy(const fs::path& oldpath, - const fs::path& newpath, - StringLiteral temp_suffix, - std::error_code& ec) = 0; - bool remove(const fs::path& path, LineInfo linfo); - bool remove(const fs::path& path, ignore_errors_t); - virtual bool remove(const fs::path& path, std::error_code& ec) = 0; - - virtual void remove_all(const fs::path& path, std::error_code& ec, fs::path& failure_point) = 0; - void remove_all(const fs::path& path, LineInfo li); - void remove_all(const fs::path& path, ignore_errors_t); - virtual void remove_all_inside(const fs::path& path, std::error_code& ec, fs::path& failure_point) = 0; - void remove_all_inside(const fs::path& path, LineInfo li); - void remove_all_inside(const fs::path& path, ignore_errors_t); - bool exists(const fs::path& path, std::error_code& ec) const; - bool exists(LineInfo li, const fs::path& path) const; - bool exists(const fs::path& path, ignore_errors_t = ignore_errors) const; - virtual bool is_directory(const fs::path& path) const = 0; - virtual bool is_regular_file(const fs::path& path) const = 0; - virtual bool is_empty(const fs::path& path) const = 0; - virtual bool create_directory(const fs::path& path, std::error_code& ec) = 0; - bool create_directory(const fs::path& path, ignore_errors_t); - bool create_directory(const fs::path& path, LineInfo li); - virtual bool create_directories(const fs::path& path, std::error_code& ec) = 0; - bool create_directories(const fs::path& path, ignore_errors_t); - bool create_directories(const fs::path& path, LineInfo); - virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) = 0; - virtual bool copy_file(const fs::path& oldpath, - const fs::path& newpath, - fs::copy_options opts, - std::error_code& ec) = 0; - void copy_file(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, LineInfo li); - virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) = 0; - virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; - virtual fs::file_status symlink_status(const fs::path& path, std::error_code& ec) const = 0; - fs::file_status status(LineInfo li, const fs::path& p) const noexcept; - fs::file_status status(const fs::path& p, ignore_errors_t) const noexcept; - fs::file_status symlink_status(LineInfo li, const fs::path& p) const noexcept; - fs::file_status symlink_status(const fs::path& p, ignore_errors_t) const noexcept; - virtual fs::path absolute(const fs::path& path, std::error_code& ec) const = 0; - fs::path absolute(LineInfo li, const fs::path& path) const; - virtual fs::path canonical(const fs::path& path, std::error_code& ec) const = 0; - fs::path canonical(LineInfo li, const fs::path& path) const; - fs::path canonical(const fs::path& path, ignore_errors_t) const; - virtual fs::path current_path(std::error_code&) const = 0; - fs::path current_path(LineInfo li) const; - virtual void current_path(const fs::path& path, std::error_code&) = 0; - void current_path(const fs::path& path, LineInfo li); - - // if the path does not exist, then (try_|)take_exclusive_file_lock attempts to create the file - // (but not any path members above the file itself) - // in other words, if `/a/b` is a directory, and you're attempting to lock `/a/b/c`, - // then these lock functions create `/a/b/c` if it doesn't exist; - // however, if `/a/b` doesn't exist, then the functions will fail. - - // waits forever for the file lock - virtual fs::SystemHandle take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0; - // waits, at most, 1.5 seconds, for the file lock - virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0; - virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code&) = 0; - - virtual std::vector<fs::path> find_from_PATH(const std::string& name) const = 0; - }; - - Filesystem& get_real_filesystem(); - - static constexpr const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; - - bool has_invalid_chars_for_filesystem(const std::string& s); - - void print_paths(const std::vector<fs::path>& paths); - - // Performs "lhs / rhs" according to the C++17 Filesystem Library Specification. - // This function exists as a workaround for TS implementations. - fs::path combine(const fs::path& lhs, const fs::path& rhs); - -#if defined(_WIN32) - constexpr char preferred_separator = '\\'; -#else - constexpr char preferred_separator = '/'; -#endif // _WIN32 - -#if defined(_WIN32) - fs::path win32_fix_path_case(const fs::path& source); -#endif // _WIN32 - - struct ExclusiveFileLock - { - enum class Wait - { - Yes, - No, - }; - - ExclusiveFileLock() = default; - ExclusiveFileLock(ExclusiveFileLock&&) = delete; - ExclusiveFileLock& operator=(ExclusiveFileLock&&) = delete; - - ExclusiveFileLock(Wait wait, Filesystem& fs, const fs::path& path_, std::error_code& ec) : m_fs(&fs) - { - switch (wait) - { - case Wait::Yes: m_handle = m_fs->take_exclusive_file_lock(path_, ec); break; - case Wait::No: m_handle = m_fs->try_take_exclusive_file_lock(path_, ec); break; - } - } - ~ExclusiveFileLock() { clear(); } - - explicit operator bool() const { return m_handle.is_valid(); } - bool has_lock() const { return m_handle.is_valid(); } - - void clear() - { - if (m_fs && m_handle.is_valid()) - { - std::error_code ignore; - m_fs->unlock_file_lock(std::exchange(m_handle, fs::SystemHandle{}), ignore); - } - } - - private: - Filesystem* m_fs; - fs::SystemHandle m_handle; - }; - -} diff --git a/toolsrc/include/vcpkg/base/fwd/json.h b/toolsrc/include/vcpkg/base/fwd/json.h deleted file mode 100644 index bb31a5f60..000000000 --- a/toolsrc/include/vcpkg/base/fwd/json.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace vcpkg::Json -{ - struct JsonStyle; - enum class ValueKind : int; - struct Value; - struct Object; - struct Array; -} diff --git a/toolsrc/include/vcpkg/base/fwd/lockguarded.h b/toolsrc/include/vcpkg/base/fwd/lockguarded.h deleted file mode 100644 index e7e88b5a1..000000000 --- a/toolsrc/include/vcpkg/base/fwd/lockguarded.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace vcpkg::Util -{ - template<class T> - struct LockGuardPtr; - - template<class T> - struct LockGuarded; -} diff --git a/toolsrc/include/vcpkg/base/fwd/optional.h b/toolsrc/include/vcpkg/base/fwd/optional.h deleted file mode 100644 index 2c3a7ea6c..000000000 --- a/toolsrc/include/vcpkg/base/fwd/optional.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace vcpkg -{ - template<class T> - struct Optional; -} diff --git a/toolsrc/include/vcpkg/base/fwd/span.h b/toolsrc/include/vcpkg/base/fwd/span.h deleted file mode 100644 index 9cd45250e..000000000 --- a/toolsrc/include/vcpkg/base/fwd/span.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace vcpkg -{ - template<class T> - struct Span; - - template<class T> - using View = Span<const T>; -} diff --git a/toolsrc/include/vcpkg/base/fwd/stringview.h b/toolsrc/include/vcpkg/base/fwd/stringview.h deleted file mode 100644 index e297fd43b..000000000 --- a/toolsrc/include/vcpkg/base/fwd/stringview.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct StringView; -} diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h deleted file mode 100644 index fd51d666b..000000000 --- a/toolsrc/include/vcpkg/base/graphs.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include <vcpkg/base/checks.h> -#include <vcpkg/base/lineinfo.h> -#include <vcpkg/base/system.print.h> - -#include <string> -#include <unordered_map> -#include <vector> - -namespace vcpkg::Graphs -{ - enum class ExplorationStatus - { - // We have not visited this vertex - NOT_EXPLORED, - - // We have visited this vertex but haven't visited all vertices in its subtree - PARTIALLY_EXPLORED, - - // We have visited this vertex and all vertices in its subtree - FULLY_EXPLORED - }; - - template<class V, class U> - struct AdjacencyProvider - { - virtual std::vector<V> adjacency_list(const U& vertex) const = 0; - virtual std::string to_string(const V& vertex) const = 0; - virtual U load_vertex_data(const V& vertex) const = 0; - }; - - struct Randomizer - { - virtual int random(int max_exclusive) = 0; - - protected: - ~Randomizer() { } - }; - - namespace details - { - template<class Container> - void shuffle(Container& c, Randomizer* r) - { - if (!r) return; - for (auto i = c.size(); i > 1; --i) - { - std::size_t j = r->random(static_cast<int>(i)); - if (j != i - 1) - { - std::swap(c[i - 1], c[j]); - } - } - } - - template<class V, class U> - void topological_sort_internal(const V& vertex, - const AdjacencyProvider<V, U>& f, - std::unordered_map<V, ExplorationStatus>& exploration_status, - std::vector<U>& sorted, - Randomizer* randomizer) - { - ExplorationStatus& status = exploration_status[vertex]; - switch (status) - { - case ExplorationStatus::FULLY_EXPLORED: return; - case ExplorationStatus::PARTIALLY_EXPLORED: - { - System::print2("Cycle detected within graph at ", f.to_string(vertex), ":\n"); - for (auto&& node : exploration_status) - { - if (node.second == ExplorationStatus::PARTIALLY_EXPLORED) - { - System::print2(" ", f.to_string(node.first), '\n'); - } - } - Checks::exit_fail(VCPKG_LINE_INFO); - } - case ExplorationStatus::NOT_EXPLORED: - { - status = ExplorationStatus::PARTIALLY_EXPLORED; - U vertex_data = f.load_vertex_data(vertex); - auto neighbours = f.adjacency_list(vertex_data); - details::shuffle(neighbours, randomizer); - for (const V& neighbour : neighbours) - topological_sort_internal(neighbour, f, exploration_status, sorted, randomizer); - - sorted.push_back(std::move(vertex_data)); - status = ExplorationStatus::FULLY_EXPLORED; - return; - } - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - template<class Range, class V, class U> - std::vector<U> topological_sort(Range starting_vertices, const AdjacencyProvider<V, U>& f, Randomizer* randomizer) - { - std::vector<U> sorted; - std::unordered_map<V, ExplorationStatus> exploration_status; - - details::shuffle(starting_vertices, randomizer); - - for (auto&& vertex : starting_vertices) - { - details::topological_sort_internal(vertex, f, exploration_status, sorted, randomizer); - } - - return sorted; - } -} diff --git a/toolsrc/include/vcpkg/base/hash.h b/toolsrc/include/vcpkg/base/hash.h deleted file mode 100644 index 0747e6737..000000000 --- a/toolsrc/include/vcpkg/base/hash.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> - -#include <string> - -namespace vcpkg::Hash -{ - enum class Algorithm - { - Sha1, - Sha256, - Sha512, - }; - - const char* to_string(Algorithm algo) noexcept; - Optional<Algorithm> algorithm_from_string(StringView sv) noexcept; - - struct Hasher - { - virtual void add_bytes(const void* start, const void* end) noexcept = 0; - - // one may only call this once before calling `clear()` or the dtor - virtual std::string get_hash() noexcept = 0; - virtual void clear() noexcept = 0; - virtual ~Hasher() = default; - }; - - std::unique_ptr<Hasher> get_hasher_for(Algorithm algo) noexcept; - - std::string get_bytes_hash(const void* first, const void* last, Algorithm algo) noexcept; - std::string get_string_hash(StringView s, Algorithm algo) noexcept; - std::string get_file_hash(const Files::Filesystem& fs, - const fs::path& path, - Algorithm algo, - std::error_code& ec) noexcept; - inline std::string get_file_hash(LineInfo li, - const Files::Filesystem& fs, - const fs::path& path, - Algorithm algo) noexcept - { - std::error_code ec; - const auto result = get_file_hash(fs, path, algo, ec); - if (ec) - { - Checks::exit_with_message( - li, "Failure to read file '%s' for hashing: %s", fs::u8string(path), ec.message()); - } - - return result; - } -} diff --git a/toolsrc/include/vcpkg/base/ignore_errors.h b/toolsrc/include/vcpkg/base/ignore_errors.h deleted file mode 100644 index ed8b38c56..000000000 --- a/toolsrc/include/vcpkg/base/ignore_errors.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct ignore_errors_t - { - }; - - constexpr ignore_errors_t ignore_errors; -} diff --git a/toolsrc/include/vcpkg/base/json.h b/toolsrc/include/vcpkg/base/json.h deleted file mode 100644 index 5321308a3..000000000 --- a/toolsrc/include/vcpkg/base/json.h +++ /dev/null @@ -1,302 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/json.h> - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/files.h> -#include <vcpkg/base/parse.h> -#include <vcpkg/base/stringview.h> - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -namespace vcpkg::Json -{ - struct JsonStyle - { - enum class Newline - { - Lf, - CrLf - } newline_kind = Newline::Lf; - - constexpr JsonStyle() noexcept = default; - - static JsonStyle with_tabs() noexcept { return JsonStyle{-1}; } - static JsonStyle with_spaces(int indent) noexcept - { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, indent >= 0); - return JsonStyle{indent}; - } - - void set_tabs() noexcept { this->indent = -1; } - void set_spaces(int indent_) noexcept - { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, indent >= 0); - this->indent = indent_; - } - - bool use_tabs() const noexcept { return indent == -1; } - bool use_spaces() const noexcept { return indent >= 0; } - - int spaces() const noexcept - { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, indent >= 0); - return indent; - } - - const char* newline() const noexcept - { - switch (this->newline_kind) - { - case Newline::Lf: return "\n"; - case Newline::CrLf: return "\r\n"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - private: - constexpr explicit JsonStyle(int indent) : indent(indent) { } - // -1 for tab, >=0 gives # of spaces - int indent = 2; - }; - - enum class ValueKind : int - { - Null, - Boolean, - Integer, - Number, - String, - Array, - Object - }; - - namespace impl - { - struct ValueImpl; - } - - struct Value - { - Value() noexcept; // equivalent to Value::null() - Value(Value&&) noexcept; - Value(const Value&); - Value& operator=(Value&&) noexcept; - Value& operator=(const Value&); - ~Value(); - - ValueKind kind() const noexcept; - - bool is_null() const noexcept; - bool is_boolean() const noexcept; - bool is_integer() const noexcept; - // either integer _or_ number - bool is_number() const noexcept; - bool is_string() const noexcept; - bool is_array() const noexcept; - bool is_object() const noexcept; - - // a.x() asserts when !a.is_x() - bool boolean() const noexcept; - int64_t integer() const noexcept; - double number() const noexcept; - StringView string() const noexcept; - - const Array& array() const& noexcept; - Array& array() & noexcept; - Array&& array() && noexcept; - - const Object& object() const& noexcept; - Object& object() & noexcept; - Object&& object() && noexcept; - - static Value null(std::nullptr_t) noexcept; - static Value boolean(bool) noexcept; - static Value integer(int64_t i) noexcept; - static Value number(double d) noexcept; - static Value string(std::string s) noexcept; - static Value array(Array&&) noexcept; - static Value array(const Array&) noexcept; - static Value object(Object&&) noexcept; - static Value object(const Object&) noexcept; - - friend bool operator==(const Value& lhs, const Value& rhs); - friend bool operator!=(const Value& lhs, const Value& rhs) { return !(lhs == rhs); } - - private: - friend struct impl::ValueImpl; - std::unique_ptr<impl::ValueImpl> underlying_; - }; - - struct Array - { - private: - using underlying_t = std::vector<Value>; - - public: - Array() = default; - Array(Array const&) = default; - Array(Array&&) = default; - Array& operator=(Array const&) = default; - Array& operator=(Array&&) = default; - ~Array() = default; - - using iterator = underlying_t::iterator; - using const_iterator = underlying_t::const_iterator; - - Value& push_back(Value&& value); - Object& push_back(Object&& value); - Array& push_back(Array&& value); - Value& insert_before(iterator it, Value&& value); - Object& insert_before(iterator it, Object&& value); - Array& insert_before(iterator it, Array&& value); - - std::size_t size() const noexcept { return this->underlying_.size(); } - - // asserts idx < size - Value& operator[](std::size_t idx) noexcept - { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, idx < this->size()); - return this->underlying_[idx]; - } - const Value& operator[](std::size_t idx) const noexcept - { - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, idx < this->size()); - return this->underlying_[idx]; - } - - iterator begin() { return underlying_.begin(); } - iterator end() { return underlying_.end(); } - const_iterator begin() const { return cbegin(); } - const_iterator end() const { return cend(); } - const_iterator cbegin() const { return underlying_.cbegin(); } - const_iterator cend() const { return underlying_.cend(); } - - friend bool operator==(const Array& lhs, const Array& rhs); - friend bool operator!=(const Array& lhs, const Array& rhs) { return !(lhs == rhs); } - - private: - underlying_t underlying_; - }; - - struct Object - { - private: - using value_type = std::pair<std::string, Value>; - using underlying_t = std::vector<value_type>; - - underlying_t::const_iterator internal_find_key(StringView key) const noexcept; - - public: - // these are here for better diagnostics - Object() = default; - Object(Object const&) = default; - Object(Object&&) = default; - Object& operator=(Object const&) = default; - Object& operator=(Object&&) = default; - ~Object() = default; - - // asserts if the key is found - Value& insert(std::string key, Value&& value); - Value& insert(std::string key, const Value& value); - Object& insert(std::string key, Object&& value); - Object& insert(std::string key, const Object& value); - Array& insert(std::string key, Array&& value); - Array& insert(std::string key, const Array& value); - - // replaces the value if the key is found, otherwise inserts a new - // value. - Value& insert_or_replace(std::string key, Value&& value); - Value& insert_or_replace(std::string key, const Value& value); - Object& insert_or_replace(std::string key, Object&& value); - Object& insert_or_replace(std::string key, const Object& value); - Array& insert_or_replace(std::string key, Array&& value); - Array& insert_or_replace(std::string key, const Array& value); - - // returns whether the key existed - bool remove(StringView key) noexcept; - - // asserts on lookup failure - Value& operator[](StringView key) noexcept - { - auto res = this->get(key); - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res, "missing key: \"%s\"", key); - return *res; - } - const Value& operator[](StringView key) const noexcept - { - auto res = this->get(key); - vcpkg::Checks::check_exit(VCPKG_LINE_INFO, res, "missing key: \"%s\"", key); - return *res; - } - - Value* get(StringView key) noexcept; - const Value* get(StringView key) const noexcept; - - bool contains(StringView key) const noexcept { return this->get(key); } - - bool is_empty() const noexcept { return size() == 0; } - std::size_t size() const noexcept { return this->underlying_.size(); } - - // sorts keys alphabetically - void sort_keys(); - - struct const_iterator - { - using value_type = std::pair<StringView, const Value&>; - using reference = value_type; - using iterator_category = std::forward_iterator_tag; - - value_type operator*() const noexcept { return *underlying_; } - const_iterator& operator++() noexcept - { - ++underlying_; - return *this; - } - const_iterator operator++(int) noexcept - { - auto res = *this; - ++underlying_; - return res; - } - - bool operator==(const_iterator other) const noexcept { return this->underlying_ == other.underlying_; } - bool operator!=(const_iterator other) const noexcept { return !(this->underlying_ == other.underlying_); } - - private: - friend struct Object; - explicit const_iterator(const underlying_t::const_iterator& it) : underlying_(it) { } - underlying_t::const_iterator underlying_; - }; - using iterator = const_iterator; - - const_iterator begin() const noexcept { return this->cbegin(); } - const_iterator end() const noexcept { return this->cend(); } - const_iterator cbegin() const noexcept { return const_iterator{this->underlying_.begin()}; } - const_iterator cend() const noexcept { return const_iterator{this->underlying_.end()}; } - - friend bool operator==(const Object& lhs, const Object& rhs); - friend bool operator!=(const Object& lhs, const Object& rhs) { return !(lhs == rhs); } - - private: - underlying_t underlying_; - }; - - ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse_file( - const Files::Filesystem&, const fs::path&, std::error_code& ec) noexcept; - ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse( - StringView text, const fs::path& filepath) noexcept; - ExpectedT<std::pair<Value, JsonStyle>, std::unique_ptr<Parse::IParseError>> parse(StringView text, - StringView origin = {}) noexcept; - std::pair<Value, JsonStyle> parse_file(vcpkg::LineInfo linfo, const Files::Filesystem&, const fs::path&) noexcept; - - std::string stringify(const Value&, JsonStyle style); - std::string stringify(const Object&, JsonStyle style); - std::string stringify(const Array&, JsonStyle style); -} diff --git a/toolsrc/include/vcpkg/base/jsonreader.h b/toolsrc/include/vcpkg/base/jsonreader.h deleted file mode 100644 index 4aca02998..000000000 --- a/toolsrc/include/vcpkg/base/jsonreader.h +++ /dev/null @@ -1,367 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/json.h> - -#include <vcpkg/base/json.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/strings.h> -#include <vcpkg/base/stringview.h> -#include <vcpkg/base/view.h> - -namespace vcpkg::Json -{ - struct Reader; - - template<class Type> - struct IDeserializer - { - using type = Type; - virtual StringView type_name() const = 0; - - private: - friend struct Reader; - Optional<Type> visit(Reader&, const Value&); - Optional<Type> visit(Reader&, const Object&); - - public: - virtual Optional<Type> visit_null(Reader&); - virtual Optional<Type> visit_boolean(Reader&, bool); - virtual Optional<Type> visit_integer(Reader& r, int64_t i); - virtual Optional<Type> visit_number(Reader&, double); - virtual Optional<Type> visit_string(Reader&, StringView); - virtual Optional<Type> visit_array(Reader&, const Array&); - virtual Optional<Type> visit_object(Reader&, const Object&); - virtual View<StringView> valid_fields() const; - - virtual ~IDeserializer() = default; - - protected: - IDeserializer() = default; - IDeserializer(const IDeserializer&) = default; - IDeserializer& operator=(const IDeserializer&) = default; - IDeserializer(IDeserializer&&) = default; - IDeserializer& operator=(IDeserializer&&) = default; - }; - - struct Reader - { - const std::vector<std::string>& errors() const { return m_errors; } - std::vector<std::string>& errors() { return m_errors; } - - void add_missing_field_error(StringView type, StringView key, StringView key_type); - void add_expected_type_error(StringView expected_type); - void add_extra_field_error(StringView type, StringView fields, StringView suggestion = {}); - template<class... Args> - void add_generic_error(StringView type, Args&&... args) - { - m_errors.push_back(Strings::concat(path(), " (", type, "): ", args...)); - } - - std::string path() const noexcept; - - private: - template<class Type> - friend struct IDeserializer; - - std::vector<std::string> m_errors; - struct Path - { - constexpr Path() = default; - constexpr Path(int64_t i) : index(i) { } - constexpr Path(StringView f) : field(f) { } - - int64_t index = -1; - StringView field; - }; - std::vector<Path> m_path; - - public: - // checks that an object doesn't contain any fields which both: - // * don't start with a `$` - // * are not in `valid_fields` - // if known_fields.empty(), then it's treated as if all field names are valid - void check_for_unexpected_fields(const Object& obj, View<StringView> valid_fields, StringView type_name); - - template<class Type> - void required_object_field( - StringView type, const Object& obj, StringView key, Type& place, IDeserializer<Type>& visitor) - { - if (auto value = obj.get(key)) - { - visit_in_key(*value, key, place, visitor); - } - else - { - this->add_missing_field_error(type, key, visitor.type_name()); - } - } - - // value should be the value at key of the currently visited object - template<class Type> - void visit_in_key(const Value& value, StringView key, Type& place, IDeserializer<Type>& visitor) - { - m_path.push_back(key); - auto opt = visitor.visit(*this, value); - - if (auto p_opt = opt.get()) - { - place = std::move(*p_opt); - } - else - { - add_expected_type_error(visitor.type_name()); - } - m_path.pop_back(); - } - - // value should be the value at key of the currently visited object - template<class Type> - void visit_at_index(const Value& value, int64_t index, Type& place, IDeserializer<Type>& visitor) - { - m_path.push_back(index); - auto opt = visitor.visit(*this, value); - - if (auto p_opt = opt.get()) - { - place = std::move(*p_opt); - } - else - { - add_expected_type_error(visitor.type_name()); - } - m_path.pop_back(); - } - - // returns whether key \in obj - template<class Type> - bool optional_object_field(const Object& obj, StringView key, Type& place, IDeserializer<Type>& visitor) - { - if (auto value = obj.get(key)) - { - visit_in_key(*value, key, place, visitor); - return true; - } - else - { - return false; - } - } - - template<class Type> - Optional<Type> visit(const Value& value, IDeserializer<Type>& visitor) - { - return visitor.visit(*this, value); - } - template<class Type> - Optional<Type> visit(const Object& value, IDeserializer<Type>& visitor) - { - return visitor.visit(*this, value); - } - - template<class Type> - Optional<std::vector<Type>> array_elements(const Array& arr, IDeserializer<Type>& visitor) - { - std::vector<Type> result; - m_path.emplace_back(); - for (size_t i = 0; i < arr.size(); ++i) - { - m_path.back().index = static_cast<int64_t>(i); - auto opt = visitor.visit(*this, arr[i]); - if (auto p = opt.get()) - { - result.push_back(std::move(*p)); - } - else - { - this->add_expected_type_error(visitor.type_name()); - for (++i; i < arr.size(); ++i) - { - m_path.back().index = static_cast<int64_t>(i); - auto opt2 = visitor.visit(*this, arr[i]); - if (!opt2) this->add_expected_type_error(visitor.type_name()); - } - } - } - m_path.pop_back(); - return std::move(result); - } - }; - - VCPKG_MSVC_WARNING(push) - VCPKG_MSVC_WARNING(disable : 4505) - - template<class Type> - Optional<Type> IDeserializer<Type>::visit(Reader& r, const Value& value) - { - switch (value.kind()) - { - case ValueKind::Null: return visit_null(r); - case ValueKind::Boolean: return visit_boolean(r, value.boolean()); - case ValueKind::Integer: return visit_integer(r, value.integer()); - case ValueKind::Number: return visit_number(r, value.number()); - case ValueKind::String: return visit_string(r, value.string()); - case ValueKind::Array: return visit_array(r, value.array()); - case ValueKind::Object: return visit(r, value.object()); // Call `visit` to get unexpected fields checking - default: vcpkg::Checks::unreachable(VCPKG_LINE_INFO); - } - } - - template<class Type> - Optional<Type> IDeserializer<Type>::visit(Reader& r, const Object& obj) - { - r.check_for_unexpected_fields(obj, valid_fields(), type_name()); - return visit_object(r, obj); - } - - template<class Type> - View<StringView> IDeserializer<Type>::valid_fields() const - { - return {}; - } - - template<class Type> - Optional<Type> IDeserializer<Type>::visit_null(Reader&) - { - return nullopt; - } - template<class Type> - Optional<Type> IDeserializer<Type>::visit_boolean(Reader&, bool) - { - return nullopt; - } - template<class Type> - Optional<Type> IDeserializer<Type>::visit_integer(Reader& r, int64_t i) - { - return this->visit_number(r, static_cast<double>(i)); - } - template<class Type> - Optional<Type> IDeserializer<Type>::visit_number(Reader&, double) - { - return nullopt; - } - template<class Type> - Optional<Type> IDeserializer<Type>::visit_string(Reader&, StringView) - { - return nullopt; - } - template<class Type> - Optional<Type> IDeserializer<Type>::visit_array(Reader&, const Array&) - { - return nullopt; - } - template<class Type> - Optional<Type> IDeserializer<Type>::visit_object(Reader&, const Object&) - { - return nullopt; - } - - VCPKG_MSVC_WARNING(pop) - - struct StringDeserializer final : IDeserializer<std::string> - { - virtual StringView type_name() const override { return type_name_; } - virtual Optional<std::string> visit_string(Reader&, StringView sv) override { return sv.to_string(); } - - explicit StringDeserializer(StringLiteral type_name_) : type_name_(type_name_) { } - - private: - StringLiteral type_name_; - }; - - struct PathDeserializer final : IDeserializer<fs::path> - { - virtual StringView type_name() const override { return "a path"; } - virtual Optional<fs::path> visit_string(Reader&, StringView sv) override { return fs::u8path(sv); } - - static PathDeserializer instance; - }; - - struct NaturalNumberDeserializer final : IDeserializer<int> - { - virtual StringView type_name() const override { return "a nonnegative integer"; } - - virtual Optional<int> visit_integer(Reader&, int64_t value) override - { - if (value > std::numeric_limits<int>::max() || value < 0) - { - return nullopt; - } - return static_cast<int>(value); - } - - static NaturalNumberDeserializer instance; - }; - - struct BooleanDeserializer final : IDeserializer<bool> - { - virtual StringView type_name() const override { return "a boolean"; } - - virtual Optional<bool> visit_boolean(Reader&, bool b) override { return b; } - - static BooleanDeserializer instance; - }; - - template<class Underlying> - struct ArrayDeserializer final : IDeserializer<std::vector<typename Underlying::type>> - { - using type = std::vector<typename Underlying::type>; - - virtual StringView type_name() const override { return m_type_name; } - - ArrayDeserializer(StringLiteral type_name_, Underlying&& t = {}) - : m_type_name(type_name_), m_underlying_visitor(static_cast<Underlying&&>(t)) - { - } - - virtual Optional<type> visit_array(Reader& r, const Array& arr) override - { - return r.array_elements(arr, m_underlying_visitor); - } - - private: - StringLiteral m_type_name; - Underlying m_underlying_visitor; - }; - - struct ParagraphDeserializer final : IDeserializer<std::vector<std::string>> - { - virtual StringView type_name() const override { return "a string or array of strings"; } - - virtual Optional<std::vector<std::string>> visit_string(Reader&, StringView sv) override; - virtual Optional<std::vector<std::string>> visit_array(Reader& r, const Array& arr) override; - - static ParagraphDeserializer instance; - }; - - struct IdentifierDeserializer final : Json::IDeserializer<std::string> - { - virtual StringView type_name() const override { return "an identifier"; } - - // [a-z0-9]+(-[a-z0-9]+)*, plus not any of {prn, aux, nul, con, lpt[1-9], com[1-9], core, default} - static bool is_ident(StringView sv); - - virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) override; - - static IdentifierDeserializer instance; - }; - - struct IdentifierArrayDeserializer final : Json::IDeserializer<std::vector<std::string>> - { - virtual StringView type_name() const override { return "an array of identifiers"; } - - virtual Optional<std::vector<std::string>> visit_array(Reader& r, const Array& arr) override; - - static IdentifierArrayDeserializer instance; - }; - - struct PackageNameDeserializer final : Json::IDeserializer<std::string> - { - virtual StringView type_name() const override { return "a package name"; } - - static bool is_package_name(StringView sv); - - virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) override; - - static PackageNameDeserializer instance; - }; -} diff --git a/toolsrc/include/vcpkg/base/lazy.h b/toolsrc/include/vcpkg/base/lazy.h deleted file mode 100644 index d0afdaeb2..000000000 --- a/toolsrc/include/vcpkg/base/lazy.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace vcpkg -{ - template<typename T> - class Lazy - { - public: - Lazy() : value(T()), initialized(false) { } - - template<class F> - T const& get_lazy(const F& f) const - { - if (!initialized) - { - value = f(); - initialized = true; - } - return value; - } - - private: - mutable T value; - mutable bool initialized; - }; -} diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h deleted file mode 100644 index 68fca2e0e..000000000 --- a/toolsrc/include/vcpkg/base/lineinfo.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct LineInfo - { - int line_number; - const char* file_name; - }; -} - -#define VCPKG_LINE_INFO \ - vcpkg::LineInfo { __LINE__, __FILE__ } diff --git a/toolsrc/include/vcpkg/base/lockguarded.h b/toolsrc/include/vcpkg/base/lockguarded.h deleted file mode 100644 index e49b0b5d9..000000000 --- a/toolsrc/include/vcpkg/base/lockguarded.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/lockguarded.h> - -#include <mutex> - -namespace vcpkg::Util -{ - template<class T> - struct LockGuarded - { - friend struct LockGuardPtr<T>; - - LockGuardPtr<T> lock() { return *this; } - - private: - std::mutex m_mutex; - T m_t; - }; - - template<class T> - struct LockGuardPtr - { - T& operator*() { return m_ptr; } - T* operator->() { return &m_ptr; } - - T* get() { return &m_ptr; } - - LockGuardPtr(LockGuarded<T>& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) { } - - private: - std::unique_lock<std::mutex> m_lock; - T& m_ptr; - }; -} diff --git a/toolsrc/include/vcpkg/base/machinetype.h b/toolsrc/include/vcpkg/base/machinetype.h deleted file mode 100644 index b85cdbb0b..000000000 --- a/toolsrc/include/vcpkg/base/machinetype.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <cstdint> - -namespace vcpkg -{ - enum class MachineType : uint16_t - { - UNKNOWN = 0x0, // The contents of this field are assumed to be applicable to any machine type - AM33 = 0x1d3, // Matsushita AM33 - AMD64 = 0x8664, // x64 - ARM = 0x1c0, // ARM little endian - ARM64 = 0xaa64, // ARM64 little endian - ARMNT = 0x1c4, // ARM Thumb-2 little endian - EBC = 0xebc, // EFI byte code - I386 = 0x14c, // Intel 386 or later processors and compatible processors - IA64 = 0x200, // Intel Itanium processor family - M32R = 0x9041, // Mitsubishi M32R little endian - MIPS16 = 0x266, // MIPS16 - MIPSFPU = 0x366, // MIPS with FPU - MIPSFPU16 = 0x466, // MIPS16 with FPU - POWERPC = 0x1f0, // Power PC little endian - POWERPCFP = 0x1f1, // Power PC with floating point support - R4000 = 0x166, // MIPS little endian - RISCV32 = 0x5032, // RISC-V 32-bit address space - RISCV64 = 0x5064, // RISC-V 64-bit address space - RISCV128 = 0x5128, // RISC-V 128-bit address space - SH3 = 0x1a2, // Hitachi SH3 - SH3DSP = 0x1a3, // Hitachi SH3 DSP - SH4 = 0x1a6, // Hitachi SH4 - SH5 = 0x1a8, // Hitachi SH5 - THUMB = 0x1c2, // Thumb - WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2 - }; - - MachineType to_machine_type(const uint16_t value); -} diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h deleted file mode 100644 index d8c72ca6d..000000000 --- a/toolsrc/include/vcpkg/base/optional.h +++ /dev/null @@ -1,382 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/optional.h> - -#include <vcpkg/base/basic_checks.h> -#include <vcpkg/base/lineinfo.h> -#include <vcpkg/base/pragmas.h> - -#include <type_traits> -#include <utility> - -namespace vcpkg -{ - struct NullOpt - { - explicit constexpr NullOpt(int) { } - }; - - const static constexpr NullOpt nullopt{0}; - - template<class T> - struct Optional; - - namespace details - { - template<class T, bool B = std::is_copy_constructible<T>::value> - struct OptionalStorage - { - VCPKG_MSVC_WARNING(suppress : 26495) - constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() { } - constexpr OptionalStorage(const T& t) : m_is_present(true), m_t(t) { } - constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) { } - template<class U, class = std::enable_if_t<!std::is_reference<U>::value>> - explicit OptionalStorage(Optional<U>&& t) : m_is_present(false), m_inactive() - { - if (auto p = t.get()) - { - m_is_present = true; - new (&m_t) T(std::move(*p)); - } - } - template<class U> - explicit OptionalStorage(const Optional<U>& t) : m_is_present(false), m_inactive() - { - if (auto p = t.get()) - { - m_is_present = true; - new (&m_t) T(*p); - } - } - - ~OptionalStorage() noexcept - { - if (m_is_present) m_t.~T(); - } - - VCPKG_MSVC_WARNING(suppress : 26495) - OptionalStorage(const OptionalStorage& o) : m_is_present(o.m_is_present), m_inactive() - { - if (m_is_present) new (&m_t) T(o.m_t); - } - - VCPKG_MSVC_WARNING(suppress : 26495) - OptionalStorage(OptionalStorage&& o) noexcept : m_is_present(o.m_is_present), m_inactive() - { - if (m_is_present) - { - new (&m_t) T(std::move(o.m_t)); - } - } - - OptionalStorage& operator=(const OptionalStorage& o) - { - if (m_is_present && o.m_is_present) - { - m_t = o.m_t; - } - else if (!m_is_present && o.m_is_present) - { - m_is_present = true; - new (&m_t) T(o.m_t); - } - else if (m_is_present && !o.m_is_present) - { - clear(); - } - return *this; - } - - OptionalStorage& operator=(OptionalStorage&& o) noexcept - { - if (m_is_present && o.m_is_present) - { - m_t = std::move(o.m_t); - } - else if (!m_is_present && o.m_is_present) - { - m_is_present = true; - new (&m_t) T(std::move(o.m_t)); - } - else if (m_is_present && !o.m_is_present) - { - clear(); - } - return *this; - } - - constexpr bool has_value() const { return m_is_present; } - - const T& value() const { return this->m_t; } - T& value() { return this->m_t; } - - private: - void clear() - { - m_is_present = false; - m_t.~T(); - m_inactive = '\0'; - } - - bool m_is_present; - union - { - char m_inactive; - T m_t; - }; - }; - - template<class T> - struct OptionalStorage<T, false> - { - VCPKG_MSVC_WARNING(suppress : 26495) - constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() { } - constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) { } - - ~OptionalStorage() noexcept - { - if (m_is_present) m_t.~T(); - } - - VCPKG_MSVC_WARNING(suppress : 26495) - OptionalStorage(OptionalStorage&& o) noexcept : m_is_present(o.m_is_present), m_inactive() - { - if (m_is_present) - { - new (&m_t) T(std::move(o.m_t)); - } - } - - OptionalStorage& operator=(OptionalStorage&& o) noexcept - { - if (m_is_present && o.m_is_present) - { - m_t = std::move(o.m_t); - } - else if (!m_is_present && o.m_is_present) - { - m_is_present = true; - new (&m_t) T(std::move(o.m_t)); - } - else if (m_is_present && !o.m_is_present) - { - clear(); - } - return *this; - } - - constexpr bool has_value() const { return m_is_present; } - - const T& value() const { return this->m_t; } - T& value() { return this->m_t; } - - private: - void clear() - { - m_is_present = false; - m_t.~T(); - m_inactive = '\0'; - } - - bool m_is_present; - union - { - char m_inactive; - T m_t; - }; - }; - - template<class T, bool B> - struct OptionalStorage<T&, B> - { - constexpr OptionalStorage() noexcept : m_t(nullptr) { } - constexpr OptionalStorage(T& t) : m_t(&t) { } - constexpr OptionalStorage(Optional<T>& t) : m_t(t.get()) { } - - constexpr bool has_value() const { return m_t != nullptr; } - - T& value() const { return *this->m_t; } - - private: - T* m_t; - }; - - template<class T, bool B> - struct OptionalStorage<const T&, B> - { - constexpr OptionalStorage() noexcept : m_t(nullptr) { } - constexpr OptionalStorage(const T& t) : m_t(&t) { } - constexpr OptionalStorage(const Optional<T>& t) : m_t(t.get()) { } - constexpr OptionalStorage(const Optional<const T>& t) : m_t(t.get()) { } - constexpr OptionalStorage(Optional<T>&& t) = delete; - constexpr OptionalStorage(Optional<const T>&& t) = delete; - - constexpr bool has_value() const { return m_t != nullptr; } - - const T& value() const { return *this->m_t; } - - private: - const T* m_t; - }; - } - - template<class T> - struct Optional - { - constexpr Optional() noexcept { } - - // Constructors are intentionally implicit - constexpr Optional(NullOpt) { } - - template<class U, class = std::enable_if_t<!std::is_same<std::decay_t<U>, Optional>::value>> - constexpr Optional(U&& t) : m_base(std::forward<U>(t)) - { - } - - T&& value_or_exit(const LineInfo& line_info) && - { - Checks::check_exit(line_info, this->m_base.has_value(), "Value was null"); - return std::move(this->m_base.value()); - } - - T& value_or_exit(const LineInfo& line_info) & - { - Checks::check_exit(line_info, this->m_base.has_value(), "Value was null"); - return this->m_base.value(); - } - - const T& value_or_exit(const LineInfo& line_info) const& - { - Checks::check_exit(line_info, this->m_base.has_value(), "Value was null"); - return this->m_base.value(); - } - - constexpr explicit operator bool() const { return this->m_base.has_value(); } - - constexpr bool has_value() const { return this->m_base.has_value(); } - - template<class U> - T value_or(U&& default_value) const& - { - return this->m_base.has_value() ? this->m_base.value() : static_cast<T>(std::forward<U>(default_value)); - } - - T value_or(T&& default_value) const& - { - return this->m_base.has_value() ? this->m_base.value() : static_cast<T&&>(default_value); - } - - template<class U> - T value_or(U&& default_value) && - { - return this->m_base.has_value() ? std::move(this->m_base.value()) - : static_cast<T>(std::forward<U>(default_value)); - } - T value_or(T&& default_value) && - { - return this->m_base.has_value() ? std::move(this->m_base.value()) : static_cast<T&&>(default_value); - } - - typename std::add_pointer<const T>::type get() const - { - return this->m_base.has_value() ? &this->m_base.value() : nullptr; - } - - typename std::add_pointer<T>::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; } - - template<class F> - using map_t = decltype(std::declval<F&>()(std::declval<const T&>())); - - template<class F, class U = map_t<F>> - Optional<U> map(F f) const& - { - if (has_value()) - { - return f(this->m_base.value()); - } - return nullopt; - } - - template<class F, class U = map_t<F>> - U then(F f) const& - { - if (has_value()) - { - return f(this->m_base.value()); - } - return nullopt; - } - - template<class F> - using move_map_t = decltype(std::declval<F&>()(std::declval<T&&>())); - - template<class F, class U = move_map_t<F>> - Optional<U> map(F f) && - { - if (has_value()) - { - return f(std::move(this->m_base.value())); - } - return nullopt; - } - - template<class F, class U = move_map_t<F>> - U then(F f) && - { - if (has_value()) - { - return f(std::move(this->m_base.value())); - } - return nullopt; - } - - friend bool operator==(const Optional& lhs, const Optional& rhs) - { - if (lhs.m_base.has_value()) - { - if (rhs.m_base.has_value()) - { - return lhs.m_base.value() == rhs.m_base.value(); - } - - return false; - } - - return !rhs.m_base.has_value(); - } - - private: - details::OptionalStorage<T> m_base; - }; - - template<class U> - Optional<std::decay_t<U>> make_optional(U&& u) - { - return Optional<std::decay_t<U>>(std::forward<U>(u)); - } - - template<class T> - bool operator==(const Optional<T>& o, const T& t) - { - if (auto p = o.get()) return *p == t; - return false; - } - template<class T> - bool operator==(const T& t, const Optional<T>& o) - { - if (auto p = o.get()) return t == *p; - return false; - } - template<class T> - bool operator!=(const Optional<T>& o, const T& t) - { - if (auto p = o.get()) return *p != t; - return true; - } - template<class T> - bool operator!=(const T& t, const Optional<T>& o) - { - if (auto p = o.get()) return t != *p; - return true; - } -} diff --git a/toolsrc/include/vcpkg/base/parse.h b/toolsrc/include/vcpkg/base/parse.h deleted file mode 100644 index b3577e821..000000000 --- a/toolsrc/include/vcpkg/base/parse.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include <vcpkg/base/cstringview.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/stringview.h> -#include <vcpkg/base/unicode.h> - -#include <vcpkg/textrowcol.h> - -#include <memory> -#include <string> - -namespace vcpkg::Parse -{ - struct IParseError - { - virtual ~IParseError() = default; - virtual std::string format() const = 0; - virtual const std::string& get_message() const = 0; - }; - - struct ParseError : IParseError - { - ParseError(std::string origin, int row, int column, int caret_col, std::string line, std::string message) - : origin(std::move(origin)) - , row(row) - , column(column) - , caret_col(caret_col) - , line(std::move(line)) - , message(std::move(message)) - { - } - - const std::string origin; - const int row; - const int column; - const int caret_col; - const std::string line; - const std::string message; - - virtual std::string format() const override; - virtual const std::string& get_message() const override; - }; - - struct ParserBase - { - struct SourceLoc - { - Unicode::Utf8Decoder it; - Unicode::Utf8Decoder start_of_line; - int row; - int column; - }; - - ParserBase(StringView text, StringView origin, TextRowCol init_rowcol = {}); - - static constexpr bool is_whitespace(char32_t ch) { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; } - static constexpr bool is_lower_alpha(char32_t ch) { return ch >= 'a' && ch <= 'z'; } - static constexpr bool is_upper_alpha(char32_t ch) { return ch >= 'A' && ch <= 'Z'; } - static constexpr bool is_ascii_digit(char32_t ch) { return ch >= '0' && ch <= '9'; } - static constexpr bool is_lineend(char32_t ch) { return ch == '\r' || ch == '\n' || ch == Unicode::end_of_file; } - static constexpr bool is_alphanum(char32_t ch) - { - return is_upper_alpha(ch) || is_lower_alpha(ch) || is_ascii_digit(ch); - } - static constexpr bool is_alphanumdash(char32_t ch) { return is_alphanum(ch) || ch == '-'; } - - StringView skip_whitespace() { return match_zero_or_more(is_whitespace); } - StringView skip_tabs_spaces() - { - return match_zero_or_more([](char32_t ch) { return ch == ' ' || ch == '\t'; }); - } - void skip_to_eof() { m_it = m_it.end(); } - void skip_newline() - { - if (cur() == '\r') next(); - if (cur() == '\n') next(); - } - void skip_line() - { - match_until(is_lineend); - skip_newline(); - } - - template<class Pred> - StringView match_zero_or_more(Pred p) - { - const char* start = m_it.pointer_to_current(); - auto ch = cur(); - while (ch != Unicode::end_of_file && p(ch)) - ch = next(); - return {start, m_it.pointer_to_current()}; - } - template<class Pred> - StringView match_until(Pred p) - { - const char* start = m_it.pointer_to_current(); - auto ch = cur(); - while (ch != Unicode::end_of_file && !p(ch)) - ch = next(); - return {start, m_it.pointer_to_current()}; - } - - StringView text() const { return m_text; } - Unicode::Utf8Decoder it() const { return m_it; } - char32_t cur() const { return m_it == m_it.end() ? Unicode::end_of_file : *m_it; } - SourceLoc cur_loc() const { return {m_it, m_start_of_line, m_row, m_column}; } - TextRowCol cur_rowcol() const { return {m_row, m_column}; } - char32_t next(); - bool at_eof() const { return m_it == m_it.end(); } - - void add_error(std::string message) { add_error(std::move(message), cur_loc()); } - void add_error(std::string message, const SourceLoc& loc); - - const Parse::IParseError* get_error() const { return m_err.get(); } - std::unique_ptr<Parse::IParseError> extract_error() { return std::move(m_err); } - - private: - Unicode::Utf8Decoder m_it; - Unicode::Utf8Decoder m_start_of_line; - int m_row; - int m_column; - - StringView m_text; - StringView m_origin; - - std::unique_ptr<IParseError> m_err; - }; -} diff --git a/toolsrc/include/vcpkg/base/pragmas.h b/toolsrc/include/vcpkg/base/pragmas.h deleted file mode 100644 index 06efd5105..000000000 --- a/toolsrc/include/vcpkg/base/pragmas.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#if defined(_MSC_VER) && _MSC_VER < 1911 -// [[nodiscard]] is not recognized before VS 2017 version 15.3 -#pragma warning(disable : 5030) -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1910 -// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4800?view=vs-2019 -#pragma warning(disable : 4800) -#endif - -#if defined(__GNUC__) && __GNUC__ < 7 -// [[nodiscard]] is not recognized before GCC version 7 -#pragma GCC diagnostic ignored "-Wattributes" -#endif - -#if defined(_MSC_VER) -#include <sal.h> -#endif - -#if defined(_MSC_VER) -#define ASSUME(expr) __assume(expr) -#else -#define ASSUME(expr) -#endif - -// the static_assert(true, "")s are to avoid the extra ';' warning -#ifdef _MSC_VER -#define VCPKG_MSVC_WARNING(...) __pragma(warning(__VA_ARGS__)) -#define GCC_DIAGNOSTIC(...) -#else -#define VCPKG_MSVC_WARNING(...) -#define GCC_DIAGNOSTIC(...) _Pragma("diagnostic " #__VA_ARGS__) -#endif diff --git a/toolsrc/include/vcpkg/base/sortedvector.h b/toolsrc/include/vcpkg/base/sortedvector.h deleted file mode 100644 index 33379676e..000000000 --- a/toolsrc/include/vcpkg/base/sortedvector.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include <algorithm> -#include <vector> - -// Add more forwarding functions to the m_data std::vector as needed. -namespace vcpkg -{ - template<class T> - class SortedVector - { - public: - using size_type = typename std::vector<T>::size_type; - using iterator = typename std::vector<T>::const_iterator; - - SortedVector() : m_data() { } - - explicit SortedVector(std::vector<T> v) : m_data(std::move(v)) - { - if (!std::is_sorted(m_data.begin(), m_data.end())) - { - std::sort(m_data.begin(), m_data.end()); - } - } - - template<class Compare> - SortedVector(std::vector<T> v, Compare comp) : m_data(std::move(v)) - { - if (!std::is_sorted(m_data.cbegin(), m_data.cend(), comp)) - { - std::sort(m_data.begin(), m_data.end(), comp); - } - } - - iterator begin() const { return this->m_data.cbegin(); } - - iterator end() const { return this->m_data.cend(); } - - iterator cbegin() const { return this->m_data.cbegin(); } - - iterator cend() const { return this->m_data.cend(); } - - bool empty() const { return this->m_data.empty(); } - - size_type size() const { return this->m_data.size(); } - - const T& operator[](int i) const { return this->m_data[i]; } - - private: - std::vector<T> m_data; - }; -} diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h deleted file mode 100644 index 7748222cf..000000000 --- a/toolsrc/include/vcpkg/base/span.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/span.h> - -#include <array> -#include <cstddef> -#include <initializer_list> -#include <type_traits> -#include <vector> - -namespace vcpkg -{ - template<class T> - struct Span - { - public: - static_assert(std::is_object<T>::value, "Span<non-object-type> is illegal"); - - using value_type = std::decay_t<T>; - using element_type = T; - using pointer = std::add_pointer_t<T>; - using reference = std::add_lvalue_reference_t<T>; - using iterator = pointer; - - constexpr Span() noexcept : m_ptr(nullptr), m_count(0) { } - constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) { } - constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) { } - constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) { } - - template<size_t N> - constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N) - { - } - - template<class Range, - class = decltype(std::declval<Range>().data()), - class = std::enable_if_t<!std::is_same<std::decay_t<Range>, Span>::value>> - constexpr Span(Range&& v) noexcept : Span(v.data(), v.size()) - { - static_assert(std::is_same<typename std::decay_t<Range>::value_type, value_type>::value, - "Cannot convert incompatible ranges"); - } - - constexpr iterator begin() const { return m_ptr; } - constexpr iterator end() const { return m_ptr + m_count; } - - constexpr reference operator[](size_t i) const { return m_ptr[i]; } - constexpr pointer data() const { return m_ptr; } - constexpr size_t size() const { return m_count; } - - private: - pointer m_ptr; - size_t m_count; - }; -} diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h deleted file mode 100644 index 43d171829..000000000 --- a/toolsrc/include/vcpkg/base/stringliteral.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include <vcpkg/base/zstringview.h> - -#include <string> - -namespace vcpkg -{ - struct StringLiteral : ZStringView - { - template<int N> - constexpr StringLiteral(const char (&str)[N]) : ZStringView(str) - { - } - - operator std::string() const { return std::string(data(), size()); } - }; -} diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h deleted file mode 100644 index 16b39001b..000000000 --- a/toolsrc/include/vcpkg/base/strings.h +++ /dev/null @@ -1,306 +0,0 @@ -#pragma once - -#include <vcpkg/base/cstringview.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/pragmas.h> -#include <vcpkg/base/stringliteral.h> -#include <vcpkg/base/stringview.h> -#include <vcpkg/base/view.h> - -#include <errno.h> -#include <inttypes.h> -#include <limits.h> - -#include <vector> - -namespace vcpkg::Strings::details -{ - template<class T> - auto to_string(const T& t) -> decltype(t.to_string()) - { - return t.to_string(); - } - - // first looks up to_string on `T` using ADL; then, if that isn't found, - // uses the above definition which returns t.to_string() - template<class T, class = std::enable_if_t<!std::is_arithmetic<T>::value>> - auto to_printf_arg(const T& t) -> decltype(to_string(t)) - { - return to_string(t); - } - - inline const char* to_printf_arg(const std::string& s) { return s.c_str(); } - - inline const char* to_printf_arg(const char* s) { return s; } - - inline const wchar_t* to_printf_arg(const wchar_t* s) { return s; } - - template<class T, class = std::enable_if_t<std::is_arithmetic<T>::value>> - T to_printf_arg(T s) - { - return s; - } - - std::string format_internal(const char* fmtstr, ...); - - inline void append_internal(std::string& into, char c) { into += c; } - template<class T, class = decltype(std::to_string(std::declval<T>()))> - inline void append_internal(std::string& into, T x) - { - into += std::to_string(x); - } - inline void append_internal(std::string& into, const char* v) { into.append(v); } - inline void append_internal(std::string& into, const std::string& s) { into.append(s); } - inline void append_internal(std::string& into, StringView s) { into.append(s.begin(), s.end()); } - - template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))> - void append_internal(std::string& into, const T& t) - { - t.to_string(into); - } - - template<class T, class = void, class = decltype(to_string(std::declval<std::string&>(), std::declval<const T&>()))> - void append_internal(std::string& into, const T& t) - { - to_string(into, t); - } - - struct tolower_char - { - char operator()(char c) const { return (c < 'A' || c > 'Z') ? c : c - 'A' + 'a'; } - }; -} - -namespace vcpkg::Strings -{ - template<class Arg> - std::string& append(std::string& into, const Arg& a) - { - details::append_internal(into, a); - return into; - } - template<class Arg, class... Args> - std::string& append(std::string& into, const Arg& a, const Args&... args) - { - append(into, a); - return append(into, args...); - } - - template<class... Args> - [[nodiscard]] std::string concat(const Args&... args) - { - std::string ret; - append(ret, args...); - return ret; - } - - template<class... Args> - [[nodiscard]] std::string concat(std::string&& first, const Args&... args) - { - append(first, args...); - return std::move(first); - } - - template<class... Args, class = void> - std::string concat_or_view(const Args&... args) - { - return Strings::concat(args...); - } - - template<class T, class = std::enable_if_t<std::is_convertible<T, StringView>::value>> - StringView concat_or_view(const T& v) - { - return v; - } - - template<class... Args> - std::string format(const char* fmtstr, const Args&... args) - { - using vcpkg::Strings::details::to_printf_arg; - return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); - } - -#if defined(_WIN32) - std::wstring to_utf16(StringView s); - - std::string to_utf8(const wchar_t* w); - inline std::string to_utf8(const std::wstring& ws) { return to_utf8(ws.c_str()); } -#endif - - std::string escape_string(std::string&& s, char char_to_escape, char escape_char); - - bool case_insensitive_ascii_contains(StringView s, StringView pattern); - - bool case_insensitive_ascii_equals(StringView left, StringView right); - - template<class It> - void ascii_to_lowercase(It first, It last) - { - std::transform(first, last, first, details::tolower_char{}); - } - std::string ascii_to_lowercase(std::string&& s); - - std::string ascii_to_uppercase(std::string&& s); - - bool case_insensitive_ascii_starts_with(StringView s, StringView pattern); - bool ends_with(StringView s, StringView pattern); - bool starts_with(StringView s, StringView pattern); - - template<class InputIterator, class Transformer> - std::string join(const char* delimiter, InputIterator begin, InputIterator end, Transformer transformer) - { - if (begin == end) - { - return std::string(); - } - - std::string output; - append(output, transformer(*begin)); - for (auto it = std::next(begin); it != end; ++it) - { - output.append(delimiter); - append(output, transformer(*it)); - } - - return output; - } - - template<class Container, class Transformer> - std::string join(const char* delimiter, const Container& v, Transformer transformer) - { - const auto begin = std::begin(v); - const auto end = std::end(v); - - return join(delimiter, begin, end, transformer); - } - - template<class InputIterator> - std::string join(const char* delimiter, InputIterator begin, InputIterator end) - { - using Element = decltype(*begin); - return join(delimiter, begin, end, [](const Element& x) -> const Element& { return x; }); - } - - template<class Container> - std::string join(const char* delimiter, const Container& v) - { - using Element = decltype(*std::begin(v)); - return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); - } - - std::string replace_all(std::string&& s, StringView search, StringView rep); - - void inplace_replace_all(std::string& s, StringView search, StringView rep); - - void inplace_replace_all(std::string& s, char search, char rep) noexcept; - - std::string trim(std::string&& s); - - StringView trim(StringView sv); - - void trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings); - - std::vector<std::string> split(StringView s, const char delimiter); - - std::vector<std::string> split_paths(StringView s); - - const char* find_first_of(StringView searched, StringView candidates); - - std::vector<StringView> find_all_enclosed(StringView input, StringView left_delim, StringView right_delim); - - StringView find_exactly_one_enclosed(StringView input, StringView left_tag, StringView right_tag); - - Optional<StringView> find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag); - - bool equals(StringView a, StringView b); - - template<class T> - std::string serialize(const T& t) - { - std::string ret; - serialize(t, ret); - return ret; - } - - // Equivalent to one of the `::strto[T]` functions. Returns `nullopt` if there is an error. - template<class T> - Optional<T> strto(CStringView sv); - - template<> - inline Optional<double> strto<double>(CStringView sv) - { - char* endptr = nullptr; - double res = strtod(sv.c_str(), &endptr); - if (endptr == sv.c_str()) - { - // no digits - return nullopt; - } - // else, we may have HUGE_VAL but we expect the caller to deal with that - return res; - } - - template<> - inline Optional<long> strto<long>(CStringView sv) - { - char* endptr = nullptr; - long res = strtol(sv.c_str(), &endptr, 10); - if (endptr == sv.c_str()) - { - // no digits - return nullopt; - } - if (errno == ERANGE) - { - // out of bounds - return nullopt; - } - - return res; - } - - template<> - inline Optional<long long> strto<long long>(CStringView sv) - { - char* endptr = nullptr; - long long res = strtoll(sv.c_str(), &endptr, 10); - if (endptr == sv.c_str()) - { - // no digits - return nullopt; - } - if (errno == ERANGE) - { - // out of bounds - return nullopt; - } - - return res; - } - - template<> - inline Optional<int> strto<int>(CStringView sv) - { - auto res = strto<long>(sv); - if (auto r = res.get()) - { - if (*r < INT_MIN || *r > INT_MAX) - { - return nullopt; - } - return static_cast<int>(*r); - } - return nullopt; - } - - const char* search(StringView haystack, StringView needle); - - bool contains(StringView haystack, StringView needle); - - // base 32 encoding, following IETC RFC 4648 - std::string b32_encode(std::uint64_t x) noexcept; - - // Implements https://en.wikipedia.org/wiki/Levenshtein_distance with a "give-up" clause for large strings - // Guarantees 0 for equal strings and nonzero for inequal strings. - size_t byte_edit_distance(StringView a, StringView b); -} diff --git a/toolsrc/include/vcpkg/base/stringview.h b/toolsrc/include/vcpkg/base/stringview.h deleted file mode 100644 index c6e0c6350..000000000 --- a/toolsrc/include/vcpkg/base/stringview.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/stringview.h> - -#include <stddef.h> - -#include <iterator> -#include <limits> -#include <string> - -namespace vcpkg -{ - struct StringView - { - constexpr StringView() = default; - StringView(const std::string& s) noexcept; // Implicit by design - - // NOTE: we do this instead of the delegating constructor since delegating ctors are a perf footgun - template<size_t Sz> - constexpr StringView(const char (&arr)[Sz]) noexcept : m_ptr(arr), m_size(Sz - 1) - { - } - - constexpr StringView(const char* ptr, size_t size) noexcept : m_ptr(ptr), m_size(size) { } - constexpr StringView(const char* b, const char* e) noexcept : m_ptr(b), m_size(static_cast<size_t>(e - b)) { } - - constexpr const char* begin() const noexcept { return m_ptr; } - constexpr const char* end() const noexcept { return m_ptr + m_size; } - - std::reverse_iterator<const char*> rbegin() const noexcept { return std::make_reverse_iterator(end()); } - std::reverse_iterator<const char*> rend() const noexcept { return std::make_reverse_iterator(begin()); } - - constexpr const char* data() const noexcept { return m_ptr; } - constexpr size_t size() const noexcept { return m_size; } - constexpr bool empty() const noexcept { return m_size == 0; } - - std::string to_string() const; - void to_string(std::string& out) const; - - StringView substr(size_t pos, size_t count = std::numeric_limits<size_t>::max()) const noexcept; - - constexpr char byte_at_index(size_t pos) const noexcept { return m_ptr[pos]; } - - private: - const char* m_ptr = 0; - size_t m_size = 0; - }; - - bool operator==(StringView lhs, StringView rhs) noexcept; - bool operator!=(StringView lhs, StringView rhs) noexcept; - bool operator<(StringView lhs, StringView rhs) noexcept; - bool operator>(StringView lhs, StringView rhs) noexcept; - bool operator<=(StringView lhs, StringView rhs) noexcept; - bool operator>=(StringView lhs, StringView rhs) noexcept; -} diff --git a/toolsrc/include/vcpkg/base/system.debug.h b/toolsrc/include/vcpkg/base/system.debug.h deleted file mode 100644 index 898052a01..000000000 --- a/toolsrc/include/vcpkg/base/system.debug.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include <vcpkg/base/chrono.h> -#include <vcpkg/base/lineinfo.h> -#include <vcpkg/base/system.print.h> - -#include <atomic> - -namespace vcpkg::Debug -{ - extern std::atomic<bool> g_debugging; - - template<class... Args> - void print(const Args&... args) - { - if (g_debugging) System::print2("[DEBUG] ", args...); - } - - template<class F, class R = std::result_of_t<F && ()>, class = std::enable_if_t<!std::is_void<R>::value>> - R time(LineInfo line, F&& f) - { - if (g_debugging) - { - auto timer = Chrono::ElapsedTimer::create_started(); - auto&& result = f(); - System::print2("[DEBUG] ", line, " took ", timer, '\n'); - return static_cast<R&&>(result); - } - else - return f(); - } - - template<class F, class R = std::result_of_t<F && ()>, class = std::enable_if_t<std::is_void<R>::value>> - void time(LineInfo line, F&& f) - { - if (g_debugging) - { - auto timer = Chrono::ElapsedTimer::create_started(); - f(); - System::print2("[DEBUG] ", line, " took ", timer, '\n'); - } - else - f(); - } -} diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h deleted file mode 100644 index 992533eb5..000000000 --- a/toolsrc/include/vcpkg/base/system.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/stringview.h> -#include <vcpkg/base/zstringview.h> - -namespace vcpkg::System -{ - Optional<std::string> get_environment_variable(ZStringView varname) noexcept; - void set_environment_variable(ZStringView varname, Optional<ZStringView> value) noexcept; - - const ExpectedS<fs::path>& get_home_dir() noexcept; - - const ExpectedS<fs::path>& get_platform_cache_home() noexcept; - -#ifdef _WIN32 - const ExpectedS<fs::path>& get_appdata_local() noexcept; -#endif - - Optional<std::string> get_registry_string(void* base_hkey, StringView subkey, StringView valuename); - - long get_process_id(); - - enum class CPUArchitecture - { - X86, - X64, - ARM, - ARM64, - S390X, - PPC64LE, - }; - - Optional<CPUArchitecture> to_cpu_architecture(StringView arch); - - ZStringView to_zstring_view(CPUArchitecture arch) noexcept; - - CPUArchitecture get_host_processor(); - - std::vector<CPUArchitecture> get_supported_host_architectures(); - - const Optional<fs::path>& get_program_files_32_bit(); - - const Optional<fs::path>& get_program_files_platform_bitness(); - - int get_num_logical_cores(); - - Optional<CPUArchitecture> guess_visual_studio_prompt_target_architecture(); -} diff --git a/toolsrc/include/vcpkg/base/system.print.h b/toolsrc/include/vcpkg/base/system.print.h deleted file mode 100644 index abe685cf5..000000000 --- a/toolsrc/include/vcpkg/base/system.print.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include <vcpkg/base/strings.h> -#include <vcpkg/base/view.h> - -namespace vcpkg::System -{ - enum class Color - { - success = 10, - error = 12, - warning = 14, - }; - - namespace details - { - void print(StringView message); - void print(const Color c, StringView message); - } - - template<class Arg1, class... Args> - void printf(const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return ::vcpkg::System::details::print(Strings::format(message_template, message_arg1, message_args...)); - } - - template<class Arg1, class... Args> - void printf(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return ::vcpkg::System::details::print(c, Strings::format(message_template, message_arg1, message_args...)); - } - - template<class... Args> - void print2(const Color c, const Args&... args) - { - ::vcpkg::System::details::print(c, Strings::concat_or_view(args...)); - } - - template<class... Args> - void print2(const Args&... args) - { - ::vcpkg::System::details::print(Strings::concat_or_view(args...)); - } - - class BufferedPrint - { - ::std::string stdout_buffer; - static constexpr ::std::size_t buffer_size_target = 2048; - static constexpr ::std::size_t expected_maximum_print = 256; - static constexpr ::std::size_t alloc_size = buffer_size_target + expected_maximum_print; - - public: - BufferedPrint() { stdout_buffer.reserve(alloc_size); } - BufferedPrint(const BufferedPrint&) = delete; - BufferedPrint& operator=(const BufferedPrint&) = delete; - void append(::vcpkg::StringView nextView) - { - stdout_buffer.append(nextView.data(), nextView.size()); - if (stdout_buffer.size() > buffer_size_target) - { - ::vcpkg::System::details::print(stdout_buffer); - stdout_buffer.clear(); - } - } - ~BufferedPrint() { ::vcpkg::System::details::print(stdout_buffer); } - }; -} diff --git a/toolsrc/include/vcpkg/base/system.process.h b/toolsrc/include/vcpkg/base/system.process.h deleted file mode 100644 index 5b6f8cd55..000000000 --- a/toolsrc/include/vcpkg/base/system.process.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> -#include <vcpkg/base/zstringview.h> - -#include <functional> -#include <string> -#include <unordered_map> -#include <vector> - -namespace vcpkg::System -{ - struct CMakeVariable - { - CMakeVariable(const StringView varname, const char* varvalue); - CMakeVariable(const StringView varname, const std::string& varvalue); - CMakeVariable(const StringView varname, const fs::path& path); - CMakeVariable(std::string var); - - std::string s; - }; - - struct Command - { - Command() = default; - explicit Command(const fs::path& p) { path_arg(p); } - explicit Command(StringView s) { string_arg(s); } - explicit Command(const std::string& s) { string_arg(s); } - explicit Command(const char* s) { string_arg({s, ::strlen(s)}); } - - Command& path_arg(const fs::path& p) & { return string_arg(fs::u8string(p)); } - Command& string_arg(StringView s) &; - Command& raw_arg(StringView s) & - { - buf.push_back(' '); - buf.append(s.data(), s.size()); - return *this; - } - - Command&& path_arg(const fs::path& p) && { return std::move(path_arg(p)); } - Command&& string_arg(StringView s) && { return std::move(string_arg(s)); }; - Command&& raw_arg(StringView s) && { return std::move(raw_arg(s)); } - - std::string&& extract() && { return std::move(buf); } - StringView command_line() const { return buf; } - - void clear() { buf.clear(); } - bool empty() const { return buf.empty(); } - - private: - std::string buf; - }; - - struct CommandLess - { - bool operator()(const Command& lhs, const Command& rhs) const - { - return lhs.command_line() < rhs.command_line(); - } - }; - - Command make_basic_cmake_cmd(const fs::path& cmake_tool_path, - const fs::path& cmake_script, - const std::vector<CMakeVariable>& pass_variables); - - fs::path get_exe_path_of_current_process(); - - struct ExitCodeAndOutput - { - int exit_code; - std::string output; - }; - - struct Environment - { -#if defined(_WIN32) - std::wstring m_env_data; -#endif - }; - - const Environment& get_clean_environment(); - Environment get_modified_clean_environment(const std::unordered_map<std::string, std::string>& extra_env, - const std::string& prepend_to_path = {}); - - struct InWorkingDirectory - { - const fs::path& working_directory; - }; - - int cmd_execute(const Command& cmd_line, InWorkingDirectory wd, const Environment& env = {}); - inline int cmd_execute(const Command& cmd_line, const Environment& env = {}) - { - return cmd_execute(cmd_line, InWorkingDirectory{fs::path()}, env); - } - - int cmd_execute_clean(const Command& cmd_line, InWorkingDirectory wd); - inline int cmd_execute_clean(const Command& cmd_line) - { - return cmd_execute_clean(cmd_line, InWorkingDirectory{fs::path()}); - } - -#if defined(_WIN32) - Environment cmd_execute_modify_env(const Command& cmd_line, const Environment& env = {}); - - void cmd_execute_background(const Command& cmd_line); -#endif - - ExitCodeAndOutput cmd_execute_and_capture_output(const Command& cmd_line, - InWorkingDirectory wd, - const Environment& env = {}); - inline ExitCodeAndOutput cmd_execute_and_capture_output(const Command& cmd_line, const Environment& env = {}) - { - return cmd_execute_and_capture_output(cmd_line, InWorkingDirectory{fs::path()}, env); - } - - int cmd_execute_and_stream_lines(const Command& cmd_line, - InWorkingDirectory wd, - std::function<void(StringView)> per_line_cb, - const Environment& env = {}); - inline int cmd_execute_and_stream_lines(const Command& cmd_line, - std::function<void(StringView)> per_line_cb, - const Environment& env = {}) - { - return cmd_execute_and_stream_lines(cmd_line, InWorkingDirectory{fs::path()}, std::move(per_line_cb), env); - } - - int cmd_execute_and_stream_data(const Command& cmd_line, - InWorkingDirectory wd, - std::function<void(StringView)> data_cb, - const Environment& env = {}); - inline int cmd_execute_and_stream_data(const Command& cmd_line, - std::function<void(StringView)> data_cb, - const Environment& env = {}) - { - return cmd_execute_and_stream_data(cmd_line, InWorkingDirectory{fs::path()}, std::move(data_cb), env); - } - - void register_console_ctrl_handler(); -#if defined(_WIN32) - void initialize_global_job_object(); - void enter_interactive_subprocess(); - void exit_interactive_subprocess(); -#endif -} diff --git a/toolsrc/include/vcpkg/base/system_headers.h b/toolsrc/include/vcpkg/base/system_headers.h deleted file mode 100644 index 6667fd395..000000000 --- a/toolsrc/include/vcpkg/base/system_headers.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#if defined(_WIN32) - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#pragma warning(suppress : 4768) -#include <windows.h> - -#pragma warning(suppress : 4768) -#include <Shlobj.h> - -#else // ^^^^ Windows / Unix vvvv - -// 2020-05-19: workaround for a c standard library bug -// ctermid is not behind an `extern "C"` barrier, so it's linked incorrectly. -// This has been reported; remove it after 2023-05-19 -#if __APPLE__ -extern "C" -{ -#endif - -#include <unistd.h> - -#if __APPLE__ -} -#endif - -#endif - -#include <sys/types.h> -// glibc defines major and minor in sys/types.h, and should not -#undef major -#undef minor diff --git a/toolsrc/include/vcpkg/base/uint128.h b/toolsrc/include/vcpkg/base/uint128.h deleted file mode 100644 index feac68bb7..000000000 --- a/toolsrc/include/vcpkg/base/uint128.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include <stdint.h> - -namespace vcpkg -{ - struct UInt128 - { - UInt128() = default; - UInt128(uint64_t value) : bottom(value), top(0) { } - - UInt128& operator<<=(int by) noexcept; - UInt128& operator>>=(int by) noexcept; - UInt128& operator+=(uint64_t lhs) noexcept; - - uint64_t bottom_64_bits() const noexcept { return bottom; } - uint64_t top_64_bits() const noexcept { return top; } - - private: - uint64_t bottom; - uint64_t top; - }; - -} diff --git a/toolsrc/include/vcpkg/base/unicode.h b/toolsrc/include/vcpkg/base/unicode.h deleted file mode 100644 index c2143a235..000000000 --- a/toolsrc/include/vcpkg/base/unicode.h +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include <stddef.h> - -namespace vcpkg::Unicode -{ - enum class Utf8CodeUnitKind - { - Invalid = -1, - Continue = 0, - StartOne = 1, - StartTwo = 2, - StartThree = 3, - StartFour = 4, - }; - - Utf8CodeUnitKind utf8_code_unit_kind(unsigned char code_unit) noexcept; - int utf8_code_unit_count(Utf8CodeUnitKind kind) noexcept; - int utf8_code_unit_count(char code_unit) noexcept; - - int utf8_encode_code_point(char (&array)[4], char32_t code_point) noexcept; - - template<class String> - String& utf8_append_code_point(String& str, char32_t code_point) - { - char buf[4] = {}; - int count = ::vcpkg::Unicode::utf8_encode_code_point(buf, code_point); - str.append(buf, buf + count); - return str; - } - - bool utf8_is_valid_string(const char* first, const char* last) noexcept; - - constexpr bool utf16_is_leading_surrogate_code_point(char32_t code_point) - { - return code_point >= 0xD800 && code_point < 0xDC00; - } - constexpr bool utf16_is_trailing_surrogate_code_point(char32_t code_point) - { - return code_point >= 0xDC00 && code_point < 0xE000; - } - constexpr bool utf16_is_surrogate_code_point(char32_t code_point) - { - return code_point >= 0xD800 && code_point < 0xE000; - } - - char32_t utf16_surrogates_to_code_point(char32_t leading, char32_t trailing); - - constexpr static char32_t end_of_file = 0xFFFF'FFFF; - - enum class utf8_errc - { - NoError = 0, - InvalidCodeUnit = 1, - InvalidCodePoint = 2, - PairedSurrogates = 3, - UnexpectedContinue = 4, - UnexpectedStart = 5, - UnexpectedEof = 6, - }; - - struct utf8_category : std::error_category - { - const char* name() const noexcept override; - std::string message(int condition) const override; - }; - - inline std::error_code make_error_code(utf8_errc err) noexcept - { - return std::error_code(static_cast<int>(err), utf8_category()); - } - - /* - There are two ways to parse utf-8: we could allow unpaired surrogates (as in [wtf-8]) -- this is important - for representing things like file paths on Windows. We could also require strict utf-8, as in the JSON - specification. We need both, since when parsing JSON, we need to require strict utf-8; however, when - outputting JSON, we need to be able to stringify unpaired surrogates (as '\uDxyz'). This dichotomy is an - issue _because_ we need to be able to decode two different kinds of utf-8: utf-8 as read off of a disk - (strict), and utf-8 as contained in a C++ string (non-strict). - - Since one is a strict superset of the other, we allow the non-strict utf-8 in this decoder; if a consumer - wishes to make certain that the utf-8 is strictly conforming, it will have to do the check on it's own with - `utf16_is_surrogate_code_point`. - - [wtf-8]: https://simonsapin.github.io/wtf-8/ - */ - struct Utf8Decoder - { - Utf8Decoder() noexcept; - Utf8Decoder(const char* first, const char* last) noexcept; - - struct sentinel - { - }; - - bool is_eof() const noexcept; - - void next(std::error_code& ec); - - Utf8Decoder& operator=(sentinel) noexcept; - - char const* pointer_to_current() const noexcept; - - char32_t operator*() const noexcept; - - Utf8Decoder& operator++() noexcept; - Utf8Decoder operator++(int) noexcept - { - auto res = *this; - ++*this; - return res; - } - - Utf8Decoder begin() const { return *this; } - - sentinel end() const { return sentinel(); } - - friend bool operator==(const Utf8Decoder& lhs, const Utf8Decoder& rhs) noexcept; - - using difference_type = std::ptrdiff_t; - using value_type = char32_t; - using pointer = void; - using reference = char32_t; - using iterator_category = std::forward_iterator_tag; - - private: - char32_t current_; - const char* next_; - const char* last_; - }; - - inline bool operator!=(const Utf8Decoder& lhs, const Utf8Decoder& rhs) noexcept { return !(lhs == rhs); } - - inline bool operator==(const Utf8Decoder& d, Utf8Decoder::sentinel) { return d.is_eof(); } - inline bool operator==(Utf8Decoder::sentinel s, const Utf8Decoder& d) { return d == s; } - inline bool operator!=(const Utf8Decoder& d, Utf8Decoder::sentinel) { return !d.is_eof(); } - inline bool operator!=(Utf8Decoder::sentinel s, const Utf8Decoder& d) { return d != s; } - -} - -namespace std -{ - template<> - struct is_error_code_enum<vcpkg::Unicode::utf8_errc> : std::true_type - { - }; - -} diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h deleted file mode 100644 index b5ad1d04f..000000000 --- a/toolsrc/include/vcpkg/base/util.h +++ /dev/null @@ -1,248 +0,0 @@ -#pragma once - -#include <vcpkg/base/optional.h> -#include <vcpkg/base/view.h> - -#include <algorithm> -#include <functional> -#include <map> -#include <type_traits> -#include <unordered_map> -#include <utility> -#include <vector> - -namespace vcpkg::Util -{ - template<class Container> - using ElementT = - std::remove_reference_t<decltype(*std::declval<typename std::remove_reference_t<Container>::iterator>())>; - - namespace Vectors - { - template<class Container, class T = ElementT<Container>> - void append(std::vector<T>* augend, const Container& addend) - { - augend->insert(augend->end(), addend.begin(), addend.end()); - } - template<class Vec, class Key> - bool contains(const Vec& container, const Key& item) - { - return std::find(container.begin(), container.end(), item) != container.end(); - } - template<class T> - std::vector<T> concat(View<T> r1, View<T> r2) - { - std::vector<T> v; - v.reserve(r1.size() + r2.size()); - v.insert(v.end(), r1.begin(), r1.end()); - v.insert(v.end(), r2.begin(), r2.end()); - return v; - } - } - - namespace Sets - { - template<class Container, class Key> - bool contains(const Container& container, const Key& item) - { - return container.find(item) != container.end(); - } - } - - namespace Maps - { - template<class K, class V1, class V2, class Func> - void transform_values(const std::unordered_map<K, V1>& container, std::unordered_map<K, V2>& output, Func func) - { - std::for_each(container.cbegin(), container.cend(), [&](const std::pair<const K, V1>& p) { - output[p.first] = func(p.second); - }); - } - } - - template<class Range, class Pred, class E = ElementT<Range>> - std::vector<E> filter(const Range& xs, Pred&& f) - { - std::vector<E> ret; - - for (auto&& x : xs) - { - if (f(x)) ret.push_back(x); - } - - return ret; - } - - template<class Range, class Func> - using FmapRefOut = decltype(std::declval<Func&>()(*std::declval<Range>().begin())); - - template<class Range, class Func> - using FmapOut = std::decay_t<FmapRefOut<Range, Func>>; - - template<class Range, class Func, class Out = FmapOut<Range, Func>> - std::vector<Out> fmap(Range&& xs, Func&& f) - { - std::vector<Out> ret; - ret.reserve(xs.size()); - - for (auto&& x : xs) - ret.push_back(f(x)); - - return ret; - } - - template<class Range, class Proj, class Out = FmapRefOut<Range, Proj>> - Optional<Out> common_projection(Range&& input, Proj&& proj) - { - const auto last = input.end(); - auto first = input.begin(); - if (first == last) - { - return nullopt; - } - - Out prototype = proj(*first); - while (++first != last) - { - if (prototype != proj(*first)) - { - return nullopt; - } - } - - return prototype; - } - - template<class Cont, class Func> - using FmapFlattenOut = std::decay_t<decltype(*begin(std::declval<Func>()(*begin(std::declval<Cont>()))))>; - - template<class Cont, class Func, class Out = FmapFlattenOut<Cont, Func>> - std::vector<Out> fmap_flatten(Cont&& xs, Func&& f) - { - std::vector<Out> ret; - - for (auto&& x : xs) - for (auto&& y : f(x)) - ret.push_back(std::move(y)); - - return ret; - } - - template<class Container, class Pred> - void erase_remove_if(Container& cont, Pred pred) - { - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); - } - - template<class Container, class V> - auto find(Container&& cont, V&& v) - { - using std::begin; - using std::end; - return std::find(begin(cont), end(cont), v); - } - - template<class Container, class Pred> - auto find_if(Container&& cont, Pred pred) - { - using std::begin; - using std::end; - return std::find_if(begin(cont), end(cont), pred); - } - - template<class Container, class Pred> - auto find_if_not(Container&& cont, Pred pred) - { - using std::begin; - using std::end; - return std::find_if_not(begin(cont), end(cont), pred); - } - - template<class K, class V, class Container, class Func> - void group_by(const Container& cont, std::map<K, std::vector<const V*>>* output, Func&& f) - { - for (const V& element : cont) - { - K key = f(element); - (*output)[key].push_back(&element); - } - } - - template<class Range, class Comp = std::less<typename Range::value_type>> - void sort(Range& cont, Comp comp = Comp()) - { - using std::begin; - using std::end; - std::sort(begin(cont), end(cont), comp); - } - - template<class Range, class Pred> - bool any_of(Range&& rng, Pred pred) - { - return std::any_of(rng.begin(), rng.end(), std::move(pred)); - } - - template<class Range> - Range&& sort_unique_erase(Range&& cont) - { - using std::begin; - using std::end; - std::sort(begin(cont), end(cont)); - cont.erase(std::unique(begin(cont), end(cont)), end(cont)); - - return std::forward<Range>(cont); - } - - template<class Range1, class Range2> - bool all_equal(const Range1& r1, const Range2& r2) - { - using std::begin; - using std::end; - return std::equal(begin(r1), end(r1), begin(r2), end(r2)); - } - - template<class AssocContainer, class K = std::decay_t<decltype(begin(std::declval<AssocContainer>())->first)>> - std::vector<K> extract_keys(AssocContainer&& input_map) - { - return fmap(input_map, [](auto&& p) { return p.first; }); - } - - struct MoveOnlyBase - { - MoveOnlyBase() = default; - MoveOnlyBase(const MoveOnlyBase&) = delete; - MoveOnlyBase(MoveOnlyBase&&) = default; - - MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; - MoveOnlyBase& operator=(MoveOnlyBase&&) = default; - - ~MoveOnlyBase() = default; - }; - - struct ResourceBase - { - ResourceBase() = default; - ResourceBase(const ResourceBase&) = delete; - ResourceBase(ResourceBase&&) = delete; - - ResourceBase& operator=(const ResourceBase&) = delete; - ResourceBase& operator=(ResourceBase&&) = delete; - - ~ResourceBase() = default; - }; - - namespace Enum - { - template<class E> - E to_enum(bool b) - { - return b ? E::YES : E::NO; - } - - template<class E> - bool to_bool(E e) - { - return e == E::YES; - } - } -} diff --git a/toolsrc/include/vcpkg/base/view.h b/toolsrc/include/vcpkg/base/view.h deleted file mode 100644 index 12908c4a5..000000000 --- a/toolsrc/include/vcpkg/base/view.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include <vcpkg/base/span.h> diff --git a/toolsrc/include/vcpkg/base/xmlserializer.h b/toolsrc/include/vcpkg/base/xmlserializer.h deleted file mode 100644 index 33b7c0811..000000000 --- a/toolsrc/include/vcpkg/base/xmlserializer.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include <vcpkg/base/stringliteral.h> -#include <vcpkg/base/stringview.h> - -#include <string> - -namespace vcpkg -{ - struct XmlSerializer - { - XmlSerializer& emit_declaration(); - XmlSerializer& open_tag(StringLiteral sl); - XmlSerializer& start_complex_open_tag(StringLiteral sl); - XmlSerializer& text_attr(StringLiteral name, StringView content); - XmlSerializer& finish_complex_open_tag(); - XmlSerializer& finish_self_closing_complex_tag(); - XmlSerializer& close_tag(StringLiteral sl); - XmlSerializer& text(StringView sv); - XmlSerializer& simple_tag(StringLiteral tag, StringView content); - XmlSerializer& line_break(); - - std::string buf; - - private: - XmlSerializer& emit_pending_indent(); - - int m_indent = 0; - bool m_pending_indent = false; - }; -} diff --git a/toolsrc/include/vcpkg/base/zstringview.h b/toolsrc/include/vcpkg/base/zstringview.h deleted file mode 100644 index ab2c23251..000000000 --- a/toolsrc/include/vcpkg/base/zstringview.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include <vcpkg/base/stringview.h> - -#include <algorithm> -#include <cstddef> -#include <cstring> -#include <string> - -namespace vcpkg -{ - // A counted view of a null-terminated string - struct ZStringView - { - using value_type = char; - - constexpr ZStringView() : m_size(0), m_cstr("") { } - - template<int N> - constexpr ZStringView(const char (&str)[N]) - : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str) - { - } - - ZStringView(const std::string& s) : m_size(s.size()), m_cstr(s.c_str()) { } - constexpr ZStringView(const char* str, size_t sz) : m_size(sz), m_cstr(str) { } - - constexpr const char* data() const { return m_cstr; } - constexpr size_t size() const { return m_size; } - constexpr char operator[](ptrdiff_t off) const { return m_cstr[off]; } - - constexpr const char* c_str() const { return m_cstr; } - - constexpr const char* begin() const { return m_cstr; } - constexpr const char* end() const { return m_cstr + m_size; } - - std::string to_string() const { return std::string(m_cstr, m_size); } - void to_string(std::string& out) const { out.append(m_cstr, m_size); } - - constexpr operator StringView() const { return StringView(m_cstr, m_size); } - - private: - size_t m_size; - const char* m_cstr; - }; - - inline bool operator==(ZStringView l, ZStringView r) { return std::equal(l.begin(), l.end(), r.begin(), r.end()); } - inline bool operator!=(ZStringView l, ZStringView r) { return !std::equal(l.begin(), l.end(), r.begin(), r.end()); } - - inline bool operator==(const char* l, ZStringView r) { return strcmp(l, r.c_str()) == 0; } - inline bool operator==(ZStringView l, const char* r) { return strcmp(l.c_str(), r) == 0; } -} diff --git a/toolsrc/include/vcpkg/binarycaching.h b/toolsrc/include/vcpkg/binarycaching.h deleted file mode 100644 index 5a127cb5c..000000000 --- a/toolsrc/include/vcpkg/binarycaching.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/dependencies.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/files.h> - -#include <vcpkg/packagespec.h> - -#include <unordered_map> - -namespace vcpkg -{ - struct MergeBinaryProviders; - - enum class RestoreResult - { - missing, - success, - build_failed, - }; - - struct IBinaryProvider - { - virtual ~IBinaryProvider() = default; - - /// Attempts to restore the package referenced by `action` into the packages directory. - virtual RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0; - - /// Called upon a successful build of `action` - virtual void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0; - - /// <summary>Gives the BinaryProvider an opportunity to batch any downloading or server communication for - /// executing `plan`.</summary> - /// <remarks>Must only be called once for a given binary provider instance</remarks> - /// <param name="actions">InOut vector of actions to be prefetched</param> - virtual void prefetch(const VcpkgPaths& paths, - std::vector<const Dependencies::InstallPlanAction*>& actions) = 0; - - /// <summary>Requests the result of <c>try_restore()</c> without actually downloading the package. Used by CI to - /// determine missing packages.</summary> - /// <param name="results_map">InOut map to track the restored packages. Should be initialized to - /// <c>{&action, RestoreResult::missing}</c> for all install actions</param> - virtual void precheck( - const VcpkgPaths& paths, - std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult>& results_map) = 0; - }; - - std::unordered_map<const Dependencies::InstallPlanAction*, RestoreResult> binary_provider_precheck( - const VcpkgPaths& paths, const Dependencies::ActionPlan& plan, IBinaryProvider& provider); - - IBinaryProvider& null_binary_provider(); - - ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs(View<std::string> args); - ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs_pure(const std::string& env_string, - View<std::string> args); - - std::string generate_nuget_packages_config(const Dependencies::ActionPlan& action); - - void help_topic_binary_caching(const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg/binarycaching.private.h b/toolsrc/include/vcpkg/binarycaching.private.h deleted file mode 100644 index 2ac446792..000000000 --- a/toolsrc/include/vcpkg/binarycaching.private.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/packagespec.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/strings.h> - -#include <vcpkg/dependencies.h> - -namespace vcpkg -{ - std::string reformat_version(const std::string& version, const std::string& abi_tag); - - struct NugetReference - { - explicit NugetReference(const Dependencies::InstallPlanAction& action) - : NugetReference(action.spec, - action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO) - .source_control_file->core_paragraph->version, - action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi) - { - } - - NugetReference(const PackageSpec& spec, const std::string& raw_version, const std::string& abi_tag) - : id(spec.dir()), version(reformat_version(raw_version, abi_tag)) - { - } - - std::string id; - std::string version; - - std::string nupkg_filename() const { return Strings::concat(id, '.', version, ".nupkg"); } - }; - - namespace details - { - struct NuGetRepoInfo - { - std::string repo; - std::string branch; - std::string commit; - }; - - NuGetRepoInfo get_nuget_repo_info_from_env(); - } - - std::string generate_nuspec(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - const NugetReference& ref, - details::NuGetRepoInfo rinfo = details::get_nuget_repo_info_from_env()); -} diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h deleted file mode 100644 index f10c41af0..000000000 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include <vcpkg/packagespec.h> -#include <vcpkg/paragraphparser.h> -#include <vcpkg/sourceparagraph.h> - -namespace vcpkg -{ - /// <summary> - /// Built package metadata - /// </summary> - struct BinaryParagraph - { - BinaryParagraph(); - explicit BinaryParagraph(Parse::Paragraph fields); - BinaryParagraph(const SourceParagraph& spgh, - Triplet triplet, - const std::string& abi_tag, - const std::vector<FeatureSpec>& deps); - BinaryParagraph(const SourceParagraph& spgh, - const FeatureParagraph& fpgh, - Triplet triplet, - const std::vector<FeatureSpec>& deps); - - std::string displayname() const; - - std::string fullstem() const; - - std::string dir() const; - - bool is_feature() const { return !feature.empty(); } - - PackageSpec spec; - std::string version; - int port_version = 0; - std::vector<std::string> description; - std::vector<std::string> maintainers; - std::string feature; - std::vector<std::string> default_features; - std::vector<std::string> dependencies; - std::string abi; - Type type = {Type::UNKNOWN}; - }; - - bool operator==(const BinaryParagraph&, const BinaryParagraph&); - bool operator!=(const BinaryParagraph&, const BinaryParagraph&); - - struct BinaryControlFile - { - BinaryParagraph core_paragraph; - std::vector<BinaryParagraph> features; - }; - - void serialize(const BinaryParagraph& pgh, std::string& out_str); -} diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h deleted file mode 100644 index ed2724435..000000000 --- a/toolsrc/include/vcpkg/build.h +++ /dev/null @@ -1,389 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/cmakevars.h> -#include <vcpkg/fwd/dependencies.h> -#include <vcpkg/fwd/portfileprovider.h> - -#include <vcpkg/base/cstringview.h> -#include <vcpkg/base/files.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/system.process.h> - -#include <vcpkg/commands.integrate.h> -#include <vcpkg/packagespec.h> -#include <vcpkg/statusparagraphs.h> -#include <vcpkg/triplet.h> -#include <vcpkg/vcpkgcmdarguments.h> -#include <vcpkg/vcpkgpaths.h> - -#include <array> -#include <map> -#include <set> -#include <vector> - -namespace vcpkg -{ - struct IBinaryProvider; -} - -namespace vcpkg::System -{ - struct Environment; -} - -namespace vcpkg::Build -{ - enum class BuildResult - { - NULLVALUE = 0, - SUCCEEDED, - BUILD_FAILED, - POST_BUILD_CHECKS_FAILED, - FILE_CONFLICTS, - CASCADED_DUE_TO_MISSING_DEPENDENCIES, - EXCLUDED, - CACHE_MISSING, - DOWNLOADED - }; - - struct IBuildLogsRecorder - { - virtual void record_build_result(const VcpkgPaths& paths, - const PackageSpec& spec, - BuildResult result) const = 0; - }; - - const IBuildLogsRecorder& null_build_logs_recorder() noexcept; - - namespace Command - { - int perform_ex(const VcpkgCmdArguments& args, - const FullPackageSpec& full_spec, - const SourceControlFileLocation& scfl, - const PortFileProvider::PathsPortFileProvider& provider, - IBinaryProvider& binaryprovider, - const IBuildLogsRecorder& build_logs_recorder, - const VcpkgPaths& paths); - void perform_and_exit_ex(const VcpkgCmdArguments& args, - const FullPackageSpec& full_spec, - const SourceControlFileLocation& scfl, - const PortFileProvider::PathsPortFileProvider& provider, - IBinaryProvider& binaryprovider, - const IBuildLogsRecorder& build_logs_recorder, - const VcpkgPaths& paths); - - int perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - } - - enum class UseHeadVersion - { - NO = 0, - YES - }; - - enum class AllowDownloads - { - NO = 0, - YES - }; - - enum class OnlyDownloads - { - NO = 0, - YES - }; - - enum class CleanBuildtrees - { - NO = 0, - YES - }; - - enum class CleanPackages - { - NO = 0, - YES - }; - - enum class CleanDownloads - { - NO = 0, - YES - }; - - enum class ConfigurationType - { - DEBUG, - RELEASE, - }; - - enum class DownloadTool - { - BUILT_IN, - ARIA2, - }; - const std::string& to_string(DownloadTool tool); - enum class PurgeDecompressFailure - { - NO = 0, - YES - }; - - enum class Editable - { - NO = 0, - YES - }; - - enum class BackcompatFeatures - { - ALLOW = 0, - PROHIBIT - }; - - enum class BuildMissing - { - NO = 0, - YES - }; - - struct BuildPackageOptions - { - BuildMissing build_missing; - UseHeadVersion use_head_version; - AllowDownloads allow_downloads; - OnlyDownloads only_downloads; - CleanBuildtrees clean_buildtrees; - CleanPackages clean_packages; - CleanDownloads clean_downloads; - DownloadTool download_tool; - PurgeDecompressFailure purge_decompress_failure; - Editable editable; - BackcompatFeatures backcompat_features; - }; - - static constexpr BuildPackageOptions default_build_package_options{ - Build::BuildMissing::YES, - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::OnlyDownloads::NO, - Build::CleanBuildtrees::YES, - Build::CleanPackages::YES, - Build::CleanDownloads::NO, - Build::DownloadTool::BUILT_IN, - Build::PurgeDecompressFailure::YES, - Build::Editable::NO, - Build::BackcompatFeatures::ALLOW, - }; - - static constexpr BuildPackageOptions backcompat_prohibiting_package_options{ - Build::BuildMissing::YES, - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::OnlyDownloads::NO, - Build::CleanBuildtrees::YES, - Build::CleanPackages::YES, - Build::CleanDownloads::NO, - Build::DownloadTool::BUILT_IN, - Build::PurgeDecompressFailure::YES, - Build::Editable::NO, - Build::BackcompatFeatures::PROHIBIT, - }; - - static constexpr std::array<BuildResult, 6> BUILD_RESULT_VALUES = { - BuildResult::SUCCEEDED, - BuildResult::BUILD_FAILED, - BuildResult::POST_BUILD_CHECKS_FAILED, - BuildResult::FILE_CONFLICTS, - BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, - BuildResult::EXCLUDED}; - - const std::string& to_string(const BuildResult build_result); - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); - std::string create_user_troubleshooting_message(const PackageSpec& spec); - - /// <summary> - /// Settings from the triplet file which impact the build environment and post-build checks - /// </summary> - struct PreBuildInfo : Util::ResourceBase - { - PreBuildInfo(const VcpkgPaths& paths, - Triplet triplet, - const std::unordered_map<std::string, std::string>& cmakevars); - - Triplet triplet; - bool load_vcvars_env = false; - std::string target_architecture; - std::string cmake_system_name; - std::string cmake_system_version; - Optional<std::string> platform_toolset; - Optional<fs::path> visual_studio_path; - Optional<std::string> external_toolchain_file; - Optional<ConfigurationType> build_type; - Optional<std::string> public_abi_override; - std::vector<std::string> passthrough_env_vars; - std::vector<std::string> passthrough_env_vars_tracked; - - fs::path toolchain_file() const; - bool using_vcvars() const; - - private: - const VcpkgPaths& m_paths; - }; - - System::Command make_build_env_cmd(const PreBuildInfo& pre_build_info, - const Toolset& toolset, - View<Toolset> all_toolsets); - - struct ExtendedBuildResult - { - ExtendedBuildResult(BuildResult code); - ExtendedBuildResult(BuildResult code, std::vector<FeatureSpec>&& unmet_deps); - ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf); - - BuildResult code; - std::vector<FeatureSpec> unmet_dependencies; - std::unique_ptr<BinaryControlFile> binary_control_file; - }; - - ExtendedBuildResult build_package(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& config, - IBinaryProvider& binaries_provider, - const IBuildLogsRecorder& build_logs_recorder, - const StatusParagraphs& status_db); - - enum class BuildPolicy - { - EMPTY_PACKAGE, - DLLS_WITHOUT_LIBS, - DLLS_WITHOUT_EXPORTS, - DLLS_IN_STATIC_LIBRARY, - MISMATCHED_NUMBER_OF_BINARIES, - ONLY_RELEASE_CRT, - EMPTY_INCLUDE_FOLDER, - ALLOW_OBSOLETE_MSVCRT, - ALLOW_RESTRICTED_HEADERS, - SKIP_DUMPBIN_CHECKS, - SKIP_ARCHITECTURE_CHECK, - // Must be last - COUNT, - }; - - // could be constexpr, but we want to generate this and that's not constexpr in C++14 - extern const std::array<BuildPolicy, size_t(BuildPolicy::COUNT)> ALL_POLICIES; - - const std::string& to_string(BuildPolicy policy); - CStringView to_cmake_variable(BuildPolicy policy); - - struct BuildPolicies - { - BuildPolicies() = default; - BuildPolicies(std::map<BuildPolicy, bool>&& map) : m_policies(std::move(map)) { } - - bool is_enabled(BuildPolicy policy) const - { - const auto it = m_policies.find(policy); - if (it != m_policies.cend()) return it->second; - return false; - } - - private: - std::map<BuildPolicy, bool> m_policies; - }; - - enum class LinkageType : char - { - DYNAMIC, - STATIC, - }; - - Optional<LinkageType> to_linkage_type(const std::string& str); - - struct BuildInfo - { - LinkageType crt_linkage = LinkageType::DYNAMIC; - LinkageType library_linkage = LinkageType::DYNAMIC; - - Optional<std::string> version; - - BuildPolicies policies; - }; - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); - - struct AbiEntry - { - std::string key; - std::string value; - - AbiEntry() = default; - AbiEntry(const std::string& key, const std::string& value) : key(key), value(value) { } - - bool operator<(const AbiEntry& other) const - { - return key < other.key || (key == other.key && value < other.value); - } - }; - - struct CompilerInfo - { - std::string id; - std::string version; - std::string hash; - }; - - struct AbiInfo - { - std::unique_ptr<PreBuildInfo> pre_build_info; - Optional<const Toolset&> toolset; - Optional<const std::string&> triplet_abi; - std::string package_abi; - Optional<fs::path> abi_tag_file; - Optional<const CompilerInfo&> compiler_info; - }; - - void compute_all_abis(const VcpkgPaths& paths, - Dependencies::ActionPlan& action_plan, - const CMakeVars::CMakeVarProvider& var_provider, - const StatusParagraphs& status_db); - - struct EnvCache - { - explicit EnvCache(bool compiler_tracking) : m_compiler_tracking(compiler_tracking) { } - - const System::Environment& get_action_env(const VcpkgPaths& paths, const AbiInfo& abi_info); - const std::string& get_triplet_info(const VcpkgPaths& paths, const AbiInfo& abi_info); - const CompilerInfo& get_compiler_info(const VcpkgPaths& paths, const AbiInfo& abi_info); - - private: - struct TripletMapEntry - { - std::string hash; - Cache<std::string, std::string> compiler_hashes; - Cache<std::string, CompilerInfo> compiler_info; - }; - Cache<fs::path, TripletMapEntry> m_triplet_cache; - Cache<fs::path, std::string> m_toolchain_cache; - -#if defined(_WIN32) - struct EnvMapEntry - { - std::unordered_map<std::string, std::string> env_map; - Cache<System::Command, System::Environment, System::CommandLess> cmd_cache; - }; - - Cache<std::vector<std::string>, EnvMapEntry> envs; -#endif - - bool m_compiler_tracking; - }; - - struct BuildCommand : Commands::TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/buildenvironment.h b/toolsrc/include/vcpkg/buildenvironment.h deleted file mode 100644 index b7ffb164f..000000000 --- a/toolsrc/include/vcpkg/buildenvironment.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/system.process.h> - -#include <string> -#include <vector> - -namespace vcpkg -{ - System::Command make_cmake_cmd(const VcpkgPaths& paths, - const fs::path& cmake_script, - std::vector<System::CMakeVariable>&& pass_variables); -} diff --git a/toolsrc/include/vcpkg/cmakevars.h b/toolsrc/include/vcpkg/cmakevars.h deleted file mode 100644 index 07c21bdfd..000000000 --- a/toolsrc/include/vcpkg/cmakevars.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/dependencies.h> -#include <vcpkg/fwd/portfileprovider.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/optional.h> - -#include <vcpkg/packagespec.h> - -namespace vcpkg::CMakeVars -{ - struct CMakeVarProvider - { - virtual ~CMakeVarProvider() = default; - - virtual Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars( - Triplet triplet) const = 0; - - virtual Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars( - const PackageSpec& spec) const = 0; - - virtual Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars( - const PackageSpec& spec) const = 0; - - virtual void load_generic_triplet_vars(Triplet triplet) const = 0; - - virtual void load_dep_info_vars(Span<const PackageSpec> specs) const = 0; - - virtual void load_tag_vars(Span<const FullPackageSpec> specs, - const PortFileProvider::PortFileProvider& port_provider) const = 0; - - void load_tag_vars(const vcpkg::Dependencies::ActionPlan& action_plan, - const PortFileProvider::PortFileProvider& port_provider) const; - }; - - std::unique_ptr<CMakeVarProvider> make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg/commands.add-version.h b/toolsrc/include/vcpkg/commands.add-version.h deleted file mode 100644 index 8b9e0336e..000000000 --- a/toolsrc/include/vcpkg/commands.add-version.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::AddVersion -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct AddVersionCommand : PathsCommand - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -}
\ No newline at end of file diff --git a/toolsrc/include/vcpkg/commands.autocomplete.h b/toolsrc/include/vcpkg/commands.autocomplete.h deleted file mode 100644 index 4f518d0f0..000000000 --- a/toolsrc/include/vcpkg/commands.autocomplete.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Autocomplete -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct AutocompleteCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.buildexternal.h b/toolsrc/include/vcpkg/commands.buildexternal.h deleted file mode 100644 index b4e1aa669..000000000 --- a/toolsrc/include/vcpkg/commands.buildexternal.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::BuildExternal -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct BuildExternalCommand : TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.cache.h b/toolsrc/include/vcpkg/commands.cache.h deleted file mode 100644 index 5d18a3f99..000000000 --- a/toolsrc/include/vcpkg/commands.cache.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Cache -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct CacheCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.ci.h b/toolsrc/include/vcpkg/commands.ci.h deleted file mode 100644 index 4657741c9..000000000 --- a/toolsrc/include/vcpkg/commands.ci.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::CI -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct CICommand : TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.ciclean.h b/toolsrc/include/vcpkg/commands.ciclean.h deleted file mode 100644 index ed9e2f005..000000000 --- a/toolsrc/include/vcpkg/commands.ciclean.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::CIClean -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct CICleanCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.civerifyversions.h b/toolsrc/include/vcpkg/commands.civerifyversions.h deleted file mode 100644 index 17d8f5613..000000000 --- a/toolsrc/include/vcpkg/commands.civerifyversions.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::CIVerifyVersions -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct CIVerifyVersionsCommand : PathsCommand - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -}
\ No newline at end of file diff --git a/toolsrc/include/vcpkg/commands.contact.h b/toolsrc/include/vcpkg/commands.contact.h deleted file mode 100644 index f0af41c14..000000000 --- a/toolsrc/include/vcpkg/commands.contact.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Contact -{ - extern const CommandStructure COMMAND_STRUCTURE; - const std::string& email(); - void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs); - - struct ContactCommand : BasicCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.create.h b/toolsrc/include/vcpkg/commands.create.h deleted file mode 100644 index a8eb99b27..000000000 --- a/toolsrc/include/vcpkg/commands.create.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Create -{ - extern const CommandStructure COMMAND_STRUCTURE; - int perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct CreateCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.dependinfo.h b/toolsrc/include/vcpkg/commands.dependinfo.h deleted file mode 100644 index 81301b6d9..000000000 --- a/toolsrc/include/vcpkg/commands.dependinfo.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::DependInfo -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct DependInfoCommand : TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.edit.h b/toolsrc/include/vcpkg/commands.edit.h deleted file mode 100644 index 9a37d2ee3..000000000 --- a/toolsrc/include/vcpkg/commands.edit.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Edit -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct EditCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.env.h b/toolsrc/include/vcpkg/commands.env.h deleted file mode 100644 index 5ba58d081..000000000 --- a/toolsrc/include/vcpkg/commands.env.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Env -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct EnvCommand : TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.fetch.h b/toolsrc/include/vcpkg/commands.fetch.h deleted file mode 100644 index c41965903..000000000 --- a/toolsrc/include/vcpkg/commands.fetch.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Fetch -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct FetchCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.format-manifest.h b/toolsrc/include/vcpkg/commands.format-manifest.h deleted file mode 100644 index 1317bbc70..000000000 --- a/toolsrc/include/vcpkg/commands.format-manifest.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::FormatManifest -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct FormatManifestCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h deleted file mode 100644 index dfabb809f..000000000 --- a/toolsrc/include/vcpkg/commands.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands -{ - template<class T> - struct PackageNameAndFunction - { - std::string name; - T function; - }; - - Span<const PackageNameAndFunction<const BasicCommand*>> get_available_basic_commands(); - Span<const PackageNameAndFunction<const PathsCommand*>> get_available_paths_commands(); - Span<const PackageNameAndFunction<const TripletCommand*>> get_available_triplet_commands(); - - template<typename T> - T find(StringView command_name, Span<const PackageNameAndFunction<T>> available_commands) - { - for (const PackageNameAndFunction<T>& cmd : available_commands) - { - if (cmd.name == command_name) - { - return cmd.function; - } - } - - // not found - return nullptr; - } -} diff --git a/toolsrc/include/vcpkg/commands.hash.h b/toolsrc/include/vcpkg/commands.hash.h deleted file mode 100644 index aa9b11c05..000000000 --- a/toolsrc/include/vcpkg/commands.hash.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Hash -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct HashCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.info.h b/toolsrc/include/vcpkg/commands.info.h deleted file mode 100644 index 556d1eb01..000000000 --- a/toolsrc/include/vcpkg/commands.info.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Info -{ - extern const CommandStructure COMMAND_STRUCTURE; - - struct InfoCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.integrate.h b/toolsrc/include/vcpkg/commands.integrate.h deleted file mode 100644 index 162f49a3c..000000000 --- a/toolsrc/include/vcpkg/commands.integrate.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Integrate -{ - extern const CommandStructure COMMAND_STRUCTURE; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - void append_helpstring(HelpTableFormatter& table); - std::string get_helpstring(); - - struct IntegrateCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.interface.h b/toolsrc/include/vcpkg/commands.interface.h deleted file mode 100644 index c8bc14ca9..000000000 --- a/toolsrc/include/vcpkg/commands.interface.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgcmdarguments.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/files.h> - -#include <vcpkg/triplet.h> - -namespace vcpkg::Commands -{ - enum class DryRun : bool - { - No, - Yes, - }; - - struct BasicCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const = 0; - virtual ~BasicCommand() = default; - }; - - struct PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const = 0; - virtual ~PathsCommand() = default; - }; - - struct TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const = 0; - virtual ~TripletCommand() = default; - }; -} diff --git a/toolsrc/include/vcpkg/commands.list.h b/toolsrc/include/vcpkg/commands.list.h deleted file mode 100644 index 77a5f41bd..000000000 --- a/toolsrc/include/vcpkg/commands.list.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::List -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct ListCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.owns.h b/toolsrc/include/vcpkg/commands.owns.h deleted file mode 100644 index 39037649d..000000000 --- a/toolsrc/include/vcpkg/commands.owns.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> -#include <vcpkg/vcpkgcmdarguments.h> - -namespace vcpkg::Commands::Owns -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct OwnsCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.porthistory.h b/toolsrc/include/vcpkg/commands.porthistory.h deleted file mode 100644 index 3ca532532..000000000 --- a/toolsrc/include/vcpkg/commands.porthistory.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::PortHistory -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct PortHistoryCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.portsdiff.h b/toolsrc/include/vcpkg/commands.portsdiff.h deleted file mode 100644 index 8cd1b094c..000000000 --- a/toolsrc/include/vcpkg/commands.portsdiff.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::PortsDiff -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct PortsDiffCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.search.h b/toolsrc/include/vcpkg/commands.search.h deleted file mode 100644 index 530a3ac28..000000000 --- a/toolsrc/include/vcpkg/commands.search.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> -#include <vcpkg/vcpkgcmdarguments.h> - -namespace vcpkg::Commands::Search -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct SearchCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.setinstalled.h b/toolsrc/include/vcpkg/commands.setinstalled.h deleted file mode 100644 index c5723669b..000000000 --- a/toolsrc/include/vcpkg/commands.setinstalled.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include <vcpkg/cmakevars.h> -#include <vcpkg/commands.interface.h> -#include <vcpkg/portfileprovider.h> - -namespace vcpkg::Commands::SetInstalled -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit_ex(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - const PortFileProvider::PathsPortFileProvider& provider, - IBinaryProvider& binary_provider, - const CMakeVars::CMakeVarProvider& cmake_vars, - Dependencies::ActionPlan action_plan, - DryRun dry_run, - const Optional<fs::path>& pkgsconfig_path); - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct SetInstalledCommand : TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.upgrade.h b/toolsrc/include/vcpkg/commands.upgrade.h deleted file mode 100644 index 340a70c97..000000000 --- a/toolsrc/include/vcpkg/commands.upgrade.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Upgrade -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct UpgradeCommand : TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.upload-metrics.h b/toolsrc/include/vcpkg/commands.upload-metrics.h deleted file mode 100644 index 4cfb66092..000000000 --- a/toolsrc/include/vcpkg/commands.upload-metrics.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::UploadMetrics -{ - extern const CommandStructure COMMAND_STRUCTURE; - struct UploadMetricsCommand : BasicCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.version.h b/toolsrc/include/vcpkg/commands.version.h deleted file mode 100644 index 6deb5167d..000000000 --- a/toolsrc/include/vcpkg/commands.version.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::Version -{ - const char* base_version() noexcept; - const char* version() noexcept; - void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs); - - struct VersionCommand : BasicCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, Files::Filesystem& fs) const override; - }; -} diff --git a/toolsrc/include/vcpkg/commands.xvsinstances.h b/toolsrc/include/vcpkg/commands.xvsinstances.h deleted file mode 100644 index fc7a39b98..000000000 --- a/toolsrc/include/vcpkg/commands.xvsinstances.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Commands::X_VSInstances -{ - extern const CommandStructure COMMAND_STRUCTURE; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct VSInstancesCommand : PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/configuration.h b/toolsrc/include/vcpkg/configuration.h deleted file mode 100644 index 6d6a9b1f4..000000000 --- a/toolsrc/include/vcpkg/configuration.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/configuration.h> -#include <vcpkg/fwd/vcpkgcmdarguments.h> - -#include <vcpkg/base/files.h> -#include <vcpkg/base/json.h> - -#include <vcpkg/registries.h> - -namespace vcpkg -{ - struct Configuration - { - // This member is set up via two different configuration options, - // `registries` and `default_registry`. The fall back logic is - // taken care of in RegistrySet. - RegistrySet registry_set; - - void validate_feature_flags(const FeatureFlagSettings& flags); - }; - - std::unique_ptr<Json::IDeserializer<Configuration>> make_configuration_deserializer( - const fs::path& config_directory); -} diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h deleted file mode 100644 index 1b1a7748b..000000000 --- a/toolsrc/include/vcpkg/dependencies.h +++ /dev/null @@ -1,188 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/cmakevars.h> -#include <vcpkg/fwd/portfileprovider.h> - -#include <vcpkg/base/optional.h> -#include <vcpkg/base/util.h> - -#include <vcpkg/build.h> -#include <vcpkg/packagespec.h> - -#include <functional> -#include <map> -#include <vector> - -namespace vcpkg::Graphs -{ - struct Randomizer; -} - -namespace vcpkg -{ - struct StatusParagraphs; -} - -namespace vcpkg::Dependencies -{ - enum class RequestType - { - UNKNOWN, - USER_REQUESTED, - AUTO_SELECTED - }; - - std::string to_output_string(RequestType request_type, - const CStringView s, - const Build::BuildPackageOptions& options); - std::string to_output_string(RequestType request_type, const CStringView s); - - enum class InstallPlanType - { - UNKNOWN, - BUILD_AND_INSTALL, - ALREADY_INSTALLED, - EXCLUDED - }; - - struct InstallPlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); - - InstallPlanAction() noexcept; - - InstallPlanAction(InstalledPackageView&& spghs, const RequestType& request_type); - - InstallPlanAction(const PackageSpec& spec, - const SourceControlFileLocation& scfl, - const RequestType& request_type, - std::map<std::string, std::vector<FeatureSpec>>&& dependencies); - - std::string displayname() const; - const std::string& public_abi() const; - bool has_package_abi() const; - Optional<const std::string&> package_abi() const; - const Build::PreBuildInfo& pre_build_info(LineInfo linfo) const; - - PackageSpec spec; - - Optional<const SourceControlFileLocation&> source_control_file_location; - Optional<InstalledPackageView> installed_package; - - InstallPlanType plan_type; - RequestType request_type; - Build::BuildPackageOptions build_options; - - std::map<std::string, std::vector<FeatureSpec>> feature_dependencies; - std::vector<PackageSpec> package_dependencies; - std::vector<std::string> feature_list; - - Optional<Build::AbiInfo> abi_info; - }; - - enum class RemovePlanType - { - UNKNOWN, - NOT_INSTALLED, - REMOVE - }; - - struct RemovePlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); - - RemovePlanAction() noexcept; - RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); - - PackageSpec spec; - RemovePlanType plan_type; - RequestType request_type; - }; - - struct ActionPlan - { - bool empty() const { return remove_actions.empty() && already_installed.empty() && install_actions.empty(); } - size_t size() const { return remove_actions.size() + already_installed.size() + install_actions.size(); } - - std::vector<RemovePlanAction> remove_actions; - std::vector<InstallPlanAction> already_installed; - std::vector<InstallPlanAction> install_actions; - }; - - enum class ExportPlanType - { - UNKNOWN, - NOT_BUILT, - ALREADY_BUILT - }; - - struct ExportPlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); - - ExportPlanAction() noexcept; - ExportPlanAction(const PackageSpec& spec, - InstalledPackageView&& installed_package, - const RequestType& request_type); - - ExportPlanAction(const PackageSpec& spec, const RequestType& request_type); - - PackageSpec spec; - ExportPlanType plan_type; - RequestType request_type; - - Optional<const BinaryParagraph&> core_paragraph() const; - std::vector<PackageSpec> dependencies() const; - - private: - Optional<InstalledPackageView> m_installed_package; - }; - - struct ClusterGraph; - - struct CreateInstallPlanOptions - { - Graphs::Randomizer* randomizer = nullptr; - }; - - std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, - const StatusParagraphs& status_db); - - std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs, - const StatusParagraphs& status_db); - - /// <summary>Figure out which actions are required to install features specifications in `specs`.</summary> - /// <param name="provider">Contains the ports of the current environment.</param> - /// <param name="specs">Feature specifications to resolve dependencies for.</param> - /// <param name="status_db">Status of installed packages in the current environment.</param> - ActionPlan create_feature_install_plan(const PortFileProvider::PortFileProvider& provider, - const CMakeVars::CMakeVarProvider& var_provider, - const std::vector<FullPackageSpec>& specs, - const StatusParagraphs& status_db, - const CreateInstallPlanOptions& options = {}); - - ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& provider, - const CMakeVars::CMakeVarProvider& var_provider, - const std::vector<PackageSpec>& specs, - const StatusParagraphs& status_db, - const CreateInstallPlanOptions& options = {}); - - // `features` should have "default" instead of missing "core". This is only exposed for testing purposes. - std::vector<FullPackageSpec> resolve_deps_as_top_level(const SourceControlFile& scf, - Triplet triplet, - std::vector<std::string> features, - CMakeVars::CMakeVarProvider& var_provider); - - /// <param name="provider">Contains the ports of the current environment.</param> - /// <param name="specs">Feature specifications to resolve dependencies for.</param> - /// <param name="status_db">Status of installed packages in the current environment.</param> - ExpectedS<ActionPlan> create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& vprovider, - const PortFileProvider::IBaselineProvider& bprovider, - const PortFileProvider::IOverlayProvider& oprovider, - const CMakeVars::CMakeVarProvider& var_provider, - const std::vector<Dependency>& deps, - const std::vector<DependencyOverride>& overrides, - const PackageSpec& toplevel); - - void print_plan(const ActionPlan& action_plan, const bool is_recursive = true, const fs::path& vcpkg_root_dir = {}); -} diff --git a/toolsrc/include/vcpkg/export.chocolatey.h b/toolsrc/include/vcpkg/export.chocolatey.h deleted file mode 100644 index 26238cf43..000000000 --- a/toolsrc/include/vcpkg/export.chocolatey.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/dependencies.h> - -#include <vector> - -namespace vcpkg::Export::Chocolatey -{ - struct Options - { - Optional<std::string> maybe_maintainer; - Optional<std::string> maybe_version_suffix; - }; - - void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan, - const VcpkgPaths& paths, - const Options& chocolatey_options); -} diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h deleted file mode 100644 index 0dd5b1aac..000000000 --- a/toolsrc/include/vcpkg/export.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Export -{ - extern const CommandStructure COMMAND_STRUCTURE; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); - - struct ExportCommand : Commands::TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/export.ifw.h b/toolsrc/include/vcpkg/export.ifw.h deleted file mode 100644 index 0fe07227c..000000000 --- a/toolsrc/include/vcpkg/export.ifw.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/dependencies.h> - -#include <string> -#include <vector> - -namespace vcpkg::Export::IFW -{ - struct Options - { - Optional<std::string> maybe_repository_url; - Optional<std::string> maybe_packages_dir_path; - Optional<std::string> maybe_repository_dir_path; - Optional<std::string> maybe_config_file_path; - Optional<std::string> maybe_installer_file_path; - }; - - void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan, - const std::string& export_id, - const Options& ifw_options, - const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg/export.prefab.h b/toolsrc/include/vcpkg/export.prefab.h deleted file mode 100644 index 2038949be..000000000 --- a/toolsrc/include/vcpkg/export.prefab.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/system.h> - -#include <vcpkg/dependencies.h> - -#include <vector> - -namespace vcpkg::Export::Prefab -{ - constexpr int kFragmentSize = 3; - - struct Options - { - Optional<std::string> maybe_group_id; - Optional<std::string> maybe_artifact_id; - Optional<std::string> maybe_version; - Optional<std::string> maybe_min_sdk; - Optional<std::string> maybe_target_sdk; - bool enable_maven = false; - bool enable_debug = false; - }; - struct NdkVersion - { - NdkVersion(int _major, int _minor, int _patch) : m_major{_major}, m_minor{_minor}, m_patch{_patch} { } - int major() { return this->m_major; } - int minor() { return this->m_minor; } - int patch() { return this->m_patch; } - std::string to_string(); - void to_string(std::string& out); - - private: - int m_major; - int m_minor; - int m_patch; - }; - - struct ABIMetadata - { - std::string abi; - int api; - int ndk; - std::string stl; - std::string to_string(); - }; - - struct PlatformModuleMetadata - { - std::vector<std::string> export_libraries; - std::string library_name; - std::string to_json(); - }; - - struct ModuleMetadata - { - std::vector<std::string> export_libraries; - std::string library_name; - PlatformModuleMetadata android; - std::string to_json(); - }; - - struct PackageMetadata - { - std::string name; - int schema; - std::vector<std::string> dependencies; - std::string version; - std::string to_json(); - }; - - void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan, - const VcpkgPaths& paths, - const Options& prefab_options, - const Triplet& triplet); - Optional<std::string> find_ndk_version(const std::string& content); - Optional<NdkVersion> to_version(const std::string& version); -} diff --git a/toolsrc/include/vcpkg/fwd/build.h b/toolsrc/include/vcpkg/fwd/build.h deleted file mode 100644 index c7f74513f..000000000 --- a/toolsrc/include/vcpkg/fwd/build.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace vcpkg::Build -{ - struct BuildInfo; - struct PreBuildInfo; -} diff --git a/toolsrc/include/vcpkg/fwd/cmakevars.h b/toolsrc/include/vcpkg/fwd/cmakevars.h deleted file mode 100644 index e1dade368..000000000 --- a/toolsrc/include/vcpkg/fwd/cmakevars.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace vcpkg::CMakeVars -{ - struct CMakeVarProvider; -} diff --git a/toolsrc/include/vcpkg/fwd/configuration.h b/toolsrc/include/vcpkg/fwd/configuration.h deleted file mode 100644 index 5fa9cee34..000000000 --- a/toolsrc/include/vcpkg/fwd/configuration.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct Configuration; -} diff --git a/toolsrc/include/vcpkg/fwd/dependencies.h b/toolsrc/include/vcpkg/fwd/dependencies.h deleted file mode 100644 index 08e824b4c..000000000 --- a/toolsrc/include/vcpkg/fwd/dependencies.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace vcpkg::Dependencies -{ - struct InstallPlanAction; - struct ActionPlan; -} diff --git a/toolsrc/include/vcpkg/fwd/packagespec.h b/toolsrc/include/vcpkg/fwd/packagespec.h deleted file mode 100644 index 2f5719e1b..000000000 --- a/toolsrc/include/vcpkg/fwd/packagespec.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct PackageSpec; -} diff --git a/toolsrc/include/vcpkg/fwd/portfileprovider.h b/toolsrc/include/vcpkg/fwd/portfileprovider.h deleted file mode 100644 index a75cfc137..000000000 --- a/toolsrc/include/vcpkg/fwd/portfileprovider.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace vcpkg::PortFileProvider -{ - struct PortFileProvider; - struct PathsPortFileProvider; - struct IVersionedPortfileProvider; - struct IBaselineProvider; - struct IOverlayProvider; -} diff --git a/toolsrc/include/vcpkg/fwd/registries.h b/toolsrc/include/vcpkg/fwd/registries.h deleted file mode 100644 index 73783cc6b..000000000 --- a/toolsrc/include/vcpkg/fwd/registries.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct RegistryEntry; - struct RegistryImplementation; - struct Registry; - struct RegistrySet; -} diff --git a/toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h deleted file mode 100644 index 152627128..000000000 --- a/toolsrc/include/vcpkg/fwd/vcpkgcmdarguments.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct ParsedArguments; - struct CommandSwitch; - struct CommandSetting; - struct CommandMultiSetting; - struct CommandOptionsStructure; - struct CommandStructure; - struct HelpTableFormatter; - struct VcpkgCmdArguments; - struct FeatureFlagSettings; -} diff --git a/toolsrc/include/vcpkg/fwd/vcpkgpaths.h b/toolsrc/include/vcpkg/fwd/vcpkgpaths.h deleted file mode 100644 index 79655bf4a..000000000 --- a/toolsrc/include/vcpkg/fwd/vcpkgpaths.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct ToolsetArchOption; - struct Toolset; - struct VcpkgPaths; -} diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h deleted file mode 100644 index 44c34f25c..000000000 --- a/toolsrc/include/vcpkg/globalstate.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/lockguarded.h> - -#include <vcpkg/base/chrono.h> - -#include <atomic> -#include <string> - -namespace vcpkg -{ - struct GlobalState - { - static Util::LockGuarded<Chrono::ElapsedTimer> timer; - static Util::LockGuarded<std::string> g_surveydate; - - static std::atomic<int> g_init_console_cp; - static std::atomic<int> g_init_console_output_cp; - static std::atomic<bool> g_init_console_initialized; - }; -} diff --git a/toolsrc/include/vcpkg/help.h b/toolsrc/include/vcpkg/help.h deleted file mode 100644 index 3e1ef381e..000000000 --- a/toolsrc/include/vcpkg/help.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include <vcpkg/commands.interface.h> - -#include <string> - -namespace vcpkg::Help -{ - extern const CommandStructure COMMAND_STRUCTURE; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - void help_topic_valid_triplet(const VcpkgPaths& paths); - - struct HelpCommand : Commands::PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h deleted file mode 100644 index 917b5af10..000000000 --- a/toolsrc/include/vcpkg/input.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <vcpkg/packagespec.h> - -namespace vcpkg::Input -{ - PackageSpec check_and_get_package_spec(std::string&& spec_string, - Triplet default_triplet, - CStringView example_text); - FullPackageSpec check_and_get_full_package_spec(std::string&& spec_string, - Triplet default_triplet, - CStringView example_text); - - void check_triplet(Triplet t, const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h deleted file mode 100644 index 8187735c5..000000000 --- a/toolsrc/include/vcpkg/install.h +++ /dev/null @@ -1,116 +0,0 @@ -#pragma once - -#include <vcpkg/base/chrono.h> - -#include <vcpkg/binaryparagraph.h> -#include <vcpkg/build.h> -#include <vcpkg/dependencies.h> -#include <vcpkg/vcpkgcmdarguments.h> -#include <vcpkg/vcpkgpaths.h> - -#include <vector> - -namespace vcpkg::Install -{ - enum class KeepGoing - { - NO = 0, - YES - }; - - inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } - - struct SpecSummary - { - SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action); - - const BinaryParagraph* get_binary_paragraph() const; - - PackageSpec spec; - Build::ExtendedBuildResult build_result; - vcpkg::Chrono::ElapsedTime timing; - - const Dependencies::InstallPlanAction* action; - }; - - struct InstallSummary - { - std::vector<SpecSummary> results; - std::string total_elapsed_time; - - void print() const; - std::string xunit_results() const; - }; - - struct InstallDir - { - static InstallDir from_destination_root(const fs::path& destination_root, - const std::string& destination_subdirectory, - const fs::path& listfile); - - private: - fs::path m_destination; - std::string m_destination_subdirectory; - fs::path m_listfile; - - public: - const fs::path& destination() const; - const std::string& destination_subdirectory() const; - const fs::path& listfile() const; - }; - - Build::ExtendedBuildResult perform_install_plan_action(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Dependencies::InstallPlanAction& action, - StatusParagraphs& status_db, - const CMakeVars::CMakeVarProvider& var_provider); - - enum class InstallResult - { - FILE_CONFLICTS, - SUCCESS, - }; - - std::vector<std::string> get_all_port_names(const VcpkgPaths& paths); - - void install_package_and_write_listfile(const VcpkgPaths& paths, const PackageSpec& spec, const InstallDir& dirs); - - void install_files_and_write_listfile(Files::Filesystem& fs, - const fs::path& source_dir, - const std::vector<fs::path>& files, - const InstallDir& destination_dir); - - InstallResult install_package(const VcpkgPaths& paths, - const BinaryControlFile& binary_paragraph, - StatusParagraphs* status_db); - - InstallSummary perform(const VcpkgCmdArguments& args, - Dependencies::ActionPlan& action_plan, - const KeepGoing keep_going, - const VcpkgPaths& paths, - StatusParagraphs& status_db, - IBinaryProvider& binaryprovider, - const Build::IBuildLogsRecorder& build_logs_recorder, - const CMakeVars::CMakeVarProvider& var_provider); - - struct CMakeUsageInfo - { - std::string message; - bool usage_file = false; - Optional<bool> header_only; - std::map<std::string, std::vector<std::string>> cmake_targets_map; - }; - - CMakeUsageInfo get_cmake_usage(const BinaryParagraph& bpgh, const VcpkgPaths& paths); - - extern const CommandStructure COMMAND_STRUCTURE; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); - - struct InstallCommand : Commands::TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h deleted file mode 100644 index b1a5e6104..000000000 --- a/toolsrc/include/vcpkg/metrics.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> -#include <vcpkg/base/lockguarded.h> -#include <vcpkg/base/util.h> - -#include <string> - -namespace vcpkg::Metrics -{ - struct Metrics : Util::ResourceBase - { - void set_send_metrics(bool should_send_metrics); - void set_print_metrics(bool should_print_metrics); - void set_disabled(bool disabled); - void set_user_information(const std::string& user_id, const std::string& first_use_time); - static void init_user_information(std::string& user_id, std::string& first_use_time); - - void track_metric(const std::string& name, double value); - void track_buildtime(const std::string& name, double value); - void track_property(const std::string& name, const std::string& value); - void track_feature(const std::string& feature, bool value); - - bool metrics_enabled(); - - void upload(const std::string& payload); - void flush(Files::Filesystem& fs); - }; - - extern Util::LockGuarded<Metrics> g_metrics; - - std::string get_MAC_user(); -} diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h deleted file mode 100644 index 43be57e68..000000000 --- a/toolsrc/include/vcpkg/packagespec.h +++ /dev/null @@ -1,226 +0,0 @@ -#pragma once - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/json.h> -#include <vcpkg/base/optional.h> - -#include <vcpkg/platform-expression.h> -#include <vcpkg/triplet.h> -#include <vcpkg/versions.h> - -namespace vcpkg::Parse -{ - struct ParserBase; -} - -namespace vcpkg -{ - /// - /// <summary> - /// Full specification of a package. Contains all information to reference - /// a specific package. - /// </summary> - /// - struct PackageSpec - { - PackageSpec() = default; - PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) { } - - static std::vector<PackageSpec> to_package_specs(const std::vector<std::string>& ports, Triplet triplet); - - const std::string& name() const; - - Triplet triplet() const; - - std::string dir() const; - - std::string to_string() const; - void to_string(std::string& s) const; - - bool operator<(const PackageSpec& other) const - { - if (name() < other.name()) return true; - if (name() > other.name()) return false; - return triplet() < other.triplet(); - } - - private: - std::string m_name; - Triplet m_triplet; - }; - - bool operator==(const PackageSpec& left, const PackageSpec& right); - inline bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); } - - /// - /// <summary> - /// Full specification of a feature. Contains all information to reference - /// a single feature in a specific package. - /// </summary> - /// - struct FeatureSpec - { - FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) { } - - const std::string& name() const { return m_spec.name(); } - const std::string& feature() const { return m_feature; } - Triplet triplet() const { return m_spec.triplet(); } - - const PackageSpec& spec() const { return m_spec; } - - std::string to_string() const; - void to_string(std::string& out) const; - - bool operator<(const FeatureSpec& other) const - { - if (name() < other.name()) return true; - if (name() > other.name()) return false; - if (feature() < other.feature()) return true; - if (feature() > other.feature()) return false; - return triplet() < other.triplet(); - } - - bool operator==(const FeatureSpec& other) const - { - return triplet() == other.triplet() && name() == other.name() && feature() == other.feature(); - } - - bool operator!=(const FeatureSpec& other) const { return !(*this == other); } - - private: - PackageSpec m_spec; - std::string m_feature; - }; - - /// - /// <summary> - /// Full specification of a package. Contains all information to reference - /// a collection of features in a single package. - /// </summary> - /// - struct FullPackageSpec - { - PackageSpec package_spec; - std::vector<std::string> features; - - FullPackageSpec() = default; - explicit FullPackageSpec(PackageSpec spec, std::vector<std::string> features = {}) - : package_spec(std::move(spec)), features(std::move(features)) - { - } - - std::vector<FeatureSpec> to_feature_specs(const std::vector<std::string>& default_features, - const std::vector<std::string>& all_features) const; - - static ExpectedS<FullPackageSpec> from_string(const std::string& spec_as_string, Triplet default_triplet); - - bool operator==(const FullPackageSpec& o) const - { - return package_spec == o.package_spec && features == o.features; - } - bool operator!=(const FullPackageSpec& o) const { return !(*this == o); } - }; - - /// - /// <summary> - /// Contains all information to reference a collection of features in a single package by their names. - /// </summary> - /// - struct Features - { - std::string name; - std::vector<std::string> features; - - static ExpectedS<Features> from_string(const std::string& input); - }; - - struct DependencyConstraint - { - Versions::Constraint::Type type = Versions::Constraint::Type::None; - std::string value; - int port_version = 0; - - friend bool operator==(const DependencyConstraint& lhs, const DependencyConstraint& rhs); - friend bool operator!=(const DependencyConstraint& lhs, const DependencyConstraint& rhs) - { - return !(lhs == rhs); - } - }; - - struct Dependency - { - std::string name; - std::vector<std::string> features; - PlatformExpression::Expr platform; - DependencyConstraint constraint; - - Json::Object extra_info; - - friend bool operator==(const Dependency& lhs, const Dependency& rhs); - friend bool operator!=(const Dependency& lhs, const Dependency& rhs) { return !(lhs == rhs); } - }; - - struct DependencyOverride - { - std::string name; - std::string version; - int port_version = 0; - Versions::Scheme version_scheme = Versions::Scheme::String; - - Json::Object extra_info; - - friend bool operator==(const DependencyOverride& lhs, const DependencyOverride& rhs); - friend bool operator!=(const DependencyOverride& lhs, const DependencyOverride& rhs) { return !(lhs == rhs); } - }; - - struct ParsedQualifiedSpecifier - { - std::string name; - Optional<std::vector<std::string>> features; - Optional<std::string> triplet; - Optional<PlatformExpression::Expr> platform; - }; - - Optional<std::string> parse_feature_name(Parse::ParserBase& parser); - Optional<std::string> parse_package_name(Parse::ParserBase& parser); - ExpectedS<ParsedQualifiedSpecifier> parse_qualified_specifier(StringView input); - Optional<ParsedQualifiedSpecifier> parse_qualified_specifier(Parse::ParserBase& parser); -} - -namespace std -{ - template<> - struct hash<vcpkg::PackageSpec> - { - size_t operator()(const vcpkg::PackageSpec& value) const - { - size_t hash = 17; - hash = hash * 31 + std::hash<std::string>()(value.name()); - hash = hash * 31 + std::hash<vcpkg::Triplet>()(value.triplet()); - return hash; - } - }; - - template<> - struct equal_to<vcpkg::PackageSpec> - { - bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } - }; - - template<> - struct hash<vcpkg::FeatureSpec> - { - size_t operator()(const vcpkg::FeatureSpec& value) const - { - size_t hash = std::hash<vcpkg::PackageSpec>()(value.spec()); - hash = hash * 31 + std::hash<std::string>()(value.feature()); - return hash; - } - }; - - template<> - struct equal_to<vcpkg::FeatureSpec> - { - bool operator()(const vcpkg::FeatureSpec& left, const vcpkg::FeatureSpec& right) const { return left == right; } - }; -} diff --git a/toolsrc/include/vcpkg/paragraphparser.h b/toolsrc/include/vcpkg/paragraphparser.h deleted file mode 100644 index 22060f32f..000000000 --- a/toolsrc/include/vcpkg/paragraphparser.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include <vcpkg/base/expected.h> - -#include <vcpkg/packagespec.h> -#include <vcpkg/textrowcol.h> - -#include <map> -#include <memory> -#include <string> -#include <unordered_map> -#include <vector> - -namespace vcpkg::Parse -{ - struct ParseControlErrorInfo - { - std::string name; - std::map<std::string, std::vector<std::string>> missing_fields; - std::map<std::string, std::vector<std::string>> extra_fields; - std::map<std::string, std::string> expected_types; - std::map<std::string, std::vector<std::string>> mutually_exclusive_fields; - std::vector<std::string> other_errors; - std::string error; - - bool has_error() const - { - return !missing_fields.empty() || !extra_fields.empty() || !expected_types.empty() || - !other_errors.empty() || !error.empty(); - } - }; - - template<class P> - using ParseExpected = vcpkg::ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>; - - using Paragraph = std::unordered_map<std::string, std::pair<std::string, TextRowCol>>; - - struct ParagraphParser - { - ParagraphParser(Paragraph&& fields) : fields(std::move(fields)) { } - - std::string required_field(const std::string& fieldname); - void required_field(const std::string& fieldname, std::string& out); - void required_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out); - - std::string optional_field(const std::string& fieldname); - void optional_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out); - - void add_type_error(const std::string& fieldname, const char* type) { expected_types[fieldname] = type; } - - std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const; - - private: - Paragraph&& fields; - std::vector<std::string> missing_fields; - std::map<std::string, std::string> expected_types; - }; - - ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str, - StringView origin = "<unknown>", - TextRowCol textrowcol = {}); - ExpectedS<std::vector<ParsedQualifiedSpecifier>> parse_qualified_specifier_list(const std::string& str, - StringView origin = "<unknown>", - TextRowCol textrowcol = {}); - ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str, - StringView origin = "<unknown>", - TextRowCol textrowcol = {}); -} diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h deleted file mode 100644 index b376eef81..000000000 --- a/toolsrc/include/vcpkg/paragraphs.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/expected.h> - -#include <vcpkg/binaryparagraph.h> - -namespace vckpg::Parse -{ - struct ParseControlErrorInfo; -} - -namespace vcpkg::Paragraphs -{ - using Paragraph = Parse::Paragraph; - - ExpectedS<Paragraph> parse_single_paragraph(const std::string& str, const std::string& origin); - ExpectedS<Paragraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); - - ExpectedS<std::vector<Paragraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); - ExpectedS<std::vector<Paragraph>> get_paragraphs_text(const std::string& text, const std::string& origin); - - ExpectedS<std::vector<Paragraph>> parse_paragraphs(const std::string& str, const std::string& origin); - - bool is_port_directory(const Files::Filesystem& fs, const fs::path& path); - - Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path); - Parse::ParseExpected<SourceControlFile> try_load_port_text(const std::string& text, - const std::string& origin, - bool is_manifest); - - ExpectedS<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); - - struct LoadResults - { - std::vector<SourceControlFileLocation> paragraphs; - std::vector<std::unique_ptr<Parse::ParseControlErrorInfo>> errors; - }; - - // this allows one to pass this around as an overload set to stuff like `Util::fmap`, - // as opposed to making it a function - constexpr struct - { - const std::string& operator()(const SourceControlFileLocation* loc) const - { - return (*this)(*loc->source_control_file); - } - const std::string& operator()(const SourceControlFileLocation& loc) const - { - return (*this)(*loc.source_control_file); - } - const std::string& operator()(const SourceControlFile& scf) const { return scf.core_paragraph->name; } - } get_name_of_control_file; - - LoadResults try_load_all_registry_ports(const VcpkgPaths& paths); - - std::vector<SourceControlFileLocation> load_all_registry_ports(const VcpkgPaths& paths); - std::vector<SourceControlFileLocation> load_overlay_ports(const Files::Filesystem& fs, const fs::path& dir); -} diff --git a/toolsrc/include/vcpkg/platform-expression.h b/toolsrc/include/vcpkg/platform-expression.h deleted file mode 100644 index 5de13b7a2..000000000 --- a/toolsrc/include/vcpkg/platform-expression.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/stringview.h> - -#include <string> -#include <unordered_map> - -namespace vcpkg::PlatformExpression -{ - // map of cmake variables and their values. - using Context = std::unordered_map<std::string, std::string>; - - namespace detail - { - struct ExprImpl; - } - struct Expr - { - static Expr Identifier(StringView id); - static Expr Not(Expr&& e); - static Expr And(std::vector<Expr>&& exprs); - static Expr Or(std::vector<Expr>&& exprs); - - // The empty expression is always true - static Expr Empty() { return Expr(); } - - // since ExprImpl is not yet defined, we need to define the ctor and dtor in the C++ file - Expr(); - Expr(const Expr&); - Expr(Expr&&); - Expr& operator=(const Expr& e); - Expr& operator=(Expr&&); - - explicit Expr(std::unique_ptr<detail::ExprImpl>&& e); - ~Expr(); - - bool evaluate(const Context& context) const; - bool is_empty() const { return !static_cast<bool>(underlying_); } - - // returns: - // - 0 for empty - // - 1 for identifiers - // - 1 + complexity(inner) for ! - // - 1 + sum(complexity(inner)) for & and | - int complexity() const; - - // these two are friends so that they're only findable via ADL - - // this does a structural equality, so, for example: - // !structurally_equal((x & y) & z, x & y & z) - // !structurally_equal((x & y) | z, (x | z) & (y | z)) - // even though these expressions are equivalent - friend bool structurally_equal(const Expr& lhs, const Expr& rhs); - - // returns 0 if and only if structurally_equal(lhs, rhs) - // Orders via the following: - // - If complexity(a) < complexity(b) => a < b - // - Otherwise, if to_string(a).size() < to_string(b).size() => a < b - // - Otherwise, if to_string(a) < to_string(b) => a < b - // - else, they must be structurally equal - friend int compare(const Expr& lhs, const Expr& rhs); - - friend std::string to_string(const Expr& expr); - - private: - std::unique_ptr<detail::ExprImpl> underlying_; - }; - - // Note: for backwards compatibility, in CONTROL files, - // multiple binary operators are allowed to be next to one another; i.e. - // (windows & arm) = (windows && arm) = (windows &&& arm), etc. - enum class MultipleBinaryOperators - { - Deny, - Allow, - }; - - // platform expression parses a platform expression; the EBNF of such is defined in - // /docs/maintainers/manifest-files.md#supports - ExpectedS<Expr> parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators); -} diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h deleted file mode 100644 index 979004f94..000000000 --- a/toolsrc/include/vcpkg/portfileprovider.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/util.h> - -#include <vcpkg/registries.h> -#include <vcpkg/sourceparagraph.h> -#include <vcpkg/versions.h> - -namespace vcpkg::PortFileProvider -{ - struct PortFileProvider - { - virtual ~PortFileProvider() = default; - virtual ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const = 0; - virtual std::vector<const SourceControlFileLocation*> load_all_control_files() const = 0; - }; - - struct MapPortFileProvider : Util::ResourceBase, PortFileProvider - { - explicit MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map); - ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override; - std::vector<const SourceControlFileLocation*> load_all_control_files() const override; - - private: - const std::unordered_map<std::string, SourceControlFileLocation>& ports; - }; - - struct IVersionedPortfileProvider - { - virtual View<VersionT> get_port_versions(StringView port_name) const = 0; - virtual ~IVersionedPortfileProvider() = default; - - virtual ExpectedS<const SourceControlFileLocation&> get_control_file( - const Versions::VersionSpec& version_spec) const = 0; - virtual void load_all_control_files(std::map<std::string, const SourceControlFileLocation*>& out) const = 0; - }; - - struct IBaselineProvider - { - virtual Optional<VersionT> get_baseline_version(StringView port_name) const = 0; - virtual ~IBaselineProvider() = default; - }; - - struct IOverlayProvider - { - virtual ~IOverlayProvider() = default; - virtual Optional<const SourceControlFileLocation&> get_control_file(StringView port_name) const = 0; - virtual void load_all_control_files(std::map<std::string, const SourceControlFileLocation*>& out) const = 0; - }; - - struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider - { - explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, const std::vector<std::string>& overlay_ports); - ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override; - std::vector<const SourceControlFileLocation*> load_all_control_files() const override; - - private: - std::unique_ptr<IBaselineProvider> m_baseline; - std::unique_ptr<IVersionedPortfileProvider> m_versioned; - std::unique_ptr<IOverlayProvider> m_overlay; - }; - - std::unique_ptr<IBaselineProvider> make_baseline_provider(const vcpkg::VcpkgPaths& paths); - std::unique_ptr<IVersionedPortfileProvider> make_versioned_portfile_provider(const vcpkg::VcpkgPaths& paths); - std::unique_ptr<IOverlayProvider> make_overlay_provider(const vcpkg::VcpkgPaths& paths, - View<std::string> overlay_ports); -} diff --git a/toolsrc/include/vcpkg/postbuildlint.buildtype.h b/toolsrc/include/vcpkg/postbuildlint.buildtype.h deleted file mode 100644 index 4d6da1494..000000000 --- a/toolsrc/include/vcpkg/postbuildlint.buildtype.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include <vcpkg/base/cstringview.h> - -#include <vcpkg/build.h> - -#include <array> -#include <regex> - -namespace vcpkg::PostBuildLint -{ - struct BuildType - { - enum class BackingEnum - { - DEBUG_STATIC = 1, - DEBUG_DYNAMIC, - RELEASE_STATIC, - RELEASE_DYNAMIC - }; - - static BuildType value_of(const Build::ConfigurationType& config, const Build::LinkageType& linkage); - - BuildType() = delete; - - constexpr BuildType(const BackingEnum backing_enum, - const Build::ConfigurationType config, - const Build::LinkageType linkage) - : backing_enum(backing_enum), m_config(config), m_linkage(linkage) - { - } - - constexpr operator BackingEnum() const { return backing_enum; } - - const Build::ConfigurationType& config() const; - const Build::LinkageType& linkage() const; - const std::regex& crt_regex() const; - const std::string& to_string() const; - - private: - BackingEnum backing_enum; - Build::ConfigurationType m_config; - Build::LinkageType m_linkage; - }; - - namespace BuildTypeC - { - using Build::LinkageType; - using BE = BuildType::BackingEnum; - - static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; - - static constexpr BuildType DEBUG_STATIC = { - BE::DEBUG_STATIC, Build::ConfigurationType::DEBUG, LinkageType::STATIC}; - static constexpr BuildType DEBUG_DYNAMIC = { - BE::DEBUG_DYNAMIC, Build::ConfigurationType::DEBUG, LinkageType::DYNAMIC}; - static constexpr BuildType RELEASE_STATIC = { - BE::RELEASE_STATIC, Build::ConfigurationType::RELEASE, LinkageType::STATIC}; - static constexpr BuildType RELEASE_DYNAMIC = { - BE::RELEASE_DYNAMIC, Build::ConfigurationType::RELEASE, LinkageType::DYNAMIC}; - - static constexpr std::array<BuildType, 4> VALUES = { - DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; - } -} diff --git a/toolsrc/include/vcpkg/postbuildlint.h b/toolsrc/include/vcpkg/postbuildlint.h deleted file mode 100644 index deaf3a2ae..000000000 --- a/toolsrc/include/vcpkg/postbuildlint.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/build.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/files.h> - -namespace vcpkg -{ - struct PackageSpec; -} - -namespace vcpkg::PostBuildLint -{ - size_t perform_all_checks(const PackageSpec& spec, - const VcpkgPaths& paths, - const Build::PreBuildInfo& pre_build_info, - const Build::BuildInfo& build_info, - const fs::path& port_dir); -} diff --git a/toolsrc/include/vcpkg/registries.h b/toolsrc/include/vcpkg/registries.h deleted file mode 100644 index 9c07f1a60..000000000 --- a/toolsrc/include/vcpkg/registries.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/configuration.h> -#include <vcpkg/fwd/registries.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/files.h> -#include <vcpkg/base/jsonreader.h> -#include <vcpkg/base/stringview.h> -#include <vcpkg/base/view.h> - -#include <vcpkg/versiondeserializers.h> -#include <vcpkg/versiont.h> - -#include <map> -#include <memory> -#include <string> -#include <system_error> -#include <vector> - -namespace vcpkg -{ - struct RegistryEntry - { - virtual View<VersionT> get_port_versions() const = 0; - - virtual ExpectedS<fs::path> get_path_to_version(const VcpkgPaths& paths, const VersionT& version) const = 0; - - virtual ~RegistryEntry() = default; - }; - - struct RegistryImplementation - { - // returns nullptr if the port doesn't exist - virtual std::unique_ptr<RegistryEntry> get_port_entry(const VcpkgPaths& paths, StringView port_name) const = 0; - - // appends the names of the ports to the out parameter - // may result in duplicated port names; make sure to Util::sort_unique_erase at the end - virtual void get_all_port_names(std::vector<std::string>& port_names, const VcpkgPaths& paths) const = 0; - - virtual Optional<VersionT> get_baseline_version(const VcpkgPaths& paths, StringView port_name) const = 0; - - virtual ~RegistryImplementation() = default; - }; - - struct Registry - { - // requires: static_cast<bool>(implementation) - Registry(std::vector<std::string>&& packages, std::unique_ptr<RegistryImplementation>&& implementation); - - Registry(std::vector<std::string>&&, std::nullptr_t) = delete; - - // always ordered lexicographically - View<std::string> packages() const { return packages_; } - const RegistryImplementation& implementation() const { return *implementation_; } - - friend RegistrySet; // for experimental_set_builtin_registry_baseline - - private: - std::vector<std::string> packages_; - std::unique_ptr<RegistryImplementation> implementation_; - }; - - // this type implements the registry fall back logic from the registries RFC: - // A port name maps to one of the non-default registries if that registry declares - // that it is the registry for that port name, else it maps to the default registry - // if that registry exists; else, there is no registry for a port. - // The way one sets this up is via the `"registries"` and `"default_registry"` - // configuration fields. - struct RegistrySet - { - RegistrySet(); - - // finds the correct registry for the port name - // Returns the null pointer if there is no registry set up for that name - const RegistryImplementation* registry_for_port(StringView port_name) const; - Optional<VersionT> baseline_for_port(const VcpkgPaths& paths, StringView port_name) const; - - View<Registry> registries() const { return registries_; } - - const RegistryImplementation* default_registry() const { return default_registry_.get(); } - - // TODO: figure out how to get this to return an error (or maybe it should be a warning?) - void add_registry(Registry&& r); - void set_default_registry(std::unique_ptr<RegistryImplementation>&& r); - void set_default_registry(std::nullptr_t r); - - // this exists in order to allow versioning and registries to be developed and tested separately - void experimental_set_builtin_registry_baseline(StringView baseline) const; - - // returns whether the registry set has any modifications to the default - // (i.e., whether `default_registry` was set, or `registries` had any entries) - // for checking against the registry feature flag. - bool has_modifications() const; - - private: - std::unique_ptr<RegistryImplementation> default_registry_; - std::vector<Registry> registries_; - }; - - std::unique_ptr<Json::IDeserializer<std::unique_ptr<RegistryImplementation>>> - get_registry_implementation_deserializer(const fs::path& configuration_directory); - - std::unique_ptr<Json::IDeserializer<std::vector<Registry>>> get_registry_array_deserializer( - const fs::path& configuration_directory); - - ExpectedS<std::vector<std::pair<SchemedVersion, std::string>>> get_builtin_versions(const VcpkgPaths& paths, - StringView port_name); - - ExpectedS<std::map<std::string, VersionT, std::less<>>> get_builtin_baseline(const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h deleted file mode 100644 index faba3e368..000000000 --- a/toolsrc/include/vcpkg/remove.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/dependencies.h> -#include <vcpkg/fwd/vcpkgcmdarguments.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/commands.interface.h> - -namespace vcpkg::Remove -{ - enum class Purge - { - NO = 0, - YES - }; - - inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; } - - void perform_remove_plan_action(const VcpkgPaths& paths, - const Dependencies::RemovePlanAction& action, - const Purge purge, - StatusParagraphs* status_db); - - extern const CommandStructure COMMAND_STRUCTURE; - - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); - - struct RemoveCommand : Commands::TripletCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - Triplet default_triplet) const override; - }; -} diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h deleted file mode 100644 index 52ce53980..000000000 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/json.h> - -#include <vcpkg/fwd/vcpkgcmdarguments.h> - -#include <vcpkg/base/expected.h> -#include <vcpkg/base/span.h> -#include <vcpkg/base/system.h> -#include <vcpkg/base/system.print.h> - -#include <vcpkg/packagespec.h> -#include <vcpkg/paragraphparser.h> -#include <vcpkg/platform-expression.h> -#include <vcpkg/versiondeserializers.h> -#include <vcpkg/versions.h> - -namespace vcpkg -{ - std::vector<FullPackageSpec> filter_dependencies(const std::vector<Dependency>& deps, - Triplet t, - const std::unordered_map<std::string, std::string>& cmake_vars); - - struct Type - { - enum - { - UNKNOWN, - PORT, - ALIAS, - } type; - - static std::string to_string(const Type&); - static Type from_string(const std::string&); - }; - - bool operator==(const Type&, const Type&); - bool operator!=(const Type&, const Type&); - - /// <summary> - /// Port metadata of additional feature in a package (part of CONTROL file) - /// </summary> - struct FeatureParagraph - { - std::string name; - std::vector<std::string> description; - std::vector<Dependency> dependencies; - - Json::Object extra_info; - - friend bool operator==(const FeatureParagraph& lhs, const FeatureParagraph& rhs); - friend bool operator!=(const FeatureParagraph& lhs, const FeatureParagraph& rhs) { return !(lhs == rhs); } - }; - - /// <summary> - /// Port metadata of the core feature of a package (part of CONTROL file) - /// </summary> - struct SourceParagraph - { - std::string name; - Versions::Scheme version_scheme = Versions::Scheme::String; - std::string version; - int port_version = 0; - std::vector<std::string> description; - std::vector<std::string> maintainers; - std::string homepage; - std::string documentation; - std::vector<Dependency> dependencies; - std::vector<DependencyOverride> overrides; - std::vector<std::string> default_features; - std::string license; // SPDX license expression - Optional<std::string> builtin_baseline; - - Type type; - PlatformExpression::Expr supports_expression; - - Json::Object extra_info; - - VersionT to_versiont() const { return VersionT{version, port_version}; } - - friend bool operator==(const SourceParagraph& lhs, const SourceParagraph& rhs); - friend bool operator!=(const SourceParagraph& lhs, const SourceParagraph& rhs) { return !(lhs == rhs); } - }; - - /// <summary> - /// Full metadata of a package: core and other features. - /// </summary> - struct SourceControlFile - { - SourceControlFile clone() const; - - static Parse::ParseExpected<SourceControlFile> parse_manifest_object(const std::string& origin, - const Json::Object& object); - - static Parse::ParseExpected<SourceControlFile> parse_manifest_file(const fs::path& path_to_manifest, - const Json::Object& object); - - static Parse::ParseExpected<SourceControlFile> parse_control_file( - const std::string& origin, std::vector<Parse::Paragraph>&& control_paragraphs); - - // Always non-null in non-error cases - std::unique_ptr<SourceParagraph> core_paragraph; - std::vector<std::unique_ptr<FeatureParagraph>> feature_paragraphs; - - Optional<const FeatureParagraph&> find_feature(const std::string& featurename) const; - Optional<const std::vector<Dependency>&> find_dependencies_for_feature(const std::string& featurename) const; - - Optional<std::string> check_against_feature_flags(const fs::path& origin, - const FeatureFlagSettings& flags) const; - - VersionT to_versiont() const { return core_paragraph->to_versiont(); } - SchemedVersion to_schemed_version() const - { - return SchemedVersion{core_paragraph->version_scheme, core_paragraph->to_versiont()}; - } - - friend bool operator==(const SourceControlFile& lhs, const SourceControlFile& rhs); - friend bool operator!=(const SourceControlFile& lhs, const SourceControlFile& rhs) { return !(lhs == rhs); } - }; - - Json::Object serialize_manifest(const SourceControlFile& scf); - Json::Object serialize_debug_manifest(const SourceControlFile& scf); - - /// <summary> - /// Full metadata of a package: core and other features, - /// as well as the port directory the SourceControlFile was loaded from - /// </summary> - struct SourceControlFileLocation - { - SourceControlFileLocation(std::unique_ptr<SourceControlFile>&& scf, fs::path&& source) - : source_control_file(std::move(scf)), source_location(std::move(source)) - { - } - - SourceControlFileLocation(std::unique_ptr<SourceControlFile>&& scf, const fs::path& source) - : source_control_file(std::move(scf)), source_location(source) - { - } - - SourceControlFileLocation clone() const - { - return {std::make_unique<SourceControlFile>(source_control_file->clone()), source_location}; - } - - VersionT to_versiont() const { return source_control_file->to_versiont(); } - - std::unique_ptr<SourceControlFile> source_control_file; - fs::path source_location; - }; - - void print_error_message(Span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list); - inline void print_error_message(const std::unique_ptr<Parse::ParseControlErrorInfo>& error_info_list) - { - return print_error_message({&error_info_list, 1}); - } -} diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h deleted file mode 100644 index 1cfa7a17c..000000000 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/binaryparagraph.h> - -#include <map> - -namespace vcpkg -{ - enum class InstallState - { - ERROR_STATE, - NOT_INSTALLED, - HALF_INSTALLED, - INSTALLED, - }; - - enum class Want - { - ERROR_STATE, - UNKNOWN, - INSTALL, - HOLD, - DEINSTALL, - PURGE - }; - - /// <summary> - /// Installed package metadata - /// </summary> - struct StatusParagraph - { - StatusParagraph() noexcept; - explicit StatusParagraph(Parse::Paragraph&& fields); - - bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; } - - BinaryParagraph package; - Want want; - InstallState state; - }; - - void serialize(const StatusParagraph& pgh, std::string& out_str); - - std::string to_string(InstallState f); - - std::string to_string(Want f); - - struct InstalledPackageView - { - InstalledPackageView() noexcept : core(nullptr) { } - - InstalledPackageView(const StatusParagraph* c, std::vector<const StatusParagraph*>&& fs) - : core(c), features(std::move(fs)) - { - } - - const PackageSpec& spec() const { return core->package.spec; } - std::vector<PackageSpec> dependencies() const; - std::map<std::string, std::vector<FeatureSpec>> feature_dependencies() const; - - const StatusParagraph* core; - std::vector<const StatusParagraph*> features; - }; - - Json::Value serialize_ipv(const InstalledPackageView& ipv, const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h deleted file mode 100644 index 8fd85b4e0..000000000 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once -#include <vcpkg/statusparagraph.h> - -#include <iterator> -#include <memory> - -namespace vcpkg -{ - /// <summary>Status paragraphs</summary> - /// - /// Collection of <see cref="vcpkg::StatusParagraph"/>, e.g. contains the information - /// about whether a package is installed or not. - /// - struct StatusParagraphs - { - StatusParagraphs(); - explicit StatusParagraphs(std::vector<std::unique_ptr<StatusParagraph>>&& ps); - - using container = std::vector<std::unique_ptr<StatusParagraph>>; - using iterator = container::reverse_iterator; - using const_iterator = container::const_reverse_iterator; - - /// <summary>Find the StatusParagraph for given spec.</summary> - /// <param name="spec">Package specification to find the status paragraph for</param> - /// <returns>Iterator for found spec</returns> - const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } - - /// <summary>Find the StatusParagraph for given feature spec.</summary> - /// <param name="spec">Feature specification to find the status paragraph for</param> - /// <returns>Iterator for found spec</returns> - const_iterator find(const FeatureSpec& spec) const { return find(spec.name(), spec.triplet(), spec.feature()); } - - /// <summary>Find a StatusParagraph by name, triplet and feature.</summary> - /// <param name="name">Package name</param> - /// <param name="triplet">Triplet</param> - /// <param name="feature">Feature name</param> - /// <returns>Iterator for found spec</returns> - iterator find(const std::string& name, Triplet triplet, const std::string& feature = {}); - const_iterator find(const std::string& name, Triplet triplet, const std::string& feature = {}) const; - - std::vector<std::unique_ptr<StatusParagraph>*> find_all(const std::string& name, Triplet triplet); - - Optional<InstalledPackageView> get_installed_package_view(const PackageSpec& spec) const; - - /// <summary>Find the StatusParagraph for given spec if installed</summary> - /// <param name="spec">Package specification to find the status for</param> - /// <returns>Iterator for found spec</returns> - const_iterator find_installed(const PackageSpec& spec) const; - - /// <summary>Find the StatusParagraph for given feature spec if installed</summary> - /// <param name="spec">Feature specification to find the status for</param> - /// <returns>Iterator for found spec</returns> - const_iterator find_installed(const FeatureSpec& spec) const; - - /// <summary>Find the StatusParagraph for given spec and return its install status</summary> - /// <param name="spec">Package specification to check if installed</param> - /// <returns>`true` if installed, `false` if not or not found.</returns> - bool is_installed(const PackageSpec& spec) const; - - /// <summary>Find the StatusParagraph for given feature spec and return its install status</summary> - /// <param name="spec">Feature specification to check if installed</param> - /// <returns>`true` if installed, `false` if not or not found.</returns> - bool is_installed(const FeatureSpec& spec) const; - - iterator insert(std::unique_ptr<StatusParagraph>); - - friend void serialize(const StatusParagraphs& pgh, std::string& out_str); - - iterator end() { return paragraphs.rend(); } - - const_iterator end() const { return paragraphs.rend(); } - - iterator begin() { return paragraphs.rbegin(); } - - const_iterator begin() const { return paragraphs.rbegin(); } - - private: - std::vector<std::unique_ptr<StatusParagraph>> paragraphs; - }; - - void serialize(const StatusParagraphs& pgh, std::string& out_str); -} diff --git a/toolsrc/include/vcpkg/textrowcol.h b/toolsrc/include/vcpkg/textrowcol.h deleted file mode 100644 index b8269f697..000000000 --- a/toolsrc/include/vcpkg/textrowcol.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -namespace vcpkg::Parse -{ - struct TextRowCol - { - constexpr TextRowCol() noexcept = default; - constexpr TextRowCol(int row, int column) noexcept : row(row), column(column) { } - /// '0' indicates uninitialized; '1' is the first row. - int row = 0; - /// '0' indicates uninitialized; '1' is the first column. - int column = 0; - - constexpr int row_or(int def) const noexcept { return row ? row : def; } - constexpr int column_or(int def) const noexcept { return column ? column : def; } - }; -} diff --git a/toolsrc/include/vcpkg/tools.h b/toolsrc/include/vcpkg/tools.h deleted file mode 100644 index 8f0398a5c..000000000 --- a/toolsrc/include/vcpkg/tools.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/files.h> - -#include <string> -#include <utility> - -namespace vcpkg -{ - namespace Tools - { - static const std::string SEVEN_ZIP = "7zip"; - static const std::string SEVEN_ZIP_ALT = "7z"; - static const std::string MAVEN = "mvn"; - static const std::string CMAKE = "cmake"; - static const std::string GIT = "git"; - static const std::string MONO = "mono"; - static const std::string NINJA = "ninja"; - static const std::string POWERSHELL_CORE = "powershell-core"; - static const std::string NUGET = "nuget"; - static const std::string IFW_INSTALLER_BASE = "ifw_installerbase"; - static const std::string IFW_BINARYCREATOR = "ifw_binarycreator"; - static const std::string IFW_REPOGEN = "ifw_repogen"; - } - - struct ToolCache - { - virtual ~ToolCache() { } - - virtual const fs::path& get_tool_path(const VcpkgPaths& paths, const std::string& tool) const = 0; - virtual const std::string& get_tool_version(const VcpkgPaths& paths, const std::string& tool) const = 0; - }; - - std::unique_ptr<ToolCache> get_tool_cache(); -} diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h deleted file mode 100644 index 40f6d6f23..000000000 --- a/toolsrc/include/vcpkg/triplet.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgcmdarguments.h> - -#include <vcpkg/base/optional.h> -#include <vcpkg/base/system.h> - -#include <string> - -namespace vcpkg -{ - struct TripletInstance; - - struct Triplet - { - public: - constexpr Triplet() noexcept : m_instance(&DEFAULT_INSTANCE) { } - - static Triplet from_canonical_name(std::string&& triplet_as_string); - - const std::string& canonical_name() const; - const std::string& to_string() const; - void to_string(std::string& out) const; - size_t hash_code() const; - Optional<System::CPUArchitecture> guess_architecture() const noexcept; - - bool operator==(Triplet other) const { return this->m_instance == other.m_instance; } - bool operator<(Triplet other) const { return canonical_name() < other.canonical_name(); } - - private: - static const TripletInstance DEFAULT_INSTANCE; - - constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) { } - - const TripletInstance* m_instance; - }; - - inline bool operator!=(Triplet left, Triplet right) { return !(left == right); } - - Triplet default_triplet(const VcpkgCmdArguments& args); -} - -namespace std -{ - template<> - struct hash<vcpkg::Triplet> - { - size_t operator()(vcpkg::Triplet t) const { return t.hash_code(); } - }; -} diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h deleted file mode 100644 index 063e16997..000000000 --- a/toolsrc/include/vcpkg/update.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/portfileprovider.h> -#include <vcpkg/fwd/vcpkgcmdarguments.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/commands.interface.h> -#include <vcpkg/packagespec.h> -#include <vcpkg/versiont.h> - -namespace vcpkg -{ - struct StatusParagraphs; -} - -namespace vcpkg::Update -{ - struct OutdatedPackage - { - static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); - - PackageSpec spec; - VersionDiff version_diff; - }; - - std::vector<OutdatedPackage> find_outdated_packages(const PortFileProvider::PortFileProvider& provider, - const StatusParagraphs& status_db); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - struct UpdateCommand : Commands::PathsCommand - { - virtual void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; - }; -} diff --git a/toolsrc/include/vcpkg/userconfig.h b/toolsrc/include/vcpkg/userconfig.h deleted file mode 100644 index 74f8c876a..000000000 --- a/toolsrc/include/vcpkg/userconfig.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include <vcpkg/base/files.h> - -#include <string> - -namespace vcpkg -{ - struct UserConfig - { - std::string user_id; - std::string user_time; - std::string user_mac; - - std::string last_completed_survey; - - static UserConfig try_read_data(const Files::Filesystem& fs); - - void try_write_data(Files::Filesystem& fs) const; - }; - - fs::path get_user_dir(); -} diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h deleted file mode 100644 index 14208e926..000000000 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ /dev/null @@ -1,236 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgcmdarguments.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/files.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/span.h> -#include <vcpkg/base/stringliteral.h> - -#include <memory> -#include <unordered_map> -#include <unordered_set> -#include <vector> - -namespace vcpkg -{ - struct ParsedArguments - { - std::unordered_set<std::string> switches; - std::unordered_map<std::string, std::string> settings; - std::unordered_map<std::string, std::vector<std::string>> multisettings; - }; - - struct CommandSwitch - { - constexpr CommandSwitch(const StringLiteral& name, const StringLiteral& short_help_text) - : name(name), short_help_text(short_help_text) - { - } - - StringLiteral name; - StringLiteral short_help_text; - }; - - struct CommandSetting - { - constexpr CommandSetting(const StringLiteral& name, const StringLiteral& short_help_text) - : name(name), short_help_text(short_help_text) - { - } - - StringLiteral name; - StringLiteral short_help_text; - }; - - struct CommandMultiSetting - { - constexpr CommandMultiSetting(const StringLiteral& name, const StringLiteral& short_help_text) - : name(name), short_help_text(short_help_text) - { - } - - StringLiteral name; - StringLiteral short_help_text; - }; - - struct CommandOptionsStructure - { - Span<const CommandSwitch> switches; - Span<const CommandSetting> settings; - Span<const CommandMultiSetting> multisettings; - }; - - struct CommandStructure - { - std::string example_text; - - size_t minimum_arity; - size_t maximum_arity; - - CommandOptionsStructure options; - - std::vector<std::string> (*valid_arguments)(const VcpkgPaths& paths); - }; - - void print_usage(); - void print_usage(const CommandStructure& command_structure); - -#if defined(_WIN32) - using CommandLineCharType = wchar_t; -#else - using CommandLineCharType = char; -#endif - - std::string create_example_string(const std::string& command_and_arguments); - - std::string format_environment_variable(StringLiteral lit); - - struct HelpTableFormatter - { - void format(StringView col1, StringView col2); - void example(StringView example_text); - void header(StringView name); - void blank(); - void text(StringView text, int indent = 0); - - std::string m_str; - }; - - struct FeatureFlagSettings - { - bool registries; - bool compiler_tracking; - bool binary_caching; - bool versions; - }; - - struct VcpkgCmdArguments - { - static VcpkgCmdArguments create_from_command_line(const Files::Filesystem& fs, - const int argc, - const CommandLineCharType* const* const argv); - static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); - - static void append_common_options(HelpTableFormatter& target); - - constexpr static StringLiteral VCPKG_ROOT_DIR_ENV = "VCPKG_ROOT"; - constexpr static StringLiteral VCPKG_ROOT_DIR_ARG = "vcpkg-root"; - std::unique_ptr<std::string> vcpkg_root_dir; - constexpr static StringLiteral MANIFEST_ROOT_DIR_ARG = "x-manifest-root"; - std::unique_ptr<std::string> manifest_root_dir; - - constexpr static StringLiteral BUILDTREES_ROOT_DIR_ARG = "x-buildtrees-root"; - std::unique_ptr<std::string> buildtrees_root_dir; - constexpr static StringLiteral DOWNLOADS_ROOT_DIR_ENV = "VCPKG_DOWNLOADS"; - constexpr static StringLiteral DOWNLOADS_ROOT_DIR_ARG = "downloads-root"; - std::unique_ptr<std::string> downloads_root_dir; - constexpr static StringLiteral INSTALL_ROOT_DIR_ARG = "x-install-root"; - std::unique_ptr<std::string> install_root_dir; - constexpr static StringLiteral PACKAGES_ROOT_DIR_ARG = "x-packages-root"; - std::unique_ptr<std::string> packages_root_dir; - constexpr static StringLiteral SCRIPTS_ROOT_DIR_ARG = "x-scripts-root"; - std::unique_ptr<std::string> scripts_root_dir; - constexpr static StringLiteral BUILTIN_PORTS_ROOT_DIR_ARG = "x-builtin-ports-root"; - std::unique_ptr<std::string> builtin_ports_root_dir; - constexpr static StringLiteral BUILTIN_REGISTRY_VERSIONS_DIR_ARG = "x-builtin-registry-versions-dir"; - std::unique_ptr<std::string> builtin_registry_versions_dir; - - constexpr static StringLiteral DEFAULT_VISUAL_STUDIO_PATH_ENV = "VCPKG_VISUAL_STUDIO_PATH"; - std::unique_ptr<std::string> default_visual_studio_path; - - constexpr static StringLiteral TRIPLET_ENV = "VCPKG_DEFAULT_TRIPLET"; - constexpr static StringLiteral TRIPLET_ARG = "triplet"; - std::unique_ptr<std::string> triplet; - constexpr static StringLiteral OVERLAY_PORTS_ENV = "VCPKG_OVERLAY_PORTS"; - constexpr static StringLiteral OVERLAY_PORTS_ARG = "overlay-ports"; - std::vector<std::string> overlay_ports; - constexpr static StringLiteral OVERLAY_TRIPLETS_ENV = "VCPKG_OVERLAY_TRIPLETS"; - constexpr static StringLiteral OVERLAY_TRIPLETS_ARG = "overlay-triplets"; - std::vector<std::string> overlay_triplets; - - constexpr static StringLiteral BINARY_SOURCES_ARG = "binarysource"; - std::vector<std::string> binary_sources; - - constexpr static StringLiteral CMAKE_SCRIPT_ARG = "x-cmake-args"; - std::vector<std::string> cmake_args; - - constexpr static StringLiteral DEBUG_SWITCH = "debug"; - Optional<bool> debug = nullopt; - constexpr static StringLiteral SEND_METRICS_SWITCH = "sendmetrics"; - Optional<bool> send_metrics = nullopt; - // fully disable metrics -- both printing and sending - constexpr static StringLiteral DISABLE_METRICS_ENV = "VCPKG_DISABLE_METRICS"; - constexpr static StringLiteral DISABLE_METRICS_SWITCH = "disable-metrics"; - Optional<bool> disable_metrics = nullopt; - constexpr static StringLiteral PRINT_METRICS_SWITCH = "printmetrics"; - Optional<bool> print_metrics = nullopt; - - constexpr static StringLiteral WAIT_FOR_LOCK_SWITCH = "x-wait-for-lock"; - Optional<bool> wait_for_lock = nullopt; - - constexpr static StringLiteral IGNORE_LOCK_FAILURES_SWITCH = "x-ignore-lock-failures"; - constexpr static StringLiteral IGNORE_LOCK_FAILURES_ENV = "X_VCPKG_IGNORE_LOCK_FAILURES"; - Optional<bool> ignore_lock_failures = nullopt; - - constexpr static StringLiteral JSON_SWITCH = "x-json"; - Optional<bool> json = nullopt; - - // feature flags - constexpr static StringLiteral FEATURE_FLAGS_ENV = "VCPKG_FEATURE_FLAGS"; - constexpr static StringLiteral FEATURE_FLAGS_ARG = "feature-flags"; - - constexpr static StringLiteral FEATURE_PACKAGES_SWITCH = "featurepackages"; - Optional<bool> feature_packages = nullopt; - constexpr static StringLiteral BINARY_CACHING_FEATURE = "binarycaching"; - constexpr static StringLiteral BINARY_CACHING_SWITCH = "binarycaching"; - Optional<bool> binary_caching = nullopt; - constexpr static StringLiteral COMPILER_TRACKING_FEATURE = "compilertracking"; - Optional<bool> compiler_tracking = nullopt; - constexpr static StringLiteral MANIFEST_MODE_FEATURE = "manifests"; - Optional<bool> manifest_mode = nullopt; - constexpr static StringLiteral REGISTRIES_FEATURE = "registries"; - Optional<bool> registries_feature = nullopt; - constexpr static StringLiteral VERSIONS_FEATURE = "versions"; - Optional<bool> versions_feature = nullopt; - - constexpr static StringLiteral RECURSIVE_DATA_ENV = "VCPKG_X_RECURSIVE_DATA"; - - bool binary_caching_enabled() const { return binary_caching.value_or(true); } - bool compiler_tracking_enabled() const { return compiler_tracking.value_or(true); } - bool registries_enabled() const { return registries_feature.value_or(false); } - bool versions_enabled() const { return versions_feature.value_or(false); } - FeatureFlagSettings feature_flag_settings() const - { - FeatureFlagSettings f; - f.binary_caching = binary_caching_enabled(); - f.compiler_tracking = compiler_tracking_enabled(); - f.registries = registries_enabled(); - f.versions = versions_enabled(); - return f; - } - - bool output_json() const { return json.value_or(false); } - - std::string command; - std::vector<std::string> command_arguments; - - ParsedArguments parse_arguments(const CommandStructure& command_structure) const; - - void imbue_from_environment(); - - // Applies recursive settings from the environment or sets a global environment variable - // to be consumed by subprocesses; may only be called once per process. - static void imbue_or_apply_process_recursion(VcpkgCmdArguments& args); - - void check_feature_flag_consistency() const; - - void debug_print_feature_flags() const; - void track_feature_flag_metrics() const; - - private: - std::unordered_set<std::string> command_switches; - std::unordered_map<std::string, std::vector<std::string>> command_options; - }; -} diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h deleted file mode 100644 index bb1d61c73..000000000 --- a/toolsrc/include/vcpkg/vcpkglib.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/sortedvector.h> - -#include <vcpkg/statusparagraphs.h> - -namespace vcpkg -{ - StatusParagraphs database_load_check(const VcpkgPaths& paths); - - void write_update(const VcpkgPaths& paths, const StatusParagraph& p); - - struct StatusParagraphAndAssociatedFiles - { - StatusParagraph pgh; - SortedVector<std::string> files; - }; - - std::vector<InstalledPackageView> get_installed_ports(const StatusParagraphs& status_db); - std::vector<StatusParagraphAndAssociatedFiles> get_installed_files(const VcpkgPaths& paths, - const StatusParagraphs& status_db); - - std::string shorten_text(const std::string& desc, const size_t length); -} // namespace vcpkg diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h deleted file mode 100644 index 643baf57e..000000000 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ /dev/null @@ -1,178 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/json.h> - -#include <vcpkg/fwd/configuration.h> -#include <vcpkg/fwd/registries.h> -#include <vcpkg/fwd/vcpkgcmdarguments.h> -#include <vcpkg/fwd/vcpkgpaths.h> - -#include <vcpkg/base/cache.h> -#include <vcpkg/base/files.h> -#include <vcpkg/base/lazy.h> -#include <vcpkg/base/optional.h> -#include <vcpkg/base/system.h> -#include <vcpkg/base/util.h> - -namespace vcpkg -{ - struct ToolsetArchOption - { - CStringView name; - System::CPUArchitecture host_arch; - System::CPUArchitecture target_arch; - }; - - struct Toolset - { - fs::path visual_studio_root_path; - fs::path dumpbin; - fs::path vcvarsall; - std::vector<std::string> vcvarsall_options; - CStringView version; - std::vector<ToolsetArchOption> supported_architectures; - }; - - namespace Build - { - struct PreBuildInfo; - struct AbiInfo; - struct CompilerInfo; - } - - namespace System - { - struct Environment; - } - - namespace details - { - struct VcpkgPathsImpl; - } - - struct BinaryParagraph; - struct PackageSpec; - struct Triplet; - - struct VcpkgPaths : Util::MoveOnlyBase - { - struct TripletFile - { - std::string name; - fs::path location; - - TripletFile(const std::string& name, const fs::path& location) : name(name), location(location) { } - }; - - VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args); - ~VcpkgPaths(); - - fs::path package_dir(const PackageSpec& spec) const; - fs::path build_dir(const PackageSpec& spec) const; - fs::path build_dir(const std::string& package_name) const; - fs::path build_info_file_path(const PackageSpec& spec) const; - fs::path listfile_path(const BinaryParagraph& pgh) const; - - bool is_valid_triplet(Triplet t) const; - const std::vector<std::string> get_available_triplets_names() const; - const std::vector<TripletFile>& get_available_triplets() const; - const std::map<std::string, std::string>& get_cmake_script_hashes() const; - const fs::path get_triplet_file_path(Triplet triplet) const; - - fs::path original_cwd; - fs::path root; - fs::path manifest_root_dir; - fs::path config_root_dir; - fs::path buildtrees; - fs::path downloads; - fs::path packages; - fs::path installed; - fs::path triplets; - fs::path community_triplets; - fs::path scripts; - fs::path prefab; - fs::path builtin_ports; - fs::path builtin_registry_versions; - - fs::path tools; - fs::path buildsystems; - fs::path buildsystems_msbuild_targets; - fs::path buildsystems_msbuild_props; - - fs::path vcpkg_dir; - fs::path vcpkg_dir_status_file; - fs::path vcpkg_dir_info; - fs::path vcpkg_dir_updates; - - fs::path baselines_dot_git_dir; - fs::path baselines_work_tree; - fs::path baselines_output; - - fs::path versions_dot_git_dir; - fs::path versions_work_tree; - fs::path versions_output; - - fs::path ports_cmake; - - const fs::path& get_tool_exe(const std::string& tool) const; - const std::string& get_tool_version(const std::string& tool) const; - - // Git manipulation in the vcpkg directory - ExpectedS<std::string> get_current_git_sha() const; - std::string get_current_git_sha_message() const; - ExpectedS<fs::path> git_checkout_baseline(StringView commit_sha) const; - ExpectedS<fs::path> git_checkout_port(StringView port_name, - StringView git_tree, - const fs::path& dot_git_dir) const; - ExpectedS<std::string> git_show(const std::string& treeish, const fs::path& dot_git_dir) const; - - ExpectedS<std::map<std::string, std::string, std::less<>>> git_get_local_port_treeish_map() const; - - // Git manipulation for remote registries - // runs `git fetch {uri} {treeish}`, and returns the hash of FETCH_HEAD. - // If `treeish` is empty, then just runs `git fetch {uri}` - ExpectedS<std::string> git_fetch_from_remote_registry(StringView uri, StringView treeish = {}) const; - ExpectedS<std::string> git_show_from_remote_registry(StringView hash, - const fs::path& relative_path_to_file) const; - ExpectedS<std::string> git_find_object_id_for_remote_registry_path(StringView hash, - const fs::path& relative_path_to_file) const; - ExpectedS<fs::path> git_checkout_object_from_remote_registry(StringView tree) const; - - Optional<const Json::Object&> get_manifest() const; - Optional<const fs::path&> get_manifest_path() const; - const Configuration& get_configuration() const; - - /// <summary>Retrieve a toolset matching a VS version</summary> - /// <remarks> - /// Valid version strings are "v120", "v140", "v141", and "". Empty string gets the latest. - /// </remarks> - const Toolset& get_toolset(const Build::PreBuildInfo& prebuildinfo) const; - - View<Toolset> get_all_toolsets() const; - - Files::Filesystem& get_filesystem() const; - - const System::Environment& get_action_env(const Build::AbiInfo& abi_info) const; - const std::string& get_triplet_info(const Build::AbiInfo& abi_info) const; - const Build::CompilerInfo& get_compiler_info(const Build::AbiInfo& abi_info) const; - bool manifest_mode_enabled() const { return get_manifest().has_value(); } - - const FeatureFlagSettings& get_feature_flags() const; - void track_feature_flag_metrics() const; - - // the directory of the builtin ports - // this should be used only for helper commands, not core commands like `install`. - fs::path builtin_ports_directory() const { return this->builtin_ports; } - - private: - std::unique_ptr<details::VcpkgPathsImpl> m_pimpl; - - static void git_checkout_subpath(const VcpkgPaths& paths, - StringView commit_sha, - const fs::path& subpath, - const fs::path& local_repo, - const fs::path& destination, - const fs::path& dot_git_dir, - const fs::path& work_tree); - }; -} diff --git a/toolsrc/include/vcpkg/versiondeserializers.h b/toolsrc/include/vcpkg/versiondeserializers.h deleted file mode 100644 index ae368f6c5..000000000 --- a/toolsrc/include/vcpkg/versiondeserializers.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include <vcpkg/base/fwd/stringview.h> - -#include <vcpkg/base/jsonreader.h> -#include <vcpkg/base/stringliteral.h> - -#include <vcpkg/versions.h> -#include <vcpkg/versiont.h> - -namespace vcpkg -{ - Json::IDeserializer<VersionT>& get_versiont_deserializer_instance(); - Json::IDeserializer<VersionT>& get_versiontag_deserializer_instance(); - std::unique_ptr<Json::IDeserializer<std::string>> make_version_deserializer(StringLiteral type_name); - - struct SchemedVersion - { - SchemedVersion() = default; - SchemedVersion(Versions::Scheme scheme_, VersionT versiont_) : scheme(scheme_), versiont(std::move(versiont_)) - { - } - - Versions::Scheme scheme = Versions::Scheme::String; - VersionT versiont; - }; - - Optional<SchemedVersion> visit_optional_schemed_deserializer(StringView parent_type, - Json::Reader& r, - const Json::Object& obj); - SchemedVersion visit_required_schemed_deserializer(StringView parent_type, - Json::Reader& r, - const Json::Object& obj); - View<StringView> schemed_deserializer_fields(); - - void serialize_schemed_version(Json::Object& out_obj, - Versions::Scheme scheme, - const std::string& version, - int port_version, - bool always_emit_port_version = false); -} diff --git a/toolsrc/include/vcpkg/versions.h b/toolsrc/include/vcpkg/versions.h deleted file mode 100644 index b26c90dfb..000000000 --- a/toolsrc/include/vcpkg/versions.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include <vcpkg/versiont.h> - -namespace vcpkg::Versions -{ - using Version = VersionT; - - enum class VerComp - { - unk, - lt, - eq, - gt, - }; - - enum class Scheme - { - Relaxed, - Semver, - Date, - String - }; - - struct VersionSpec - { - std::string port_name; - VersionT version; - - VersionSpec(const std::string& port_name, const VersionT& version); - - VersionSpec(const std::string& port_name, const std::string& version_string, int port_version); - - friend bool operator==(const VersionSpec& lhs, const VersionSpec& rhs); - friend bool operator!=(const VersionSpec& lhs, const VersionSpec& rhs); - }; - - struct VersionSpecHasher - { - std::size_t operator()(const VersionSpec& key) const; - }; - - struct RelaxedVersion - { - std::string original_string; - std::vector<uint64_t> version; - - static ExpectedS<RelaxedVersion> from_string(const std::string& str); - }; - - struct SemanticVersion - { - std::string original_string; - std::string version_string; - std::string prerelease_string; - - std::vector<uint64_t> version; - std::vector<std::string> identifiers; - - static ExpectedS<SemanticVersion> from_string(const std::string& str); - }; - - struct DateVersion - { - std::string original_string; - std::string version_string; - std::string identifiers_string; - - std::vector<uint64_t> identifiers; - - static ExpectedS<DateVersion> from_string(const std::string& str); - }; - - VerComp compare(const std::string& a, const std::string& b, Scheme scheme); - VerComp compare(const RelaxedVersion& a, const RelaxedVersion& b); - VerComp compare(const SemanticVersion& a, const SemanticVersion& b); - VerComp compare(const DateVersion& a, const DateVersion& b); - - struct Constraint - { - enum class Type - { - None, - Minimum - }; - }; -} diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h deleted file mode 100644 index 910183b9d..000000000 --- a/toolsrc/include/vcpkg/versiont.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include <string> - -namespace vcpkg -{ - struct VersionT - { - VersionT() noexcept; - VersionT(std::string&& value, int port_version); - VersionT(const std::string& value, int port_version); - - std::string to_string() const; - void to_string(std::string& out) const; - - friend bool operator==(const VersionT& left, const VersionT& right); - friend bool operator!=(const VersionT& left, const VersionT& right); - - friend struct VersionTMapLess; - - const std::string text() const { return m_text; } - int port_version() const { return m_port_version; } - - private: - std::string m_text; - int m_port_version = 0; - }; - - struct VersionDiff - { - VersionT left; - VersionT right; - - VersionDiff() noexcept; - VersionDiff(const VersionT& left, const VersionT& right); - - std::string to_string() const; - }; - - struct VersionTMapLess - { - bool operator()(const VersionT& left, const VersionT& right) const; - }; -} diff --git a/toolsrc/include/vcpkg/visualstudio.h b/toolsrc/include/vcpkg/visualstudio.h deleted file mode 100644 index da6652b3e..000000000 --- a/toolsrc/include/vcpkg/visualstudio.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#if defined(_WIN32) - -#include <vcpkg/vcpkgpaths.h> - -namespace vcpkg::VisualStudio -{ - std::vector<std::string> get_visual_studio_instances(const VcpkgPaths& paths); - - std::vector<Toolset> find_toolset_instances_preferred_first(const VcpkgPaths& paths); -} - -#endif |
