mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
v3.5.1
This commit is contained in:
parent
b7b71ffd3a
commit
f981c9cbca
@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(Catch2
|
project(Catch2
|
||||||
VERSION 3.5.0 # CML version placeholder, don't delete
|
VERSION 3.5.1 # CML version placeholder, don't delete
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||||
# we do not target yet.
|
# we do not target yet.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
# Release notes
|
# Release notes
|
||||||
**Contents**<br>
|
**Contents**<br>
|
||||||
|
[3.5.1](#351)<br>
|
||||||
[3.5.0](#350)<br>
|
[3.5.0](#350)<br>
|
||||||
[3.4.0](#340)<br>
|
[3.4.0](#340)<br>
|
||||||
[3.3.2](#332)<br>
|
[3.3.2](#332)<br>
|
||||||
@ -58,6 +59,17 @@
|
|||||||
[Even Older versions](#even-older-versions)<br>
|
[Even Older versions](#even-older-versions)<br>
|
||||||
|
|
||||||
|
|
||||||
|
## 3.5.1
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
* Significantly improved performance of the CLI parsing.
|
||||||
|
* This includes the cost of preparing the CLI parser, so Catch2's binaries start much faster.
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
* Added support for Bazel modules (#2781)
|
||||||
|
* Added CMake option to disable the build reproducibility settings (#2785)
|
||||||
|
* Added `log` library linking to the Meson build (#2784)
|
||||||
|
|
||||||
|
|
||||||
## 3.5.0
|
## 3.5.0
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
// Catch v3.5.0
|
// Catch v3.5.1
|
||||||
// Generated: 2023-12-11 00:51:07.662625
|
// Generated: 2023-12-31 15:10:55.864983
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
// This file is an amalgamation of multiple different files.
|
// This file is an amalgamation of multiple different files.
|
||||||
// You probably shouldn't edit it directly.
|
// You probably shouldn't edit it directly.
|
||||||
@ -2273,7 +2273,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 3, 5, 0, "", 0 );
|
static Version version( 3, 5, 1, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2415,9 +2415,7 @@ namespace Catch {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@ -2627,13 +2625,29 @@ namespace {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string normaliseOpt( std::string const& optName ) {
|
Catch::StringRef normaliseOpt( Catch::StringRef optName ) {
|
||||||
#ifdef CATCH_PLATFORM_WINDOWS
|
if ( optName[0] == '-'
|
||||||
if ( optName[0] == '/' )
|
#if defined(CATCH_PLATFORM_WINDOWS)
|
||||||
return "-" + optName.substr( 1 );
|
|| optName[0] == '/'
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
return optName;
|
) {
|
||||||
|
return optName.substr( 1, optName.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return optName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t find_first_separator(Catch::StringRef sr) {
|
||||||
|
auto is_separator = []( char c ) {
|
||||||
|
return c == ' ' || c == ':' || c == '=';
|
||||||
|
};
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < sr.size()) {
|
||||||
|
if (is_separator(sr[pos])) { return pos; }
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Catch::StringRef::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -2651,23 +2665,23 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( it != itEnd ) {
|
if ( it != itEnd ) {
|
||||||
auto const& next = *it;
|
StringRef next = *it;
|
||||||
if ( isOptPrefix( next[0] ) ) {
|
if ( isOptPrefix( next[0] ) ) {
|
||||||
auto delimiterPos = next.find_first_of( " :=" );
|
auto delimiterPos = find_first_separator(next);
|
||||||
if ( delimiterPos != std::string::npos ) {
|
if ( delimiterPos != StringRef::npos ) {
|
||||||
m_tokenBuffer.push_back(
|
m_tokenBuffer.push_back(
|
||||||
{ TokenType::Option,
|
{ TokenType::Option,
|
||||||
next.substr( 0, delimiterPos ) } );
|
next.substr( 0, delimiterPos ) } );
|
||||||
m_tokenBuffer.push_back(
|
m_tokenBuffer.push_back(
|
||||||
{ TokenType::Argument,
|
{ TokenType::Argument,
|
||||||
next.substr( delimiterPos + 1 ) } );
|
next.substr( delimiterPos + 1, next.size() ) } );
|
||||||
} else {
|
} else {
|
||||||
if ( next[1] != '-' && next.size() > 2 ) {
|
if ( next[1] != '-' && next.size() > 2 ) {
|
||||||
std::string opt = "- ";
|
// Combined short args, e.g. "-ab" for "-a -b"
|
||||||
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(
|
m_tokenBuffer.push_back(
|
||||||
{ TokenType::Option, opt } );
|
{ TokenType::Option,
|
||||||
|
next.substr( i, 1 ) } );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_tokenBuffer.push_back(
|
m_tokenBuffer.push_back(
|
||||||
@ -2727,12 +2741,12 @@ namespace Catch {
|
|||||||
size_t ParserBase::cardinality() const { return 1; }
|
size_t ParserBase::cardinality() const { return 1; }
|
||||||
|
|
||||||
InternalParseResult ParserBase::parse( Args const& args ) const {
|
InternalParseResult ParserBase::parse( Args const& args ) const {
|
||||||
return parse( args.exeName(), TokenStream( args ) );
|
return parse( static_cast<std::string>(args.exeName()), TokenStream( args ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseState::ParseState( ParseResultType type,
|
ParseState::ParseState( ParseResultType type,
|
||||||
TokenStream const& remainingTokens ):
|
TokenStream remainingTokens ):
|
||||||
m_type( type ), m_remainingTokens( remainingTokens ) {}
|
m_type( type ), m_remainingTokens( CATCH_MOVE(remainingTokens) ) {}
|
||||||
|
|
||||||
ParserResult BoundFlagRef::setFlag( bool flag ) {
|
ParserResult BoundFlagRef::setFlag( bool flag ) {
|
||||||
m_ref = flag;
|
m_ref = flag;
|
||||||
@ -2750,34 +2764,34 @@ namespace Catch {
|
|||||||
} // namespace Detail
|
} // namespace Detail
|
||||||
|
|
||||||
Detail::InternalParseResult Arg::parse(std::string const&,
|
Detail::InternalParseResult Arg::parse(std::string const&,
|
||||||
Detail::TokenStream const& tokens) const {
|
Detail::TokenStream tokens) const {
|
||||||
auto validationResult = validate();
|
auto validationResult = validate();
|
||||||
if (!validationResult)
|
if (!validationResult)
|
||||||
return Detail::InternalParseResult(validationResult);
|
return Detail::InternalParseResult(validationResult);
|
||||||
|
|
||||||
auto remainingTokens = tokens;
|
auto token = *tokens;
|
||||||
auto const& token = *remainingTokens;
|
|
||||||
if (token.type != Detail::TokenType::Argument)
|
if (token.type != Detail::TokenType::Argument)
|
||||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||||
ParseResultType::NoMatch, remainingTokens));
|
ParseResultType::NoMatch, CATCH_MOVE(tokens)));
|
||||||
|
|
||||||
assert(!m_ref->isFlag());
|
assert(!m_ref->isFlag());
|
||||||
auto valueRef =
|
auto valueRef =
|
||||||
static_cast<Detail::BoundValueRefBase*>(m_ref.get());
|
static_cast<Detail::BoundValueRefBase*>(m_ref.get());
|
||||||
|
|
||||||
auto result = valueRef->setValue(remainingTokens->token);
|
auto result = valueRef->setValue(static_cast<std::string>(token.token));
|
||||||
if (!result)
|
if ( !result )
|
||||||
return Detail::InternalParseResult(result);
|
return Detail::InternalParseResult( result );
|
||||||
else
|
else
|
||||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
return Detail::InternalParseResult::ok(
|
||||||
ParseResultType::Matched, ++remainingTokens));
|
Detail::ParseState( ParseResultType::Matched,
|
||||||
|
CATCH_MOVE( ++tokens ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Opt::Opt(bool& ref) :
|
Opt::Opt(bool& ref) :
|
||||||
ParserRefImpl(std::make_shared<Detail::BoundFlagRef>(ref)) {}
|
ParserRefImpl(std::make_shared<Detail::BoundFlagRef>(ref)) {}
|
||||||
|
|
||||||
std::vector<Detail::HelpColumns> Opt::getHelpColumns() const {
|
Detail::HelpColumns Opt::getHelpColumns() const {
|
||||||
std::ostringstream oss;
|
ReusableStringStream oss;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto const& opt : m_optNames) {
|
for (auto const& opt : m_optNames) {
|
||||||
if (first)
|
if (first)
|
||||||
@ -2788,10 +2802,10 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
if (!m_hint.empty())
|
if (!m_hint.empty())
|
||||||
oss << " <" << m_hint << '>';
|
oss << " <" << m_hint << '>';
|
||||||
return { { oss.str(), m_description } };
|
return { oss.str(), m_description };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Opt::isMatch(std::string const& optToken) const {
|
bool Opt::isMatch(StringRef optToken) const {
|
||||||
auto normalisedToken = normaliseOpt(optToken);
|
auto normalisedToken = normaliseOpt(optToken);
|
||||||
for (auto const& name : m_optNames) {
|
for (auto const& name : m_optNames) {
|
||||||
if (normaliseOpt(name) == normalisedToken)
|
if (normaliseOpt(name) == normalisedToken)
|
||||||
@ -2801,15 +2815,14 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Detail::InternalParseResult Opt::parse(std::string const&,
|
Detail::InternalParseResult Opt::parse(std::string const&,
|
||||||
Detail::TokenStream const& tokens) const {
|
Detail::TokenStream tokens) const {
|
||||||
auto validationResult = validate();
|
auto validationResult = validate();
|
||||||
if (!validationResult)
|
if (!validationResult)
|
||||||
return Detail::InternalParseResult(validationResult);
|
return Detail::InternalParseResult(validationResult);
|
||||||
|
|
||||||
auto remainingTokens = tokens;
|
if (tokens &&
|
||||||
if (remainingTokens &&
|
tokens->type == Detail::TokenType::Option) {
|
||||||
remainingTokens->type == Detail::TokenType::Option) {
|
auto const& token = *tokens;
|
||||||
auto const& token = *remainingTokens;
|
|
||||||
if (isMatch(token.token)) {
|
if (isMatch(token.token)) {
|
||||||
if (m_ref->isFlag()) {
|
if (m_ref->isFlag()) {
|
||||||
auto flagRef =
|
auto flagRef =
|
||||||
@ -2821,35 +2834,35 @@ namespace Catch {
|
|||||||
if (result.value() ==
|
if (result.value() ==
|
||||||
ParseResultType::ShortCircuitAll)
|
ParseResultType::ShortCircuitAll)
|
||||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||||
result.value(), remainingTokens));
|
result.value(), CATCH_MOVE(tokens)));
|
||||||
} else {
|
} else {
|
||||||
auto valueRef =
|
auto valueRef =
|
||||||
static_cast<Detail::BoundValueRefBase*>(
|
static_cast<Detail::BoundValueRefBase*>(
|
||||||
m_ref.get());
|
m_ref.get());
|
||||||
++remainingTokens;
|
++tokens;
|
||||||
if (!remainingTokens)
|
if (!tokens)
|
||||||
return Detail::InternalParseResult::runtimeError(
|
return Detail::InternalParseResult::runtimeError(
|
||||||
"Expected argument following " +
|
"Expected argument following " +
|
||||||
token.token);
|
token.token);
|
||||||
auto const& argToken = *remainingTokens;
|
auto const& argToken = *tokens;
|
||||||
if (argToken.type != Detail::TokenType::Argument)
|
if (argToken.type != Detail::TokenType::Argument)
|
||||||
return Detail::InternalParseResult::runtimeError(
|
return Detail::InternalParseResult::runtimeError(
|
||||||
"Expected argument following " +
|
"Expected argument following " +
|
||||||
token.token);
|
token.token);
|
||||||
const auto result = valueRef->setValue(argToken.token);
|
const auto result = valueRef->setValue(static_cast<std::string>(argToken.token));
|
||||||
if (!result)
|
if (!result)
|
||||||
return Detail::InternalParseResult(result);
|
return Detail::InternalParseResult(result);
|
||||||
if (result.value() ==
|
if (result.value() ==
|
||||||
ParseResultType::ShortCircuitAll)
|
ParseResultType::ShortCircuitAll)
|
||||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||||
result.value(), remainingTokens));
|
result.value(), CATCH_MOVE(tokens)));
|
||||||
}
|
}
|
||||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||||
ParseResultType::Matched, ++remainingTokens));
|
ParseResultType::Matched, CATCH_MOVE(++tokens)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Detail::InternalParseResult::ok(
|
return Detail::InternalParseResult::ok(
|
||||||
Detail::ParseState(ParseResultType::NoMatch, remainingTokens));
|
Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Detail::Result Opt::validate() const {
|
Detail::Result Opt::validate() const {
|
||||||
@ -2881,9 +2894,9 @@ namespace Catch {
|
|||||||
|
|
||||||
Detail::InternalParseResult
|
Detail::InternalParseResult
|
||||||
ExeName::parse(std::string const&,
|
ExeName::parse(std::string const&,
|
||||||
Detail::TokenStream const& tokens) const {
|
Detail::TokenStream tokens) const {
|
||||||
return Detail::InternalParseResult::ok(
|
return Detail::InternalParseResult::ok(
|
||||||
Detail::ParseState(ParseResultType::NoMatch, tokens));
|
Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ParserResult ExeName::set(std::string const& newName) {
|
ParserResult ExeName::set(std::string const& newName) {
|
||||||
@ -2913,9 +2926,9 @@ namespace Catch {
|
|||||||
|
|
||||||
std::vector<Detail::HelpColumns> Parser::getHelpColumns() const {
|
std::vector<Detail::HelpColumns> Parser::getHelpColumns() const {
|
||||||
std::vector<Detail::HelpColumns> cols;
|
std::vector<Detail::HelpColumns> cols;
|
||||||
|
cols.reserve( m_options.size() );
|
||||||
for ( auto const& o : m_options ) {
|
for ( auto const& o : m_options ) {
|
||||||
auto childCols = o.getHelpColumns();
|
cols.push_back(o.getHelpColumns());
|
||||||
cols.insert( cols.end(), childCols.begin(), childCols.end() );
|
|
||||||
}
|
}
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
@ -2953,12 +2966,12 @@ namespace Catch {
|
|||||||
|
|
||||||
optWidth = ( std::min )( optWidth, consoleWidth / 2 );
|
optWidth = ( std::min )( optWidth, consoleWidth / 2 );
|
||||||
|
|
||||||
for ( auto const& cols : rows ) {
|
for ( auto& cols : rows ) {
|
||||||
auto row = TextFlow::Column( cols.left )
|
auto row = TextFlow::Column( CATCH_MOVE(cols.left) )
|
||||||
.width( optWidth )
|
.width( optWidth )
|
||||||
.indent( 2 ) +
|
.indent( 2 ) +
|
||||||
TextFlow::Spacer( 4 ) +
|
TextFlow::Spacer( 4 ) +
|
||||||
TextFlow::Column( cols.right )
|
TextFlow::Column( static_cast<std::string>(cols.descriptions) )
|
||||||
.width( consoleWidth - 7 - optWidth );
|
.width( consoleWidth - 7 - optWidth );
|
||||||
os << row << '\n';
|
os << row << '\n';
|
||||||
}
|
}
|
||||||
@ -2980,7 +2993,7 @@ namespace Catch {
|
|||||||
|
|
||||||
Detail::InternalParseResult
|
Detail::InternalParseResult
|
||||||
Parser::parse( std::string const& exeName,
|
Parser::parse( std::string const& exeName,
|
||||||
Detail::TokenStream const& tokens ) const {
|
Detail::TokenStream tokens ) const {
|
||||||
|
|
||||||
struct ParserInfo {
|
struct ParserInfo {
|
||||||
ParserBase const* parser = nullptr;
|
ParserBase const* parser = nullptr;
|
||||||
@ -2998,7 +3011,7 @@ namespace Catch {
|
|||||||
m_exeName.set( exeName );
|
m_exeName.set( exeName );
|
||||||
|
|
||||||
auto result = Detail::InternalParseResult::ok(
|
auto result = Detail::InternalParseResult::ok(
|
||||||
Detail::ParseState( ParseResultType::NoMatch, tokens ) );
|
Detail::ParseState( ParseResultType::NoMatch, CATCH_MOVE(tokens) ) );
|
||||||
while ( result.value().remainingTokens() ) {
|
while ( result.value().remainingTokens() ) {
|
||||||
bool tokenParsed = false;
|
bool tokenParsed = false;
|
||||||
|
|
||||||
@ -3006,7 +3019,7 @@ namespace Catch {
|
|||||||
if ( parseInfo.parser->cardinality() == 0 ||
|
if ( parseInfo.parser->cardinality() == 0 ||
|
||||||
parseInfo.count < parseInfo.parser->cardinality() ) {
|
parseInfo.count < parseInfo.parser->cardinality() ) {
|
||||||
result = parseInfo.parser->parse(
|
result = parseInfo.parser->parse(
|
||||||
exeName, result.value().remainingTokens() );
|
exeName, CATCH_MOVE(result).value().remainingTokens() );
|
||||||
if ( !result )
|
if ( !result )
|
||||||
return result;
|
return result;
|
||||||
if ( result.value().type() !=
|
if ( result.value().type() !=
|
||||||
@ -3032,7 +3045,7 @@ namespace Catch {
|
|||||||
Args::Args(int argc, char const* const* argv) :
|
Args::Args(int argc, char const* const* argv) :
|
||||||
m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
|
m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
|
||||||
|
|
||||||
Args::Args(std::initializer_list<std::string> args) :
|
Args::Args(std::initializer_list<StringRef> args) :
|
||||||
m_exeName(*args.begin()),
|
m_exeName(*args.begin()),
|
||||||
m_args(args.begin() + 1, args.end()) {}
|
m_args(args.begin() + 1, args.end()) {}
|
||||||
|
|
||||||
@ -3338,8 +3351,8 @@ namespace Catch {
|
|||||||
( "split the tests to execute into this many groups" )
|
( "split the tests to execute into this many groups" )
|
||||||
| Opt( setShardIndex, "shard index" )
|
| Opt( setShardIndex, "shard index" )
|
||||||
["--shard-index"]
|
["--shard-index"]
|
||||||
( "index of the group of tests to execute (see --shard-count)" ) |
|
( "index of the group of tests to execute (see --shard-count)" )
|
||||||
Opt( config.allowZeroTests )
|
| Opt( config.allowZeroTests )
|
||||||
["--allow-running-no-tests"]
|
["--allow-running-no-tests"]
|
||||||
( "Treat 'No tests run' as a success" )
|
( "Treat 'No tests run' as a success" )
|
||||||
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
||||||
@ -4641,7 +4654,6 @@ Catch::LeakDetector::~LeakDetector() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -6527,7 +6539,6 @@ namespace Catch {
|
|||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
case TestRunOrder::Randomized: {
|
case TestRunOrder::Randomized: {
|
||||||
seedRng(config);
|
|
||||||
using TestWithHash = std::pair<TestCaseInfoHasher::hash_t, TestCaseHandle>;
|
using TestWithHash = std::pair<TestCaseInfoHasher::hash_t, TestCaseHandle>;
|
||||||
|
|
||||||
TestCaseInfoHasher h{ config.rngSeed() };
|
TestCaseInfoHasher h{ config.rngSeed() };
|
||||||
@ -7390,23 +7401,36 @@ namespace Catch {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
Columns Column::operator+( Column const& other ) {
|
Columns operator+(Column const& lhs, Column const& rhs) {
|
||||||
Columns cols;
|
Columns cols;
|
||||||
cols += *this;
|
cols += lhs;
|
||||||
cols += other;
|
cols += rhs;
|
||||||
|
return cols;
|
||||||
|
}
|
||||||
|
Columns operator+(Column&& lhs, Column&& rhs) {
|
||||||
|
Columns cols;
|
||||||
|
cols += CATCH_MOVE( lhs );
|
||||||
|
cols += CATCH_MOVE( rhs );
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
Columns& Columns::operator+=( Column const& col ) {
|
Columns& operator+=(Columns& lhs, Column const& rhs) {
|
||||||
m_columns.push_back( col );
|
lhs.m_columns.push_back( rhs );
|
||||||
return *this;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
Columns& operator+=(Columns& lhs, Column&& rhs) {
|
||||||
Columns Columns::operator+( Column const& col ) {
|
lhs.m_columns.push_back( CATCH_MOVE(rhs) );
|
||||||
Columns combined = *this;
|
return lhs;
|
||||||
combined += col;
|
}
|
||||||
|
Columns operator+( Columns const& lhs, Column const& rhs ) {
|
||||||
|
auto combined( lhs );
|
||||||
|
combined += rhs;
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
Columns operator+( Columns&& lhs, Column&& rhs ) {
|
||||||
|
lhs += CATCH_MOVE( rhs );
|
||||||
|
return CATCH_MOVE( lhs );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace TextFlow
|
} // namespace TextFlow
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
@ -8881,11 +8905,10 @@ public:
|
|||||||
*this << RowBreak();
|
*this << RowBreak();
|
||||||
|
|
||||||
TextFlow::Columns headerCols;
|
TextFlow::Columns headerCols;
|
||||||
auto spacer = TextFlow::Spacer(2);
|
|
||||||
for (auto const& info : m_columnInfos) {
|
for (auto const& info : m_columnInfos) {
|
||||||
assert(info.width > 2);
|
assert(info.width > 2);
|
||||||
headerCols += TextFlow::Column(info.name).width(info.width - 2);
|
headerCols += TextFlow::Column(info.name).width(info.width - 2);
|
||||||
headerCols += spacer;
|
headerCols += TextFlow::Spacer( 2 );
|
||||||
}
|
}
|
||||||
m_os << headerCols << '\n';
|
m_os << headerCols << '\n';
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
// Catch v3.5.0
|
// Catch v3.5.1
|
||||||
// Generated: 2023-12-11 00:51:06.770598
|
// Generated: 2023-12-31 15:10:53.044176
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
// This file is an amalgamation of multiple different files.
|
// This file is an amalgamation of multiple different files.
|
||||||
// You probably shouldn't edit it directly.
|
// You probably shouldn't edit it directly.
|
||||||
@ -690,6 +690,8 @@ namespace Catch {
|
|||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
using const_iterator = const char*;
|
using const_iterator = const char*;
|
||||||
|
|
||||||
|
static constexpr size_type npos{ static_cast<size_type>( -1 ) };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr char const* const s_empty = "";
|
static constexpr char const* const s_empty = "";
|
||||||
|
|
||||||
@ -740,7 +742,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a substring of [start, start + length).
|
// Returns a substring of [start, start + length).
|
||||||
// If start + length > size(), then the substring is [start, start + size()).
|
// If start + length > size(), then the substring is [start, size()).
|
||||||
// If start > size(), then the substring is empty.
|
// If start > size(), then the substring is empty.
|
||||||
constexpr StringRef substr(size_type start, size_type length) const noexcept {
|
constexpr StringRef substr(size_type start, size_type length) const noexcept {
|
||||||
if (start < m_size) {
|
if (start < m_size) {
|
||||||
@ -1969,12 +1971,12 @@ namespace Catch {
|
|||||||
|
|
||||||
template <typename Clock>
|
template <typename Clock>
|
||||||
int warmup() {
|
int warmup() {
|
||||||
return run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(warmup_time), warmup_seed, &resolution<Clock>)
|
return run_for_at_least<Clock>(warmup_time, warmup_seed, &resolution<Clock>)
|
||||||
.iterations;
|
.iterations;
|
||||||
}
|
}
|
||||||
template <typename Clock>
|
template <typename Clock>
|
||||||
EnvironmentEstimate estimate_clock_resolution(int iterations) {
|
EnvironmentEstimate estimate_clock_resolution(int iterations) {
|
||||||
auto r = run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
|
auto r = run_for_at_least<Clock>(clock_resolution_estimation_time, iterations, &resolution<Clock>)
|
||||||
.result;
|
.result;
|
||||||
return {
|
return {
|
||||||
FDuration(mean(r.data(), r.data() + r.size())),
|
FDuration(mean(r.data(), r.data() + r.size())),
|
||||||
@ -1996,7 +1998,7 @@ namespace Catch {
|
|||||||
};
|
};
|
||||||
time_clock(1);
|
time_clock(1);
|
||||||
int iters = clock_cost_estimation_iterations;
|
int iters = clock_cost_estimation_iterations;
|
||||||
auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(clock_cost_estimation_time), iters, time_clock);
|
auto&& r = run_for_at_least<Clock>(clock_cost_estimation_time, iters, time_clock);
|
||||||
std::vector<double> times;
|
std::vector<double> times;
|
||||||
int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
|
int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
|
||||||
times.reserve(static_cast<size_t>(nsamples));
|
times.reserve(static_cast<size_t>(nsamples));
|
||||||
@ -3639,141 +3641,6 @@ namespace Catch {
|
|||||||
#define CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
|
#define CATCH_REPORTER_SPEC_PARSER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CATCH_CONSOLE_COLOUR_HPP_INCLUDED
|
|
||||||
#define CATCH_CONSOLE_COLOUR_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace Catch {
|
|
||||||
|
|
||||||
enum class ColourMode : std::uint8_t;
|
|
||||||
class IStream;
|
|
||||||
|
|
||||||
struct Colour {
|
|
||||||
enum Code {
|
|
||||||
None = 0,
|
|
||||||
|
|
||||||
White,
|
|
||||||
Red,
|
|
||||||
Green,
|
|
||||||
Blue,
|
|
||||||
Cyan,
|
|
||||||
Yellow,
|
|
||||||
Grey,
|
|
||||||
|
|
||||||
Bright = 0x10,
|
|
||||||
|
|
||||||
BrightRed = Bright | Red,
|
|
||||||
BrightGreen = Bright | Green,
|
|
||||||
LightGrey = Bright | Grey,
|
|
||||||
BrightWhite = Bright | White,
|
|
||||||
BrightYellow = Bright | Yellow,
|
|
||||||
|
|
||||||
// By intention
|
|
||||||
FileName = LightGrey,
|
|
||||||
Warning = BrightYellow,
|
|
||||||
ResultError = BrightRed,
|
|
||||||
ResultSuccess = BrightGreen,
|
|
||||||
ResultExpectedFailure = Warning,
|
|
||||||
|
|
||||||
Error = BrightRed,
|
|
||||||
Success = Green,
|
|
||||||
Skip = LightGrey,
|
|
||||||
|
|
||||||
OriginalExpression = Cyan,
|
|
||||||
ReconstructedExpression = BrightYellow,
|
|
||||||
|
|
||||||
SecondaryText = LightGrey,
|
|
||||||
Headers = White
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class ColourImpl {
|
|
||||||
protected:
|
|
||||||
//! The associated stream of this ColourImpl instance
|
|
||||||
IStream* m_stream;
|
|
||||||
public:
|
|
||||||
ColourImpl( IStream* stream ): m_stream( stream ) {}
|
|
||||||
|
|
||||||
//! RAII wrapper around writing specific colour of text using specific
|
|
||||||
//! colour impl into a stream.
|
|
||||||
class ColourGuard {
|
|
||||||
ColourImpl const* m_colourImpl;
|
|
||||||
Colour::Code m_code;
|
|
||||||
bool m_engaged = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! Does **not** engage the guard/start the colour
|
|
||||||
ColourGuard( Colour::Code code,
|
|
||||||
ColourImpl const* colour );
|
|
||||||
|
|
||||||
ColourGuard( ColourGuard const& rhs ) = delete;
|
|
||||||
ColourGuard& operator=( ColourGuard const& rhs ) = delete;
|
|
||||||
|
|
||||||
ColourGuard( ColourGuard&& rhs ) noexcept;
|
|
||||||
ColourGuard& operator=( ColourGuard&& rhs ) noexcept;
|
|
||||||
|
|
||||||
//! Removes colour _if_ the guard was engaged
|
|
||||||
~ColourGuard();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Explicitly engages colour for given stream.
|
|
||||||
*
|
|
||||||
* The API based on operator<< should be preferred.
|
|
||||||
*/
|
|
||||||
ColourGuard& engage( std::ostream& stream ) &;
|
|
||||||
/**
|
|
||||||
* Explicitly engages colour for given stream.
|
|
||||||
*
|
|
||||||
* The API based on operator<< should be preferred.
|
|
||||||
*/
|
|
||||||
ColourGuard&& engage( std::ostream& stream ) &&;
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! Engages the guard and starts using colour
|
|
||||||
friend std::ostream& operator<<( std::ostream& lhs,
|
|
||||||
ColourGuard& guard ) {
|
|
||||||
guard.engageImpl( lhs );
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
//! Engages the guard and starts using colour
|
|
||||||
friend std::ostream& operator<<( std::ostream& lhs,
|
|
||||||
ColourGuard&& guard) {
|
|
||||||
guard.engageImpl( lhs );
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void engageImpl( std::ostream& stream );
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~ColourImpl(); // = default
|
|
||||||
/**
|
|
||||||
* Creates a guard object for given colour and this colour impl
|
|
||||||
*
|
|
||||||
* **Important:**
|
|
||||||
* the guard starts disengaged, and has to be engaged explicitly.
|
|
||||||
*/
|
|
||||||
ColourGuard guardColour( Colour::Code colourCode );
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void use( Colour::Code colourCode ) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Provides ColourImpl based on global config and target compilation platform
|
|
||||||
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
|
|
||||||
IStream* stream );
|
|
||||||
|
|
||||||
//! Checks if specific colour impl has been compiled into the binary
|
|
||||||
bool isColourImplAvailable( ColourMode colourSelection );
|
|
||||||
|
|
||||||
} // end namespace Catch
|
|
||||||
|
|
||||||
#endif // CATCH_CONSOLE_COLOUR_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -4387,17 +4254,16 @@ namespace Catch {
|
|||||||
enum class TokenType { Option, Argument };
|
enum class TokenType { Option, Argument };
|
||||||
struct Token {
|
struct Token {
|
||||||
TokenType type;
|
TokenType type;
|
||||||
std::string token;
|
StringRef token;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Abstracts iterators into args as a stream of tokens, with option
|
// Abstracts iterators into args as a stream of tokens, with option
|
||||||
// arguments uniformly handled
|
// arguments uniformly handled
|
||||||
class TokenStream {
|
class TokenStream {
|
||||||
using Iterator = std::vector<std::string>::const_iterator;
|
using Iterator = std::vector<StringRef>::const_iterator;
|
||||||
Iterator it;
|
Iterator it;
|
||||||
Iterator itEnd;
|
Iterator itEnd;
|
||||||
std::vector<Token> m_tokenBuffer;
|
std::vector<Token> m_tokenBuffer;
|
||||||
|
|
||||||
void loadBuffer();
|
void loadBuffer();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -4449,12 +4315,17 @@ namespace Catch {
|
|||||||
ResultType m_type;
|
ResultType m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> class ResultValueBase : public ResultBase {
|
template <typename T>
|
||||||
|
class ResultValueBase : public ResultBase {
|
||||||
public:
|
public:
|
||||||
auto value() const -> T const& {
|
T const& value() const& {
|
||||||
enforceOk();
|
enforceOk();
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
T&& value() && {
|
||||||
|
enforceOk();
|
||||||
|
return CATCH_MOVE( m_value );
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ResultValueBase( ResultType type ): ResultBase( type ) {}
|
ResultValueBase( ResultType type ): ResultBase( type ) {}
|
||||||
@ -4464,13 +4335,23 @@ namespace Catch {
|
|||||||
if ( m_type == ResultType::Ok )
|
if ( m_type == ResultType::Ok )
|
||||||
new ( &m_value ) T( other.m_value );
|
new ( &m_value ) T( other.m_value );
|
||||||
}
|
}
|
||||||
|
ResultValueBase( ResultValueBase&& other ):
|
||||||
ResultValueBase( ResultType, T const& value ): ResultBase( ResultType::Ok ) {
|
ResultBase( other ) {
|
||||||
new ( &m_value ) T( value );
|
if ( m_type == ResultType::Ok )
|
||||||
|
new ( &m_value ) T( CATCH_MOVE(other.m_value) );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator=( ResultValueBase const& other )
|
|
||||||
-> ResultValueBase& {
|
ResultValueBase( ResultType, T const& value ):
|
||||||
|
ResultBase( ResultType::Ok ) {
|
||||||
|
new ( &m_value ) T( value );
|
||||||
|
}
|
||||||
|
ResultValueBase( ResultType, T&& value ):
|
||||||
|
ResultBase( ResultType::Ok ) {
|
||||||
|
new ( &m_value ) T( CATCH_MOVE(value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultValueBase& operator=( ResultValueBase const& other ) {
|
||||||
if ( m_type == ResultType::Ok )
|
if ( m_type == ResultType::Ok )
|
||||||
m_value.~T();
|
m_value.~T();
|
||||||
ResultBase::operator=( other );
|
ResultBase::operator=( other );
|
||||||
@ -4478,6 +4359,14 @@ namespace Catch {
|
|||||||
new ( &m_value ) T( other.m_value );
|
new ( &m_value ) T( other.m_value );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
ResultValueBase& operator=( ResultValueBase&& other ) {
|
||||||
|
if ( m_type == ResultType::Ok ) m_value.~T();
|
||||||
|
ResultBase::operator=( other );
|
||||||
|
if ( m_type == ResultType::Ok )
|
||||||
|
new ( &m_value ) T( CATCH_MOVE(other.m_value) );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
~ResultValueBase() override {
|
~ResultValueBase() override {
|
||||||
if ( m_type == ResultType::Ok )
|
if ( m_type == ResultType::Ok )
|
||||||
@ -4505,8 +4394,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
static auto ok( U const& value ) -> BasicResult {
|
static auto ok( U&& value ) -> BasicResult {
|
||||||
return { ResultType::Ok, value };
|
return { ResultType::Ok, CATCH_FORWARD(value) };
|
||||||
}
|
}
|
||||||
static auto ok() -> BasicResult { return { ResultType::Ok }; }
|
static auto ok() -> BasicResult { return { ResultType::Ok }; }
|
||||||
static auto logicError( std::string&& message )
|
static auto logicError( std::string&& message )
|
||||||
@ -4553,12 +4442,15 @@ namespace Catch {
|
|||||||
class ParseState {
|
class ParseState {
|
||||||
public:
|
public:
|
||||||
ParseState( ParseResultType type,
|
ParseState( ParseResultType type,
|
||||||
TokenStream const& remainingTokens );
|
TokenStream remainingTokens );
|
||||||
|
|
||||||
ParseResultType type() const { return m_type; }
|
ParseResultType type() const { return m_type; }
|
||||||
TokenStream const& remainingTokens() const {
|
TokenStream const& remainingTokens() const& {
|
||||||
return m_remainingTokens;
|
return m_remainingTokens;
|
||||||
}
|
}
|
||||||
|
TokenStream&& remainingTokens() && {
|
||||||
|
return CATCH_MOVE( m_remainingTokens );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParseResultType m_type;
|
ParseResultType m_type;
|
||||||
@ -4571,7 +4463,7 @@ namespace Catch {
|
|||||||
|
|
||||||
struct HelpColumns {
|
struct HelpColumns {
|
||||||
std::string left;
|
std::string left;
|
||||||
std::string right;
|
StringRef descriptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -4731,7 +4623,7 @@ namespace Catch {
|
|||||||
virtual ~ParserBase() = default;
|
virtual ~ParserBase() = default;
|
||||||
virtual auto validate() const -> Result { return Result::ok(); }
|
virtual auto validate() const -> Result { return Result::ok(); }
|
||||||
virtual auto parse( std::string const& exeName,
|
virtual auto parse( std::string const& exeName,
|
||||||
TokenStream const& tokens ) const
|
TokenStream tokens ) const
|
||||||
-> InternalParseResult = 0;
|
-> InternalParseResult = 0;
|
||||||
virtual size_t cardinality() const;
|
virtual size_t cardinality() const;
|
||||||
|
|
||||||
@ -4751,8 +4643,8 @@ namespace Catch {
|
|||||||
protected:
|
protected:
|
||||||
Optionality m_optionality = Optionality::Optional;
|
Optionality m_optionality = Optionality::Optional;
|
||||||
std::shared_ptr<BoundRef> m_ref;
|
std::shared_ptr<BoundRef> m_ref;
|
||||||
std::string m_hint;
|
StringRef m_hint;
|
||||||
std::string m_description;
|
StringRef m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl( std::shared_ptr<BoundRef> const& ref ):
|
explicit ParserRefImpl( std::shared_ptr<BoundRef> const& ref ):
|
||||||
m_ref( ref ) {}
|
m_ref( ref ) {}
|
||||||
@ -4761,28 +4653,32 @@ namespace Catch {
|
|||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
ParserRefImpl( accept_many_t,
|
ParserRefImpl( accept_many_t,
|
||||||
LambdaT const& ref,
|
LambdaT const& ref,
|
||||||
std::string const& hint ):
|
StringRef hint ):
|
||||||
m_ref( std::make_shared<BoundManyLambda<LambdaT>>( ref ) ),
|
m_ref( std::make_shared<BoundManyLambda<LambdaT>>( ref ) ),
|
||||||
m_hint( hint ) {}
|
m_hint( hint ) {}
|
||||||
|
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if_t<
|
typename = typename std::enable_if_t<
|
||||||
!Detail::is_unary_function<T>::value>>
|
!Detail::is_unary_function<T>::value>>
|
||||||
ParserRefImpl( T& ref, std::string const& hint ):
|
ParserRefImpl( T& ref, StringRef hint ):
|
||||||
m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||||
m_hint( hint ) {}
|
m_hint( hint ) {}
|
||||||
|
|
||||||
template <typename LambdaT,
|
template <typename LambdaT,
|
||||||
typename = typename std::enable_if_t<
|
typename = typename std::enable_if_t<
|
||||||
Detail::is_unary_function<LambdaT>::value>>
|
Detail::is_unary_function<LambdaT>::value>>
|
||||||
ParserRefImpl( LambdaT const& ref, std::string const& hint ):
|
ParserRefImpl( LambdaT const& ref, StringRef hint ):
|
||||||
m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
|
m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
|
||||||
m_hint( hint ) {}
|
m_hint( hint ) {}
|
||||||
|
|
||||||
auto operator()( std::string const& description ) -> DerivedT& {
|
DerivedT& operator()( StringRef description ) & {
|
||||||
m_description = description;
|
m_description = description;
|
||||||
return static_cast<DerivedT&>( *this );
|
return static_cast<DerivedT&>( *this );
|
||||||
}
|
}
|
||||||
|
DerivedT&& operator()( StringRef description ) && {
|
||||||
|
m_description = description;
|
||||||
|
return static_cast<DerivedT&&>( *this );
|
||||||
|
}
|
||||||
|
|
||||||
auto optional() -> DerivedT& {
|
auto optional() -> DerivedT& {
|
||||||
m_optionality = Optionality::Optional;
|
m_optionality = Optionality::Optional;
|
||||||
@ -4805,7 +4701,7 @@ namespace Catch {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const& hint() const { return m_hint; }
|
StringRef hint() const { return m_hint; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -4819,13 +4715,13 @@ namespace Catch {
|
|||||||
|
|
||||||
Detail::InternalParseResult
|
Detail::InternalParseResult
|
||||||
parse(std::string const&,
|
parse(std::string const&,
|
||||||
Detail::TokenStream const& tokens) const override;
|
Detail::TokenStream tokens) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A parser for options
|
// A parser for options
|
||||||
class Opt : public Detail::ParserRefImpl<Opt> {
|
class Opt : public Detail::ParserRefImpl<Opt> {
|
||||||
protected:
|
protected:
|
||||||
std::vector<std::string> m_optNames;
|
std::vector<StringRef> m_optNames;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
@ -4838,33 +4734,37 @@ namespace Catch {
|
|||||||
template <typename LambdaT,
|
template <typename LambdaT,
|
||||||
typename = typename std::enable_if_t<
|
typename = typename std::enable_if_t<
|
||||||
Detail::is_unary_function<LambdaT>::value>>
|
Detail::is_unary_function<LambdaT>::value>>
|
||||||
Opt( LambdaT const& ref, std::string const& hint ):
|
Opt( LambdaT const& ref, StringRef hint ):
|
||||||
ParserRefImpl( ref, hint ) {}
|
ParserRefImpl( ref, hint ) {}
|
||||||
|
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
Opt( accept_many_t, LambdaT const& ref, std::string const& hint ):
|
Opt( accept_many_t, LambdaT const& ref, StringRef hint ):
|
||||||
ParserRefImpl( accept_many, ref, hint ) {}
|
ParserRefImpl( accept_many, ref, hint ) {}
|
||||||
|
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if_t<
|
typename = typename std::enable_if_t<
|
||||||
!Detail::is_unary_function<T>::value>>
|
!Detail::is_unary_function<T>::value>>
|
||||||
Opt( T& ref, std::string const& hint ):
|
Opt( T& ref, StringRef hint ):
|
||||||
ParserRefImpl( ref, hint ) {}
|
ParserRefImpl( ref, hint ) {}
|
||||||
|
|
||||||
auto operator[](std::string const& optName) -> Opt& {
|
Opt& operator[]( StringRef optName ) & {
|
||||||
m_optNames.push_back(optName);
|
m_optNames.push_back(optName);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
Opt&& operator[]( StringRef optName ) && {
|
||||||
|
m_optNames.push_back( optName );
|
||||||
|
return CATCH_MOVE(*this);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Detail::HelpColumns> getHelpColumns() const;
|
Detail::HelpColumns getHelpColumns() const;
|
||||||
|
|
||||||
bool isMatch(std::string const& optToken) const;
|
bool isMatch(StringRef optToken) const;
|
||||||
|
|
||||||
using ParserBase::parse;
|
using ParserBase::parse;
|
||||||
|
|
||||||
Detail::InternalParseResult
|
Detail::InternalParseResult
|
||||||
parse(std::string const&,
|
parse(std::string const&,
|
||||||
Detail::TokenStream const& tokens) const override;
|
Detail::TokenStream tokens) const override;
|
||||||
|
|
||||||
Detail::Result validate() const override;
|
Detail::Result validate() const override;
|
||||||
};
|
};
|
||||||
@ -4887,7 +4787,7 @@ namespace Catch {
|
|||||||
// handled specially
|
// handled specially
|
||||||
Detail::InternalParseResult
|
Detail::InternalParseResult
|
||||||
parse(std::string const&,
|
parse(std::string const&,
|
||||||
Detail::TokenStream const& tokens) const override;
|
Detail::TokenStream tokens) const override;
|
||||||
|
|
||||||
std::string const& name() const { return *m_name; }
|
std::string const& name() const { return *m_name; }
|
||||||
Detail::ParserResult set(std::string const& newName);
|
Detail::ParserResult set(std::string const& newName);
|
||||||
@ -4912,16 +4812,26 @@ namespace Catch {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator|=(Opt const& opt) -> Parser& {
|
friend Parser& operator|=( Parser& p, Opt const& opt ) {
|
||||||
m_options.push_back(opt);
|
p.m_options.push_back( opt );
|
||||||
return *this;
|
return p;
|
||||||
|
}
|
||||||
|
friend Parser& operator|=( Parser& p, Opt&& opt ) {
|
||||||
|
p.m_options.push_back( CATCH_MOVE(opt) );
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser& operator|=(Parser const& other);
|
Parser& operator|=(Parser const& other);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto operator|(T const& other) const -> Parser {
|
friend Parser operator|( Parser const& p, T&& rhs ) {
|
||||||
return Parser(*this) |= other;
|
return Parser( p ) |= CATCH_FORWARD(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
friend Parser operator|( Parser&& p, T&& rhs ) {
|
||||||
|
p |= CATCH_FORWARD(rhs);
|
||||||
|
return CATCH_MOVE(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Detail::HelpColumns> getHelpColumns() const;
|
std::vector<Detail::HelpColumns> getHelpColumns() const;
|
||||||
@ -4939,21 +4849,23 @@ namespace Catch {
|
|||||||
using ParserBase::parse;
|
using ParserBase::parse;
|
||||||
Detail::InternalParseResult
|
Detail::InternalParseResult
|
||||||
parse(std::string const& exeName,
|
parse(std::string const& exeName,
|
||||||
Detail::TokenStream const& tokens) const override;
|
Detail::TokenStream tokens) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transport for raw args (copied from main args, or supplied via
|
/**
|
||||||
// init list for testing)
|
* Wrapper over argc + argv, assumes that the inputs outlive it
|
||||||
|
*/
|
||||||
class Args {
|
class Args {
|
||||||
friend Detail::TokenStream;
|
friend Detail::TokenStream;
|
||||||
std::string m_exeName;
|
StringRef m_exeName;
|
||||||
std::vector<std::string> m_args;
|
std::vector<StringRef> m_args;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Args(int argc, char const* const* argv);
|
Args(int argc, char const* const* argv);
|
||||||
Args(std::initializer_list<std::string> args);
|
// Helper constructor for testing
|
||||||
|
Args(std::initializer_list<StringRef> args);
|
||||||
|
|
||||||
std::string const& exeName() const { return m_exeName; }
|
StringRef exeName() const { return m_exeName; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -6997,6 +6909,7 @@ namespace Catch {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ITestInvoker;
|
class ITestInvoker;
|
||||||
|
struct NameAndTags;
|
||||||
|
|
||||||
enum class TestCaseProperties : uint8_t {
|
enum class TestCaseProperties : uint8_t {
|
||||||
None = 0,
|
None = 0,
|
||||||
@ -7233,7 +7146,7 @@ namespace Catch {
|
|||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 3
|
#define CATCH_VERSION_MAJOR 3
|
||||||
#define CATCH_VERSION_MINOR 5
|
#define CATCH_VERSION_MINOR 5
|
||||||
#define CATCH_VERSION_PATCH 0
|
#define CATCH_VERSION_PATCH 1
|
||||||
|
|
||||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||||
|
|
||||||
@ -8133,12 +8046,12 @@ class uniform_integer_distribution {
|
|||||||
|
|
||||||
using UnsignedIntegerType = Detail::make_unsigned_t<IntegerType>;
|
using UnsignedIntegerType = Detail::make_unsigned_t<IntegerType>;
|
||||||
|
|
||||||
// We store the left range bound converted to internal representation,
|
// Only the left bound is stored, and we store it converted to its
|
||||||
// because it will be used in computation in the () operator.
|
// unsigned image. This avoids having to do the conversions inside
|
||||||
|
// the operator(), at the cost of having to do the conversion in
|
||||||
|
// the a() getter. The right bound is only needed in the b() getter,
|
||||||
|
// so we recompute it there from other stored data.
|
||||||
UnsignedIntegerType m_a;
|
UnsignedIntegerType m_a;
|
||||||
// After initialization, right bound is only used for the b() getter,
|
|
||||||
// so we keep it in the original type.
|
|
||||||
IntegerType m_b;
|
|
||||||
|
|
||||||
// How many different values are there in [a, b]. a == b => 1, can be 0 for distribution over all values in the type.
|
// How many different values are there in [a, b]. a == b => 1, can be 0 for distribution over all values in the type.
|
||||||
UnsignedIntegerType m_ab_distance;
|
UnsignedIntegerType m_ab_distance;
|
||||||
@ -8151,11 +8064,10 @@ class uniform_integer_distribution {
|
|||||||
// distribution will be reused many times and this is an optimization.
|
// distribution will be reused many times and this is an optimization.
|
||||||
UnsignedIntegerType m_rejection_threshold = 0;
|
UnsignedIntegerType m_rejection_threshold = 0;
|
||||||
|
|
||||||
// Assumes m_b and m_a are already filled
|
UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) const {
|
||||||
UnsignedIntegerType computeDistance() const {
|
// This overflows and returns 0 if a == 0 and b == TYPE_MAX.
|
||||||
// This overflows and returns 0 if ua == 0 and ub == TYPE_MAX.
|
|
||||||
// We handle that later when generating the number.
|
// We handle that later when generating the number.
|
||||||
return transposeTo(m_b) - m_a + 1;
|
return transposeTo(b) - transposeTo(a) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) {
|
static UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) {
|
||||||
@ -8179,8 +8091,7 @@ public:
|
|||||||
|
|
||||||
uniform_integer_distribution( IntegerType a, IntegerType b ):
|
uniform_integer_distribution( IntegerType a, IntegerType b ):
|
||||||
m_a( transposeTo(a) ),
|
m_a( transposeTo(a) ),
|
||||||
m_b( b ),
|
m_ab_distance( computeDistance(a, b) ),
|
||||||
m_ab_distance( computeDistance() ),
|
|
||||||
m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) {
|
m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) {
|
||||||
assert( a <= b );
|
assert( a <= b );
|
||||||
}
|
}
|
||||||
@ -8205,7 +8116,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
result_type a() const { return transposeBack(m_a); }
|
result_type a() const { return transposeBack(m_a); }
|
||||||
result_type b() const { return m_b; }
|
result_type b() const { return transposeBack(m_ab_distance + m_a - 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
@ -9065,6 +8976,141 @@ namespace Catch {
|
|||||||
#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
|
#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CATCH_CONSOLE_COLOUR_HPP_INCLUDED
|
||||||
|
#define CATCH_CONSOLE_COLOUR_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
enum class ColourMode : std::uint8_t;
|
||||||
|
class IStream;
|
||||||
|
|
||||||
|
struct Colour {
|
||||||
|
enum Code {
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
White,
|
||||||
|
Red,
|
||||||
|
Green,
|
||||||
|
Blue,
|
||||||
|
Cyan,
|
||||||
|
Yellow,
|
||||||
|
Grey,
|
||||||
|
|
||||||
|
Bright = 0x10,
|
||||||
|
|
||||||
|
BrightRed = Bright | Red,
|
||||||
|
BrightGreen = Bright | Green,
|
||||||
|
LightGrey = Bright | Grey,
|
||||||
|
BrightWhite = Bright | White,
|
||||||
|
BrightYellow = Bright | Yellow,
|
||||||
|
|
||||||
|
// By intention
|
||||||
|
FileName = LightGrey,
|
||||||
|
Warning = BrightYellow,
|
||||||
|
ResultError = BrightRed,
|
||||||
|
ResultSuccess = BrightGreen,
|
||||||
|
ResultExpectedFailure = Warning,
|
||||||
|
|
||||||
|
Error = BrightRed,
|
||||||
|
Success = Green,
|
||||||
|
Skip = LightGrey,
|
||||||
|
|
||||||
|
OriginalExpression = Cyan,
|
||||||
|
ReconstructedExpression = BrightYellow,
|
||||||
|
|
||||||
|
SecondaryText = LightGrey,
|
||||||
|
Headers = White
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ColourImpl {
|
||||||
|
protected:
|
||||||
|
//! The associated stream of this ColourImpl instance
|
||||||
|
IStream* m_stream;
|
||||||
|
public:
|
||||||
|
ColourImpl( IStream* stream ): m_stream( stream ) {}
|
||||||
|
|
||||||
|
//! RAII wrapper around writing specific colour of text using specific
|
||||||
|
//! colour impl into a stream.
|
||||||
|
class ColourGuard {
|
||||||
|
ColourImpl const* m_colourImpl;
|
||||||
|
Colour::Code m_code;
|
||||||
|
bool m_engaged = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Does **not** engage the guard/start the colour
|
||||||
|
ColourGuard( Colour::Code code,
|
||||||
|
ColourImpl const* colour );
|
||||||
|
|
||||||
|
ColourGuard( ColourGuard const& rhs ) = delete;
|
||||||
|
ColourGuard& operator=( ColourGuard const& rhs ) = delete;
|
||||||
|
|
||||||
|
ColourGuard( ColourGuard&& rhs ) noexcept;
|
||||||
|
ColourGuard& operator=( ColourGuard&& rhs ) noexcept;
|
||||||
|
|
||||||
|
//! Removes colour _if_ the guard was engaged
|
||||||
|
~ColourGuard();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explicitly engages colour for given stream.
|
||||||
|
*
|
||||||
|
* The API based on operator<< should be preferred.
|
||||||
|
*/
|
||||||
|
ColourGuard& engage( std::ostream& stream ) &;
|
||||||
|
/**
|
||||||
|
* Explicitly engages colour for given stream.
|
||||||
|
*
|
||||||
|
* The API based on operator<< should be preferred.
|
||||||
|
*/
|
||||||
|
ColourGuard&& engage( std::ostream& stream ) &&;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Engages the guard and starts using colour
|
||||||
|
friend std::ostream& operator<<( std::ostream& lhs,
|
||||||
|
ColourGuard& guard ) {
|
||||||
|
guard.engageImpl( lhs );
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
//! Engages the guard and starts using colour
|
||||||
|
friend std::ostream& operator<<( std::ostream& lhs,
|
||||||
|
ColourGuard&& guard) {
|
||||||
|
guard.engageImpl( lhs );
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void engageImpl( std::ostream& stream );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~ColourImpl(); // = default
|
||||||
|
/**
|
||||||
|
* Creates a guard object for given colour and this colour impl
|
||||||
|
*
|
||||||
|
* **Important:**
|
||||||
|
* the guard starts disengaged, and has to be engaged explicitly.
|
||||||
|
*/
|
||||||
|
ColourGuard guardColour( Colour::Code colourCode );
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void use( Colour::Code colourCode ) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Provides ColourImpl based on global config and target compilation platform
|
||||||
|
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
|
||||||
|
IStream* stream );
|
||||||
|
|
||||||
|
//! Checks if specific colour impl has been compiled into the binary
|
||||||
|
bool isColourImplAvailable( ColourMode colourSelection );
|
||||||
|
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#endif // CATCH_CONSOLE_COLOUR_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
|
#ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED
|
||||||
#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
|
#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
|
||||||
|
|
||||||
@ -9340,7 +9386,6 @@ namespace Catch {
|
|||||||
#ifndef CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
|
#ifndef CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
|
||||||
#define CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
|
#define CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
@ -10421,7 +10466,7 @@ namespace Catch {
|
|||||||
#ifndef CATCH_SHARDING_HPP_INCLUDED
|
#ifndef CATCH_SHARDING_HPP_INCLUDED
|
||||||
#define CATCH_SHARDING_HPP_INCLUDED
|
#define CATCH_SHARDING_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -10769,6 +10814,7 @@ namespace Catch {
|
|||||||
#ifndef CATCH_TEXTFLOW_HPP_INCLUDED
|
#ifndef CATCH_TEXTFLOW_HPP_INCLUDED
|
||||||
#define CATCH_TEXTFLOW_HPP_INCLUDED
|
#define CATCH_TEXTFLOW_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -10797,7 +10843,7 @@ namespace Catch {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Iterates "lines" in `Column` and return sthem
|
* Iterates "lines" in `Column` and returns them
|
||||||
*/
|
*/
|
||||||
class const_iterator {
|
class const_iterator {
|
||||||
friend Column;
|
friend Column;
|
||||||
@ -10851,20 +10897,35 @@ namespace Catch {
|
|||||||
using iterator = const_iterator;
|
using iterator = const_iterator;
|
||||||
|
|
||||||
explicit Column( std::string const& text ): m_string( text ) {}
|
explicit Column( std::string const& text ): m_string( text ) {}
|
||||||
|
explicit Column( std::string&& text ):
|
||||||
|
m_string( CATCH_MOVE(text)) {}
|
||||||
|
|
||||||
Column& width( size_t newWidth ) {
|
Column& width( size_t newWidth ) & {
|
||||||
assert( newWidth > 0 );
|
assert( newWidth > 0 );
|
||||||
m_width = newWidth;
|
m_width = newWidth;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Column& indent( size_t newIndent ) {
|
Column&& width( size_t newWidth ) && {
|
||||||
|
assert( newWidth > 0 );
|
||||||
|
m_width = newWidth;
|
||||||
|
return CATCH_MOVE( *this );
|
||||||
|
}
|
||||||
|
Column& indent( size_t newIndent ) & {
|
||||||
m_indent = newIndent;
|
m_indent = newIndent;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Column& initialIndent( size_t newIndent ) {
|
Column&& indent( size_t newIndent ) && {
|
||||||
|
m_indent = newIndent;
|
||||||
|
return CATCH_MOVE( *this );
|
||||||
|
}
|
||||||
|
Column& initialIndent( size_t newIndent ) & {
|
||||||
m_initialIndent = newIndent;
|
m_initialIndent = newIndent;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
Column&& initialIndent( size_t newIndent ) && {
|
||||||
|
m_initialIndent = newIndent;
|
||||||
|
return CATCH_MOVE( *this );
|
||||||
|
}
|
||||||
|
|
||||||
size_t width() const { return m_width; }
|
size_t width() const { return m_width; }
|
||||||
const_iterator begin() const { return const_iterator( *this ); }
|
const_iterator begin() const { return const_iterator( *this ); }
|
||||||
@ -10873,7 +10934,8 @@ namespace Catch {
|
|||||||
friend std::ostream& operator<<( std::ostream& os,
|
friend std::ostream& operator<<( std::ostream& os,
|
||||||
Column const& col );
|
Column const& col );
|
||||||
|
|
||||||
Columns operator+( Column const& other );
|
friend Columns operator+( Column const& lhs, Column const& rhs );
|
||||||
|
friend Columns operator+( Column&& lhs, Column&& rhs );
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Creates a column that serves as an empty space of specific width
|
//! Creates a column that serves as an empty space of specific width
|
||||||
@ -10917,8 +10979,10 @@ namespace Catch {
|
|||||||
iterator begin() const { return iterator( *this ); }
|
iterator begin() const { return iterator( *this ); }
|
||||||
iterator end() const { return { *this, iterator::EndTag() }; }
|
iterator end() const { return { *this, iterator::EndTag() }; }
|
||||||
|
|
||||||
Columns& operator+=( Column const& col );
|
friend Columns& operator+=( Columns& lhs, Column const& rhs );
|
||||||
Columns operator+( Column const& col );
|
friend Columns& operator+=( Columns& lhs, Column&& rhs );
|
||||||
|
friend Columns operator+( Columns const& lhs, Column const& rhs );
|
||||||
|
friend Columns operator+( Columns&& lhs, Column&& rhs );
|
||||||
|
|
||||||
friend std::ostream& operator<<( std::ostream& os,
|
friend std::ostream& operator<<( std::ostream& os,
|
||||||
Columns const& cols );
|
Columns const& cols );
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
project(
|
project(
|
||||||
'catch2',
|
'catch2',
|
||||||
'cpp',
|
'cpp',
|
||||||
version: '3.5.0', # CML version placeholder, don't delete
|
version: '3.5.1', # CML version placeholder, don't delete
|
||||||
license: 'BSL-1.0',
|
license: 'BSL-1.0',
|
||||||
meson_version: '>=0.54.1',
|
meson_version: '>=0.54.1',
|
||||||
)
|
)
|
||||||
|
@ -36,7 +36,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 3, 5, 0, "", 0 );
|
static Version version( 3, 5, 1, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 3
|
#define CATCH_VERSION_MAJOR 3
|
||||||
#define CATCH_VERSION_MINOR 5
|
#define CATCH_VERSION_MINOR 5
|
||||||
#define CATCH_VERSION_PATCH 0
|
#define CATCH_VERSION_PATCH 1
|
||||||
|
|
||||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||||
|
Loading…
Reference in New Issue
Block a user