dev build 5
diff --git a/conanfile.py b/conanfile.py
index d1dfa81..5c7d993 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,7 +4,7 @@
class CatchConan(ConanFile):
name = "Catch"
- version = "2.0.0-develop.4"
+ version = "2.0.0-develop.5"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index b635800..e684f3f 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@
}
Version const& libraryVersion() {
- static Version version( 2, 0, 0, "develop", 4 );
+ static Version version( 2, 0, 0, "develop", 5 );
return version;
}
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
index e5ae619..f9568b0 100644
--- a/single_include/catch.hpp
+++ b/single_include/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.0.0-develop.4
- * Generated: 2017-09-19 17:37:34.480115
+ * Catch v2.0.0-develop.5
+ * Generated: 2017-10-12 13:05:08.135067
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
@@ -480,7 +480,6 @@
#include <sstream>
#include <vector>
#include <cstddef>
-#include <tuple>
#include <type_traits>
#include <string>
@@ -749,7 +748,53 @@
}
};
- // === Pair ===
+ 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) {
+ if (!nsstring)
+ return "nil";
+ return std::string("@") + [nsstring UTF8String];
+ }
+ };
+ template<>
+ struct StringMaker<NSObject*> {
+ static std::string convert(NSObject* nsObject) {
+ return ::Catch::Detail::stringify([nsObject description]);
+ }
+
+ };
+ namespace Detail {
+ inline std::string stringify( NSString* nsstring ) {
+ return StringMaker<NSString*>::convert( nsstring );
+ }
+
+ } // namespace Detail
+#endif // __OBJC__
+
+} // namespace Catch
+
+//////////////////////////////////////////////////////
+// Separate std-lib types stringification, so it can be selectively enabled
+// This means that we do not bring in
+
+#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
+# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
+# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#endif
+
+// Separate std::pair specialization
+#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
+#include <utility>
+namespace Catch {
template<typename T1, typename T2>
struct StringMaker<std::pair<T1, T2> > {
static std::string convert(const std::pair<T1, T2>& pair) {
@@ -762,7 +807,13 @@
return oss.str();
}
};
+}
+#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
+// Separate std::tuple specialization
+#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
+#include <tuple>
+namespace Catch {
namespace Detail {
template<
typename Tuple,
@@ -797,39 +848,124 @@
return os.str();
}
};
+}
+#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
- 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));
+// Separate std::chrono::duration specialization
+#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#include <ctime>
+#include <ratio>
+#include <chrono>
+
+template <class Ratio>
+struct ratio_string {
+ static std::string symbol();
+};
+
+template <class Ratio>
+std::string ratio_string<Ratio>::symbol() {
+ std::ostringstream oss;
+ oss << '[' << Ratio::num << '/'
+ << Ratio::den << ']';
+ return oss.str();
+}
+template <>
+struct ratio_string<std::atto> {
+ static std::string symbol() { return "a"; }
+};
+template <>
+struct ratio_string<std::femto> {
+ static std::string symbol() { return "f"; }
+};
+template <>
+struct ratio_string<std::pico> {
+ static std::string symbol() { return "p"; }
+};
+template <>
+struct ratio_string<std::nano> {
+ static std::string symbol() { return "n"; }
+};
+template <>
+struct ratio_string<std::micro> {
+ static std::string symbol() { return "u"; }
+};
+template <>
+struct ratio_string<std::milli> {
+ static std::string symbol() { return "m"; }
+};
+
+namespace Catch {
+ ////////////
+ // std::chrono::duration specializations
+ template<typename Value, typename Ratio>
+ struct StringMaker<std::chrono::duration<Value, Ratio>> {
+ static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
+ std::ostringstream oss;
+ oss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
+ return oss.str();
+ }
+ };
+ template<typename Value>
+ struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
+ static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
+ std::ostringstream oss;
+ oss << duration.count() << " s";
+ return oss.str();
+ }
+ };
+ template<typename Value>
+ struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
+ static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
+ std::ostringstream oss;
+ oss << duration.count() << " m";
+ return oss.str();
+ }
+ };
+ template<typename Value>
+ struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
+ static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
+ std::ostringstream oss;
+ oss << duration.count() << " h";
+ return oss.str();
}
};
-#ifdef __OBJC__
- template<>
- struct StringMaker<NSString*> {
- static std::string convert(NSString * nsstring) {
- if (!nsstring)
- return "nil";
- return std::string("@") + [nsstring UTF8String];
+ ////////////
+ // std::chrono::time_point specialization
+ // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
+ template<typename Clock, typename Duration>
+ struct StringMaker<std::chrono::time_point<Clock, Duration>> {
+ static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
+ return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
}
};
- template<>
- struct StringMaker<NSObject*> {
- static std::string convert(NSObject* nsObject) {
- return ::Catch::Detail::stringify([nsObject description]);
- }
+ // std::chrono::time_point<system_clock> specialization
+ template<typename Duration>
+ struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
+ static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
+ auto converted = std::chrono::system_clock::to_time_t(time_point);
+#ifdef _MSC_VER
+ std::tm timeInfo = {};
+ gmtime_s(&timeInfo, &converted);
+#else
+ std::tm* timeInfo = std::gmtime(&converted);
+#endif
+
+ auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
+ char timeStamp[timeStampSize];
+ const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
+
+#ifdef _MSC_VER
+ std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
+#else
+ std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+#endif
+ return std::string(timeStamp);
+ }
};
- namespace Detail {
- inline std::string stringify( NSString* nsstring ) {
- return StringMaker<NSString*>::convert( nsstring );
- }
-
- } // namespace Detail
-#endif // __OBJC__
-
-} // namespace Catch
+}
+#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#ifdef _MSC_VER
#pragma warning(pop)
@@ -1614,6 +1750,7 @@
static std::string translatorName( signature )
#endif
+#include <exception>
#include <string>
#include <vector>
@@ -1646,7 +1783,7 @@
std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
try {
if( it == itEnd )
- throw;
+ std::rethrow_exception(std::current_exception());
else
return (*it)->translate( it+1, itEnd );
}
@@ -4205,6 +4342,10 @@
#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
#endif
+#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
// ----------- #included from clara_textflow.hpp -----------
// TextFlowCpp
@@ -4538,9 +4679,8 @@
#include <set>
#include <algorithm>
-#if !defined(CLARA_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
-#define CLARA_PLATFORM_WINDOWS
-
+#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
+#define CATCH_PLATFORM_WINDOWS
#endif
namespace Catch { namespace clara {
@@ -4548,15 +4688,15 @@
// Traits for extracting arg and return type of lambdas (for single argument lambdas)
template<typename L>
- struct UnaryLambdaTraits : UnaryLambdaTraits<decltype(&L::operator())> {};
+ struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
template<typename ClassT, typename ReturnT, typename... Args>
- struct UnaryLambdaTraits<ReturnT(ClassT::*)(Args...) const> {
+ struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
static const bool isValid = false;
};
template<typename ClassT, typename ReturnT, typename ArgT>
- struct UnaryLambdaTraits<ReturnT(ClassT::*)(ArgT) const> {
+ struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
static const bool isValid = true;
using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
using ReturnType = ReturnT;
@@ -4571,13 +4711,13 @@
std::vector<std::string> m_args;
public:
- Args(int argc, char *argv[]) {
+ Args( int argc, char *argv[] ) {
m_exeName = argv[0];
- for (int i = 1; i < argc; ++i)
- m_args.push_back(argv[i]);
+ for( int i = 1; i < argc; ++i )
+ m_args.push_back( argv[i] );
}
- Args(std::initializer_list<std::string> args)
+ Args( std::initializer_list<std::string> args )
: m_exeName( *args.begin() ),
m_args( args.begin()+1, args.end() )
{}
@@ -4605,40 +4745,40 @@
std::vector<Token> m_tokenBuffer;
void loadBuffer() {
- m_tokenBuffer.resize(0);
+ m_tokenBuffer.resize( 0 );
// Skip any empty strings
- while (it != itEnd && it->empty())
+ while( it != itEnd && it->empty() )
++it;
- if (it != itEnd) {
+ if( it != itEnd ) {
auto const &next = *it;
- if (next[0] == '-' || next[0] == '/') {
- auto delimiterPos = next.find_first_of(" :=");
- if (delimiterPos != std::string::npos) {
- m_tokenBuffer.push_back({TokenType::Option, next.substr(0, delimiterPos)});
- m_tokenBuffer.push_back({TokenType::Argument, next.substr(delimiterPos + 1)});
+ if( next[0] == '-' || next[0] == '/' ) {
+ auto delimiterPos = next.find_first_of( " :=" );
+ if( delimiterPos != std::string::npos ) {
+ m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
+ m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
} else {
- if (next[1] != '-' && next.size() > 2) {
+ if( next[1] != '-' && next.size() > 2 ) {
std::string opt = "- ";
- for (size_t i = 1; i < next.size(); ++i) {
+ for( size_t i = 1; i < next.size(); ++i ) {
opt[1] = next[i];
- m_tokenBuffer.push_back({TokenType::Option, opt});
+ m_tokenBuffer.push_back( { TokenType::Option, opt } );
}
} else {
- m_tokenBuffer.push_back({TokenType::Option, next});
+ m_tokenBuffer.push_back( { TokenType::Option, next } );
}
}
} else {
- m_tokenBuffer.push_back({TokenType::Argument, next});
+ m_tokenBuffer.push_back( { TokenType::Argument, next } );
}
}
}
public:
- explicit TokenStream(Args const &args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
+ explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
- TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) {
+ TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
loadBuffer();
}
@@ -4649,20 +4789,20 @@
auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
auto operator*() const -> Token {
- assert(!m_tokenBuffer.empty());
+ assert( !m_tokenBuffer.empty() );
return m_tokenBuffer.front();
}
auto operator->() const -> Token const * {
- assert(!m_tokenBuffer.empty());
+ assert( !m_tokenBuffer.empty() );
return &m_tokenBuffer.front();
}
auto operator++() -> TokenStream & {
- if (m_tokenBuffer.size() >= 2) {
- m_tokenBuffer.erase(m_tokenBuffer.begin());
+ if( m_tokenBuffer.size() >= 2 ) {
+ m_tokenBuffer.erase( m_tokenBuffer.begin() );
} else {
- if (it != itEnd)
+ if( it != itEnd )
++it;
loadBuffer();
}
@@ -4677,7 +4817,7 @@
};
protected:
- ResultBase(Type type) : m_type(type) {}
+ ResultBase( Type type ) : m_type( type ) {}
virtual ~ResultBase() = default;
virtual void enforceOk() const = 0;
@@ -4694,28 +4834,28 @@
}
protected:
- ResultValueBase(Type type) : ResultBase(type) {}
+ ResultValueBase( Type type ) : ResultBase( type ) {}
- ResultValueBase(ResultValueBase const &other) : ResultBase(other) {
- if (m_type == ResultBase::Ok)
- new(&m_value) T(other.m_value);
+ ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
+ if( m_type == ResultBase::Ok )
+ new( &m_value ) T( other.m_value );
}
- ResultValueBase(Type, T const &value) : ResultBase(Ok) {
- new(&m_value) T(value);
+ ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
+ new( &m_value ) T( value );
}
- auto operator=(ResultValueBase const &other) -> ResultValueBase & {
- if (m_type == ResultBase::Ok)
+ auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
+ if( m_type == ResultBase::Ok )
m_value.~T();
ResultBase::operator=(other);
- if (m_type == ResultBase::Ok)
- new(&m_value) T(other.m_value);
+ if( m_type == ResultBase::Ok )
+ new( &m_value ) T( other.m_value );
return *this;
}
~ResultValueBase() {
- if (m_type == Ok)
+ if( m_type == Ok )
m_value.~T();
}
@@ -4734,37 +4874,31 @@
class BasicResult : public ResultValueBase<T> {
public:
template<typename U>
- explicit BasicResult(BasicResult<U> const &other)
- : ResultValueBase<T>(other.type()),
- m_errorMessage(other.errorMessage()) {
- assert(type() != ResultBase::Ok);
+ explicit BasicResult( BasicResult<U> const &other )
+ : ResultValueBase<T>( other.type() ),
+ m_errorMessage( other.errorMessage() )
+ {
+ assert( type() != ResultBase::Ok );
}
- static auto ok() -> BasicResult { return {ResultBase::Ok}; }
-
template<typename U>
- static auto ok(U const &value) -> BasicResult { return {ResultBase::Ok, value}; }
-
- static auto logicError(std::string const &message) -> BasicResult { return {ResultBase::LogicError, message}; }
-
- static auto runtimeError(std::string const &message) -> BasicResult {
- return {ResultBase::RuntimeError, message};
- }
+ static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
+ static auto ok() -> BasicResult { return { ResultBase::Ok }; }
+ static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
+ static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
explicit operator bool() const { return m_type == ResultBase::Ok; }
-
auto type() const -> ResultBase::Type { return m_type; }
-
auto errorMessage() const -> std::string { return m_errorMessage; }
protected:
virtual void enforceOk() const {
// !TBD: If no exceptions, std::terminate here or something
- switch (m_type) {
+ switch( m_type ) {
case ResultBase::LogicError:
- throw std::logic_error(m_errorMessage);
+ throw std::logic_error( m_errorMessage );
case ResultBase::RuntimeError:
- throw std::runtime_error(m_errorMessage);
+ throw std::runtime_error( m_errorMessage );
case ResultBase::Ok:
break;
}
@@ -4772,10 +4906,11 @@
std::string m_errorMessage; // Only populated if resultType is an error
- BasicResult(ResultBase::Type type, std::string const &message)
- : ResultValueBase<T>(type),
- m_errorMessage(message) {
- assert(m_type != ResultBase::Ok);
+ BasicResult( ResultBase::Type type, std::string const &message )
+ : ResultValueBase<T>(type),
+ m_errorMessage(message)
+ {
+ assert( m_type != ResultBase::Ok );
}
using ResultValueBase<T>::ResultValueBase;
@@ -4789,12 +4924,12 @@
class ParseState {
public:
- ParseState(ParseResultType type, TokenStream const &remainingTokens)
- : m_type(type),
- m_remainingTokens(remainingTokens) {}
+ ParseState( ParseResultType type, TokenStream const &remainingTokens )
+ : m_type(type),
+ m_remainingTokens( remainingTokens )
+ {}
auto type() const -> ParseResultType { return m_type; }
-
auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
private:
@@ -4812,69 +4947,62 @@
};
template<typename T>
- inline auto convertInto(std::string const &source, T& target) -> ParserResult {
+ inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
std::stringstream ss;
ss << source;
ss >> target;
- if (ss.fail())
- return ParserResult::runtimeError("Unable to convert '" + source + "' to destination type");
+ if( ss.fail() )
+ return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
else
- return ParserResult::ok(ParseResultType::Matched);
+ return ParserResult::ok( ParseResultType::Matched );
}
- inline auto convertInto(std::string const &source, std::string& target) -> ParserResult {
+ inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
target = source;
- return ParserResult::ok(ParseResultType::Matched);
+ return ParserResult::ok( ParseResultType::Matched );
}
- inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
+ inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
std::string srcLC = source;
- std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), [](char c) { return static_cast<char>( ::tolower(c) ); } );
+ std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } );
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
target = true;
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
target = false;
else
- return ParserResult::runtimeError("Expected a boolean value but did not recognise: '" + source + "'");
- return ParserResult::ok(ParseResultType::Matched);
+ return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
+ 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;
+ BoundRefBase( BoundRefBase const & ) = delete;
+ BoundRefBase( BoundRefBase && ) = delete;
+ BoundRefBase &operator=( BoundRefBase const & ) = delete;
+ BoundRefBase &operator=( BoundRefBase && ) = delete;
virtual ~BoundRefBase() = default;
virtual auto isFlag() const -> bool = 0;
-
virtual auto isContainer() const -> bool { return false; }
-
- virtual auto setValue(std::string const &arg) -> ParserResult = 0;
-
- virtual auto setFlag(bool flag) -> ParserResult = 0;
+ virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
+ 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");
+ 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 {
+ auto setValue( std::string const &arg ) -> ParserResult override {
bool flag;
- auto result = convertInto(arg, flag);
- if (result)
- setFlag(flag);
+ auto result = convertInto( arg, flag );
+ if( result )
+ setFlag( flag );
return result;
}
};
@@ -4883,10 +5011,10 @@
struct BoundRef : BoundValueRefBase {
T &m_ref;
- explicit BoundRef(T &ref) : m_ref(ref) {}
+ explicit BoundRef( T &ref ) : m_ref( ref ) {}
- auto setValue(std::string const &arg) -> ParserResult override {
- return convertInto(arg, m_ref);
+ auto setValue( std::string const &arg ) -> ParserResult override {
+ return convertInto( arg, m_ref );
}
};
@@ -4894,15 +5022,15 @@
struct BoundRef<std::vector<T>> : BoundValueRefBase {
std::vector<T> &m_ref;
- explicit BoundRef(std::vector<T> &ref) : m_ref(ref) {}
+ explicit BoundRef( std::vector<T> &ref ) : m_ref( ref ) {}
auto isContainer() const -> bool override { return true; }
- auto setValue(std::string const &arg) -> ParserResult override {
+ auto setValue( std::string const &arg ) -> ParserResult override {
T temp;
- auto result = convertInto(arg, temp);
- if (result)
- m_ref.push_back(temp);
+ auto result = convertInto( arg, temp );
+ if( result )
+ m_ref.push_back( temp );
return result;
}
};
@@ -4910,40 +5038,40 @@
struct BoundFlagRef : BoundFlagRefBase {
bool &m_ref;
- explicit BoundFlagRef(bool &ref) : m_ref(ref) {}
+ explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
- auto setFlag(bool flag) -> ParserResult override {
+ auto setFlag( bool flag ) -> ParserResult override {
m_ref = flag;
- return ParserResult::ok(ParseResultType::Matched);
+ return ParserResult::ok( ParseResultType::Matched );
}
};
template<typename ReturnType>
struct LambdaInvoker {
- static_assert(std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult");
+ static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
template<typename L, typename ArgType>
- static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
- return lambda(arg);
+ static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
+ return lambda( arg );
}
};
template<>
struct LambdaInvoker<void> {
template<typename L, typename ArgType>
- static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
- lambda(arg);
- return ParserResult::ok(ParseResultType::Matched);
+ static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
+ lambda( arg );
+ return ParserResult::ok( ParseResultType::Matched );
}
};
template<typename ArgType, typename L>
- inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult {
+ inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
ArgType temp;
- auto result = convertInto(arg, temp);
+ auto result = convertInto( arg, temp );
return !result
- ? result
- : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(lambda, temp);
+ ? result
+ : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
};
template<typename L>
@@ -4951,10 +5079,10 @@
L m_lambda;
static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
- explicit BoundLambda(L const &lambda) : m_lambda(lambda) {}
+ explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
- auto setValue(std::string const &arg) -> ParserResult override {
- return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
+ auto setValue( std::string const &arg ) -> ParserResult override {
+ return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
}
};
@@ -4965,16 +5093,14 @@
static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
- explicit BoundFlagLambda(L const &lambda) : m_lambda(lambda) {}
+ explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
- auto setFlag(bool flag) -> ParserResult override {
- return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
+ auto setFlag( bool flag ) -> ParserResult override {
+ return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
}
};
- enum class Optionality {
- Optional, Required
- };
+ enum class Optionality { Optional, Required };
struct Parser;
@@ -4985,8 +5111,8 @@
virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
virtual auto cardinality() const -> size_t { return 1; }
- auto parse(Args const &args) const -> InternalParseResult {
- return parse( args.exeName(), TokenStream(args));
+ auto parse( Args const &args ) const -> InternalParseResult {
+ return parse( args.exeName(), TokenStream( args ) );
}
};
@@ -4994,7 +5120,7 @@
class ComposableParserImpl : public ParserBase {
public:
template<typename T>
- auto operator+(T const &other) const -> Parser;
+ auto operator|( T const &other ) const -> Parser;
};
// Common code and state for Args and Opts
@@ -5006,17 +5132,22 @@
std::string m_hint;
std::string m_description;
- explicit ParserRefImpl(std::shared_ptr<BoundRefBase> const &ref) : m_ref(ref) {}
+ explicit ParserRefImpl( std::shared_ptr<BoundRefBase> const &ref ) : m_ref( ref ) {}
public:
template<typename T>
- ParserRefImpl(T &ref, std::string const &hint) : m_ref(std::make_shared<BoundRef<T>>(ref)), m_hint(hint) {}
+ ParserRefImpl( T &ref, std::string const &hint )
+ : m_ref( std::make_shared<BoundRef<T>>( ref ) ),
+ m_hint( hint )
+ {}
template<typename LambdaT>
- ParserRefImpl(LambdaT const &ref, std::string const &hint) : m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)),
- m_hint(hint) {}
+ ParserRefImpl( LambdaT const &ref, std::string const &hint )
+ : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
+ m_hint(hint)
+ {}
- auto operator()(std::string const &description) -> DerivedT & {
+ auto operator()( std::string const &description ) -> DerivedT & {
m_description = description;
return static_cast<DerivedT &>( *this );
}
@@ -5036,7 +5167,7 @@
}
auto cardinality() const -> size_t override {
- if (m_ref->isContainer())
+ if( m_ref->isContainer() )
return 0;
else
return 1;
@@ -5051,13 +5182,13 @@
template<typename LambdaT>
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
- return std::make_shared<BoundLambda<LambdaT>>(lambda);
+ return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
}
public:
- ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
+ ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
- explicit ExeName(std::string &ref) : ExeName() {
+ explicit ExeName( std::string &ref ) : ExeName() {
m_ref = std::make_shared<BoundRef<std::string>>( ref );
}
@@ -5068,14 +5199,14 @@
// The exe name is not parsed out of the normal tokens, but is handled specially
auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
- return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
+ return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
}
auto name() const -> std::string { return *m_name; }
auto set( std::string const& newName ) -> ParserResult {
auto lastSlash = newName.find_last_of( "\\/" );
- auto filename = (lastSlash == std::string::npos)
+ auto filename = ( lastSlash == std::string::npos )
? newName
: newName.substr( lastSlash+1 );
@@ -5091,27 +5222,27 @@
public:
using ParserRefImpl::ParserRefImpl;
- auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
+ auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
auto validationResult = validate();
- if (!validationResult)
- return InternalParseResult(validationResult);
+ if( !validationResult )
+ return InternalParseResult( validationResult );
auto remainingTokens = tokens;
auto const &token = *remainingTokens;
- if (token.type != TokenType::Argument)
- return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
+ if( token.type != TokenType::Argument )
+ return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
- auto result = m_ref->setValue(remainingTokens->token);
- if (!result)
- return InternalParseResult(result);
+ auto result = m_ref->setValue( remainingTokens->token );
+ if( !result )
+ return InternalParseResult( result );
else
- return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
+ return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
}
};
- inline auto normaliseOpt(std::string const &optName) -> std::string {
- if (optName[0] == '/')
- return "-" + optName.substr(1);
+ inline auto normaliseOpt( std::string const &optName ) -> std::string {
+ if( optName[0] == '/' )
+ return "-" + optName.substr( 1 );
else
return optName;
}
@@ -5122,9 +5253,9 @@
public:
template<typename LambdaT>
- explicit Opt( LambdaT const &ref ) : ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {}
+ explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
- explicit Opt( bool &ref ) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
+ explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
template<typename LambdaT>
Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
@@ -5132,34 +5263,34 @@
template<typename T>
Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
- auto operator[](std::string const &optName) -> Opt & {
- m_optNames.push_back(optName);
+ auto operator[]( std::string const &optName ) -> Opt & {
+ m_optNames.push_back( optName );
return *this;
}
auto getHelpColumns() const -> std::vector<HelpColumns> {
std::ostringstream oss;
bool first = true;
- for (auto const &opt : m_optNames) {
+ for( auto const &opt : m_optNames ) {
if (first)
first = false;
else
oss << ", ";
oss << opt;
}
- if (!m_hint.empty())
+ if( !m_hint.empty() )
oss << " <" << m_hint << ">";
- return {{oss.str(), m_description}};
+ return { { oss.str(), m_description } };
}
- auto isMatch(std::string const &optToken) const -> bool {
-#ifdef CLARA_PLATFORM_WINDOWS
+ auto isMatch( std::string const &optToken ) const -> bool {
+#ifdef CATCH_PLATFORM_WINDOWS
auto normalisedToken = normaliseOpt( optToken );
#else
auto const &normalisedToken = optToken;
#endif
- for (auto const &name : m_optNames) {
- if (normaliseOpt(name) == normalisedToken)
+ for( auto const &name : m_optNames ) {
+ if( normaliseOpt( name ) == normalisedToken )
return true;
}
return false;
@@ -5169,46 +5300,46 @@
auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
auto validationResult = validate();
- if (!validationResult)
- return InternalParseResult(validationResult);
+ if( !validationResult )
+ return InternalParseResult( validationResult );
auto remainingTokens = tokens;
- if (remainingTokens && remainingTokens->type == TokenType::Option) {
+ 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 (!result)
- return InternalParseResult(result);
- if (result.value() == ParseResultType::ShortCircuitAll)
- return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
+ if( isMatch(token.token ) ) {
+ if( m_ref->isFlag() ) {
+ auto result = m_ref->setFlag( true );
+ if( !result )
+ return InternalParseResult( result );
+ if( result.value() == ParseResultType::ShortCircuitAll )
+ return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
} else {
++remainingTokens;
- if (!remainingTokens)
- return InternalParseResult::runtimeError("Expected argument following " + token.token);
+ 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);
- if (!result)
- return InternalParseResult(result);
- if (result.value() == ParseResultType::ShortCircuitAll)
- return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
+ if( argToken.type != TokenType::Argument )
+ return InternalParseResult::runtimeError( "Expected argument following " + token.token );
+ auto result = m_ref->setValue( argToken.token );
+ if( !result )
+ return InternalParseResult( result );
+ if( result.value() == ParseResultType::ShortCircuitAll )
+ return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
}
- return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
+ return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
}
}
- return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
+ return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
}
auto validate() const -> Result override {
- if (m_optNames.empty())
- return Result::logicError("No options supplied to Opt");
- for (auto const &name : m_optNames) {
- if (name.empty())
- return Result::logicError("Option name cannot be empty");
- if (name[0] != '-' && name[0] != '/')
- return Result::logicError("Option name must begin with '-' or '/'");
+ if( m_optNames.empty() )
+ return Result::logicError( "No options supplied to Opt" );
+ for( auto const &name : m_optNames ) {
+ if( name.empty() )
+ return Result::logicError( "Option name cannot be empty" );
+ if( name[0] != '-' && name[0] != '/' )
+ return Result::logicError( "Option name must begin with '-' or '/'" );
}
return ParserRefImpl::validate();
}
@@ -5217,11 +5348,11 @@
struct Help : Opt {
Help( bool &showHelpFlag )
: Opt([&]( bool flag ) {
- showHelpFlag = flag;
- return ParserResult::ok(ParseResultType::ShortCircuitAll);
+ showHelpFlag = flag;
+ return ParserResult::ok( ParseResultType::ShortCircuitAll );
})
{
- static_cast<Opt &>(*this)
+ static_cast<Opt &>( *this )
("display usage information")
["-?"]["-h"]["--help"]
.optional();
@@ -5234,61 +5365,61 @@
std::vector<Opt> m_options;
std::vector<Arg> m_args;
- auto operator+=(ExeName const &exeName) -> Parser & {
+ auto operator|=( ExeName const &exeName ) -> Parser & {
m_exeName = exeName;
return *this;
}
- auto operator+=(Arg const &arg) -> Parser & {
+ auto operator|=( Arg const &arg ) -> Parser & {
m_args.push_back(arg);
return *this;
}
- auto operator+=(Opt const &opt) -> Parser & {
+ auto operator|=( Opt const &opt ) -> Parser & {
m_options.push_back(opt);
return *this;
}
- auto operator+=(Parser const &other) -> Parser & {
+ auto operator|=( Parser const &other ) -> Parser & {
m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
return *this;
}
template<typename T>
- auto operator+(T const &other) const -> Parser {
- return Parser(*this) += other;
+ auto operator|( T const &other ) const -> Parser {
+ return Parser( *this ) |= other;
}
auto getHelpColumns() const -> std::vector<HelpColumns> {
std::vector<HelpColumns> cols;
for (auto const &o : m_options) {
auto childCols = o.getHelpColumns();
- cols.insert(cols.end(), childCols.begin(), childCols.end());
+ cols.insert( cols.end(), childCols.begin(), childCols.end() );
}
return cols;
}
- void writeToStream(std::ostream &os) const {
+ void writeToStream( std::ostream &os ) const {
if (!m_exeName.name().empty()) {
os << "usage:\n" << " " << m_exeName.name() << " ";
bool required = true, first = true;
- for (auto const &arg : m_args) {
+ for( auto const &arg : m_args ) {
if (first)
first = false;
else
os << " ";
- if (arg.isOptional() && required) {
+ if( arg.isOptional() && required ) {
os << "[";
required = false;
}
os << "<" << arg.hint() << ">";
- if (arg.cardinality() == 0)
+ if( arg.cardinality() == 0 )
os << " ... ";
}
- if (!required)
+ if( !required )
os << "]";
- if (!m_options.empty())
+ if( !m_options.empty() )
os << " options";
os << "\n\nwhere options are:" << std::endl;
}
@@ -5296,32 +5427,32 @@
auto rows = getHelpColumns();
size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
size_t optWidth = 0;
- for (auto const &cols : rows)
+ for( auto const &cols : rows )
optWidth = std::max(optWidth, cols.left.size() + 2);
- for (auto const &cols : rows) {
+ for( auto const &cols : rows ) {
auto row =
- TextFlow::Column(cols.left).width(optWidth).indent(2) +
+ TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
TextFlow::Spacer(4) +
- TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
+ TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
os << row << std::endl;
}
}
- friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream & {
- parser.writeToStream(os);
+ friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
+ parser.writeToStream( os );
return os;
}
auto validate() const -> Result override {
- for (auto const &opt : m_options) {
+ for( auto const &opt : m_options ) {
auto result = opt.validate();
- if (!result)
+ if( !result )
return result;
}
- for (auto const &arg : m_args) {
+ for( auto const &arg : m_args ) {
auto result = arg.validate();
- if (!result)
+ if( !result )
return result;
}
return Result::ok();
@@ -5329,47 +5460,47 @@
using ParserBase::parse;
- auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult override {
- std::vector<ParserBase const *> allParsers;
- allParsers.reserve(m_args.size() + m_options.size());
- std::set<ParserBase const *> requiredParsers;
+ auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
- for (auto const &opt : m_options) {
- allParsers.push_back(&opt);
- if (!opt.isOptional())
- requiredParsers.insert(&opt);
- }
+ struct ParserInfo {
+ ParserBase const* parser = nullptr;
+ size_t count = 0;
+ };
+ const size_t totalParsers = m_options.size() + m_args.size();
+ assert( totalParsers < 512 );
+ // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
+ ParserInfo parseInfos[512];
- size_t optionalArgs = 0;
- for (auto const &arg : m_args) {
- allParsers.push_back(&arg);
- if (!arg.isOptional()) {
- if (optionalArgs > 0)
- return InternalParseResult::logicError(
- "Required arguments must preceed any optional arguments");
- else
- ++optionalArgs;
- requiredParsers.insert(&arg);
- }
+ {
+ size_t i = 0;
+ for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
+ for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
}
m_exeName.set( exeName );
- auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
- while (result.value().remainingTokens()) {
- auto remainingTokenCount = result.value().remainingTokens().count();
- for (auto parser : allParsers) {
- result = parser->parse( exeName, result.value().remainingTokens() );
- if (!result || result.value().type() != ParseResultType::NoMatch) {
- if (parser->cardinality() == 1)
- allParsers.erase(std::remove(allParsers.begin(), allParsers.end(), parser),
- allParsers.end());
- requiredParsers.erase(parser);
- break;
+ auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
+ while( result.value().remainingTokens() ) {
+ bool tokenParsed = false;
+
+ for( size_t i = 0; i < totalParsers; ++i ) {
+ auto& parseInfo = parseInfos[i];
+ if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
+ result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
+ if (!result)
+ return result;
+ if (result.value().type() != ParseResultType::NoMatch) {
+ tokenParsed = true;
+ ++parseInfo.count;
+ break;
+ }
}
}
- if (!result || remainingTokenCount == result.value().remainingTokens().count())
+
+ if( result.value().type() == ParseResultType::ShortCircuitAll )
return result;
+ if( !tokenParsed )
+ return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
}
// !TBD Check missing required options
return result;
@@ -5378,8 +5509,8 @@
template<typename DerivedT>
template<typename T>
- auto ComposableParserImpl<DerivedT>::operator+(T const &other) const -> Parser {
- return Parser() + static_cast<DerivedT const &>( *this ) + other;
+ auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
+ return Parser() | static_cast<DerivedT const &>( *this ) | other;
}
} // namespace detail
@@ -5516,84 +5647,84 @@
auto cli
= ExeName( config.processName )
- + Help( config.showHelp )
- + Opt( config.listTests )
+ | Help( config.showHelp )
+ | Opt( config.listTests )
["-l"]["--list-tests"]
( "list all/matching test cases" )
- + Opt( config.listTags )
+ | Opt( config.listTags )
["-t"]["--list-tags"]
( "list all/matching tags" )
- + Opt( config.showSuccessfulTests )
+ | Opt( config.showSuccessfulTests )
["-s"]["--success"]
( "include successful tests in output" )
- + Opt( config.shouldDebugBreak )
+ | Opt( config.shouldDebugBreak )
["-b"]["--break"]
( "break into debugger on failure" )
- + Opt( config.noThrow )
+ | Opt( config.noThrow )
["-e"]["--nothrow"]
( "skip exception tests" )
- + Opt( config.showInvisibles )
+ | Opt( config.showInvisibles )
["-i"]["--invisibles"]
( "show invisibles (tabs, newlines)" )
- + Opt( config.outputFilename, "filename" )
+ | Opt( config.outputFilename, "filename" )
["-o"]["--out"]
( "output filename" )
- + Opt( config.reporterNames, "name" )
+ | Opt( config.reporterNames, "name" )
["-r"]["--reporter"]
( "reporter to use (defaults to console)" )
- + Opt( config.name, "name" )
+ | Opt( config.name, "name" )
["-n"]["--name"]
( "suite name" )
- + Opt( [&]( bool ){ config.abortAfter = 1; } )
+ | Opt( [&]( bool ){ config.abortAfter = 1; } )
["-a"]["--abort"]
( "abort at first failure" )
- + Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
+ | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
["-x"]["--abortx"]
( "abort after x failures" )
- + Opt( setWarning, "warning name" )
+ | Opt( setWarning, "warning name" )
["-w"]["--warn"]
( "enable warnings" )
- + Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
+ | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
["-d"]["--durations"]
( "show test durations" )
- + Opt( loadTestNamesFromFile, "filename" )
+ | Opt( loadTestNamesFromFile, "filename" )
["-f"]["--input-file"]
( "load test names to run from a file" )
- + Opt( config.filenamesAsTags )
+ | Opt( config.filenamesAsTags )
["-#"]["--filenames-as-tags"]
( "adds a tag for the filename" )
- + Opt( config.sectionsToRun, "section name" )
+ | Opt( config.sectionsToRun, "section name" )
["-c"]["--section"]
( "specify section to run" )
- + Opt( setVerbosity, "quiet|normal|high" )
+ | Opt( setVerbosity, "quiet|normal|high" )
["-v"]["--verbosity"]
( "set output verbosity" )
- + Opt( config.listTestNamesOnly )
+ | Opt( config.listTestNamesOnly )
["--list-test-names-only"]
( "list all/matching test cases names only" )
- + Opt( config.listReporters )
+ | Opt( config.listReporters )
["--list-reporters"]
( "list all reporters" )
- + Opt( setTestOrder, "decl|lex|rand" )
+ | Opt( setTestOrder, "decl|lex|rand" )
["--order"]
( "test case order (defaults to decl)" )
- + Opt( setRngSeed, "'time'|number" )
+ | Opt( setRngSeed, "'time'|number" )
["--rng-seed"]
( "set a specific seed for random numbers" )
- + Opt( setColourUsage, "yes|no" )
+ | Opt( setColourUsage, "yes|no" )
["--use-colour"]
( "should output be colourised" )
- + Opt( config.libIdentify )
+ | Opt( config.libIdentify )
["--libidentify"]
( "report name and version according to libidentify standard" )
- + Opt( setWaitForKeypress, "start|exit|both" )
+ | Opt( setWaitForKeypress, "start|exit|both" )
["--wait-for-keypress"]
( "waits for a keypress before exiting" )
- + Opt( config.benchmarkResolutionMultiple, "multiplier" )
+ | Opt( config.benchmarkResolutionMultiple, "multiplier" )
["--benchmark-resolution-multiple"]
( "multiple of clock resolution to run benchmarks" )
- + Arg( config.testsOrTags, "test name|pattern|tags" )
+ | Arg( config.testsOrTags, "test name|pattern|tags" )
( "which test or tests to use" );
return cli;
@@ -5731,6 +5862,36 @@
}
// end catch_errno_guard.h
+// start catch_windows_h_proxy.h
+
+
+#if defined(CATCH_PLATFORM_WINDOWS)
+
+#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+# define CATCH_DEFINED_NOMINMAX
+# define NOMINMAX
+#endif
+#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+#ifdef CATCH_DEFINED_NOMINMAX
+# undef NOMINMAX
+#endif
+#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+#endif // defined(CATCH_PLATFORM_WINDOWS)
+
+// end catch_windows_h_proxy.h
namespace Catch {
namespace {
@@ -5761,34 +5922,6 @@
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
-// start catch_windows_h_proxy.h
-
-
-#if defined(CATCH_PLATFORM_WINDOWS)
-# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
-# define CATCH_DEFINED_NOMINMAX
-# define NOMINMAX
-# endif
-# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
-# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-# endif
-#endif
-
-#ifdef __AFXDLL
-#include <AfxWin.h>
-#else
-#include <windows.h>
-#endif
-
-#ifdef CATCH_DEFINED_NOMINMAX
-# undef NOMINMAX
-#endif
-#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
-# undef WIN32_LEAN_AND_MEAN
-#endif
-
-// end catch_windows_h_proxy.h
namespace Catch {
namespace {
@@ -6220,7 +6353,7 @@
#endif
}
catch( TestFailureException& ) {
- throw;
+ std::rethrow_exception(std::current_exception());
}
catch( std::exception& ex ) {
return ex.what();
@@ -6238,7 +6371,7 @@
std::string ExceptionTranslatorRegistry::tryTranslators() const {
if( m_translators.empty() )
- throw;
+ std::rethrow_exception(std::current_exception());
else
return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
}
@@ -6523,6 +6656,9 @@
static std::set<Verbosity> getSupportedVerbosities();
+ void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
+ void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
+
void testRunStarting( TestRunInfo const& testRunInfo ) override;
void testGroupStarting( GroupInfo const& groupInfo ) override;
void testCaseStarting( TestCaseInfo const& testInfo ) override;
@@ -9649,7 +9785,7 @@
}
Version const& libraryVersion() {
- static Version version( 2, 0, 0, "develop", 4 );
+ static Version version( 2, 0, 0, "develop", 5 );
return version;
}
@@ -11204,6 +11340,15 @@
reporter->noMatchingTestCases( spec );
}
+ void MultipleReporters::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
+ for( auto const& reporter : m_reporters )
+ reporter->benchmarkStarting( benchmarkInfo );
+ }
+ void MultipleReporters::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
+ for( auto const& reporter : m_reporters )
+ reporter->benchmarkEnded( benchmarkStats );
+ }
+
void MultipleReporters::testRunStarting( TestRunInfo const& testRunInfo ) {
for( auto const& reporter : m_reporters )
reporter->testRunStarting( testRunInfo );
diff --git a/test_package/conanfile.py b/test_package/conanfile.py
index 2311ab7..96d9398 100644
--- a/test_package/conanfile.py
+++ b/test_package/conanfile.py
@@ -10,7 +10,7 @@
settings = "os", "compiler", "arch", "build_type"
username = getenv("CONAN_USERNAME", "philsquared")
channel = getenv("CONAN_CHANNEL", "testing")
- requires = "Catch/2.0.0-develop.4@%s/%s" % (username, channel)
+ requires = "Catch/2.0.0-develop.5@%s/%s" % (username, channel)
def build(self):
cmake = CMake(self)