This commit is contained in:
Martin Hořeňovský 2020-03-19 12:37:51 +01:00
parent 695a356f93
commit 5f94c8dafb
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
8 changed files with 130 additions and 98 deletions

View File

@ -14,7 +14,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif() endif()
project(Catch2 LANGUAGES CXX VERSION 2.11.1) project(Catch2 LANGUAGES CXX VERSION 2.11.2)
# Provide path for scripts # Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")

View File

@ -5,11 +5,11 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2) [![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2) [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2) [![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/Fj98nizVNqgaWH3i) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/ZI5SYb7JE1UJhAKP)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD) [![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
<a href="https://github.com/catchorg/Catch2/releases/download/v2.11.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a> <a href="https://github.com/catchorg/Catch2/releases/download/v2.11.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released! ## Catch2 is released!

View File

@ -323,7 +323,7 @@ Instead the user code is only measured and the plain mean from the samples is re
## Specify the amount of time in milliseconds spent on warming up each test ## Specify the amount of time in milliseconds spent on warming up each test
<pre>--benchmark-warmup-time</pre> <pre>--benchmark-warmup-time</pre>
> [Introduced](https://github.com/catchorg/Catch2/pull/1844) in Catch X.Y.Z. > [Introduced](https://github.com/catchorg/Catch2/pull/1844) in Catch 2.11.2.
Configure the amount of time spent warming up each test. Configure the amount of time spent warming up each test.

View File

@ -260,7 +260,7 @@ namespace Catch {
## Overriding Catch's debug break (`-b`) ## Overriding Catch's debug break (`-b`)
> [Introduced](https://github.com/catchorg/Catch2/pull/1846) in Catch X.Y.Z. > [Introduced](https://github.com/catchorg/Catch2/pull/1846) in Catch 2.11.2.
You can override Catch2's break-into-debugger code by defining the You can override Catch2's break-into-debugger code by defining the
`CATCH_BREAK_INTO_DEBUGGER()` macro. This can be used if e.g. Catch2 does `CATCH_BREAK_INTO_DEBUGGER()` macro. This can be used if e.g. Catch2 does

View File

@ -2,6 +2,7 @@
# Release notes # Release notes
**Contents**<br> **Contents**<br>
[2.11.2](#2112)<br>
[2.11.1](#2111)<br> [2.11.1](#2111)<br>
[2.11.0](#2110)<br> [2.11.0](#2110)<br>
[2.10.2](#2102)<br> [2.10.2](#2102)<br>
@ -32,6 +33,32 @@
[Older versions](#older-versions)<br> [Older versions](#older-versions)<br>
[Even Older versions](#even-older-versions)<br> [Even Older versions](#even-older-versions)<br>
## 2.11.2
### Improvements
* GCC and Clang now issue warnings for suspicious code in assertions (#1880)
* E.g. `REQUIRE( int != unsigned int )` will now issue mixed signedness comparison warning
* This has always worked on MSVC, but it now also works for GCC and current Clang versions
* Colorization of "Test filters" output should be more robust now
* `--wait-for-keypress` now also accepts `never` as an option (#1866)
* Reporters no longer round-off nanoseconds when reporting benchmarking results (#1876)
* Catch2's debug break now supports iOS while using Thumb instruction set (#1862)
* It is now possible to customize benchmark's warm-up time when running the test binary (#1844)
* `--benchmark-warmup-time {ms}`
* User can now specify how Catch2 should break into debugger (#1846)
### Fixes
* Fixes missing `<random>` include in benchmarking (#1831)
* Fixed missing `<iterator>` include in benchmarking (#1874)
* Hidden test cases are now also tagged with `[!hide]` as per documentation (#1847)
* Detection of whether libc provides `std::nextafter` has been improved (#1854)
* Detection of `wmain` no longer incorrectly looks for `WIN32` macro (#1849)
* Now it just detects Windows platform
* Composing already-composed matchers no longer modifies the partially-composed matcher expression
* This bug has been present for the last ~2 years and nobody reported it
## 2.11.1 ## 2.11.1
### Improvements ### Improvements

View File

@ -11,7 +11,7 @@
#define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 11 #define CATCH_VERSION_MINOR 11
#define CATCH_VERSION_PATCH 1 #define CATCH_VERSION_PATCH 2
#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header

View File

@ -37,7 +37,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 2, 11, 1, "", 0 ); static Version version( 2, 11, 2, "", 0 );
return version; return version;
} }

View File

@ -1,9 +1,9 @@
/* /*
* Catch v2.11.1 * Catch v2.11.2
* Generated: 2019-12-28 21:22:11.930976 * Generated: 2020-03-19 12:35:04.038733
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
* *
* Distributed under the Boost Software License, Version 1.0. (See accompanying * Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -15,7 +15,7 @@
#define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 11 #define CATCH_VERSION_MINOR 11
#define CATCH_VERSION_PATCH 1 #define CATCH_VERSION_PATCH 2
#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header
@ -141,6 +141,9 @@ namespace Catch {
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
#endif #endif
#if defined(__clang__) #if defined(__clang__)
@ -148,6 +151,8 @@ namespace Catch {
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
_Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
@ -226,6 +231,8 @@ namespace Catch {
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)sizeof(__VA_ARGS__)
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
# endif # endif
@ -294,7 +301,7 @@ namespace Catch {
#define CATCH_CONFIG_COLOUR_NONE #define CATCH_CONFIG_COLOUR_NONE
#endif #endif
#if defined(__UCLIBC__) #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
#endif #endif
@ -420,6 +427,12 @@ namespace Catch {
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
#endif #endif
// The goal of this macro is to avoid evaluation of the arguments, but
// still have the compiler warn on problems inside...
#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
#endif
#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#elif defined(__clang__) && (__clang_major__ < 5) #elif defined(__clang__) && (__clang_major__ < 5)
@ -2663,6 +2676,7 @@ namespace Catch {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { \ do { \
CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
INTERNAL_CATCH_TRY { \ INTERNAL_CATCH_TRY { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
@ -2671,8 +2685,7 @@ namespace Catch {
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look } while( false )
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
@ -3266,9 +3279,10 @@ namespace Matchers {
return description; return description;
} }
MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) { MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
m_matchers.push_back( &other ); auto copy(*this);
return *this; copy.m_matchers.push_back( &other );
return copy;
} }
std::vector<MatcherBase<ArgT> const*> m_matchers; std::vector<MatcherBase<ArgT> const*> m_matchers;
@ -3299,9 +3313,10 @@ namespace Matchers {
return description; return description;
} }
MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) { MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
m_matchers.push_back( &other ); auto copy(*this);
return *this; copy.m_matchers.push_back( &other );
return copy;
} }
std::vector<MatcherBase<ArgT> const*> m_matchers; std::vector<MatcherBase<ArgT> const*> m_matchers;
@ -4411,6 +4426,7 @@ namespace Catch {
} // end namespace Catch } // end namespace Catch
// end catch_option.hpp // end catch_option.hpp
#include <chrono>
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
#include <vector> #include <vector>
@ -4481,6 +4497,7 @@ namespace Catch {
virtual int benchmarkSamples() const = 0; virtual int benchmarkSamples() const = 0;
virtual double benchmarkConfidenceInterval() const = 0; virtual double benchmarkConfidenceInterval() const = 0;
virtual unsigned int benchmarkResamples() const = 0; virtual unsigned int benchmarkResamples() const = 0;
virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
}; };
using IConfigPtr = std::shared_ptr<IConfig const>; using IConfigPtr = std::shared_ptr<IConfig const>;
@ -5234,6 +5251,7 @@ namespace Catch {
unsigned int benchmarkSamples = 100; unsigned int benchmarkSamples = 100;
double benchmarkConfidenceInterval = 0.95; double benchmarkConfidenceInterval = 0.95;
unsigned int benchmarkResamples = 100000; unsigned int benchmarkResamples = 100000;
std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
Verbosity verbosity = Verbosity::Normal; Verbosity verbosity = Verbosity::Normal;
WarnAbout::What warnings = WarnAbout::Nothing; WarnAbout::What warnings = WarnAbout::Nothing;
@ -5299,6 +5317,7 @@ namespace Catch {
int benchmarkSamples() const override; int benchmarkSamples() const override;
double benchmarkConfidenceInterval() const override; double benchmarkConfidenceInterval() const override;
unsigned int benchmarkResamples() const override; unsigned int benchmarkResamples() const override;
std::chrono::milliseconds benchmarkWarmupTime() const override;
private: private:
@ -6884,11 +6903,13 @@ namespace Catch {
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
#include <vector> #include <vector>
#include <iterator>
#include <numeric> #include <numeric>
#include <tuple> #include <tuple>
#include <cmath> #include <cmath>
#include <utility> #include <utility>
#include <cstddef> #include <cstddef>
#include <random>
namespace Catch { namespace Catch {
namespace Benchmark { namespace Benchmark {
@ -7238,10 +7259,10 @@ namespace Catch {
template <typename Clock> template <typename Clock>
ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
auto min_time = env.clock_resolution.mean * Detail::minimum_ticks; auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time)); auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun); auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations }; return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
} }
template <typename Clock = default_clock> template <typename Clock = default_clock>
@ -7868,8 +7889,10 @@ namespace Catch {
#define CATCH_TRAP() __asm__("int $3") #define CATCH_TRAP() __asm__("int $3")
#elif defined(__aarch64__) #elif defined(__aarch64__)
#define CATCH_TRAP() __asm__(".inst 0xd4200000") #define CATCH_TRAP() __asm__(".inst 0xd4200000")
#elif defined(__arm__) #elif defined(__arm__) && !defined(__thumb__)
#define CATCH_TRAP() __asm__(".inst 0xe7f001f0") #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
#elif defined(__arm__) && defined(__thumb__)
#define CATCH_TRAP() __asm__(".inst 0xde01")
#endif #endif
#elif defined(CATCH_PLATFORM_LINUX) #elif defined(CATCH_PLATFORM_LINUX)
@ -7890,11 +7913,13 @@ namespace Catch {
#define CATCH_TRAP() DebugBreak() #define CATCH_TRAP() DebugBreak()
#endif #endif
#ifndef CATCH_BREAK_INTO_DEBUGGER
#ifdef CATCH_TRAP #ifdef CATCH_TRAP
#define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
#else #else
#define CATCH_BREAK_INTO_DEBUGGER() []{}() #define CATCH_BREAK_INTO_DEBUGGER() []{}()
#endif #endif
#endif
// end catch_debugger.h // end catch_debugger.h
// start catch_run_context.h // start catch_run_context.h
@ -9665,8 +9690,7 @@ namespace Catch {
if( !startsWith( line, '"' ) ) if( !startsWith( line, '"' ) )
line = '"' + line + '"'; line = '"' + line + '"';
config.testsOrTags.push_back( line ); config.testsOrTags.push_back( line );
config.testsOrTags.push_back( "," ); config.testsOrTags.emplace_back( "," );
} }
} }
//Remove comma in the end //Remove comma in the end
@ -9707,14 +9731,16 @@ namespace Catch {
}; };
auto const setWaitForKeypress = [&]( std::string const& keypress ) { auto const setWaitForKeypress = [&]( std::string const& keypress ) {
auto keypressLc = toLower( keypress ); auto keypressLc = toLower( keypress );
if( keypressLc == "start" ) if (keypressLc == "never")
config.waitForKeypress = WaitForKeypress::Never;
else if( keypressLc == "start" )
config.waitForKeypress = WaitForKeypress::BeforeStart; config.waitForKeypress = WaitForKeypress::BeforeStart;
else if( keypressLc == "exit" ) else if( keypressLc == "exit" )
config.waitForKeypress = WaitForKeypress::BeforeExit; config.waitForKeypress = WaitForKeypress::BeforeExit;
else if( keypressLc == "both" ) else if( keypressLc == "both" )
config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
else else
return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
return ParserResult::ok( ParseResultType::Matched ); return ParserResult::ok( ParseResultType::Matched );
}; };
auto const setVerbosity = [&]( std::string const& verbosity ) { auto const setVerbosity = [&]( std::string const& verbosity ) {
@ -9814,7 +9840,7 @@ namespace Catch {
| Opt( config.libIdentify ) | Opt( config.libIdentify )
["--libidentify"] ["--libidentify"]
( "report name and version according to libidentify standard" ) ( "report name and version according to libidentify standard" )
| Opt( setWaitForKeypress, "start|exit|both" ) | Opt( setWaitForKeypress, "never|start|exit|both" )
["--wait-for-keypress"] ["--wait-for-keypress"]
( "waits for a keypress before exiting" ) ( "waits for a keypress before exiting" )
| Opt( config.benchmarkSamples, "samples" ) | Opt( config.benchmarkSamples, "samples" )
@ -9829,6 +9855,9 @@ namespace Catch {
| Opt( config.benchmarkNoAnalysis ) | Opt( config.benchmarkNoAnalysis )
["--benchmark-no-analysis"] ["--benchmark-no-analysis"]
( "perform only measurements; do not perform any analysis" ) ( "perform only measurements; do not perform any analysis" )
| Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
["--benchmark-warmup-time"]
( "amount of time in milliseconds spent on warming up each test (default: 100)" )
| Arg( config.testsOrTags, "test name|pattern|tags" ) | Arg( config.testsOrTags, "test name|pattern|tags" )
( "which test or tests to use" ); ( "which test or tests to use" );
@ -9940,6 +9969,7 @@ namespace Catch {
int Config::benchmarkSamples() const { return m_data.benchmarkSamples; } int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; } double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; } unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
IStream const* Config::openStream() { IStream const* Config::openStream() {
return Catch::makeStream(m_data.outputFilename); return Catch::makeStream(m_data.outputFilename);
@ -9980,7 +10010,7 @@ namespace Catch {
}; };
struct NoColourImpl : IColourImpl { struct NoColourImpl : IColourImpl {
void use( Colour::Code ) {} void use( Colour::Code ) override {}
static IColourImpl* instance() { static IColourImpl* instance() {
static NoColourImpl s_instance; static NoColourImpl s_instance;
@ -10153,13 +10183,13 @@ namespace Catch {
namespace Catch { namespace Catch {
Colour::Colour( Code _colourCode ) { use( _colourCode ); } Colour::Colour( Code _colourCode ) { use( _colourCode ); }
Colour::Colour( Colour&& rhs ) noexcept { Colour::Colour( Colour&& other ) noexcept {
m_moved = rhs.m_moved; m_moved = other.m_moved;
rhs.m_moved = true; other.m_moved = true;
} }
Colour& Colour::operator=( Colour&& rhs ) noexcept { Colour& Colour::operator=( Colour&& other ) noexcept {
m_moved = rhs.m_moved; m_moved = other.m_moved;
rhs.m_moved = true; other.m_moved = true;
return *this; return *this;
} }
@ -10171,7 +10201,7 @@ namespace Catch {
// However, under some conditions it does happen (see #1626), // However, under some conditions it does happen (see #1626),
// and this change is small enough that we can let practicality // and this change is small enough that we can let practicality
// triumph over purity in this case. // triumph over purity in this case.
if (impl != NULL) { if (impl != nullptr) {
impl->use( _colourCode ); impl->use( _colourCode );
} }
} }
@ -10524,7 +10554,7 @@ namespace Catch {
assert( valueNames.size() == values.size() ); assert( valueNames.size() == values.size() );
std::size_t i = 0; std::size_t i = 0;
for( auto value : values ) for( auto value : values )
enumInfo->m_values.push_back({ value, valueNames[i++] }); enumInfo->m_values.emplace_back(value, valueNames[i++]);
return enumInfo; return enumInfo;
} }
@ -11100,7 +11130,7 @@ namespace Catch {
namespace Catch { namespace Catch {
std::size_t listTests( Config const& config ) { std::size_t listTests( Config const& config ) {
TestSpec testSpec = config.testSpec(); TestSpec const& testSpec = config.testSpec();
if( config.hasTestFilters() ) if( config.hasTestFilters() )
Catch::cout() << "Matching test cases:\n"; Catch::cout() << "Matching test cases:\n";
else { else {
@ -11134,7 +11164,7 @@ namespace Catch {
} }
std::size_t listTestsNamesOnly( Config const& config ) { std::size_t listTestsNamesOnly( Config const& config ) {
TestSpec testSpec = config.testSpec(); TestSpec const& testSpec = config.testSpec();
std::size_t matchedTests = 0; std::size_t matchedTests = 0;
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( auto const& testCaseInfo : matchedTestCases ) { for( auto const& testCaseInfo : matchedTestCases ) {
@ -11172,7 +11202,7 @@ namespace Catch {
} }
std::size_t listTags( Config const& config ) { std::size_t listTags( Config const& config ) {
TestSpec testSpec = config.testSpec(); TestSpec const& testSpec = config.testSpec();
if( config.hasTestFilters() ) if( config.hasTestFilters() )
Catch::cout() << "Tags for matching test cases:\n"; Catch::cout() << "Tags for matching test cases:\n";
else { else {
@ -11364,16 +11394,8 @@ namespace {
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff; return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
} }
} //end anonymous namespace
#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
#if defined(__clang__)
#pragma clang diagnostic push
// The long double overload is currently unused
#pragma clang diagnostic ignored "-Wunused-function"
#endif
float nextafter(float x, float y) { float nextafter(float x, float y) {
return ::nextafterf(x, y); return ::nextafterf(x, y);
} }
@ -11382,18 +11404,8 @@ namespace {
return ::nextafter(x, y); return ::nextafter(x, y);
} }
long double nextafter(long double x, long double y) {
return ::nextafterl(x, y);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^ #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
namespace {
template <typename FP> template <typename FP>
FP step(FP start, FP direction, uint64_t steps) { FP step(FP start, FP direction, uint64_t steps) {
for (uint64_t i = 0; i < steps; ++i) { for (uint64_t i = 0; i < steps; ++i) {
@ -11772,7 +11784,7 @@ namespace Catch {
pos = skipq(pos, c); pos = skipq(pos, c);
break; break;
case ',': case ',':
if (start != pos && openings.size() == 0) { if (start != pos && openings.empty()) {
m_messages.emplace_back(macroName, lineInfo, resultType); m_messages.emplace_back(macroName, lineInfo, resultType);
m_messages.back().message = static_cast<std::string>(trimmed(start, pos)); m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
m_messages.back().message += " := "; m_messages.back().message += " := ";
@ -11780,7 +11792,7 @@ namespace Catch {
} }
} }
} }
assert(openings.size() == 0 && "Mismatched openings"); assert(openings.empty() && "Mismatched openings");
m_messages.emplace_back(macroName, lineInfo, resultType); m_messages.emplace_back(macroName, lineInfo, resultType);
m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1)); m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
m_messages.back().message += " := "; m_messages.back().message += " := ";
@ -13268,11 +13280,11 @@ namespace Catch {
char **utf8Argv = new char *[ argc ]; char **utf8Argv = new char *[ argc ];
for ( int i = 0; i < argc; ++i ) { for ( int i = 0; i < argc; ++i ) {
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
utf8Argv[ i ] = new char[ bufSize ]; utf8Argv[ i ] = new char[ bufSize ];
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
} }
int returnCode = applyCommandLine( argc, utf8Argv ); int returnCode = applyCommandLine( argc, utf8Argv );
@ -13871,7 +13883,8 @@ namespace Catch {
} }
} }
if( isHidden ) { if( isHidden ) {
tags.push_back( "." ); // Add all "hidden" tags to make them behave identically
tags.insert( tags.end(), { ".", "!hide" } );
} }
TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo ); TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
@ -14282,8 +14295,8 @@ namespace TestCaseTracking {
void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) { void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
if( !filters.empty() ) { if( !filters.empty() ) {
m_filters.reserve( m_filters.size() + filters.size() + 2 ); m_filters.reserve( m_filters.size() + filters.size() + 2 );
m_filters.push_back(""); // Root - should never be consulted m_filters.emplace_back(""); // Root - should never be consulted
m_filters.push_back(""); // Test Case - not a section filter m_filters.emplace_back(""); // Test Case - not a section filter
m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
} }
} }
@ -15068,7 +15081,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 2, 11, 1, "", 0 ); static Version version( 2, 11, 2, "", 0 );
return version; return version;
} }
@ -15118,8 +15131,6 @@ namespace Catch {
#include <iomanip> #include <iomanip>
#include <type_traits> #include <type_traits>
using uchar = unsigned char;
namespace Catch { namespace Catch {
namespace { namespace {
@ -15192,7 +15203,7 @@ namespace {
// (see: http://www.w3.org/TR/xml/#syntax) // (see: http://www.w3.org/TR/xml/#syntax)
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
uchar c = m_str[idx]; unsigned char c = m_str[idx];
switch (c) { switch (c) {
case '<': os << "&lt;"; break; case '<': os << "&lt;"; break;
case '&': os << "&amp;"; break; case '&': os << "&amp;"; break;
@ -15252,7 +15263,7 @@ namespace {
bool valid = true; bool valid = true;
uint32_t value = headerValue(c); uint32_t value = headerValue(c);
for (std::size_t n = 1; n < encBytes; ++n) { for (std::size_t n = 1; n < encBytes; ++n) {
uchar nc = m_str[idx + n]; unsigned char nc = m_str[idx + n];
valid &= ((nc & 0xC0) == 0x80); valid &= ((nc & 0xC0) == 0x80);
value = (value << 6) | (nc & 0x3F); value = (value << 6) | (nc & 0x3F);
} }
@ -15981,15 +15992,11 @@ class Duration {
static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond; static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond; static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
uint64_t m_inNanoseconds; double m_inNanoseconds;
Unit m_units; Unit m_units;
public: public:
explicit Duration(double inNanoseconds, Unit units = Unit::Auto) explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
: Duration(static_cast<uint64_t>(inNanoseconds), units) {
}
explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
: m_inNanoseconds(inNanoseconds), : m_inNanoseconds(inNanoseconds),
m_units(units) { m_units(units) {
if (m_units == Unit::Auto) { if (m_units == Unit::Auto) {
@ -16018,7 +16025,7 @@ public:
case Unit::Minutes: case Unit::Minutes:
return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute); return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
default: default:
return static_cast<double>(m_inNanoseconds); return m_inNanoseconds;
} }
} }
auto unitsAsString() const -> std::string { auto unitsAsString() const -> std::string {
@ -16454,8 +16461,10 @@ void ConsoleReporter::printSummaryDivider() {
} }
void ConsoleReporter::printTestFilters() { void ConsoleReporter::printTestFilters() {
if (m_config->testSpec().hasFilters()) if (m_config->testSpec().hasFilters()) {
stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n'; Colour guard(Colour::BrightYellow);
stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
}
} }
CATCH_REGISTER_REPORTER("console", ConsoleReporter) CATCH_REGISTER_REPORTER("console", ConsoleReporter)
@ -16681,11 +16690,7 @@ namespace Catch {
elementName = "error"; elementName = "error";
break; break;
case ResultWas::ExplicitFailure: case ResultWas::ExplicitFailure:
elementName = "failure";
break;
case ResultWas::ExpressionFailed: case ResultWas::ExpressionFailed:
elementName = "failure";
break;
case ResultWas::DidntThrowException: case ResultWas::DidntThrowException:
elementName = "failure"; elementName = "failure";
break; break;
@ -17111,16 +17116,16 @@ namespace Catch {
m_xml.writeAttribute("samples", info.samples) m_xml.writeAttribute("samples", info.samples)
.writeAttribute("resamples", info.resamples) .writeAttribute("resamples", info.resamples)
.writeAttribute("iterations", info.iterations) .writeAttribute("iterations", info.iterations)
.writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution)) .writeAttribute("clockResolution", info.clockResolution)
.writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration)) .writeAttribute("estimatedDuration", info.estimatedDuration)
.writeComment("All values in nano seconds"); .writeComment("All values in nano seconds");
} }
void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) { void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
m_xml.startElement("mean") m_xml.startElement("mean")
.writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count())) .writeAttribute("value", benchmarkStats.mean.point.count())
.writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count())) .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
.writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count())) .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
.writeAttribute("ci", benchmarkStats.mean.confidence_interval); .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
m_xml.endElement(); m_xml.endElement();
m_xml.startElement("standardDeviation") m_xml.startElement("standardDeviation")
@ -17171,7 +17176,7 @@ namespace Catch {
#ifndef __OBJC__ #ifndef __OBJC__
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point // Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else #else