diff options
| author | Martin Hořeňovský | 2020-04-21 16:33:15 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2020-04-21 16:33:15 +0200 |
| commit | cfb695669830ceb73b0875a20af4241944eb48e0 (patch) | |
| tree | 52cc5de0fb29fcfad48093ec152f211527f5d0d1 /single_include | |
| parent | e59fc2c3b329493eda676ffa7fcefc7f6059fd0b (diff) | |
| download | catch3-2.12.0.tar.gz | |
v2.12.0v2.12.0
--- Improvements ---
* Running tests in random order (`--order rand`) has been reworked significantly (#1908)
* Given same seed, all platforms now produce the same order
* Given same seed, the relative order of tests does not change if you select only a subset of them
* Vector matchers support custom allocators (#1909)
* `|` and `&` (bitwise or and bitwise and) are now supported in `CHECK` and `REQUIRE`
* The resulting type must be convertible to `bool`
--- Fixes ---
* Fixed computation of benchmarking column widths in ConsoleReporter (#1885, #1886)
* Suppressed clang-tidy's `cppcoreguidelines-pro-type-vararg` in assertions (#1901)
* It was a false positive trigered by the new warning support workaround
* Fixed bug in test specification parser handling of OR'd patterns using escaping (#1905)
--- Miscellaneous ---
* Worked around IBM XL's codegen bug (#1907)
* It would emit code for _destructors_ of temporaries in an unevaluated context
* Improved detection of stdlib's support for `std::uncaught_exceptions` (#1911)
Diffstat (limited to 'single_include')
| -rw-r--r-- | single_include/catch2/catch.hpp | 194 |
1 files changed, 135 insertions, 59 deletions
diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp index 51618b38..d27223f4 100644 --- a/single_include/catch2/catch.hpp +++ b/single_include/catch2/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.11.3 - * Generated: 2020-03-19 13:44:21.042491 + * Catch v2.12.0 + * Generated: 2020-04-21 16:27:54.138031 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. @@ -14,8 +14,8 @@ #define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 11 -#define CATCH_VERSION_PATCH 3 +#define CATCH_VERSION_MINOR 12 +#define CATCH_VERSION_PATCH 0 #ifdef __clang__ # pragma clang system_header @@ -132,7 +132,7 @@ namespace Catch { #endif -#if defined(CATCH_CPP17_OR_GREATER) +#if defined(__cpp_lib_uncaught_exceptions) # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS #endif @@ -151,7 +151,20 @@ namespace Catch { # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg) */ +# endif # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ @@ -2356,6 +2369,14 @@ namespace Catch { auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs }; } + template <typename RhsT> + auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs }; + } + template <typename RhsT> + auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs }; + } template<typename RhsT> auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const { @@ -3000,6 +3021,9 @@ namespace Catch { {} std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + return ""; +#else try { if( it == itEnd ) std::rethrow_exception(std::current_exception()); @@ -3009,6 +3033,7 @@ namespace Catch { catch( T& ex ) { return m_translateFunction( ex ); } +#endif } protected: @@ -3571,12 +3596,12 @@ namespace Catch { namespace Matchers { namespace Vector { - template<typename T> - struct ContainsElementMatcher : MatcherBase<std::vector<T>> { + template<typename T, typename Alloc> + struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> { ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} - bool match(std::vector<T> const &v) const override { + bool match(std::vector<T, Alloc> const &v) const override { for (auto const& el : v) { if (el == m_comparator) { return true; @@ -3592,12 +3617,12 @@ namespace Matchers { T const& m_comparator; }; - template<typename T> - struct ContainsMatcher : MatcherBase<std::vector<T>> { + template<typename T, typename AllocComp, typename AllocMatch> + struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> { - ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} + ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {} - bool match(std::vector<T> const &v) const override { + bool match(std::vector<T, AllocMatch> const &v) const override { // !TBD: see note in EqualsMatcher if (m_comparator.size() > v.size()) return false; @@ -3619,18 +3644,18 @@ namespace Matchers { return "Contains: " + ::Catch::Detail::stringify( m_comparator ); } - std::vector<T> const& m_comparator; + std::vector<T, AllocComp> const& m_comparator; }; - template<typename T> - struct EqualsMatcher : MatcherBase<std::vector<T>> { + template<typename T, typename AllocComp, typename AllocMatch> + struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> { - EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} + EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {} - bool match(std::vector<T> const &v) const override { + bool match(std::vector<T, AllocMatch> const &v) const override { // !TBD: This currently works if all elements can be compared using != // - a more general approach would be via a compare template that defaults - // to using !=. but could be specialised for, e.g. std::vector<T> etc + // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc // - then just call that directly if (m_comparator.size() != v.size()) return false; @@ -3642,15 +3667,15 @@ namespace Matchers { std::string describe() const override { return "Equals: " + ::Catch::Detail::stringify( m_comparator ); } - std::vector<T> const& m_comparator; + std::vector<T, AllocComp> const& m_comparator; }; - template<typename T> - struct ApproxMatcher : MatcherBase<std::vector<T>> { + template<typename T, typename AllocComp, typename AllocMatch> + struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> { - ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {} + ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {} - bool match(std::vector<T> const &v) const override { + bool match(std::vector<T, AllocMatch> const &v) const override { if (m_comparator.size() != v.size()) return false; for (std::size_t i = 0; i < v.size(); ++i) @@ -3677,14 +3702,14 @@ namespace Matchers { return *this; } - std::vector<T> const& m_comparator; + std::vector<T, AllocComp> const& m_comparator; mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom(); }; - template<typename T> - struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> { - UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {} - bool match(std::vector<T> const& vec) const override { + template<typename T, typename AllocComp, typename AllocMatch> + struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> { + UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {} + bool match(std::vector<T, AllocMatch> const& vec) const override { // Note: This is a reimplementation of std::is_permutation, // because I don't want to include <algorithm> inside the common path if (m_target.size() != vec.size()) { @@ -3697,7 +3722,7 @@ namespace Matchers { return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); } private: - std::vector<T> const& m_target; + std::vector<T, AllocComp> const& m_target; }; } // namespace Vector @@ -3705,29 +3730,29 @@ namespace Matchers { // The following functions create the actual matcher objects. // This allows the types to be inferred - template<typename T> - Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) { - return Vector::ContainsMatcher<T>( comparator ); + template<typename T, typename AllocComp, typename AllocMatch = AllocComp> + Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) { + return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator ); } - template<typename T> - Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) { - return Vector::ContainsElementMatcher<T>( comparator ); + template<typename T, typename Alloc = std::allocator<T>> + Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher<T, Alloc>( comparator ); } - template<typename T> - Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) { - return Vector::EqualsMatcher<T>( comparator ); + template<typename T, typename AllocComp, typename AllocMatch = AllocComp> + Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) { + return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator ); } - template<typename T> - Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) { - return Vector::ApproxMatcher<T>( comparator ); + template<typename T, typename AllocComp, typename AllocMatch = AllocComp> + Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) { + return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator ); } - template<typename T> - Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) { - return Vector::UnorderedEqualsMatcher<T>(target); + template<typename T, typename AllocComp, typename AllocMatch = AllocComp> + Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) { + return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target ); } } // namespace Matchers @@ -10319,8 +10344,7 @@ namespace Catch { #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE) -# include <assert.h> -# include <stdbool.h> +# include <cassert> # include <sys/types.h> # include <unistd.h> # include <cstddef> @@ -13977,27 +14001,77 @@ namespace Catch { // end catch_test_case_info.cpp // start catch_test_case_registry_impl.cpp +#include <algorithm> #include <sstream> namespace Catch { - std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) { + namespace { + struct TestHasher { + explicit TestHasher(Catch::SimplePcg32& rng) { + basis = rng(); + basis <<= 32; + basis |= rng(); + } - std::vector<TestCase> sorted = unsortedTestCases; + uint64_t basis; + uint64_t operator()(TestCase const& t) const { + // Modified FNV-1a hash + static constexpr uint64_t prime = 1099511628211; + uint64_t hash = basis; + for (const char c : t.name) { + hash ^= c; + hash *= prime; + } + return hash; + } + }; + } // end unnamed namespace + + std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) { switch( config.runOrder() ) { - case RunTests::InLexicographicalOrder: - std::sort( sorted.begin(), sorted.end() ); - break; - case RunTests::InRandomOrder: - seedRng( config ); - std::shuffle( sorted.begin(), sorted.end(), rng() ); - break; case RunTests::InDeclarationOrder: // already in declaration order break; + + case RunTests::InLexicographicalOrder: { + std::vector<TestCase> sorted = unsortedTestCases; + std::sort( sorted.begin(), sorted.end() ); + return sorted; + } + + case RunTests::InRandomOrder: { + seedRng( config ); + TestHasher h( rng() ); + + using hashedTest = std::pair<uint64_t, TestCase const*>; + std::vector<hashedTest> indexed_tests; + indexed_tests.reserve( unsortedTestCases.size() ); + + for (auto const& testCase : unsortedTestCases) { + indexed_tests.emplace_back(h(testCase), &testCase); + } + + std::sort(indexed_tests.begin(), indexed_tests.end(), + [](hashedTest const& lhs, hashedTest const& rhs) { + if (lhs.first == rhs.first) { + return lhs.second->name < rhs.second->name; + } + return lhs.first < rhs.first; + }); + + std::vector<TestCase> sorted; + sorted.reserve( indexed_tests.size() ); + + for (auto const& hashed : indexed_tests) { + sorted.emplace_back(*hashed.second); + } + + return sorted; + } } - return sorted; + return unsortedTestCases; } bool isThrowSafe( TestCase const& testCase, IConfig const& config ) { @@ -14591,6 +14665,7 @@ namespace Catch { m_pos = m_arg.size(); m_substring.clear(); m_patternName.clear(); + m_realPatternPos = 0; return false; } endMode(); @@ -14609,6 +14684,7 @@ namespace Catch { } m_patternName.clear(); + m_realPatternPos = 0; return token; } @@ -15079,7 +15155,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 11, 3, "", 0 ); + static Version version( 2, 12, 0, "", 0 ); return version; } @@ -16142,7 +16218,7 @@ ConsoleReporter::ConsoleReporter(ReporterConfig const& config) else { return{ - { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left }, + { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left }, { "samples mean std dev", 14, ColumnInfo::Right }, { "iterations low mean low std dev", 14, ColumnInfo::Right }, { "estimated high mean high std dev", 14, ColumnInfo::Right } |