diff --git a/CMakeLists.txt b/CMakeLists.txt
index 92a55dae..41d2f44a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark)
set(HEADER_DIR ${CATCH_DIR}/include)
-set(CATCH_VERSION_NUMBER 2.0.0-develop.6)
+set(CATCH_VERSION_NUMBER 2.0.1)
if(USE_CPP14)
message(STATUS "Enabling C++14")
diff --git a/conanfile.py b/conanfile.py
index 5e6886ca..b4993b71 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,7 +4,7 @@ from conans import ConanFile
class CatchConan(ConanFile):
name = "Catch"
- version = "2.0.0-develop.6"
+ version = "2.0.1"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 92659884..f51f68fb 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,5 +1,5 @@
-# 2.0.0 (in progress)
+# 2.0.1
## Breaking changes
* Removed C++98 support
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index 699a4843..a9dc64e6 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 0, 0, "develop", 6 );
+ static Version version( 2, 0, 1, "", 0 );
return version;
}
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
index bc9e447d..362f8693 100644
--- a/single_include/catch.hpp
+++ b/single_include/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.0.0-develop.6
- * Generated: 2017-10-31 15:09:47.277913
+ * Catch v2.0.1
+ * Generated: 2017-11-03 11:53:39.642003
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
@@ -1835,16 +1835,15 @@ namespace Catch {
do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
// end catch_enforce.h
-#include
-
#include
namespace Catch {
namespace Detail {
- double dmax(double lhs, double rhs);
-
class Approx {
+ private:
+ bool equalityComparisonImpl(double other) const;
+
public:
explicit Approx ( double value );
@@ -1865,14 +1864,8 @@ namespace Detail {
template ::value>::type>
friend bool operator == ( const T& lhs, Approx const& rhs ) {
- // Thanks to Richard Harris for his help refining this formula
auto lhs_v = static_cast(lhs);
- bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale +
- dmax(std::fabs(lhs_v), std::fabs(rhs.m_value)));
- if (relativeOK) {
- return true;
- }
- return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin;
+ return rhs.equalityComparisonImpl(lhs_v);
}
template ::value>::type>
@@ -1912,14 +1905,21 @@ namespace Detail {
template ::value>::type>
Approx& epsilon( T const& newEpsilon ) {
- m_epsilon = static_cast(newEpsilon);
+ double epsilonAsDouble = static_cast(newEpsilon);
+ CATCH_ENFORCE(epsilonAsDouble >= 0 && epsilonAsDouble <= 1.0,
+ "Invalid Approx::epsilon: " << epsilonAsDouble
+ << ", Approx::epsilon has to be between 0 and 1");
+ m_epsilon = epsilonAsDouble;
return *this;
}
template ::value>::type>
Approx& margin( T const& newMargin ) {
- m_margin = static_cast(newMargin);
- CATCH_ENFORCE(m_margin >= 0, "Invalid Approx::margin: " << m_margin << ", Approx::Margin has to be non-negative.");
+ double marginAsDouble = static_cast(newMargin);
+ CATCH_ENFORCE(marginAsDouble >= 0,
+ "Invalid Approx::margin: " << marginAsDouble
+ << ", Approx::Margin has to be non-negative.");
+ m_margin = marginAsDouble;
return *this;
}
@@ -3980,22 +3980,26 @@ namespace Catch {
// Cpp files will be included in the single-header file here
// start catch_approx.cpp
+#include
#include
+namespace {
+
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+ return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
+
+}
+
namespace Catch {
namespace Detail {
- double dmax(double lhs, double rhs) {
- if (lhs < rhs) {
- return rhs;
- }
- return lhs;
- }
-
Approx::Approx ( double value )
: m_epsilon( std::numeric_limits::epsilon()*100 ),
m_margin( 0.0 ),
- m_scale( 1.0 ),
+ m_scale( 0.0 ),
m_value( value )
{}
@@ -4009,6 +4013,12 @@ namespace Detail {
return oss.str();
}
+ bool Approx::equalityComparisonImpl(const double other) const {
+ // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
+ // Thanks to Richard Harris for his help refining the scaled margin value
+ return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
+ }
+
} // end namespace Detail
std::string StringMaker::convert(Catch::Detail::Approx const& value) {
@@ -8055,6 +8065,7 @@ namespace Catch {
clara::Parser m_cli;
ConfigData m_configData;
std::shared_ptr m_config;
+ bool m_startupExceptions = false;
};
} // end namespace Catch
@@ -8186,8 +8197,26 @@ namespace Catch {
Session::Session() {
static bool alreadyInstantiated = false;
- if( alreadyInstantiated )
- CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" );
+ if( alreadyInstantiated ) {
+ try { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+ catch(...) { getMutableRegistryHub().registerStartupException(); }
+ }
+
+ const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
+ if ( !exceptions.empty() ) {
+ m_startupExceptions = true;
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << "Errors occured during startup!" << '\n';
+ // iterate over all exceptions and notify user
+ for ( const auto& ex_ptr : exceptions ) {
+ try {
+ std::rethrow_exception(ex_ptr);
+ } catch ( std::exception const& ex ) {
+ Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
+ }
+ }
+ }
+
alreadyInstantiated = true;
m_cli = makeCommandLineParser( m_configData );
}
@@ -8210,6 +8239,9 @@ namespace Catch {
}
int Session::applyCommandLine( int argc, char* argv[] ) {
+ if( m_startupExceptions )
+ return 1;
+
auto result = m_cli.parse( clara::Args( argc, argv ) );
if( !result ) {
Catch::cerr()
@@ -8235,19 +8267,8 @@ namespace Catch {
}
int Session::run( int argc, char* argv[] ) {
- const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
- if ( !exceptions.empty() ) {
- Catch::cerr() << "Errors occured during startup!" << '\n';
- // iterate over all exceptions and notify user
- for ( const auto& ex_ptr : exceptions ) {
- try {
- std::rethrow_exception(ex_ptr);
- } catch ( std::exception const& ex ) {
- Catch::cerr() << ex.what() << '\n';
- }
- }
+ if( m_startupExceptions )
return 1;
- }
int returnCode = applyCommandLine( argc, argv );
if( returnCode == 0 )
returnCode = run();
@@ -8306,6 +8327,9 @@ namespace Catch {
}
int Session::runInternal() {
+ if( m_startupExceptions )
+ return 1;
+
if( m_configData.showHelp || m_configData.libIdentify )
return 0;
@@ -9802,7 +9826,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 0, 0, "develop", 6 );
+ static Version version( 2, 0, 1, "", 0 );
return version;
}
diff --git a/test_package/conanfile.py b/test_package/conanfile.py
index ec99f3bc..207c480e 100644
--- a/test_package/conanfile.py
+++ b/test_package/conanfile.py
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
settings = "os", "compiler", "arch", "build_type"
username = getenv("CONAN_USERNAME", "philsquared")
channel = getenv("CONAN_CHANNEL", "testing")
- requires = "Catch/2.0.0-develop.6@%s/%s" % (username, channel)
+ requires = "Catch/2.0.1@%s/%s" % (username, channel)
def build(self):
cmake = CMake(self)