diff --git a/CMakeLists.txt b/CMakeLists.txt
index ce225c0e0e..7c3e855a44 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2
- VERSION 3.5.3 # CML version placeholder, don't delete
+ VERSION 3.5.4 # CML version placeholder, don't delete
LANGUAGES CXX
# HOMEPAGE_URL is not supported until CMake version 3.12, which
# we do not target yet.
diff --git a/docs/release-notes.md b/docs/release-notes.md
index b462b01f73..87cec24be9 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,6 +2,7 @@
# Release notes
**Contents**
+[3.5.4](#354)
[3.5.3](#353)
[3.5.2](#352)
[3.5.1](#351)
@@ -61,6 +62,29 @@
[Even Older versions](#even-older-versions)
+## 3.5.4
+
+### Fixes
+* Fixed potential compilation error when asked to generate random integers whose type did not match `std::(u)int*_t`.
+ * This manifested itself when generating random `size_t`s on MacOS
+* Added missing outlined destructor causing `Wdelete-incomplete` when compiling against libstdc++ in C++23 mode (#2852)
+* Fixed regression where decomposing assertion with const instance of `std::foo_ordering` would not compile
+
+### Improvements
+* Reintroduced support for GCC 5 and 6 (#2836)
+ * As with VS2017, if they start causing trouble again, they will be dropped again.
+* Added workaround for targetting newest MacOS (Sonoma) using GCC (#2837, #2839)
+* `CATCH_CONFIG_DEFAULT_REPORTER` can now be an arbitrary reporter spec
+ * Previously it could only be a plain reporter name, so it was impossible to compile in custom arguments to the reporter.
+* Improved performance of generating 64bit random integers by 20+%
+
+### Miscellaneous
+* Significantly improved Conan in-tree recipe (#2831)
+* `DL_PATHS` in `catch_discover_tests` now supports multiple arguments (#2852, #2736)
+* Fixed preprocessor logic for checking whether we expect reproducible floating point results in tests.
+* Improved the floating point tests structure to avoid `Wunused` when the reproducibility tests are disabled (#2845)
+
+
## 3.5.3
### Fixes
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index c3fbc06157..6aa67884c1 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.5.3
-// Generated: 2024-03-01 22:05:56.038084
+// Catch v3.5.4
+// Generated: 2024-04-10 12:03:46.281848
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -187,7 +187,7 @@ namespace Catch {
double const* last,
Estimator& estimator ) {
auto n = static_cast( last - first );
- std::uniform_int_distribution dist( 0, n - 1 );
+ Catch::uniform_integer_distribution dist( 0, n - 1 );
sample out;
out.reserve( resamples );
@@ -807,14 +807,16 @@ namespace Catch {
// Insert the default reporter if user hasn't asked for a specific one
if ( m_data.reporterSpecifications.empty() ) {
- m_data.reporterSpecifications.push_back( {
#if defined( CATCH_CONFIG_DEFAULT_REPORTER )
- CATCH_CONFIG_DEFAULT_REPORTER,
+ const auto default_spec = CATCH_CONFIG_DEFAULT_REPORTER;
#else
- "console",
+ const auto default_spec = "console";
#endif
- {}, {}, {}
- } );
+ auto parsed = parseReporterSpec(default_spec);
+ CATCH_ENFORCE( parsed,
+ "Cannot parse the provided default reporter spec: '"
+ << default_spec << '\'' );
+ m_data.reporterSpecifications.push_back( std::move( *parsed ) );
}
if ( enableBazelEnvSupport() ) {
@@ -2271,7 +2273,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 5, 3, "", 0 );
+ static Version version( 3, 5, 4, "", 0 );
return version;
}
@@ -6601,6 +6603,8 @@ namespace Catch {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
+ TestRegistry::~TestRegistry() = default;
+
void TestRegistry::registerTest(Detail::unique_ptr testInfo, Detail::unique_ptr testInvoker) {
m_handles.emplace_back(testInfo.get(), testInvoker.get());
m_viewed_test_infos.push_back(testInfo.get());
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp
index e57543142c..7e75a5d197 100644
--- a/extras/catch_amalgamated.hpp
+++ b/extras/catch_amalgamated.hpp
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.5.3
-// Generated: 2024-03-01 22:05:55.031514
+// Catch v3.5.4
+// Generated: 2024-04-10 12:03:45.785902
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -87,6 +87,9 @@
// See e.g.:
// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
#ifdef __APPLE__
+# ifndef __has_extension
+# define __has_extension(x) 0
+# endif
# include
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
(defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
@@ -5254,6 +5257,12 @@ namespace Detail {
namespace Catch {
+ namespace Detail {
+ // This was added in C++20, but we require only C++14 for now.
+ template
+ using RemoveCVRef_t = std::remove_cv_t>;
+ }
+
// Note: There is nothing that stops us from extending this,
// e.g. to `std::is_scalar`, but the more encompassing
// traits are usually also more expensive. For now we
@@ -5293,14 +5302,13 @@ namespace Catch {
ITransientExpression(ITransientExpression const&) = default;
ITransientExpression& operator=(ITransientExpression const&) = default;
- // We don't actually need a virtual destructor, but many static analysers
- // complain if it's not here :-(
- virtual ~ITransientExpression() = default;
-
friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
expr.streamReconstructedExpression(out);
return out;
}
+
+ protected:
+ ~ITransientExpression() = default;
};
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
@@ -5406,17 +5414,17 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction, \
Detail::negation>>>::value, \
+ Detail::RemoveCVRef_t>>>::value, \
BinaryExpr> { \
return { \
static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction, \
capture_by_value>::value, \
BinaryExpr> { \
@@ -5425,7 +5433,7 @@ namespace Catch {
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction< \
Detail::negation>, \
Detail::is_eq_0_comparable, \
@@ -5439,7 +5447,7 @@ namespace Catch {
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction< \
Detail::negation>, \
Detail::is_eq_0_comparable, \
@@ -5460,17 +5468,17 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction, \
Detail::negation>>>::value, \
+ Detail::RemoveCVRef_t>>>::value, \
BinaryExpr> { \
return { \
static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction, \
capture_by_value>::value, \
BinaryExpr> { \
@@ -5479,7 +5487,7 @@ namespace Catch {
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction< \
Detail::negation>, \
Detail::is_##id##_0_comparable, \
@@ -5491,7 +5499,7 @@ namespace Catch {
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t< \
+ -> std::enable_if_t< \
Detail::conjunction< \
Detail::negation>, \
Detail::is_##id##_0_comparable, \
@@ -5512,16 +5520,16 @@ namespace Catch {
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
- ->std::enable_if_t< \
- !capture_by_value>::value, \
+ -> std::enable_if_t< \
+ !capture_by_value>::value, \
BinaryExpr> { \
return { \
static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
} \
template \
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- ->std::enable_if_t::value, \
- BinaryExpr> { \
+ -> std::enable_if_t::value, \
+ BinaryExpr> { \
return { \
static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
}
@@ -5553,8 +5561,7 @@ namespace Catch {
struct Decomposer {
template >::value,
+ std::enable_if_t>::value,
int> = 0>
constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs {
return ExprLhs{ lhs };
@@ -7263,7 +7270,7 @@ namespace Catch {
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 5
-#define CATCH_VERSION_PATCH 3
+#define CATCH_VERSION_PATCH 4
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@@ -7935,6 +7942,32 @@ namespace Catch {
#include
#include
+// Note: We use the usual enable-disable-autodetect dance here even though
+// we do not support these in CMake configuration options (yet?).
+// It is highly unlikely that we will need to make these actually
+// user-configurable, but this will make it simpler if weend up needing
+// it, and it provides an escape hatch to the users who need it.
+#if defined( __SIZEOF_INT128__ )
+# define CATCH_CONFIG_INTERNAL_UINT128
+#elif defined( _MSC_VER ) && ( defined( _WIN64 ) || defined( _M_ARM64 ) )
+# define CATCH_CONFIG_INTERNAL_MSVC_UMUL128
+#endif
+
+#if defined( CATCH_CONFIG_INTERNAL_UINT128 ) && \
+ !defined( CATCH_CONFIG_NO_UINT128 ) && \
+ !defined( CATCH_CONFIG_UINT128 )
+#define CATCH_CONFIG_UINT128
+#endif
+
+#if defined( CATCH_CONFIG_INTERNAL_MSVC_UMUL128 ) && \
+ !defined( CATCH_CONFIG_NO_MSVC_UMUL128 ) && \
+ !defined( CATCH_CONFIG_MSVC_UMUL128 )
+# define CATCH_CONFIG_MSVC_UMUL128
+# include
+# pragma intrinsic( _umul128 )
+#endif
+
+
namespace Catch {
namespace Detail {
@@ -7967,59 +8000,52 @@ namespace Catch {
}
};
- // Returns 128 bit result of multiplying lhs and rhs
+ /**
+ * Returns 128 bit result of lhs * rhs using portable C++ code
+ *
+ * This implementation is almost twice as fast as naive long multiplication,
+ * and unlike intrinsic-based approach, it supports constexpr evaluation.
+ */
constexpr ExtendedMultResult
- extendedMult( std::uint64_t lhs, std::uint64_t rhs ) {
- // We use the simple long multiplication approach for
- // correctness, we can use platform specific builtins
- // for performance later.
-
- // Split the lhs and rhs into two 32bit "digits", so that we can
- // do 64 bit arithmetic to handle carry bits.
- // 32b 32b 32b 32b
- // lhs L1 L2
- // * rhs R1 R2
- // ------------------------
- // | R2 * L2 |
- // | R2 * L1 |
- // | R1 * L2 |
- // | R1 * L1 |
- // -------------------------
- // | a | b | c | d |
-
+ extendedMultPortable(std::uint64_t lhs, std::uint64_t rhs) {
#define CarryBits( x ) ( x >> 32 )
#define Digits( x ) ( x & 0xFF'FF'FF'FF )
-
- auto r2l2 = Digits( rhs ) * Digits( lhs );
- auto r2l1 = Digits( rhs ) * CarryBits( lhs );
- auto r1l2 = CarryBits( rhs ) * Digits( lhs );
- auto r1l1 = CarryBits( rhs ) * CarryBits( lhs );
-
- // Sum to columns first
- auto d = Digits( r2l2 );
- auto c = CarryBits( r2l2 ) + Digits( r2l1 ) + Digits( r1l2 );
- auto b = CarryBits( r2l1 ) + CarryBits( r1l2 ) + Digits( r1l1 );
- auto a = CarryBits( r1l1 );
-
- // Propagate carries between columns
- c += CarryBits( d );
- b += CarryBits( c );
- a += CarryBits( b );
-
- // Remove the used carries
- c = Digits( c );
- b = Digits( b );
- a = Digits( a );
-
+ std::uint64_t lhs_low = Digits( lhs );
+ std::uint64_t rhs_low = Digits( rhs );
+ std::uint64_t low_low = ( lhs_low * rhs_low );
+ std::uint64_t high_high = CarryBits( lhs ) * CarryBits( rhs );
+
+ // We add in carry bits from low-low already
+ std::uint64_t high_low =
+ ( CarryBits( lhs ) * rhs_low ) + CarryBits( low_low );
+ // Note that we can add only low bits from high_low, to avoid
+ // overflow with large inputs
+ std::uint64_t low_high =
+ ( lhs_low * CarryBits( rhs ) ) + Digits( high_low );
+
+ return { high_high + CarryBits( high_low ) + CarryBits( low_high ),
+ ( low_high << 32 ) | Digits( low_low ) };
#undef CarryBits
#undef Digits
+ }
- return {
- a << 32 | b, // upper 64 bits
- c << 32 | d // lower 64 bits
- };
+ //! Returns 128 bit result of lhs * rhs
+ inline ExtendedMultResult
+ extendedMult( std::uint64_t lhs, std::uint64_t rhs ) {
+#if defined( CATCH_CONFIG_UINT128 )
+ auto result = __uint128_t( lhs ) * __uint128_t( rhs );
+ return { static_cast( result >> 64 ),
+ static_cast( result ) };
+#elif defined( CATCH_CONFIG_MSVC_UMUL128 )
+ std::uint64_t high;
+ std::uint64_t low = _umul128( lhs, rhs, &high );
+ return { high, low };
+#else
+ return extendedMultPortable( lhs, rhs );
+#endif
}
+
template
constexpr ExtendedMultResult extendedMult( UInt lhs, UInt rhs ) {
static_assert( std::is_unsigned::value,
@@ -8123,22 +8149,6 @@ namespace Catch {
namespace Catch {
- namespace Detail {
- // Indirection to enable make_unsigned behaviour.
- template
- struct make_unsigned {
- using type = std::make_unsigned_t;
- };
-
- template <>
- struct make_unsigned {
- using type = uint8_t;
- };
-
- template
- using make_unsigned_t = typename make_unsigned::type;
- }
-
/**
* Implementation of uniform distribution on integers.
*
@@ -8154,7 +8164,7 @@ template
class uniform_integer_distribution {
static_assert(std::is_integral::value, "...");
- using UnsignedIntegerType = Detail::make_unsigned_t;
+ using UnsignedIntegerType = Detail::SizedUnsignedType_t;
// Only the left bound is stored, and we store it converted to its
// unsigned image. This avoids having to do the conversions inside
@@ -10823,6 +10833,8 @@ namespace Catch {
std::vector const& getAllTests() const override;
std::vector const& getAllTestsSorted( IConfig const& config ) const override;
+ ~TestRegistry() override; // = default
+
private:
std::vector> m_owned_test_infos;
// Keeps a materialized vector for `getAllInfos`.
diff --git a/meson.build b/meson.build
index 3d0e715e37..7c216f96b4 100644
--- a/meson.build
+++ b/meson.build
@@ -8,7 +8,7 @@
project(
'catch2',
'cpp',
- version: '3.5.3', # CML version placeholder, don't delete
+ version: '3.5.4', # CML version placeholder, don't delete
license: 'BSL-1.0',
meson_version: '>=0.54.1',
)
diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp
index 2604be358d..9e8765b39f 100644
--- a/src/catch2/catch_version.cpp
+++ b/src/catch2/catch_version.cpp
@@ -36,7 +36,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 5, 3, "", 0 );
+ static Version version( 3, 5, 4, "", 0 );
return version;
}
diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp
index 921ff52676..ff50c09c97 100644
--- a/src/catch2/catch_version_macros.hpp
+++ b/src/catch2/catch_version_macros.hpp
@@ -10,6 +10,6 @@
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 5
-#define CATCH_VERSION_PATCH 3
+#define CATCH_VERSION_PATCH 4
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED