Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/single_include
diff options
context:
space:
mode:
authorPhil Nash2017-08-17 08:29:57 +0100
committerPhil Nash2017-08-17 08:29:57 +0100
commit581aaae57ec2a54c60248e0fd98932c649dd5a3c (patch)
tree630bd59f3714de7b1ab6a3a17ce209e4fd3f339a /single_include
parent0b52dbe8bbdc7289d1f025a4906ea4107c1e0446 (diff)
downloadcatch3-2.0.0-develop.1.tar.gz
Generated single include for develop buildv2.0.0-develop.1
Diffstat (limited to 'single_include')
-rw-r--r--single_include/catch.hpp11539
1 files changed, 11539 insertions, 0 deletions
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
new file mode 100644
index 00000000..77035aa9
--- /dev/null
+++ b/single_include/catch.hpp
@@ -0,0 +1,11539 @@
+/*
+ * Catch v2.0.0-develop.1
+ * Generated: 2017-08-17 08:29:20.059622
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 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)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+// start catch.hpp
+
+
+#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 ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# 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__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic ignored "-Wparentheses"
+
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+// end catch_suppress_warnings.h
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// start catch_context.h
+
+#include <memory>
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IConfig;
+
+ using IConfigPtr = std::shared_ptr<IConfig const>;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual IConfigPtr 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;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+}
+
+// end catch_context.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?
+// ****************
+// 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
+# define CATCH_CPP14_OR_GREATER
+# endif
+
+#endif
+
+#ifdef __clang__
+
+# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ _Pragma( "clang diagnostic push" ) \
+ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
+# define CATCH_INTERNAL_UNSUPPRESS_ETD_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" )
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// We know some environments not to support full POSIX signals
+#if defined(__CYGWIN__) || defined(__QNX__)
+
+# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
+# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+# endif
+
+#endif
+
+#ifdef __OS400__
+# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+# define CATCH_CONFIG_COLOUR_NONE
+#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
+
+#endif // __CYGWIN__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use __COUNTER__ if the compiler supports it
+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
+ ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
+ ( defined __clang__ && __clang_major__ >= 3 )
+
+#define CATCH_INTERNAL_CONFIG_COUNTER
+
+#endif
+
+// Now set the actual defines based on the above + anything the user has configured
+
+// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
+// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
+// This does not affect compilation
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
+# define CATCH_CONFIG_COUNTER
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_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_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
+# define CATCH_CONFIG_POSIX_SIGNALS
+#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_ETD_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
+# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+#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
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <iosfwd>
+#include <string>
+#include <cstdint>
+
+namespace Catch {
+
+ struct IConfig;
+
+ 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;
+
+ SourceLineInfo( SourceLineInfo const& other ) = default;
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = 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 );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ bool isTrue( bool value );
+ bool alwaysTrue();
+ bool alwaysFalse();
+
+ void seedRng( IConfig const& config );
+ unsigned int rngSeed();
+
+ // 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 ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+
+// end catch_tag_alias_autoregistrar.h
+// start catch_test_registry.hpp
+
+// start catch_interfaces_testcase.h
+
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestInvoker {
+ virtual void invoke () const = 0;
+ virtual ~ITestInvoker();
+ };
+
+ using ITestCasePtr = std::shared_ptr<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 {
+
+ class StringData;
+
+ /// 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 {
+ friend struct StringRefTestAccess;
+
+ using size_type = size_t;
+
+ char const* m_start;
+ size_type m_size;
+
+ char* m_data = nullptr;
+
+ void takeOwnership();
+
+ public: // construction/ assignment
+ StringRef() noexcept;
+ StringRef( StringRef const& other ) noexcept;
+ StringRef( StringRef&& other ) noexcept;
+ StringRef( char const* rawChars ) noexcept;
+ StringRef( char const* rawChars, size_type size ) noexcept;
+ StringRef( std::string const& stdString ) noexcept;
+ ~StringRef() noexcept;
+
+ auto operator = ( StringRef other ) noexcept -> StringRef&;
+ 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;
+ auto size() const noexcept -> size_type;
+ 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;
+
+ private: // ownership queries - may not be consistent between calls
+ auto isOwned() const noexcept -> bool;
+ auto isSubstring() const noexcept -> bool;
+ auto data() const noexcept -> char const*;
+ };
+
+ 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::ostream& os, StringRef const& sr ) -> std::ostream&;
+
+} // namespace Catch
+
+// end catch_stringref.h
+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 name_ = "", StringRef tags_ = "" ) noexcept;
+ StringRef name;
+ StringRef tags;
+};
+
+struct AutoReg : NonCopyable {
+ AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept;
+ ~AutoReg() = default;
+};
+
+} // end namespace Catch
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+ static void TestName(); \
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_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_ETD_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ namespace{ \
+ struct TestName : 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_ETD_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_ETD_WARNINGS \
+ Catch::AutoReg( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+// end catch_test_registry.hpp
+// start catch_capture.hpp
+
+// start catch_assertionhandler.h
+
+// start catch_decomposer.h
+
+// start catch_tostring.h
+
+#include <sstream>
+#include <vector>
+#include <cstddef>
+#include <tuple>
+#include <type_traits>
+#include <string>
+
+#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
+
+// 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 {
+ // Bring in operator<< from global namespace into Catch namespace
+ using ::operator<<;
+
+ 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;
+ };
+
+ } // namespace Detail
+
+ // If we decide for C++14, change these to enable_if_ts
+ template <typename T>
+ struct StringMaker {
+ template <typename Fake = T>
+ static
+ typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
+ convert(const Fake& t) {
+ std::ostringstream sstr;
+ sstr << t;
+ return sstr.str();
+ }
+
+ template <typename Fake = T>
+ static
+ typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
+ convert(const Fake&) {
+ return Detail::unprintableString;
+ }
+ };
+
+ 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);
+ }
+
+ } // namespace Detail
+
+ // Some predefined specializations
+
+ template<>
+ struct StringMaker<std::string> {
+ static std::string convert(const std::string& str);
+ };
+ template<>
+ struct StringMaker<std::wstring> {
+ static std::string convert(const std::wstring& wstr);
+ };
+
+ template<>
+ struct StringMaker<char const *> {
+ static std::string convert(char const * str);
+ };
+ template<>
+ struct StringMaker<char *> {
+ static std::string convert(char * str);
+ };
+ 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);
+ };
+
+ template<int SZ>
+ struct StringMaker<char[SZ]> {
+ static std::string convert(const char* str) {
+ return ::Catch::Detail::stringify(std::string{ str });
+ }
+ };
+ template<int SZ>
+ struct StringMaker<signed char[SZ]> {
+ static std::string convert(const char* str) {
+ return ::Catch::Detail::stringify(std::string{ str });
+ }
+ };
+ template<int SZ>
+ struct StringMaker<unsigned char[SZ]> {
+ static std::string convert(const char* str) {
+ return ::Catch::Detail::stringify(std::string{ 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);
+ };
+ template<>
+ struct StringMaker<double> {
+ static std::string convert(double value);
+ };
+
+ 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";
+ }
+ }
+ };
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString(InputIterator first, InputIterator last) {
+ std::ostringstream oss;
+ oss << "{ ";
+ if (first != last) {
+ oss << ::Catch::Detail::stringify(*first);
+ for (++first; first != last; ++first)
+ oss << ", " << ::Catch::Detail::stringify(*first);
+ }
+ oss << " }";
+ return oss.str();
+ }
+ }
+
+ template<typename T, typename Allocator>
+ struct StringMaker<std::vector<T, Allocator> > {
+ static std::string convert( std::vector<T,Allocator> const& v ) {
+ return ::Catch::Detail::rangeToString( v.begin(), v.end() );
+ }
+ };
+
+ // === Pair ===
+ template<typename T1, typename T2>
+ struct StringMaker<std::pair<T1, T2> > {
+ static std::string convert(const std::pair<T1, T2>& pair) {
+ std::ostringstream oss;
+ oss << "{ "
+ << ::Catch::Detail::stringify(pair.first)
+ << ", "
+ << ::Catch::Detail::stringify(pair.second)
+ << " }";
+ return oss.str();
+ }
+ };
+
+ 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) {
+ std::ostringstream os;
+ os << '{';
+ Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, os);
+ os << " }";
+ return os.str();
+ }
+ };
+
+ template<typename T>
+ struct EnumStringMaker {
+ static std::string convert(const T& t) {
+ return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<T>::type>(t));
+ }
+ };
+
+#ifdef __OBJC__
+ template<>
+ struct StringMaker<NSString*> {
+ static std::string convert(NSString* nsstring);
+ };
+ template<>
+ struct StringMaker<NSString* CATCH_ARC_STRONG> {
+ static std::string convert(NSString * CATCH_ARC_STRONG nsstring);
+ };
+ template<>
+ struct StringMaker<NSObject *> {
+ static std::string convert(NSObject* nsObject);
+ };
+#endif
+
+} // namespace Catch
+
+// end catch_tostring.h
+#include <ostream>
+
+#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)
+#endif
+
+namespace Catch {
+
+ struct ITransientExpression {
+ virtual auto isBinaryExpression() const -> bool = 0;
+ virtual auto getResult() const -> bool = 0;
+ virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
+
+ // We don't actually need a virtual destructore, but many static analysers
+ // complain if it's not here :-(
+ virtual ~ITransientExpression() = default;
+ };
+
+ void formatReconstructedExpression( std::ostream &os, std::string const& lhs, std::string const& op, std::string const& rhs );
+
+ template<typename LhsT, typename RhsT>
+ class BinaryExpr : public ITransientExpression {
+ bool m_result;
+ LhsT m_lhs;
+ std::string m_op;
+ RhsT m_rhs;
+
+ auto isBinaryExpression() const -> bool override { return true; }
+ auto getResult() const -> bool override { return m_result; }
+
+ void streamReconstructedExpression( std::ostream &os ) const override {
+ formatReconstructedExpression
+ ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
+ }
+
+ public:
+ BinaryExpr( bool comparisionResult, LhsT lhs, StringRef op, RhsT rhs )
+ : m_result( comparisionResult ),
+ m_lhs( lhs ),
+ m_op( op ),
+ m_rhs( rhs )
+ {}
+ };
+
+ template<typename LhsT>
+ class UnaryExpr : public ITransientExpression {
+ LhsT m_lhs;
+
+ auto isBinaryExpression() const -> bool override { return false; }
+ auto getResult() const -> bool override { return m_lhs ? true : false; }
+
+ void streamReconstructedExpression( std::ostream &os ) const override {
+ os << Catch::Detail::stringify( m_lhs );
+ }
+
+ public:
+ UnaryExpr( LhsT 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 lhs, RhsT&& rhs ) -> bool { return 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( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; };
+
+ template<typename LhsT, typename RhsT>
+ auto compareNotEqual( LhsT lhs, RhsT&& rhs ) -> bool { return 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( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; };
+
+ template<typename LhsT>
+ class ExprLhs {
+ LhsT m_lhs;
+ public:
+ ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
+
+ template<typename RhsT>
+ auto operator == ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
+ return BinaryExpr<LhsT, RhsT&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs );
+ }
+ auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
+ return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs );
+ }
+
+ template<typename RhsT>
+ auto operator != ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
+ return BinaryExpr<LhsT, RhsT&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs );
+ }
+ auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
+ return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs );
+ }
+
+ template<typename RhsT>
+ auto operator > ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
+ return BinaryExpr<LhsT, RhsT&>( m_lhs > rhs, m_lhs, ">", rhs );
+ }
+ template<typename RhsT>
+ auto operator < ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
+ return BinaryExpr<LhsT, RhsT&>( m_lhs < rhs, m_lhs, "<", rhs );
+ }
+ template<typename RhsT>
+ auto operator >= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
+ return BinaryExpr<LhsT, RhsT&>( m_lhs >= rhs, m_lhs, ">=", rhs );
+ }
+ template<typename RhsT>
+ auto operator <= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
+ return BinaryExpr<LhsT, RhsT&>( m_lhs <= rhs, m_lhs, "<=", rhs );
+ }
+
+ auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
+ return UnaryExpr<LhsT>( m_lhs );
+ }
+ };
+
+ voi