diff --git a/.cirrus.yml b/.cirrus.yml
index 68223d7d5c4..7000bf6816b 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -8,7 +8,7 @@ task:
macos_instance:
image: ghcr.io/cirruslabs/macos-ventura-xcode
Dependencies_script: brew install ninja icu4c && mkdir -p build
- CMake_script: cd build && cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DSTATIC_LIBRARY=ON -DEMBED_ICU=ON -DDISABLE_JIT=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..
+ CMake_script: cd build && cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DSTATIC_LIBRARY=ON -DICU_INCLUDE_PATH=/opt/homebrew/opt/icu4c/include -DDISABLE_JIT=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..
Build_script: cd build && ninja
Test_script: cd build && ninja check
@@ -17,7 +17,7 @@ task:
macos_instance:
image: ghcr.io/cirruslabs/macos-ventura-xcode
Dependencies_script: brew install ninja icu4c && mkdir -p build
- CMake_script: cd build && cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DEMBED_ICU=ON -DDISABLE_JIT=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..
+ CMake_script: cd build && cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DICU_INCLUDE_PATH=/opt/homebrew/opt/icu4c/include -DDISABLE_JIT=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..
Build_script: cd build && ninja
Test_script: cd build && ninja check
@@ -26,6 +26,6 @@ task:
macos_instance:
image: ghcr.io/cirruslabs/macos-ventura-xcode
Dependencies_script: brew install ninja icu4c && mkdir -p build
- CMake_script: cd build && cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DSTATIC_LIBRARY=ON -DEMBED_ICU=ON -DDISABLE_JIT=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..
+ CMake_script: cd build && cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DSTATIC_LIBRARY=ON -DICU_INCLUDE_PATH=/opt/homebrew/opt/icu4c/include -DDISABLE_JIT=ON -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..
Build_script: cd build && ninja
Test_script: cd build && ninja check
diff --git a/.editorconfig b/.editorconfig
index 90120a467d7..f45849e2094 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -14,5 +14,5 @@ cpp_new_line_before_catch = true
cpp_new_line_before_else = true
# Xml files
-[*.xml]
+[*.{xml,props}]
indent_size = 2
diff --git a/Build/Common.Build.props b/Build/Common.Build.props
index 6bbec5610c6..7fda48ba400 100644
--- a/Build/Common.Build.props
+++ b/Build/Common.Build.props
@@ -98,7 +98,7 @@
%(PreprocessorDefinitions);CHAKRA_VERSION_BUILD_COMMIT=$(ChakraVersionBuildCommit)
%(PreprocessorDefinitions);CHAKRA_VERSION_BUILD_DATE=$(ChakraVersionBuildDate)
-
+ stdcpp17
%(PreprocessorDefinitions);CHAKRA_VERSION_BUILD_NUMBER=$(ChakraVersionBuildNumber)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c3a8aa5fdfd..beaf6298d2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -372,7 +372,7 @@ if(CLR_CMAKE_PLATFORM_XPLAT)
-D__STDC_WANT_LIB_EXT1__=1
)
- set(CMAKE_CXX_STANDARD 14)
+ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED On)
# todo: fix general visibility of the interface
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 52c77b7a86e..1e79fd37156 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -71,12 +71,12 @@ jobs:
image_name: 'macOS-latest'
deps: 'brew install ninja icu4c'
build_type: 'RelWithDebInfo'
- libtype_flag: '-DEMBED_ICU=ON'
+ libtype_flag: '-DICU_INCLUDE_PATH=/usr/local/opt/icu4c/include'
OSX.Release:
image_name: 'macOS-latest'
deps: 'brew install ninja icu4c'
build_type: 'Release'
- libtype_flag: '-DEMBED_ICU=ON'
+ libtype_flag: '-DICU_INCLUDE_PATH=/usr/local/opt/icu4c/include'
pool:
vmImage: $(image_name)
@@ -163,6 +163,14 @@ jobs:
do_test: true
test_tags: '--include-slow'
build_outdir_suffix: ''
+ win25.x64.Test:
+ image_name: 'windows-2025'
+ build_type: 'test'
+ target: 'x64'
+ special_build: ''
+ do_test: true
+ test_tags: '--include-slow'
+ build_outdir_suffix: ''
x64.Release:
image_name: 'windows-2022'
build_type: 'release'
diff --git a/bin/External/catch.hpp b/bin/External/catch.hpp
index 5739e527452..be38f26fe78 100644
--- a/bin/External/catch.hpp
+++ b/bin/External/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v1.5.6
- * Generated: 2016-06-09 19:20:41.460328
+ * Catch v1.12.2
+ * Generated: 2018-05-14 15:10:01.112442
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -40,6 +40,8 @@
#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
@@ -60,21 +62,6 @@
// #included from: catch_common.h
#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
-#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
-#include
-#include
-
// #included from: catch_compiler_capabilities.h
#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
@@ -89,11 +76,15 @@
// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
+// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
// 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
@@ -129,11 +120,46 @@
# endif
# if defined(CATCH_CPP11_OR_GREATER)
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+# 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
#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__
@@ -160,10 +186,6 @@
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# endif
-# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
-# endif
-
// - otherwise more recent versions define __cplusplus >= 201103L
// and will get picked up below
@@ -173,6 +195,8 @@
// Visual C++
#ifdef _MSC_VER
+#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
+
#if (_MSC_VER >= 1600)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
@@ -181,6 +205,8 @@
#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
+#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
#endif
#endif // _MSC_VER
@@ -199,10 +225,15 @@
// Use __COUNTER__ if the compiler supports it
#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
- ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
+ ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
( defined __clang__ && __clang_major__ >= 3 )
-#define CATCH_INTERNAL_CONFIG_COUNTER
+// Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former,
+// because __COUNTER__ is not properly handled by it.
+// This does not affect compilation
+#if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L )
+ #define CATCH_INTERNAL_CONFIG_COUNTER
+#endif
#endif
@@ -246,6 +277,12 @@
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
+# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
+# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
+# endif
#endif // __cplusplus >= 201103L
@@ -268,21 +305,39 @@
#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
# define CATCH_CONFIG_VARIADIC_MACROS
#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_LONG_LONG
#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_OVERRIDE
#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
#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_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_SHUFFLE
+#endif
+# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TYPE_TRAITS
+# 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
// noexcept support:
@@ -315,6 +370,20 @@
# define CATCH_AUTO_PTR( T ) std::auto_ptr
#endif
+#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
+#include
+
namespace Catch {
struct IConfig;
@@ -352,14 +421,14 @@ namespace Catch {
};
template
- inline void deleteAll( ContainerT& container ) {
+ void deleteAll( ContainerT& container ) {
typename ContainerT::const_iterator it = container.begin();
typename ContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )
delete *it;
}
template
- inline void deleteAllValues( AssociativeContainerT& container ) {
+ void deleteAllValues( AssociativeContainerT& container ) {
typename AssociativeContainerT::const_iterator it = container.begin();
typename AssociativeContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )
@@ -367,7 +436,9 @@ 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 );
@@ -387,8 +458,8 @@ namespace Catch {
SourceLineInfo();
SourceLineInfo( char const* _file, std::size_t _line );
- SourceLineInfo( SourceLineInfo const& other );
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SourceLineInfo(SourceLineInfo const& other) = default;
SourceLineInfo( SourceLineInfo && ) = default;
SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
SourceLineInfo& operator = ( SourceLineInfo && ) = default;
@@ -397,7 +468,7 @@ namespace Catch {
bool operator == ( SourceLineInfo const& other ) const;
bool operator < ( SourceLineInfo const& other ) const;
- std::string file;
+ char const* file;
std::size_t line;
};
@@ -431,15 +502,12 @@ namespace Catch {
#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) )
#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
-#include
-
namespace Catch {
class NotImplementedException : public std::exception
{
public:
NotImplementedException( SourceLineInfo const& lineInfo );
- NotImplementedException( NotImplementedException const& ) {}
virtual ~NotImplementedException() CATCH_NOEXCEPT {}
@@ -565,10 +633,6 @@ namespace Catch {
#pragma clang diagnostic pop
#endif
-#include
-#include
-#include
-
namespace Catch {
class TestCase;
@@ -712,59 +776,76 @@ void registerTestCaseFunction
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __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, ... ) \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* 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 ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* 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::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
#else
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
static void TestName(); \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
namespace{ \
struct TestCaseName : ClassName{ \
void test(); \
}; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
} \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
void TestCaseName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
- Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \
+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
#endif
// #included from: internal/catch_capture.hpp
@@ -832,27 +913,83 @@ namespace Catch {
namespace Catch {
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct DecomposedExpression
+ {
+ virtual ~DecomposedExpression() {}
+ virtual bool isBinaryExpression() const {
+ return false;
+ }
+ virtual void reconstructExpression( std::string& dest ) const = 0;
+
+ // Only simple binary comparisons can be decomposed.
+ // If more complex check is required then wrap sub-expressions in parentheses.
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
+
+ private:
+ DecomposedExpression& operator = (DecomposedExpression const&);
+ };
+
struct AssertionInfo
{
- AssertionInfo() {}
- AssertionInfo( std::string const& _macroName,
+ AssertionInfo();
+ AssertionInfo( char const * _macroName,
SourceLineInfo const& _lineInfo,
- std::string const& _capturedExpression,
- ResultDisposition::Flags _resultDisposition );
+ char const * _capturedExpression,
+ ResultDisposition::Flags _resultDisposition,
+ char const * _secondArg = "");
- std::string macroName;
+ char const * macroName;
SourceLineInfo lineInfo;
- std::string capturedExpression;
+ char const * capturedExpression;
ResultDisposition::Flags resultDisposition;
+ char const * secondArg;
};
struct AssertionResultData
{
- AssertionResultData() : resultType( ResultWas::Unknown ) {}
+ AssertionResultData() : decomposedExpression( CATCH_NULL )
+ , resultType( ResultWas::Unknown )
+ , negated( false )
+ , parenthesized( false ) {}
+
+ void negate( bool parenthesize ) {
+ negated = !negated;
+ parenthesized = parenthesize;
+ if( resultType == ResultWas::Ok )
+ resultType = ResultWas::ExpressionFailed;
+ else if( resultType == ResultWas::ExpressionFailed )
+ resultType = ResultWas::Ok;
+ }
+
+ std::string const& reconstructExpression() const {
+ if( decomposedExpression != CATCH_NULL ) {
+ decomposedExpression->reconstructExpression( reconstructedExpression );
+ if( parenthesized ) {
+ reconstructedExpression.insert( 0, 1, '(' );
+ reconstructedExpression.append( 1, ')' );
+ }
+ if( negated ) {
+ reconstructedExpression.insert( 0, 1, '!' );
+ }
+ decomposedExpression = CATCH_NULL;
+ }
+ return reconstructedExpression;
+ }
- std::string reconstructedExpression;
+ mutable DecomposedExpression const* decomposedExpression;
+ mutable std::string reconstructedExpression;
std::string message;
ResultWas::OfType resultType;
+ bool negated;
+ bool parenthesized;
};
class AssertionResult {
@@ -879,6 +1016,8 @@ namespace Catch {
std::string getMessage() const;
SourceLineInfo getSourceInfo() const;
std::string getTestMacroName() const;
+ void discardDecomposedExpression() const;
+ void expandDecomposedExpression() const;
protected:
AssertionInfo m_info;
@@ -894,313 +1033,161 @@ namespace Catch {
namespace Matchers {
namespace Impl {
- namespace Generic {
- template class AllOf;
- template class AnyOf;
- template class Not;
- }
-
- template
- struct Matcher : SharedImpl
- {
- typedef ExpressionT ExpressionType;
+ template struct MatchAllOf;
+ template struct MatchAnyOf;
+ template struct MatchNotOf;
- virtual ~Matcher() {}
- virtual Ptr clone() const = 0;
- virtual bool match( ExpressionT const& expr ) const = 0;
- virtual std::string toString() const = 0;
-
- Generic::AllOf operator && ( Matcher const& other ) const;
- Generic::AnyOf operator || ( Matcher const& other ) const;
- Generic::Not operator ! () const;
- };
-
- template
- struct MatcherImpl : Matcher {
-
- virtual Ptr > clone() const {
- return Ptr >( new DerivedT( static_cast( *this ) ) );
- }
- };
-
- namespace Generic {
- template
- class Not : public MatcherImpl, ExpressionT> {
+ class MatcherUntypedBase {
public:
- explicit Not( Matcher const& matcher ) : m_matcher(matcher.clone()) {}
- Not( Not const& other ) : m_matcher( other.m_matcher ) {}
-
- virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
- return !m_matcher->match( expr );
+ std::string toString() const {
+ if( m_cachedToString.empty() )
+ m_cachedToString = describe();
+ return m_cachedToString;
}
- virtual std::string toString() const CATCH_OVERRIDE {
- return "not " + m_matcher->toString();
- }
+ protected:
+ virtual ~MatcherUntypedBase();
+ virtual std::string describe() const = 0;
+ mutable std::string m_cachedToString;
private:
- Ptr< Matcher > m_matcher;
+ MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
};
- template
- class AllOf : public MatcherImpl, ExpressionT> {
- public:
+ template
+ struct MatcherMethod {
+ virtual bool match( ObjectT const& arg ) const = 0;
+ };
+ template
+ struct MatcherMethod {
+ virtual bool match( PtrT* arg ) const = 0;
+ };
- AllOf() {}
- AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
+ template
+ struct MatcherBase : MatcherUntypedBase, MatcherMethod {
- AllOf& add( Matcher const& matcher ) {
- m_matchers.push_back( matcher.clone() );
- return *this;
- }
- virtual bool match( ExpressionT const& expr ) const
- {
- for( std::size_t i = 0; i < m_matchers.size(); ++i )
- if( !m_matchers[i]->match( expr ) )
+ MatchAllOf operator && ( MatcherBase const& other ) const;
+ MatchAnyOf operator || ( MatcherBase const& other ) const;
+ MatchNotOf operator ! () const;
+ };
+
+ template
+ struct MatchAllOf : MatcherBase {
+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if (!m_matchers[i]->match(arg))
return false;
+ }
return true;
}
- virtual std::string toString() const {
- std::ostringstream oss;
- oss << "( ";
+ virtual std::string describe() const CATCH_OVERRIDE {
+ std::string description;
+ description.reserve( 4 + m_matchers.size()*32 );
+ description += "( ";
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
if( i != 0 )
- oss << " and ";
- oss << m_matchers[i]->toString();
+ description += " and ";
+ description += m_matchers[i]->toString();
}
- oss << " )";
- return oss.str();
+ description += " )";
+ return description;
}
- AllOf operator && ( Matcher const& other ) const {
- AllOf allOfExpr( *this );
- allOfExpr.add( other );
- return allOfExpr;
+ MatchAllOf& operator && ( MatcherBase const& other ) {
+ m_matchers.push_back( &other );
+ return *this;
}
- private:
- std::vector > > m_matchers;
+ std::vector const*> m_matchers;
};
+ template
+ struct MatchAnyOf : MatcherBase {
- template
- class AnyOf : public MatcherImpl, ExpressionT> {
- public:
-
- AnyOf() {}
- AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
-
- AnyOf& add( Matcher const& matcher ) {
- m_matchers.push_back( matcher.clone() );
- return *this;
- }
- virtual bool match( ExpressionT const& expr ) const
- {
- for( std::size_t i = 0; i < m_matchers.size(); ++i )
- if( m_matchers[i]->match( expr ) )
+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if (m_matchers[i]->match(arg))
return true;
+ }
return false;
}
- virtual std::string toString() const {
- std::ostringstream oss;
- oss << "( ";
+ virtual std::string describe() const CATCH_OVERRIDE {
+ std::string description;
+ description.reserve( 4 + m_matchers.size()*32 );
+ description += "( ";
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
if( i != 0 )
- oss << " or ";
- oss << m_matchers[i]->toString();
+ description += " or ";
+ description += m_matchers[i]->toString();
}
- oss << " )";
- return oss.str();
- }
-
- AnyOf operator || ( Matcher const& other ) const {
- AnyOf anyOfExpr( *this );
- anyOfExpr.add( other );
- return anyOfExpr;
+ description += " )";
+ return description;
}
- private:
- std::vector > > m_matchers;
- };
-
- } // namespace Generic
-
- template
- Generic::AllOf Matcher::operator && ( Matcher const& other ) const {
- Generic::AllOf allOfExpr;
- allOfExpr.add( *this );
- allOfExpr.add( other );
- return allOfExpr;
- }
-
- template
- Generic::AnyOf Matcher::operator || ( Matcher const& other ) const {
- Generic::AnyOf anyOfExpr;
- anyOfExpr.add( *this );
- anyOfExpr.add( other );
- return anyOfExpr;
- }
-
- template
- Generic::Not Matcher::operator ! () const {
- return Generic::Not( *this );
- }
-
- namespace StdString {
-
- inline std::string makeString( std::string const& str ) { return str; }
- inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
-
- struct CasedString
- {
- CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
- : m_caseSensitivity( caseSensitivity ),
- m_str( adjustString( str ) )
- {}
- std::string adjustString( std::string const& str ) const {
- return m_caseSensitivity == CaseSensitive::No
- ? toLower( str )
- : str;
-
- }
- std::string toStringSuffix() const
- {
- return m_caseSensitivity == CaseSensitive::No
- ? " (case insensitive)"
- : "";
- }
- CaseSensitive::Choice m_caseSensitivity;
- std::string m_str;
- };
-
- struct Equals : MatcherImpl {
- Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
- : m_data( str, caseSensitivity )
- {}
- Equals( Equals const& other ) : m_data( other.m_data ){}
-
- virtual ~Equals();
-
- virtual bool match( std::string const& expr ) const {
- return m_data.m_str == m_data.adjustString( expr );;
- }
- virtual std::string toString() const {
- return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ MatchAnyOf& operator || ( MatcherBase const& other ) {
+ m_matchers.push_back( &other );
+ return *this;
}
- CasedString m_data;
+ std::vector const*> m_matchers;
};
- struct Contains : MatcherImpl {
- Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
- : m_data( substr, caseSensitivity ){}
- Contains( Contains const& other ) : m_data( other.m_data ){}
+ template
+ struct MatchNotOf : MatcherBase {
- virtual ~Contains();
+ MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
- virtual bool match( std::string const& expr ) const {
- return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
- }
- virtual std::string toString() const {
- return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+ return !m_underlyingMatcher.match( arg );
}
- CasedString m_data;
- };
-
- struct StartsWith : MatcherImpl {
- StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
- : m_data( substr, caseSensitivity ){}
-
- StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
-
- virtual ~StartsWith();
-
- virtual bool match( std::string const& expr ) const {
- return startsWith( m_data.adjustString( expr ), m_data.m_str );
- }
- virtual std::string toString() const {
- return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ virtual std::string describe() const CATCH_OVERRIDE {
+ return "not " + m_underlyingMatcher.toString();
}
-
- CasedString m_data;
+ MatcherBase const& m_underlyingMatcher;
};
- struct EndsWith : MatcherImpl {
- EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
- : m_data( substr, caseSensitivity ){}
- EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
-
- virtual ~EndsWith();
-
- virtual bool match( std::string const& expr ) const {
- return endsWith( m_data.adjustString( expr ), m_data.m_str );
- }
- virtual std::string toString() const {
- return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
- }
+ template
+ MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const {
+ return MatchAllOf() && *this && other;
+ }
+ template
+ MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const {
+ return MatchAnyOf() || *this || other;
+ }
+ template
+ MatchNotOf MatcherBase::operator ! () const {
+ return MatchNotOf( *this );
+ }
- CasedString m_data;
- };
- } // namespace StdString
} // namespace Impl
// The following functions create the actual matcher objects.
// This allows the types to be inferred
- template
- inline Impl::Generic::Not Not( Impl::Matcher const& m ) {
- return Impl::Generic::Not( m );
- }
-
- template
- inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1,
- Impl::Matcher const& m2 ) {
- return Impl::Generic::AllOf().add( m1 ).add( m2 );
- }
- template
- inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1,
- Impl::Matcher const& m2,
- Impl::Matcher const& m3 ) {
- return Impl::Generic::AllOf().add( m1 ).add( m2 ).add( m3 );
- }
- template
- inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1,
- Impl::Matcher const& m2 ) {
- return Impl::Generic::AnyOf().add( m1 ).add( m2 );
- }
- template
- inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1,
- Impl::Matcher const& m2,
- Impl::Matcher const& m3 ) {
- return Impl::Generic::AnyOf().add( m1 ).add( m2 ).add( m3 );
- }
-
- inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
- return Impl::StdString::Equals( str, caseSensitivity );
- }
- inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
- return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
- }
- inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
- return Impl::StdString::Contains( substr, caseSensitivity );
- }
- inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
- return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
+ // - deprecated: prefer ||, && and !
+ template
+ Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) {
+ return Impl::MatchNotOf( underlyingMatcher );
}
- inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
- return Impl::StdString::StartsWith( substr );
+ template
+ Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) {
+ return Impl::MatchAllOf() && m1 && m2;
}
- inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
- return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
+ template
+ Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) {
+ return Impl::MatchAllOf() && m1 && m2 && m3;
}
- inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
- return Impl::StdString::EndsWith( substr );
+ template
+ Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) {
+ return Impl::MatchAnyOf() || m1 || m2;
}
- inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
- return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
+ template
+ Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) {
+ return Impl::MatchAnyOf() || m1 || m2 || m3;
}
} // namespace Matchers
using namespace Matchers;
+using Matchers::Impl::MatcherBase;
} // namespace Catch
@@ -1210,28 +1197,27 @@ namespace Catch {
template class ExpressionLhs;
- struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
-
struct CopyableStream {
CopyableStream() {}
CopyableStream( CopyableStream const& other ) {
oss << other.oss.str();
}
CopyableStream& operator=( CopyableStream const& other ) {
- oss.str("");
+ oss.str(std::string());
oss << other.oss.str();
return *this;
}
std::ostringstream oss;
};
- class ResultBuilder {
+ class ResultBuilder : public DecomposedExpression {
public:
ResultBuilder( char const* macroName,
SourceLineInfo const& lineInfo,
char const* capturedExpression,
ResultDisposition::Flags resultDisposition,
char const* secondArg = "" );
+ ~ResultBuilder();
template
ExpressionLhs operator <= ( T const& operand );
@@ -1239,46 +1225,60 @@ namespace Catch {
template
ResultBuilder& operator << ( T const& value ) {
- m_stream.oss << value;
+ stream().oss << value;
return *this;
}
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
-
ResultBuilder& setResultType( ResultWas::OfType result );
ResultBuilder& setResultType( bool result );
- ResultBuilder& setLhs( std::string const& lhs );
- ResultBuilder& setRhs( std::string const& rhs );
- ResultBuilder& setOp( std::string const& op );
- void endExpression();
+ void endExpression( DecomposedExpression const& expr );
+
+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
- std::string reconstructExpression() const;
AssertionResult build() const;
+ AssertionResult build( DecomposedExpression const& expr ) const;
void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
void captureResult( ResultWas::OfType resultType );
void captureExpression();
void captureExpectedException( std::string const& expectedMessage );
- void captureExpectedException( Matchers::Impl::Matcher const& matcher );
+ void captureExpectedException( Matchers::Impl::MatcherBase const& matcher );
void handleResult( AssertionResult const& result );
void react();
bool shouldDebugBreak() const;
bool allowThrows() const;
+ template
+ void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
+
+ void setExceptionGuard();
+ void unsetExceptionGuard();
+
private:
AssertionInfo m_assertionInfo;
AssertionResultData m_data;
- struct ExprComponents {
- ExprComponents() : testFalse( false ) {}
- bool testFalse;
- std::string lhs, rhs, op;
- } m_exprComponents;
- CopyableStream m_stream;
+
+ CopyableStream &stream()
+ {
+ if(!m_usedStream)
+ {
+ m_usedStream = true;
+ m_stream().oss.str("");
+ }
+ return m_stream();
+ }
+
+ static CopyableStream &m_stream()
+ {
+ static CopyableStream s;
+ return s;
+ }
bool m_shouldDebugBreak;
bool m_shouldThrow;
+ bool m_guardException;
+ bool m_usedStream;
};
} // namespace Catch
@@ -1293,6 +1293,8 @@ namespace Catch {
#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
#include
@@ -1318,7 +1320,7 @@ namespace Internal {
template<> struct OperatorTraits{ static const char* getName(){ return ">="; } };
template
- inline T& opCast(T const& t) { return const_cast(t); }
+ T& opCast(T const& t) { return const_cast(t); }
// nullptr_t support based on pull request #154 from Konstantin Baumann
#ifdef CATCH_CONFIG_CPP11_NULLPTR
@@ -1328,7 +1330,7 @@ namespace Internal {
// So the compare overloads can be operator agnostic we convey the operator as a template
// enum, which is used to specialise an Evaluator for doing the comparison.
template
- class Evaluator{};
+ struct Evaluator{};
template
struct Evaluator {
@@ -1571,8 +1573,8 @@ std::string toString( std::string const& value );
std::string toString( std::wstring const& value );
std::string toString( const char* const value );
std::string toString( char* const value );
-std::string toString( const WCHAR* const value );
-std::string toString( WCHAR* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
std::string toString( int value );
std::string toString( unsigned long value );
std::string toString( unsigned int value );
@@ -1594,7 +1596,7 @@ std::string toString( std::nullptr_t );
#ifdef __OBJC__
std::string toString( NSString const * const& nsstring );
- std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
+ std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
std::string toString( NSObject* const& nsObject );
#endif
@@ -1602,6 +1604,7 @@ namespace Detail {
extern const std::string unprintableString;
+ #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
struct BorgType {
template BorgType( T const& );
};
@@ -1620,6 +1623,20 @@ namespace Detail {
static T const&t;
enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
};
+#else
+ template
+ class IsStreamInsertable {
+ template
+ static auto test(int)
+ -> decltype( std::declval() << std::declval(), std::true_type() );
+
+ template
+ static auto test(...) -> std::false_type;
+
+ public:
+ static const bool value = decltype(test(0))::value;
+ };
+#endif
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
template
- inline std::string rawMemoryToString( const T& object ) {
+ std::string rawMemoryToString( const T& object ) {
return rawMemoryToString( &object, sizeof(object) );
}
@@ -1796,90 +1813,159 @@ std::string toString( T const& value ) {
namespace Catch {
-// Wraps the LHS of an expression and captures the operator and RHS (if any) -
-// wrapping them all in a ResultBuilder object
-template
-class ExpressionLhs {
- ExpressionLhs& operator = ( ExpressionLhs const& );
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
-# endif
+template
+class BinaryExpression;
+
+template
+class MatchExpression;
+// Wraps the LHS of an expression and overloads comparison operators
+// for also capturing those and RHS (if any)
+template
+class ExpressionLhs : public DecomposedExpression {
public:
- ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
- ExpressionLhs( ExpressionLhs const& ) = default;
- ExpressionLhs( ExpressionLhs && ) = default;
-# endif
+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
+
+ ExpressionLhs& operator = ( const ExpressionLhs& );
template
- ResultBuilder& operator == ( RhsT const& rhs ) {
+ BinaryExpression
+ operator == ( RhsT const& rhs ) {
return captureExpression( rhs );
}
template
- ResultBuilder& operator != ( RhsT const& rhs ) {
+ BinaryExpression
+ operator != ( RhsT const& rhs ) {
return captureExpression( rhs );
}
template
- ResultBuilder& operator < ( RhsT const& rhs ) {
+ BinaryExpression
+ operator < ( RhsT const& rhs ) {
return captureExpression( rhs );
}
template
- ResultBuilder& operator > ( RhsT const& rhs ) {
+ BinaryExpression
+ operator > ( RhsT const& rhs ) {
return captureExpression( rhs );
}
template
- ResultBuilder& operator <= ( RhsT const& rhs ) {
+ BinaryExpression
+ operator <= ( RhsT const& rhs ) {
return captureExpression( rhs );
}
template
- ResultBuilder& operator >= ( RhsT const& rhs ) {
+ BinaryExpression
+ operator >= ( RhsT const& rhs ) {
return captureExpression( rhs );
}
- ResultBuilder& operator == ( bool rhs ) {
+ BinaryExpression operator == ( bool rhs ) {
return captureExpression( rhs );
}
- ResultBuilder& operator != ( bool rhs ) {
+ BinaryExpression operator != ( bool rhs ) {
return captureExpression( rhs );
}
void endExpression() {
- bool value = m_lhs ? true : false;
+ m_truthy = m_lhs ? true : false;
m_rb
- .setLhs( Catch::toString( value ) )
- .setResultType( value )
- .endExpression();
+ .setResultType( m_truthy )
+ .endExpression( *this );
}
- // Only simple binary expressions are allowed on the LHS.
- // If more complex compositions are required then place the sub expression in parentheses
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
- template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
+ dest = Catch::toString( m_lhs );
+ }
private:
template
- ResultBuilder& captureExpression( RhsT const& rhs ) {
- return m_rb
- .setResultType( Internal::compare( m_lhs, rhs ) )
- .setLhs( Catch::toString( m_lhs ) )
- .setRhs( Catch::toString( rhs ) )
- .setOp( Internal::OperatorTraits::getName() );
+ BinaryExpression captureExpression( RhsT& rhs ) const {
+ return BinaryExpression( m_rb, m_lhs, rhs );
+ }
+
+ template
+ BinaryExpression captureExpression( bool rhs ) const {
+ return BinaryExpression( m_rb, m_lhs, rhs );
}
private:
ResultBuilder& m_rb;
T m_lhs;
+ bool m_truthy;
+};
+
+template
+class BinaryExpression : public DecomposedExpression {
+public:
+ BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
+ : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
+
+ BinaryExpression& operator = ( BinaryExpression& );
+
+ void endExpression() const {
+ m_rb
+ .setResultType( Internal::compare( m_lhs, m_rhs ) )
+ .endExpression( *this );
+ }
+
+ virtual bool isBinaryExpression() const CATCH_OVERRIDE {
+ return true;
+ }
+
+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
+ std::string lhs = Catch::toString( m_lhs );
+ std::string rhs = Catch::toString( m_rhs );
+ char delim = lhs.size() + rhs.size() < 40 &&
+ lhs.find('\n') == std::string::npos &&
+ rhs.find('\n') == std::string::npos ? ' ' : '\n';
+ dest.reserve( 7 + lhs.size() + rhs.size() );
+ // 2 for spaces around operator
+ // 2 for operator
+ // 2 for parentheses (conditionally added later)
+ // 1 for negation (conditionally added later)
+ dest = lhs;
+ dest += delim;
+ dest += Internal::OperatorTraits::getName();
+ dest += delim;
+ dest += rhs;
+ }
+
+private:
+ ResultBuilder& m_rb;
+ LhsT m_lhs;
+ RhsT m_rhs;
+};
+
+template
+class MatchExpression : public DecomposedExpression {
+public:
+ MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
+ : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
+
+ virtual bool isBinaryExpression() const CATCH_OVERRIDE {
+ return true;
+ }
+
+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
+ std::string matcherAsString = m_matcher.toString();
+ dest = Catch::toString( m_arg );
+ dest += ' ';
+ if( matcherAsString == Detail::unprintableString )
+ dest += m_matcherString;
+ else
+ dest += matcherAsString;
+ }
+
+private:
+ ArgT m_arg;
+ MatcherT m_matcher;
+ char const* m_matcherString;
};
} // end namespace Catch
@@ -1888,7 +1974,7 @@ class ExpressionLhs {
namespace Catch {
template
- inline ExpressionLhs ResultBuilder::operator <= ( T const& operand ) {
+ ExpressionLhs ResultBuilder::operator <= ( T const& operand ) {
return ExpressionLhs( *this, operand );
}
@@ -1896,6 +1982,14 @@ namespace Catch {
return ExpressionLhs( *this, value );
}
+ template
+ void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
+ char const* matcherString ) {
+ MatchExpression expr( arg, matcher, matcherString );
+ setResultType( matcher.match( arg ) );
+ endExpression( expr );
+ }
+
} // namespace Catch
// #included from: catch_message.h
@@ -1985,7 +2079,13 @@ namespace Catch {
virtual std::string getCurrentTestName() const = 0;
virtual const AssertionResult* getLastResult() const = 0;
+ virtual void exceptionEarlyReported() = 0;
+
virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+
+ virtual bool lastAssertionPassed() = 0;
+ virtual void assertionPassed() = 0;
+ virtual void assertionRun() = 0;
};
IResultCapture& getResultCapture();
@@ -1998,11 +2098,19 @@ namespace Catch {
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
-#define CATCH_PLATFORM_MAC
+# define CATCH_PLATFORM_MAC
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
-#define CATCH_PLATFORM_IPHONE
+# define CATCH_PLATFORM_IPHONE
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+# define CATCH_PLATFORM_LINUX
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
-#define CATCH_PLATFORM_WINDOWS
+# define CATCH_PLATFORM_WINDOWS
+# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+# define CATCH_DEFINES_NOMINMAX
+# endif
+# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
+# endif
#endif
#include
@@ -2017,27 +2125,36 @@ namespace Catch{
// The following code snippet based on:
// http://cocoawithlove.com/2008/03/break-into-debugger.html
- #ifdef DEBUG
- #if defined(__ppc64__) || defined(__ppc__)
- #define CATCH_BREAK_INTO_DEBUGGER() \
- if( Catch::isDebuggerActive() ) { \
- __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
- : : : "memory","r0","r3","r4" ); \
- }
- #else
- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
- #endif
+ #if defined(__ppc64__) || defined(__ppc__)
+ #define CATCH_TRAP() \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ) /* NOLINT */
+ #else
+ #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
#endif
+#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
+
+ #define CATCH_TRAP() raise(SIGTRAP)
+ #endif
#elif defined(_MSC_VER)
- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
+ #define CATCH_TRAP() __debugbreak()
#elif defined(__MINGW32__)
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
+ #define CATCH_TRAP() DebugBreak()
#endif
-#ifndef CATCH_BREAK_INTO_DEBUGGER
-#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#ifdef CATCH_TRAP
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
+#else
+ #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
#endif
// #included from: catch_interfaces_runner.h
@@ -2052,6 +2169,47 @@ namespace Catch {
};
}
+#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
+# define CATCH_INTERNAL_STRINGIFY(expr) #expr
+#else
+# define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
+#endif
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+///////////////////////////////////////////////////////////////////////////////
+// We can speedup compilation significantly by breaking into debugger lower in
+// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
+// macro in each assertion
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+ resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
+// macros.
+// This can potentially cause false negative, if the test code catches
+// the exception before it propagates back up to the runner.
+#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
+ __catchResult.setExceptionGuard(); \
+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ ( __catchResult <= expr ).endExpression(); \
+ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+ __catchResult.unsetExceptionGuard(); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr 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_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+ __catchResult.setExceptionGuard(); \
+ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
+ __catchResult.unsetExceptionGuard(); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+#else
///////////////////////////////////////////////////////////////////////////////
// In the event of a failure works out if the debugger needs to be invoked
// and/or an exception thrown and takes appropriate action.
@@ -2060,37 +2218,40 @@ namespace Catch {
#define INTERNAL_CATCH_REACT( resultBuilder ) \
if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
resultBuilder.react();
+#endif
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
+#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
try { \
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
( __catchResult <= expr ).endExpression(); \
+ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
} \
catch( ... ) { \
- __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
+ __catchResult.useActiveException( resultDisposition ); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
- } while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+ } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr 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( expr, resultDisposition, macroName ) \
- INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
- if( Catch::getResultCapture().getLastResult()->succeeded() )
+#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
+ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
+ if( Catch::getResultCapture().lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
- INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
- if( !Catch::getResultCapture().getLastResult()->succeeded() )
+#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
+ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
+ if( !Catch::getResultCapture().lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
+#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
try { \
- expr; \
+ static_cast(expr); \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
} \
catch( ... ) { \
@@ -2100,12 +2261,12 @@ namespace Catch {
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
+#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \
if( __catchResult.allowThrows() ) \
try { \
- expr; \
+ static_cast(expr); \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( ... ) { \
@@ -2117,12 +2278,12 @@ namespace Catch {
} while( Catch::alwaysFalse() )
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
+#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
if( __catchResult.allowThrows() ) \
try { \
- expr; \
+ static_cast(expr); \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( exceptionType ) { \
@@ -2138,7 +2299,7 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////////
#ifdef CATCH_CONFIG_VARIADIC_MACROS
- #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
+ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
@@ -2146,7 +2307,7 @@ namespace Catch {
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#else
- #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
+ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << log + ::Catch::StreamEndStop(); \
@@ -2156,21 +2317,15 @@ namespace Catch {
#endif
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CATCH_INFO( log, macroName ) \
+#define INTERNAL_CATCH_INFO( macroName, log ) \
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
///////////////////////////////////////////////////////////////////////////////
-#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
+#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
do { \
- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
try { \
- std::string matcherAsString = (matcher).toString(); \
- __catchResult \
- .setLhs( Catch::toString( arg ) ) \
- .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
- .setOp( "matches" ) \
- .setResultType( (matcher).match( arg ) ); \
- __catchResult.captureExpression(); \
+ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
} catch( ... ) { \
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
} \
@@ -2253,6 +2408,8 @@ namespace Catch {
};
}
+#include
+
namespace Catch {
struct SectionInfo {
@@ -2281,14 +2438,19 @@ namespace Catch {
// #included from: catch_timer.h
#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
-#ifdef CATCH_PLATFORM_WINDOWS
-typedef unsigned long long uint64_t;
+#ifdef _MSC_VER
+
+namespace Catch {
+ typedef unsigned long long UInt64;
+}
#else
#include
+namespace Catch {
+ typedef uint64_t UInt64;
+}
#endif
namespace Catch {
-
class Timer {
public:
Timer() : m_ticks( 0 ) {}
@@ -2298,7 +2460,7 @@ namespace Catch {
double getElapsedSeconds() const;
private:
- uint64_t m_ticks;
+ UInt64 m_ticks;
};
} // namespace Catch
@@ -2337,7 +2499,6 @@ namespace Catch {
// #included from: internal/catch_generators.hpp
#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
-#include
#include
#include
#include
@@ -2451,7 +2612,7 @@ class CompositeGenerator {
private:
void move( CompositeGenerator& other ) {
- std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
+ m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
m_totalSize += other.m_totalSize;
other.m_composed.clear();
}
@@ -2533,12 +2694,15 @@ namespace Catch {
struct IExceptionTranslator;
struct IReporterRegistry;
struct IReporterFactory;
+ struct ITagAliasRegistry;
struct IRegistryHub {
virtual ~IRegistryHub();
virtual IReporterRegistry const& getReporterRegistry() const = 0;
virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
+
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
};
@@ -2548,6 +2712,7 @@ namespace Catch {
virtual void registerListener( Ptr 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;
};
IRegistryHub& getRegistryHub();
@@ -2623,6 +2788,10 @@ namespace Catch {
#include
#include
+#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
+#include
+#endif
+
namespace Catch {
namespace Detail {
@@ -2630,30 +2799,112 @@ namespace Detail {
public:
explicit Approx ( double value )
: m_epsilon( std::numeric_limits::epsilon()*100 ),
+ m_margin( 0.0 ),
m_scale( 1.0 ),
m_value( value )
{}
- Approx( Approx const& other )
- : m_epsilon( other.m_epsilon ),
- m_scale( other.m_scale ),
- m_value( other.m_value )
- {}
-
static Approx custom() {
return Approx( 0 );
}
+#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
+
+ template ::value>::type>
+ Approx operator()( T value ) {
+ Approx approx( static_cast(value) );
+ approx.epsilon( m_epsilon );
+ approx.margin( m_margin );
+ approx.scale( m_scale );
+ return approx;
+ }
+
+ template