diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e631097..65f1927b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
-project(Catch2 LANGUAGES CXX VERSION 2.1.0)
+project(Catch2 LANGUAGES CXX VERSION 2.1.1)
include(GNUInstallDirs)
diff --git a/README.md b/README.md
index e82aea00..1c2c03b0 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/nerce2MiN6sVmfCi)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TpIcJaLaH4WrKlhS)
-The latest version of the single header can be downloaded directly using this link
+The latest version of the single header can be downloaded directly using this link
## Catch2 is released!
diff --git a/conanfile.py b/conanfile.py
index 354f68a4..fa9fdce1 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,7 +4,7 @@ from conans import ConanFile
class CatchConan(ConanFile):
name = "Catch"
- version = "2.1.0"
+ version = "2.1.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 5c02f6bf..565d6cd8 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,5 +1,27 @@
+# 2.1.1
+
+## Improvements
+* Static arrays are now properly stringified like ranges across MSVC/GCC/Clang
+* Embedded newer version of Clara -- v1.1.1
+ * This should fix some warnings dragged in from Clara
+* MSVC's CLR exceptions are supported
+
+
+## Fixes
+* Fixed compilation when comparison operators do not return bool (#1147)
+* Fixed CLR exceptions blowing up the executable during translation (#1138)
+
+
+## Other changes
+* Many CMake changes
+ * `NO_SELFTEST` option is deprecated, use `BUILD_TESTING` instead.
+ * Catch specific CMake options were prefixed with `CATCH_` for namespacing purposes
+ * Other changes to simplify Catch2's packaging
+
+
+
# 2.1.0
## Improvements
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index 8b50ace0..fc196d91 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, 1, 0, "", 0 );
+ static Version version( 2, 1, 1, "", 0 );
return version;
}
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
index ef720908..160bad07 100644
--- a/single_include/catch.hpp
+++ b/single_include/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.1.0
- * Generated: 2018-01-10 13:51:15.378034
+ * Catch v2.1.1
+ * Generated: 2018-01-26 16:04:07.190063
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
@@ -807,18 +807,6 @@ namespace Catch {
static std::string convert(wchar_t * str);
};
- template
- struct is_string_array : std::false_type {};
-
- template
- struct is_string_array : std::true_type {};
-
- template
- struct is_string_array : std::true_type {};
-
- template
- struct is_string_array : std::true_type {};
-
template
struct StringMaker {
static std::string convert(const char* str) {
@@ -1069,12 +1057,19 @@ namespace Catch {
}
template
- struct StringMaker::value && !is_string_array::value>::type> {
+ struct StringMaker::value && !std::is_array::value>::type> {
static std::string convert( R const& range ) {
return rangeToString( range );
}
};
+ template
+ struct StringMaker {
+ static std::string convert(T const(&arr)[SZ]) {
+ return rangeToString(arr);
+ }
+ };
+
} // namespace Catch
// Separate std::chrono::duration specialization
@@ -1269,7 +1264,7 @@ namespace Catch {
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
template
- auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return lhs == rhs; };
+ auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast(lhs == rhs); };
template
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast( rhs ); }
template
@@ -1280,7 +1275,7 @@ namespace Catch {
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; }
template
- auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs != rhs; };
+ auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast(lhs != rhs); };
template
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast( rhs ); }
template
@@ -1314,19 +1309,19 @@ namespace Catch {
template
auto operator > ( RhsT const& rhs ) -> BinaryExpr const {
- return { m_lhs > rhs, m_lhs, ">", rhs };
+ return { static_cast(m_lhs > rhs), m_lhs, ">", rhs };
}
template
auto operator < ( RhsT const& rhs ) -> BinaryExpr const {
- return { m_lhs < rhs, m_lhs, "<", rhs };
+ return { static_cast(m_lhs < rhs), m_lhs, "<", rhs };
}
template
auto operator >= ( RhsT const& rhs ) -> BinaryExpr const {
- return { m_lhs >= rhs, m_lhs, ">=", rhs };
+ return { static_cast(m_lhs >= rhs), m_lhs, ">=", rhs };
}
template
auto operator <= ( RhsT const& rhs ) -> BinaryExpr const {
- return { m_lhs <= rhs, m_lhs, "<=", rhs };
+ return { static_cast(m_lhs <= rhs), m_lhs, "<=", rhs };
}
auto makeUnaryExpr() const -> UnaryExpr {
@@ -5093,8 +5088,14 @@ namespace Catch {
#endif
// start clara.hpp
-// v1.0-develop.2
-// See https://github.com/philsquared/Clara
+// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See https://github.com/philsquared/Clara for more details
+
+// Clara v1.1.1
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
@@ -5457,7 +5458,7 @@ namespace detail {
template
struct UnaryLambdaTraits {
static const bool isValid = true;
- using ArgType = typename std::remove_const::type>::type;;
+ using ArgType = typename std::remove_const::type>::type;
using ReturnType = ReturnT;
};
@@ -5621,7 +5622,7 @@ namespace detail {
return *this;
}
- ~ResultValueBase() {
+ ~ResultValueBase() override {
if( m_type == Ok )
m_value.~T();
}
@@ -5659,7 +5660,7 @@ namespace detail {
auto errorMessage() const -> std::string { return m_errorMessage; }
protected:
- virtual void enforceOk() const {
+ void enforceOk() const override {
// !TBD: If no exceptions, std::terminate here or something
switch( m_type ) {
case ResultBase::LogicError:
@@ -5739,46 +5740,30 @@ namespace detail {
return ParserResult::ok( ParseResultType::Matched );
}
- struct BoundRefBase {
- BoundRefBase() = default;
- BoundRefBase( BoundRefBase const & ) = delete;
- BoundRefBase( BoundRefBase && ) = delete;
- BoundRefBase &operator=( BoundRefBase const & ) = delete;
- BoundRefBase &operator=( BoundRefBase && ) = delete;
+ struct NonCopyable {
+ NonCopyable() = default;
+ NonCopyable( NonCopyable const & ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable &operator=( NonCopyable const & ) = delete;
+ NonCopyable &operator=( NonCopyable && ) = delete;
+ };
- virtual ~BoundRefBase() = default;
-
- virtual auto isFlag() const -> bool = 0;
+ struct BoundRef : NonCopyable {
+ virtual ~BoundRef() = default;
virtual auto isContainer() const -> bool { return false; }
+ };
+ struct BoundValueRefBase : BoundRef {
virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
+ };
+ struct BoundFlagRefBase : BoundRef {
virtual auto setFlag( bool flag ) -> ParserResult = 0;
};
- struct BoundValueRefBase : BoundRefBase {
- auto isFlag() const -> bool override { return false; }
-
- auto setFlag( bool ) -> ParserResult override {
- return ParserResult::logicError( "Flags can only be set on boolean fields" );
- }
- };
-
- struct BoundFlagRefBase : BoundRefBase {
- auto isFlag() const -> bool override { return true; }
-
- auto setValue( std::string const &arg ) -> ParserResult override {
- bool flag;
- auto result = convertInto( arg, flag );
- if( result )
- setFlag( flag );
- return result;
- }
- };
-
template
- struct BoundRef : BoundValueRefBase {
+ struct BoundValueRef : BoundValueRefBase {
T &m_ref;
- explicit BoundRef( T &ref ) : m_ref( ref ) {}
+ explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
auto setValue( std::string const &arg ) -> ParserResult override {
return convertInto( arg, m_ref );
@@ -5786,10 +5771,10 @@ namespace detail {
};
template
- struct BoundRef> : BoundValueRefBase {
+ struct BoundValueRef> : BoundValueRefBase {
std::vector &m_ref;
- explicit BoundRef( std::vector &ref ) : m_ref( ref ) {}
+ explicit BoundValueRef( std::vector &ref ) : m_ref( ref ) {}
auto isContainer() const -> bool override { return true; }
@@ -5834,12 +5819,12 @@ namespace detail {
template
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
- ArgType temp;
+ ArgType temp{};
auto result = convertInto( arg, temp );
return !result
? result
: LambdaInvoker::ReturnType>::invoke( lambda, temp );
- };
+ }
template
struct BoundLambda : BoundValueRefBase {
@@ -5888,6 +5873,9 @@ namespace detail {
public:
template
auto operator|( T const &other ) const -> Parser;
+
+ template
+ auto operator+( T const &other ) const -> Parser;
};
// Common code and state for Args and Opts
@@ -5895,16 +5883,16 @@ namespace detail {
class ParserRefImpl : public ComposableParserImpl {
protected:
Optionality m_optionality = Optionality::Optional;
- std::shared_ptr m_ref;
+ std::shared_ptr m_ref;
std::string m_hint;
std::string m_description;
- explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {}
+ explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {}
public:
template
ParserRefImpl( T &ref, std::string const &hint )
- : m_ref( std::make_shared>( ref ) ),
+ : m_ref( std::make_shared>( ref ) ),
m_hint( hint )
{}
@@ -5945,10 +5933,10 @@ namespace detail {
class ExeName : public ComposableParserImpl {
std::shared_ptr m_name;
- std::shared_ptr m_ref;
+ std::shared_ptr m_ref;
template
- static auto makeRef(LambdaT const &lambda) -> std::shared_ptr {
+ static auto makeRef(LambdaT const &lambda) -> std::shared_ptr {
return std::make_shared>( lambda) ;
}
@@ -5956,7 +5944,7 @@ namespace detail {
ExeName() : m_name( std::make_shared( "" ) ) {}
explicit ExeName( std::string &ref ) : ExeName() {
- m_ref = std::make_shared>( ref );
+ m_ref = std::make_shared>( ref );
}
template
@@ -5999,7 +5987,10 @@ namespace detail {
if( token.type != TokenType::Argument )
return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
- auto result = m_ref->setValue( remainingTokens->token );
+ assert( dynamic_cast( m_ref.get() ) );
+ auto valueRef = static_cast( m_ref.get() );
+
+ auto result = valueRef->setValue( remainingTokens->token );
if( !result )
return InternalParseResult( result );
else
@@ -6072,20 +6063,22 @@ namespace detail {
if( remainingTokens && remainingTokens->type == TokenType::Option ) {
auto const &token = *remainingTokens;
if( isMatch(token.token ) ) {
- if( m_ref->isFlag() ) {
- auto result = m_ref->setFlag( true );
+ if( auto flagRef = dynamic_cast( m_ref.get() ) ) {
+ auto result = flagRef->setFlag( true );
if( !result )
return InternalParseResult( result );
if( result.value() == ParseResultType::ShortCircuitAll )
return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
} else {
+ assert( dynamic_cast( m_ref.get() ) );
+ auto valueRef = static_cast( m_ref.get() );
++remainingTokens;
if( !remainingTokens )
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
auto const &argToken = *remainingTokens;
if( argToken.type != TokenType::Argument )
return InternalParseResult::runtimeError( "Expected argument following " + token.token );
- auto result = m_ref->setValue( argToken.token );
+ auto result = valueRef->setValue( argToken.token );
if( !result )
return InternalParseResult( result );
if( result.value() == ParseResultType::ShortCircuitAll )
@@ -6161,6 +6154,12 @@ namespace detail {
return Parser( *this ) |= other;
}
+ // Forward deprecated interface with '+' instead of '|'
+ template
+ auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
+ template
+ auto operator+( T const &other ) const -> Parser { return operator|( other ); }
+
auto getHelpColumns() const -> std::vector {
std::vector cols;
for (auto const &o : m_options) {
@@ -6200,6 +6199,8 @@ namespace detail {
for( auto const &cols : rows )
optWidth = (std::max)(optWidth, cols.left.size() + 2);
+ optWidth = (std::min)(optWidth, consoleWidth/2);
+
for( auto const &cols : rows ) {
auto row =
TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
@@ -7086,6 +7087,17 @@ namespace Catch {
return Catch::Detail::stringify( [exception description] );
}
#else
+ // Compiling a mixed mode project with MSVC means that CLR
+ // exceptions will be caught in (...) as well. However, these
+ // do not fill-in std::current_exception and thus lead to crash
+ // when attempting rethrow.
+ // /EHa switch also causes structured exceptions to be caught
+ // here, but they fill-in current_exception properly, so
+ // at worst the output should be a little weird, instead of
+ // causing a crash.
+ if (std::current_exception() == nullptr) {
+ return "Non C++ exception. Possibly a CLR exception.";
+ }
return tryTranslators();
#endif
}
@@ -9148,6 +9160,9 @@ namespace Catch {
if( Option listed = list( config() ) )
return static_cast( *listed );
+ // Note that on unices only the lower 8 bits are usually used, clamping
+ // the return value to 255 prevents false negative when some multiple
+ // of 256 tests has failed
return (std::min)( MaxExitCode, static_cast( runTests( m_config ).assertions.failed ) );
}
catch( std::exception& ex ) {
@@ -10689,7 +10704,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 1, 0, "", 0 );
+ static Version version( 2, 1, 1, "", 0 );
return version;
}
diff --git a/test_package/conanfile.py b/test_package/conanfile.py
index 730773e4..174beba9 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.1.0@%s/%s" % (username, channel)
+ requires = "Catch/2.1.1@%s/%s" % (username, channel)
def build(self):
cmake = CMake(self)