mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-19 03:15:40 +02:00
Compare commits
1 Commits
v3.5.2
...
remove_red
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a5245ac76b |
@@ -78,7 +78,6 @@ function(add_warnings_to_targets targets)
|
||||
"-Wreturn-std-move"
|
||||
"-Wshadow"
|
||||
"-Wstrict-aliasing"
|
||||
"-Wsubobject-linkage"
|
||||
"-Wsuggest-destructor-override"
|
||||
"-Wsuggest-override"
|
||||
"-Wundef"
|
||||
|
@@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
project(Catch2
|
||||
VERSION 3.5.2 # CML version placeholder, don't delete
|
||||
VERSION 3.5.0 # CML version placeholder, don't delete
|
||||
LANGUAGES CXX
|
||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||
# we do not target yet.
|
||||
|
@@ -2,8 +2,6 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[3.5.2](#352)<br>
|
||||
[3.5.1](#351)<br>
|
||||
[3.5.0](#350)<br>
|
||||
[3.4.0](#340)<br>
|
||||
[3.3.2](#332)<br>
|
||||
@@ -60,24 +58,6 @@
|
||||
[Even Older versions](#even-older-versions)<br>
|
||||
|
||||
|
||||
## 3.5.1
|
||||
|
||||
### Fixes
|
||||
* Fixed `-Wsubobject-linkage` in the Console reporter (#2794)
|
||||
* Fixed adding new CLI Options to lvalue parser using `|` (#2787)
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
|
@@ -1,41 +0,0 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// 232-Cfg-CustomMain.cpp
|
||||
// Show how to use custom main and add a custom option to the CLI parser
|
||||
|
||||
#include <catch2/catch_session.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Catch::Session session; // There must be exactly one instance
|
||||
|
||||
int height = 0; // Some user variable you want to be able to set
|
||||
|
||||
// Build a new parser on top of Catch2's
|
||||
using namespace Catch::Clara;
|
||||
auto cli
|
||||
= session.cli() // Get Catch2's command line parser
|
||||
| Opt( height, "height" ) // bind variable to a new option, with a hint string
|
||||
["--height"] // the option names it will respond to
|
||||
("how high?"); // description string for the help output
|
||||
|
||||
// Now pass the new composite back to Catch2 so it uses that
|
||||
session.cli( cli );
|
||||
|
||||
// Let Catch2 (using Clara) parse the command line
|
||||
int returnCode = session.applyCommandLine( argc, argv );
|
||||
if( returnCode != 0 ) // Indicates a command line error
|
||||
return returnCode;
|
||||
|
||||
// if set on the command line then 'height' is now set at this point
|
||||
std::cout << "height: " << height << std::endl;
|
||||
|
||||
return session.run();
|
||||
}
|
@@ -30,7 +30,6 @@ set( SOURCES_IDIOMATIC_EXAMPLES
|
||||
110-Fix-ClassFixture.cpp
|
||||
120-Bdd-ScenarioGivenWhenThen.cpp
|
||||
210-Evt-EventListeners.cpp
|
||||
232-Cfg-CustomMain.cpp
|
||||
300-Gen-OwnGenerator.cpp
|
||||
301-Gen-MapTypeConversion.cpp
|
||||
302-Gen-Table.cpp
|
||||
|
@@ -6,8 +6,8 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// Catch v3.5.2
|
||||
// Generated: 2024-01-15 14:06:36.675713
|
||||
// Catch v3.5.0
|
||||
// Generated: 2023-12-11 00:51:07.662625
|
||||
// ----------------------------------------------------------
|
||||
// This file is an amalgamation of multiple different files.
|
||||
// You probably shouldn't edit it directly.
|
||||
@@ -187,16 +187,21 @@ namespace Catch {
|
||||
double const* last,
|
||||
Estimator& estimator ) {
|
||||
auto n = static_cast<size_t>( last - first );
|
||||
std::uniform_int_distribution<size_t> dist( 0, n - 1 );
|
||||
std::uniform_int_distribution<decltype( n )> dist( 0,
|
||||
n - 1 );
|
||||
|
||||
sample out;
|
||||
out.reserve( resamples );
|
||||
// We allocate the vector outside the loop to avoid realloc
|
||||
// per resample
|
||||
std::vector<double> resampled;
|
||||
resampled.reserve( n );
|
||||
for ( size_t i = 0; i < resamples; ++i ) {
|
||||
resampled.clear();
|
||||
for ( size_t s = 0; s < n; ++s ) {
|
||||
resampled.push_back( first[dist( rng )] );
|
||||
resampled.push_back(
|
||||
first[static_cast<std::ptrdiff_t>(
|
||||
dist( rng ) )] );
|
||||
}
|
||||
const auto estimate =
|
||||
estimator( resampled.data(), resampled.data() + resampled.size() );
|
||||
@@ -2268,7 +2273,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 5, 2, "", 0 );
|
||||
static Version version( 3, 5, 0, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -2410,7 +2415,9 @@ namespace Catch {
|
||||
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -2620,29 +2627,13 @@ namespace {
|
||||
;
|
||||
}
|
||||
|
||||
Catch::StringRef normaliseOpt( Catch::StringRef optName ) {
|
||||
if ( optName[0] == '-'
|
||||
#if defined(CATCH_PLATFORM_WINDOWS)
|
||||
|| optName[0] == '/'
|
||||
std::string normaliseOpt( std::string const& optName ) {
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
if ( optName[0] == '/' )
|
||||
return "-" + optName.substr( 1 );
|
||||
else
|
||||
#endif
|
||||
) {
|
||||
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;
|
||||
return optName;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -2660,23 +2651,23 @@ namespace Catch {
|
||||
}
|
||||
|
||||
if ( it != itEnd ) {
|
||||
StringRef next = *it;
|
||||
auto const& next = *it;
|
||||
if ( isOptPrefix( next[0] ) ) {
|
||||
auto delimiterPos = find_first_separator(next);
|
||||
if ( delimiterPos != StringRef::npos ) {
|
||||
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, next.size() ) } );
|
||||
next.substr( delimiterPos + 1 ) } );
|
||||
} else {
|
||||
if ( next[1] != '-' && next.size() > 2 ) {
|
||||
// Combined short args, e.g. "-ab" for "-a -b"
|
||||
std::string opt = "- ";
|
||||
for ( size_t i = 1; i < next.size(); ++i ) {
|
||||
opt[1] = next[i];
|
||||
m_tokenBuffer.push_back(
|
||||
{ TokenType::Option,
|
||||
next.substr( i, 1 ) } );
|
||||
{ TokenType::Option, opt } );
|
||||
}
|
||||
} else {
|
||||
m_tokenBuffer.push_back(
|
||||
@@ -2736,12 +2727,12 @@ namespace Catch {
|
||||
size_t ParserBase::cardinality() const { return 1; }
|
||||
|
||||
InternalParseResult ParserBase::parse( Args const& args ) const {
|
||||
return parse( static_cast<std::string>(args.exeName()), TokenStream( args ) );
|
||||
return parse( args.exeName(), TokenStream( args ) );
|
||||
}
|
||||
|
||||
ParseState::ParseState( ParseResultType type,
|
||||
TokenStream remainingTokens ):
|
||||
m_type( type ), m_remainingTokens( CATCH_MOVE(remainingTokens) ) {}
|
||||
TokenStream const& remainingTokens ):
|
||||
m_type( type ), m_remainingTokens( remainingTokens ) {}
|
||||
|
||||
ParserResult BoundFlagRef::setFlag( bool flag ) {
|
||||
m_ref = flag;
|
||||
@@ -2759,34 +2750,34 @@ namespace Catch {
|
||||
} // namespace Detail
|
||||
|
||||
Detail::InternalParseResult Arg::parse(std::string const&,
|
||||
Detail::TokenStream tokens) const {
|
||||
Detail::TokenStream const& tokens) const {
|
||||
auto validationResult = validate();
|
||||
if (!validationResult)
|
||||
return Detail::InternalParseResult(validationResult);
|
||||
|
||||
auto token = *tokens;
|
||||
auto remainingTokens = tokens;
|
||||
auto const& token = *remainingTokens;
|
||||
if (token.type != Detail::TokenType::Argument)
|
||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||
ParseResultType::NoMatch, CATCH_MOVE(tokens)));
|
||||
ParseResultType::NoMatch, remainingTokens));
|
||||
|
||||
assert(!m_ref->isFlag());
|
||||
auto valueRef =
|
||||
static_cast<Detail::BoundValueRefBase*>(m_ref.get());
|
||||
|
||||
auto result = valueRef->setValue(static_cast<std::string>(token.token));
|
||||
if ( !result )
|
||||
return Detail::InternalParseResult( result );
|
||||
auto result = valueRef->setValue(remainingTokens->token);
|
||||
if (!result)
|
||||
return Detail::InternalParseResult(result);
|
||||
else
|
||||
return Detail::InternalParseResult::ok(
|
||||
Detail::ParseState( ParseResultType::Matched,
|
||||
CATCH_MOVE( ++tokens ) ) );
|
||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||
ParseResultType::Matched, ++remainingTokens));
|
||||
}
|
||||
|
||||
Opt::Opt(bool& ref) :
|
||||
ParserRefImpl(std::make_shared<Detail::BoundFlagRef>(ref)) {}
|
||||
|
||||
Detail::HelpColumns Opt::getHelpColumns() const {
|
||||
ReusableStringStream oss;
|
||||
std::vector<Detail::HelpColumns> Opt::getHelpColumns() const {
|
||||
std::ostringstream oss;
|
||||
bool first = true;
|
||||
for (auto const& opt : m_optNames) {
|
||||
if (first)
|
||||
@@ -2797,10 +2788,10 @@ namespace Catch {
|
||||
}
|
||||
if (!m_hint.empty())
|
||||
oss << " <" << m_hint << '>';
|
||||
return { oss.str(), m_description };
|
||||
return { { oss.str(), m_description } };
|
||||
}
|
||||
|
||||
bool Opt::isMatch(StringRef optToken) const {
|
||||
bool Opt::isMatch(std::string const& optToken) const {
|
||||
auto normalisedToken = normaliseOpt(optToken);
|
||||
for (auto const& name : m_optNames) {
|
||||
if (normaliseOpt(name) == normalisedToken)
|
||||
@@ -2810,14 +2801,15 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Detail::InternalParseResult Opt::parse(std::string const&,
|
||||
Detail::TokenStream tokens) const {
|
||||
Detail::TokenStream const& tokens) const {
|
||||
auto validationResult = validate();
|
||||
if (!validationResult)
|
||||
return Detail::InternalParseResult(validationResult);
|
||||
|
||||
if (tokens &&
|
||||
tokens->type == Detail::TokenType::Option) {
|
||||
auto const& token = *tokens;
|
||||
auto remainingTokens = tokens;
|
||||
if (remainingTokens &&
|
||||
remainingTokens->type == Detail::TokenType::Option) {
|
||||
auto const& token = *remainingTokens;
|
||||
if (isMatch(token.token)) {
|
||||
if (m_ref->isFlag()) {
|
||||
auto flagRef =
|
||||
@@ -2829,35 +2821,35 @@ namespace Catch {
|
||||
if (result.value() ==
|
||||
ParseResultType::ShortCircuitAll)
|
||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||
result.value(), CATCH_MOVE(tokens)));
|
||||
result.value(), remainingTokens));
|
||||
} else {
|
||||
auto valueRef =
|
||||
static_cast<Detail::BoundValueRefBase*>(
|
||||
m_ref.get());
|
||||
++tokens;
|
||||
if (!tokens)
|
||||
++remainingTokens;
|
||||
if (!remainingTokens)
|
||||
return Detail::InternalParseResult::runtimeError(
|
||||
"Expected argument following " +
|
||||
token.token);
|
||||
auto const& argToken = *tokens;
|
||||
auto const& argToken = *remainingTokens;
|
||||
if (argToken.type != Detail::TokenType::Argument)
|
||||
return Detail::InternalParseResult::runtimeError(
|
||||
"Expected argument following " +
|
||||
token.token);
|
||||
const auto result = valueRef->setValue(static_cast<std::string>(argToken.token));
|
||||
const auto result = valueRef->setValue(argToken.token);
|
||||
if (!result)
|
||||
return Detail::InternalParseResult(result);
|
||||
if (result.value() ==
|
||||
ParseResultType::ShortCircuitAll)
|
||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||
result.value(), CATCH_MOVE(tokens)));
|
||||
result.value(), remainingTokens));
|
||||
}
|
||||
return Detail::InternalParseResult::ok(Detail::ParseState(
|
||||
ParseResultType::Matched, CATCH_MOVE(++tokens)));
|
||||
ParseResultType::Matched, ++remainingTokens));
|
||||
}
|
||||
}
|
||||
return Detail::InternalParseResult::ok(
|
||||
Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
|
||||
Detail::ParseState(ParseResultType::NoMatch, remainingTokens));
|
||||
}
|
||||
|
||||
Detail::Result Opt::validate() const {
|
||||
@@ -2889,9 +2881,9 @@ namespace Catch {
|
||||
|
||||
Detail::InternalParseResult
|
||||
ExeName::parse(std::string const&,
|
||||
Detail::TokenStream tokens) const {
|
||||
Detail::TokenStream const& tokens) const {
|
||||
return Detail::InternalParseResult::ok(
|
||||
Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
|
||||
Detail::ParseState(ParseResultType::NoMatch, tokens));
|
||||
}
|
||||
|
||||
ParserResult ExeName::set(std::string const& newName) {
|
||||
@@ -2921,9 +2913,9 @@ namespace Catch {
|
||||
|
||||
std::vector<Detail::HelpColumns> Parser::getHelpColumns() const {
|
||||
std::vector<Detail::HelpColumns> cols;
|
||||
cols.reserve( m_options.size() );
|
||||
for ( auto const& o : m_options ) {
|
||||
cols.push_back(o.getHelpColumns());
|
||||
auto childCols = o.getHelpColumns();
|
||||
cols.insert( cols.end(), childCols.begin(), childCols.end() );
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
@@ -2961,12 +2953,12 @@ namespace Catch {
|
||||
|
||||
optWidth = ( std::min )( optWidth, consoleWidth / 2 );
|
||||
|
||||
for ( auto& cols : rows ) {
|
||||
auto row = TextFlow::Column( CATCH_MOVE(cols.left) )
|
||||
for ( auto const& cols : rows ) {
|
||||
auto row = TextFlow::Column( cols.left )
|
||||
.width( optWidth )
|
||||
.indent( 2 ) +
|
||||
TextFlow::Spacer( 4 ) +
|
||||
TextFlow::Column( static_cast<std::string>(cols.descriptions) )
|
||||
TextFlow::Column( cols.right )
|
||||
.width( consoleWidth - 7 - optWidth );
|
||||
os << row << '\n';
|
||||
}
|
||||
@@ -2988,7 +2980,7 @@ namespace Catch {
|
||||
|
||||
Detail::InternalParseResult
|
||||
Parser::parse( std::string const& exeName,
|
||||
Detail::TokenStream tokens ) const {
|
||||
Detail::TokenStream const& tokens ) const {
|
||||
|
||||
struct ParserInfo {
|
||||
ParserBase const* parser = nullptr;
|
||||
@@ -3006,7 +2998,7 @@ namespace Catch {
|
||||
m_exeName.set( exeName );
|
||||
|
||||
auto result = Detail::InternalParseResult::ok(
|
||||
Detail::ParseState( ParseResultType::NoMatch, CATCH_MOVE(tokens) ) );
|
||||
Detail::ParseState( ParseResultType::NoMatch, tokens ) );
|
||||
while ( result.value().remainingTokens() ) {
|
||||
bool tokenParsed = false;
|
||||
|
||||
@@ -3014,7 +3006,7 @@ namespace Catch {
|
||||
if ( parseInfo.parser->cardinality() == 0 ||
|
||||
parseInfo.count < parseInfo.parser->cardinality() ) {
|
||||
result = parseInfo.parser->parse(
|
||||
exeName, CATCH_MOVE(result).value().remainingTokens() );
|
||||
exeName, result.value().remainingTokens() );
|
||||
if ( !result )
|
||||
return result;
|
||||
if ( result.value().type() !=
|
||||
@@ -3040,7 +3032,7 @@ namespace Catch {
|
||||
Args::Args(int argc, char const* const* argv) :
|
||||
m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
|
||||
|
||||
Args::Args(std::initializer_list<StringRef> args) :
|
||||
Args::Args(std::initializer_list<std::string> args) :
|
||||
m_exeName(*args.begin()),
|
||||
m_args(args.begin() + 1, args.end()) {}
|
||||
|
||||
@@ -3346,8 +3338,8 @@ namespace Catch {
|
||||
( "split the tests to execute into this many groups" )
|
||||
| Opt( setShardIndex, "shard index" )
|
||||
["--shard-index"]
|
||||
( "index of the group of tests to execute (see --shard-count)" )
|
||||
| Opt( config.allowZeroTests )
|
||||
( "index of the group of tests to execute (see --shard-count)" ) |
|
||||
Opt( config.allowZeroTests )
|
||||
["--allow-running-no-tests"]
|
||||
( "Treat 'No tests run' as a success" )
|
||||
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
||||
@@ -4375,6 +4367,7 @@ namespace Detail {
|
||||
CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << '\'' );
|
||||
m_ofs << std::unitbuf;
|
||||
}
|
||||
~FileStream() override = default;
|
||||
public: // IStream
|
||||
std::ostream& stream() override {
|
||||
return m_ofs;
|
||||
@@ -4389,6 +4382,7 @@ namespace Detail {
|
||||
// Store the streambuf from cout up-front because
|
||||
// cout may get redirected when running tests
|
||||
CoutStream() : m_os( Catch::cout().rdbuf() ) {}
|
||||
~CoutStream() override = default;
|
||||
|
||||
public: // IStream
|
||||
std::ostream& stream() override { return m_os; }
|
||||
@@ -4402,6 +4396,7 @@ namespace Detail {
|
||||
// Store the streambuf from cerr up-front because
|
||||
// cout may get redirected when running tests
|
||||
CerrStream(): m_os( Catch::cerr().rdbuf() ) {}
|
||||
~CerrStream() override = default;
|
||||
|
||||
public: // IStream
|
||||
std::ostream& stream() override { return m_os; }
|
||||
@@ -4419,6 +4414,8 @@ namespace Detail {
|
||||
m_os( m_streamBuf.get() )
|
||||
{}
|
||||
|
||||
~DebugOutStream() override = default;
|
||||
|
||||
public: // IStream
|
||||
std::ostream& stream() override { return m_os; }
|
||||
};
|
||||
@@ -4644,6 +4641,7 @@ Catch::LeakDetector::~LeakDetector() {
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
|
||||
@@ -5431,6 +5429,7 @@ namespace Catch {
|
||||
TrackerContext& ctx,
|
||||
ITracker* parent ):
|
||||
TrackerBase( CATCH_MOVE( nameAndLocation ), ctx, parent ) {}
|
||||
~GeneratorTracker() override = default;
|
||||
|
||||
static GeneratorTracker*
|
||||
acquire( TrackerContext& ctx,
|
||||
@@ -6528,6 +6527,7 @@ namespace Catch {
|
||||
return sorted;
|
||||
}
|
||||
case TestRunOrder::Randomized: {
|
||||
seedRng(config);
|
||||
using TestWithHash = std::pair<TestCaseInfoHasher::hash_t, TestCaseHandle>;
|
||||
|
||||
TestCaseInfoHasher h{ config.rngSeed() };
|
||||
@@ -7390,36 +7390,23 @@ namespace Catch {
|
||||
return os;
|
||||
}
|
||||
|
||||
Columns operator+(Column const& lhs, Column const& rhs) {
|
||||
Columns Column::operator+( Column const& other ) {
|
||||
Columns cols;
|
||||
cols += lhs;
|
||||
cols += rhs;
|
||||
return cols;
|
||||
}
|
||||
Columns operator+(Column&& lhs, Column&& rhs) {
|
||||
Columns cols;
|
||||
cols += CATCH_MOVE( lhs );
|
||||
cols += CATCH_MOVE( rhs );
|
||||
cols += *this;
|
||||
cols += other;
|
||||
return cols;
|
||||
}
|
||||
|
||||
Columns& operator+=(Columns& lhs, Column const& rhs) {
|
||||
lhs.m_columns.push_back( rhs );
|
||||
return lhs;
|
||||
Columns& Columns::operator+=( Column const& col ) {
|
||||
m_columns.push_back( col );
|
||||
return *this;
|
||||
}
|
||||
Columns& operator+=(Columns& lhs, Column&& rhs) {
|
||||
lhs.m_columns.push_back( CATCH_MOVE(rhs) );
|
||||
return lhs;
|
||||
}
|
||||
Columns operator+( Columns const& lhs, Column const& rhs ) {
|
||||
auto combined( lhs );
|
||||
combined += rhs;
|
||||
|
||||
Columns Columns::operator+( Column const& col ) {
|
||||
Columns combined = *this;
|
||||
combined += col;
|
||||
return combined;
|
||||
}
|
||||
Columns operator+( Columns&& lhs, Column&& rhs ) {
|
||||
lhs += CATCH_MOVE( rhs );
|
||||
return CATCH_MOVE( lhs );
|
||||
}
|
||||
|
||||
} // namespace TextFlow
|
||||
} // namespace Catch
|
||||
@@ -8788,6 +8775,13 @@ findMax( std::size_t& i, std::size_t& j, std::size_t& k, std::size_t& l ) {
|
||||
return l;
|
||||
}
|
||||
|
||||
enum class Justification { Left, Right };
|
||||
|
||||
struct ColumnInfo {
|
||||
std::string name;
|
||||
std::size_t width;
|
||||
Justification justification;
|
||||
};
|
||||
struct ColumnBreak {};
|
||||
struct RowBreak {};
|
||||
struct OutputFlush {};
|
||||
@@ -8865,14 +8859,6 @@ public:
|
||||
};
|
||||
} // end anon namespace
|
||||
|
||||
enum class Justification { Left, Right };
|
||||
|
||||
struct ColumnInfo {
|
||||
std::string name;
|
||||
std::size_t width;
|
||||
Justification justification;
|
||||
};
|
||||
|
||||
class TablePrinter {
|
||||
std::ostream& m_os;
|
||||
std::vector<ColumnInfo> m_columnInfos;
|
||||
@@ -8895,10 +8881,11 @@ public:
|
||||
*this << RowBreak();
|
||||
|
||||
TextFlow::Columns headerCols;
|
||||
auto spacer = TextFlow::Spacer(2);
|
||||
for (auto const& info : m_columnInfos) {
|
||||
assert(info.width > 2);
|
||||
headerCols += TextFlow::Column(info.name).width(info.width - 2);
|
||||
headerCols += TextFlow::Spacer( 2 );
|
||||
headerCols += spacer;
|
||||
}
|
||||
m_os << headerCols << '\n';
|
||||
|
||||
|
@@ -6,8 +6,8 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// Catch v3.5.2
|
||||
// Generated: 2024-01-15 14:06:34.036475
|
||||
// Catch v3.5.0
|
||||
// Generated: 2023-12-11 00:51:06.770598
|
||||
// ----------------------------------------------------------
|
||||
// This file is an amalgamation of multiple different files.
|
||||
// You probably shouldn't edit it directly.
|
||||
@@ -690,8 +690,6 @@ namespace Catch {
|
||||
using size_type = std::size_t;
|
||||
using const_iterator = const char*;
|
||||
|
||||
static constexpr size_type npos{ static_cast<size_type>( -1 ) };
|
||||
|
||||
private:
|
||||
static constexpr char const* const s_empty = "";
|
||||
|
||||
@@ -742,7 +740,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
// Returns a substring of [start, start + length).
|
||||
// If start + length > size(), then the substring is [start, size()).
|
||||
// If start + length > size(), then the substring is [start, start + size()).
|
||||
// If start > size(), then the substring is empty.
|
||||
constexpr StringRef substr(size_type start, size_type length) const noexcept {
|
||||
if (start < m_size) {
|
||||
@@ -1971,12 +1969,12 @@ namespace Catch {
|
||||
|
||||
template <typename Clock>
|
||||
int warmup() {
|
||||
return run_for_at_least<Clock>(warmup_time, warmup_seed, &resolution<Clock>)
|
||||
return run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(warmup_time), warmup_seed, &resolution<Clock>)
|
||||
.iterations;
|
||||
}
|
||||
template <typename Clock>
|
||||
EnvironmentEstimate estimate_clock_resolution(int iterations) {
|
||||
auto r = run_for_at_least<Clock>(clock_resolution_estimation_time, iterations, &resolution<Clock>)
|
||||
auto r = run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
|
||||
.result;
|
||||
return {
|
||||
FDuration(mean(r.data(), r.data() + r.size())),
|
||||
@@ -1998,7 +1996,7 @@ namespace Catch {
|
||||
};
|
||||
time_clock(1);
|
||||
int iters = clock_cost_estimation_iterations;
|
||||
auto&& r = run_for_at_least<Clock>(clock_cost_estimation_time, iters, time_clock);
|
||||
auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(clock_cost_estimation_time), iters, time_clock);
|
||||
std::vector<double> times;
|
||||
int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
|
||||
times.reserve(static_cast<size_t>(nsamples));
|
||||
@@ -3641,6 +3639,141 @@ namespace Catch {
|
||||
#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 <string>
|
||||
#include <vector>
|
||||
@@ -3766,7 +3899,7 @@ namespace Catch {
|
||||
bool benchmarkNoAnalysis = false;
|
||||
unsigned int benchmarkSamples = 100;
|
||||
double benchmarkConfidenceInterval = 0.95;
|
||||
unsigned int benchmarkResamples = 100'000;
|
||||
unsigned int benchmarkResamples = 100000;
|
||||
std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
|
||||
|
||||
Verbosity verbosity = Verbosity::Normal;
|
||||
@@ -4254,16 +4387,17 @@ namespace Catch {
|
||||
enum class TokenType { Option, Argument };
|
||||
struct Token {
|
||||
TokenType type;
|
||||
StringRef token;
|
||||
std::string token;
|
||||
};
|
||||
|
||||
// Abstracts iterators into args as a stream of tokens, with option
|
||||
// arguments uniformly handled
|
||||
class TokenStream {
|
||||
using Iterator = std::vector<StringRef>::const_iterator;
|
||||
using Iterator = std::vector<std::string>::const_iterator;
|
||||
Iterator it;
|
||||
Iterator itEnd;
|
||||
std::vector<Token> m_tokenBuffer;
|
||||
|
||||
void loadBuffer();
|
||||
|
||||
public:
|
||||
@@ -4315,17 +4449,12 @@ namespace Catch {
|
||||
ResultType m_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ResultValueBase : public ResultBase {
|
||||
template <typename T> class ResultValueBase : public ResultBase {
|
||||
public:
|
||||
T const& value() const& {
|
||||
auto value() const -> T const& {
|
||||
enforceOk();
|
||||
return m_value;
|
||||
}
|
||||
T&& value() && {
|
||||
enforceOk();
|
||||
return CATCH_MOVE( m_value );
|
||||
}
|
||||
|
||||
protected:
|
||||
ResultValueBase( ResultType type ): ResultBase( type ) {}
|
||||
@@ -4335,23 +4464,13 @@ namespace Catch {
|
||||
if ( m_type == ResultType::Ok )
|
||||
new ( &m_value ) T( other.m_value );
|
||||
}
|
||||
ResultValueBase( ResultValueBase&& other ):
|
||||
ResultBase( other ) {
|
||||
if ( m_type == ResultType::Ok )
|
||||
new ( &m_value ) T( CATCH_MOVE(other.m_value) );
|
||||
}
|
||||
|
||||
|
||||
ResultValueBase( ResultType, T const& value ):
|
||||
ResultBase( ResultType::Ok ) {
|
||||
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 ) {
|
||||
auto operator=( ResultValueBase const& other )
|
||||
-> ResultValueBase& {
|
||||
if ( m_type == ResultType::Ok )
|
||||
m_value.~T();
|
||||
ResultBase::operator=( other );
|
||||
@@ -4359,14 +4478,6 @@ namespace Catch {
|
||||
new ( &m_value ) T( other.m_value );
|
||||
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 {
|
||||
if ( m_type == ResultType::Ok )
|
||||
@@ -4394,8 +4505,8 @@ namespace Catch {
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
static auto ok( U&& value ) -> BasicResult {
|
||||
return { ResultType::Ok, CATCH_FORWARD(value) };
|
||||
static auto ok( U const& value ) -> BasicResult {
|
||||
return { ResultType::Ok, value };
|
||||
}
|
||||
static auto ok() -> BasicResult { return { ResultType::Ok }; }
|
||||
static auto logicError( std::string&& message )
|
||||
@@ -4442,15 +4553,12 @@ namespace Catch {
|
||||
class ParseState {
|
||||
public:
|
||||
ParseState( ParseResultType type,
|
||||
TokenStream remainingTokens );
|
||||
TokenStream const& remainingTokens );
|
||||
|
||||
ParseResultType type() const { return m_type; }
|
||||
TokenStream const& remainingTokens() const& {
|
||||
TokenStream const& remainingTokens() const {
|
||||
return m_remainingTokens;
|
||||
}
|
||||
TokenStream&& remainingTokens() && {
|
||||
return CATCH_MOVE( m_remainingTokens );
|
||||
}
|
||||
|
||||
private:
|
||||
ParseResultType m_type;
|
||||
@@ -4463,7 +4571,7 @@ namespace Catch {
|
||||
|
||||
struct HelpColumns {
|
||||
std::string left;
|
||||
StringRef descriptions;
|
||||
std::string right;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -4623,7 +4731,7 @@ namespace Catch {
|
||||
virtual ~ParserBase() = default;
|
||||
virtual auto validate() const -> Result { return Result::ok(); }
|
||||
virtual auto parse( std::string const& exeName,
|
||||
TokenStream tokens ) const
|
||||
TokenStream const& tokens ) const
|
||||
-> InternalParseResult = 0;
|
||||
virtual size_t cardinality() const;
|
||||
|
||||
@@ -4643,8 +4751,8 @@ namespace Catch {
|
||||
protected:
|
||||
Optionality m_optionality = Optionality::Optional;
|
||||
std::shared_ptr<BoundRef> m_ref;
|
||||
StringRef m_hint;
|
||||
StringRef m_description;
|
||||
std::string m_hint;
|
||||
std::string m_description;
|
||||
|
||||
explicit ParserRefImpl( std::shared_ptr<BoundRef> const& ref ):
|
||||
m_ref( ref ) {}
|
||||
@@ -4653,32 +4761,28 @@ namespace Catch {
|
||||
template <typename LambdaT>
|
||||
ParserRefImpl( accept_many_t,
|
||||
LambdaT const& ref,
|
||||
StringRef hint ):
|
||||
std::string const& hint ):
|
||||
m_ref( std::make_shared<BoundManyLambda<LambdaT>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
|
||||
template <typename T,
|
||||
typename = typename std::enable_if_t<
|
||||
!Detail::is_unary_function<T>::value>>
|
||||
ParserRefImpl( T& ref, StringRef hint ):
|
||||
ParserRefImpl( T& ref, std::string const& hint ):
|
||||
m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
|
||||
template <typename LambdaT,
|
||||
typename = typename std::enable_if_t<
|
||||
Detail::is_unary_function<LambdaT>::value>>
|
||||
ParserRefImpl( LambdaT const& ref, StringRef hint ):
|
||||
ParserRefImpl( LambdaT const& ref, std::string const& hint ):
|
||||
m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
|
||||
m_hint( hint ) {}
|
||||
|
||||
DerivedT& operator()( StringRef description ) & {
|
||||
auto operator()( std::string const& description ) -> DerivedT& {
|
||||
m_description = description;
|
||||
return static_cast<DerivedT&>( *this );
|
||||
}
|
||||
DerivedT&& operator()( StringRef description ) && {
|
||||
m_description = description;
|
||||
return static_cast<DerivedT&&>( *this );
|
||||
}
|
||||
|
||||
auto optional() -> DerivedT& {
|
||||
m_optionality = Optionality::Optional;
|
||||
@@ -4701,7 +4805,7 @@ namespace Catch {
|
||||
return 1;
|
||||
}
|
||||
|
||||
StringRef hint() const { return m_hint; }
|
||||
std::string const& hint() const { return m_hint; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@@ -4715,13 +4819,13 @@ namespace Catch {
|
||||
|
||||
Detail::InternalParseResult
|
||||
parse(std::string const&,
|
||||
Detail::TokenStream tokens) const override;
|
||||
Detail::TokenStream const& tokens) const override;
|
||||
};
|
||||
|
||||
// A parser for options
|
||||
class Opt : public Detail::ParserRefImpl<Opt> {
|
||||
protected:
|
||||
std::vector<StringRef> m_optNames;
|
||||
std::vector<std::string> m_optNames;
|
||||
|
||||
public:
|
||||
template <typename LambdaT>
|
||||
@@ -4734,37 +4838,33 @@ namespace Catch {
|
||||
template <typename LambdaT,
|
||||
typename = typename std::enable_if_t<
|
||||
Detail::is_unary_function<LambdaT>::value>>
|
||||
Opt( LambdaT const& ref, StringRef hint ):
|
||||
Opt( LambdaT const& ref, std::string const& hint ):
|
||||
ParserRefImpl( ref, hint ) {}
|
||||
|
||||
template <typename LambdaT>
|
||||
Opt( accept_many_t, LambdaT const& ref, StringRef hint ):
|
||||
Opt( accept_many_t, LambdaT const& ref, std::string const& hint ):
|
||||
ParserRefImpl( accept_many, ref, hint ) {}
|
||||
|
||||
template <typename T,
|
||||
typename = typename std::enable_if_t<
|
||||
!Detail::is_unary_function<T>::value>>
|
||||
Opt( T& ref, StringRef hint ):
|
||||
Opt( T& ref, std::string const& hint ):
|
||||
ParserRefImpl( ref, hint ) {}
|
||||
|
||||
Opt& operator[]( StringRef optName ) & {
|
||||
auto operator[](std::string const& optName) -> Opt& {
|
||||
m_optNames.push_back(optName);
|
||||
return *this;
|
||||
}
|
||||
Opt&& operator[]( StringRef optName ) && {
|
||||
m_optNames.push_back( optName );
|
||||
return CATCH_MOVE(*this);
|
||||
}
|
||||
|
||||
Detail::HelpColumns getHelpColumns() const;
|
||||
std::vector<Detail::HelpColumns> getHelpColumns() const;
|
||||
|
||||
bool isMatch(StringRef optToken) const;
|
||||
bool isMatch(std::string const& optToken) const;
|
||||
|
||||
using ParserBase::parse;
|
||||
|
||||
Detail::InternalParseResult
|
||||
parse(std::string const&,
|
||||
Detail::TokenStream tokens) const override;
|
||||
Detail::TokenStream const& tokens) const override;
|
||||
|
||||
Detail::Result validate() const override;
|
||||
};
|
||||
@@ -4787,7 +4887,7 @@ namespace Catch {
|
||||
// handled specially
|
||||
Detail::InternalParseResult
|
||||
parse(std::string const&,
|
||||
Detail::TokenStream tokens) const override;
|
||||
Detail::TokenStream const& tokens) const override;
|
||||
|
||||
std::string const& name() const { return *m_name; }
|
||||
Detail::ParserResult set(std::string const& newName);
|
||||
@@ -4812,28 +4912,16 @@ namespace Catch {
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Parser& operator|=( Parser& p, Opt const& opt ) {
|
||||
p.m_options.push_back( opt );
|
||||
return p;
|
||||
}
|
||||
friend Parser& operator|=( Parser& p, Opt&& opt ) {
|
||||
p.m_options.push_back( CATCH_MOVE(opt) );
|
||||
return p;
|
||||
auto operator|=(Opt const& opt) -> Parser& {
|
||||
m_options.push_back(opt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Parser& operator|=(Parser const& other);
|
||||
|
||||
template <typename T>
|
||||
friend Parser operator|( Parser const& p, T&& rhs ) {
|
||||
Parser temp( p );
|
||||
temp |= rhs;
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend Parser operator|( Parser&& p, T&& rhs ) {
|
||||
p |= CATCH_FORWARD(rhs);
|
||||
return CATCH_MOVE(p);
|
||||
auto operator|(T const& other) const -> Parser {
|
||||
return Parser(*this) |= other;
|
||||
}
|
||||
|
||||
std::vector<Detail::HelpColumns> getHelpColumns() const;
|
||||
@@ -4851,23 +4939,21 @@ namespace Catch {
|
||||
using ParserBase::parse;
|
||||
Detail::InternalParseResult
|
||||
parse(std::string const& exeName,
|
||||
Detail::TokenStream tokens) const override;
|
||||
Detail::TokenStream const& tokens) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper over argc + argv, assumes that the inputs outlive it
|
||||
*/
|
||||
// Transport for raw args (copied from main args, or supplied via
|
||||
// init list for testing)
|
||||
class Args {
|
||||
friend Detail::TokenStream;
|
||||
StringRef m_exeName;
|
||||
std::vector<StringRef> m_args;
|
||||
std::string m_exeName;
|
||||
std::vector<std::string> m_args;
|
||||
|
||||
public:
|
||||
Args(int argc, char const* const* argv);
|
||||
// Helper constructor for testing
|
||||
Args(std::initializer_list<StringRef> args);
|
||||
Args(std::initializer_list<std::string> args);
|
||||
|
||||
StringRef exeName() const { return m_exeName; }
|
||||
std::string const& exeName() const { return m_exeName; }
|
||||
};
|
||||
|
||||
|
||||
@@ -6911,7 +6997,6 @@ namespace Catch {
|
||||
};
|
||||
|
||||
class ITestInvoker;
|
||||
struct NameAndTags;
|
||||
|
||||
enum class TestCaseProperties : uint8_t {
|
||||
None = 0,
|
||||
@@ -7148,7 +7233,7 @@ namespace Catch {
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 5
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
#define CATCH_VERSION_PATCH 0
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
||||
@@ -8042,12 +8127,12 @@ class uniform_integer_distribution {
|
||||
|
||||
using UnsignedIntegerType = Detail::make_unsigned_t<IntegerType>;
|
||||
|
||||
// Only the left bound is stored, and we store it converted to its
|
||||
// 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.
|
||||
// We store the left range bound converted to internal representation,
|
||||
// because it will be used in computation in the () operator.
|
||||
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.
|
||||
UnsignedIntegerType m_ab_distance;
|
||||
@@ -8060,10 +8145,11 @@ class uniform_integer_distribution {
|
||||
// distribution will be reused many times and this is an optimization.
|
||||
UnsignedIntegerType m_rejection_threshold = 0;
|
||||
|
||||
UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) const {
|
||||
// This overflows and returns 0 if a == 0 and b == TYPE_MAX.
|
||||
// Assumes m_b and m_a are already filled
|
||||
UnsignedIntegerType computeDistance() const {
|
||||
// This overflows and returns 0 if ua == 0 and ub == TYPE_MAX.
|
||||
// We handle that later when generating the number.
|
||||
return transposeTo(b) - transposeTo(a) + 1;
|
||||
return transposeTo(m_b) - m_a + 1;
|
||||
}
|
||||
|
||||
static UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) {
|
||||
@@ -8087,7 +8173,8 @@ public:
|
||||
|
||||
uniform_integer_distribution( IntegerType a, IntegerType b ):
|
||||
m_a( transposeTo(a) ),
|
||||
m_ab_distance( computeDistance(a, b) ),
|
||||
m_b( b ),
|
||||
m_ab_distance( computeDistance() ),
|
||||
m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) {
|
||||
assert( a <= b );
|
||||
}
|
||||
@@ -8112,7 +8199,7 @@ public:
|
||||
}
|
||||
|
||||
result_type a() const { return transposeBack(m_a); }
|
||||
result_type b() const { return transposeBack(m_ab_distance + m_a - 1); }
|
||||
result_type b() const { return m_b; }
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
@@ -8972,141 +9059,6 @@ namespace Catch {
|
||||
#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
|
||||
#define CATCH_CONSOLE_WIDTH_HPP_INCLUDED
|
||||
|
||||
@@ -9382,6 +9334,7 @@ namespace Catch {
|
||||
#ifndef CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
|
||||
#define CATCH_FATAL_CONDITION_HANDLER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace Catch {
|
||||
@@ -10462,7 +10415,7 @@ namespace Catch {
|
||||
#ifndef CATCH_SHARDING_HPP_INCLUDED
|
||||
#define CATCH_SHARDING_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -10808,7 +10761,6 @@ namespace Catch {
|
||||
#ifndef CATCH_TEXTFLOW_HPP_INCLUDED
|
||||
#define CATCH_TEXTFLOW_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -10837,7 +10789,7 @@ namespace Catch {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Iterates "lines" in `Column` and returns them
|
||||
* Iterates "lines" in `Column` and return sthem
|
||||
*/
|
||||
class const_iterator {
|
||||
friend Column;
|
||||
@@ -10891,35 +10843,20 @@ namespace Catch {
|
||||
using iterator = const_iterator;
|
||||
|
||||
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 );
|
||||
m_width = newWidth;
|
||||
return *this;
|
||||
}
|
||||
Column&& width( size_t newWidth ) && {
|
||||
assert( newWidth > 0 );
|
||||
m_width = newWidth;
|
||||
return CATCH_MOVE( *this );
|
||||
}
|
||||
Column& indent( size_t newIndent ) & {
|
||||
Column& indent( size_t newIndent ) {
|
||||
m_indent = newIndent;
|
||||
return *this;
|
||||
}
|
||||
Column&& indent( size_t newIndent ) && {
|
||||
m_indent = newIndent;
|
||||
return CATCH_MOVE( *this );
|
||||
}
|
||||
Column& initialIndent( size_t newIndent ) & {
|
||||
Column& initialIndent( size_t newIndent ) {
|
||||
m_initialIndent = newIndent;
|
||||
return *this;
|
||||
}
|
||||
Column&& initialIndent( size_t newIndent ) && {
|
||||
m_initialIndent = newIndent;
|
||||
return CATCH_MOVE( *this );
|
||||
}
|
||||
|
||||
size_t width() const { return m_width; }
|
||||
const_iterator begin() const { return const_iterator( *this ); }
|
||||
@@ -10928,8 +10865,7 @@ namespace Catch {
|
||||
friend std::ostream& operator<<( std::ostream& os,
|
||||
Column const& col );
|
||||
|
||||
friend Columns operator+( Column const& lhs, Column const& rhs );
|
||||
friend Columns operator+( Column&& lhs, Column&& rhs );
|
||||
Columns operator+( Column const& other );
|
||||
};
|
||||
|
||||
//! Creates a column that serves as an empty space of specific width
|
||||
@@ -10973,10 +10909,8 @@ namespace Catch {
|
||||
iterator begin() const { return iterator( *this ); }
|
||||
iterator end() const { return { *this, iterator::EndTag() }; }
|
||||
|
||||
friend Columns& operator+=( Columns& lhs, Column const& rhs );
|
||||
friend Columns& operator+=( Columns& lhs, Column&& rhs );
|
||||
friend Columns operator+( Columns const& lhs, Column const& rhs );
|
||||
friend Columns operator+( Columns&& lhs, Column&& rhs );
|
||||
Columns& operator+=( Column const& col );
|
||||
Columns operator+( Column const& col );
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& os,
|
||||
Columns const& cols );
|
||||
|
@@ -8,7 +8,7 @@
|
||||
project(
|
||||
'catch2',
|
||||
'cpp',
|
||||
version: '3.5.2', # CML version placeholder, don't delete
|
||||
version: '3.5.0', # CML version placeholder, don't delete
|
||||
license: 'BSL-1.0',
|
||||
meson_version: '>=0.54.1',
|
||||
)
|
||||
|
@@ -38,16 +38,21 @@ namespace Catch {
|
||||
double const* last,
|
||||
Estimator& estimator ) {
|
||||
auto n = static_cast<size_t>( last - first );
|
||||
std::uniform_int_distribution<size_t> dist( 0, n - 1 );
|
||||
std::uniform_int_distribution<decltype( n )> dist( 0,
|
||||
n - 1 );
|
||||
|
||||
sample out;
|
||||
out.reserve( resamples );
|
||||
// We allocate the vector outside the loop to avoid realloc
|
||||
// per resample
|
||||
std::vector<double> resampled;
|
||||
resampled.reserve( n );
|
||||
for ( size_t i = 0; i < resamples; ++i ) {
|
||||
resampled.clear();
|
||||
for ( size_t s = 0; s < n; ++s ) {
|
||||
resampled.push_back( first[dist( rng )] );
|
||||
resampled.push_back(
|
||||
first[static_cast<std::ptrdiff_t>(
|
||||
dist( rng ) )] );
|
||||
}
|
||||
const auto estimate =
|
||||
estimator( resampled.data(), resampled.data() + resampled.size() );
|
||||
|
@@ -69,7 +69,7 @@ namespace Catch {
|
||||
bool benchmarkNoAnalysis = false;
|
||||
unsigned int benchmarkSamples = 100;
|
||||
double benchmarkConfidenceInterval = 0.95;
|
||||
unsigned int benchmarkResamples = 100'000;
|
||||
unsigned int benchmarkResamples = 100000;
|
||||
std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
|
||||
|
||||
Verbosity verbosity = Verbosity::Normal;
|
||||
|
@@ -36,7 +36,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 5, 2, "", 0 );
|
||||
static Version version( 3, 5, 0, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,6 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 5
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
#define CATCH_VERSION_PATCH 0
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
@@ -673,9 +673,7 @@ namespace Catch {
|
||||
|
||||
template <typename T>
|
||||
friend Parser operator|( Parser const& p, T&& rhs ) {
|
||||
Parser temp( p );
|
||||
temp |= rhs;
|
||||
return temp;
|
||||
return Parser( p ) |= CATCH_FORWARD(rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@@ -209,6 +209,13 @@ findMax( std::size_t& i, std::size_t& j, std::size_t& k, std::size_t& l ) {
|
||||
return l;
|
||||
}
|
||||
|
||||
enum class Justification { Left, Right };
|
||||
|
||||
struct ColumnInfo {
|
||||
std::string name;
|
||||
std::size_t width;
|
||||
Justification justification;
|
||||
};
|
||||
struct ColumnBreak {};
|
||||
struct RowBreak {};
|
||||
struct OutputFlush {};
|
||||
@@ -286,14 +293,6 @@ public:
|
||||
};
|
||||
} // end anon namespace
|
||||
|
||||
enum class Justification { Left, Right };
|
||||
|
||||
struct ColumnInfo {
|
||||
std::string name;
|
||||
std::size_t width;
|
||||
Justification justification;
|
||||
};
|
||||
|
||||
class TablePrinter {
|
||||
std::ostream& m_os;
|
||||
std::vector<ColumnInfo> m_columnInfos;
|
||||
|
@@ -123,12 +123,6 @@ TEST_CASE( "count_equidistant_floats",
|
||||
CHECK( count_floats_with_scaled_ulp( 1., 1.5 ) == 1ull << 51 );
|
||||
CHECK( count_floats_with_scaled_ulp( 1.25, 1.5 ) == 1ull << 50 );
|
||||
CHECK( count_floats_with_scaled_ulp( 1.f, 1.5f ) == 1 << 22 );
|
||||
CHECK( count_floats_with_scaled_ulp( -std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max() ) ==
|
||||
33554430 ); // (1 << 25) - 2 due to not including infinities
|
||||
CHECK( count_floats_with_scaled_ulp( -std::numeric_limits<double>::max(),
|
||||
std::numeric_limits<double>::max() ) ==
|
||||
18014398509481982 ); // (1 << 54) - 2 due to not including infinities
|
||||
|
||||
STATIC_REQUIRE( std::is_same<std::uint64_t,
|
||||
decltype( count_floats_with_scaled_ulp(
|
||||
|
Reference in New Issue
Block a user