diff options
| author | Martin Hořeňovský | 2025-07-29 23:51:13 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2025-07-30 20:20:38 +0200 |
| commit | ccabd4de891e749f472121497941bb9437b83c2e (patch) | |
| tree | bed41bf34331cae112e53dba4104796324a92e7f /src/catch2 | |
| parent | a1c7ee115f17c1e83b382f33ef2614070974626f (diff) | |
| download | catch3-ccabd4de891e749f472121497941bb9437b83c2e.tar.gz | |
Add enum types to what is captured by value by default
As it turns out, enums can be used to declare bitfields, and we
cannot form a reference to a bitfield in the cpature. Thus, we add
`std::is_enum` as a criteria to the default for `capture_by_value`,
so that enum-based bitfields are also captured by value and thus
decomposable.
Closes #3001
Diffstat (limited to 'src/catch2')
| -rw-r--r-- | src/catch2/internal/catch_decomposer.hpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/catch2/internal/catch_decomposer.hpp b/src/catch2/internal/catch_decomposer.hpp index b6592c54..fcc017dd 100644 --- a/src/catch2/internal/catch_decomposer.hpp +++ b/src/catch2/internal/catch_decomposer.hpp @@ -78,10 +78,11 @@ * * 3) If a type has no linkage, we also cannot capture it by reference. * The solution is once again to capture them by value. We handle - * the common cases by using `std::is_arithmetic` as the default - * for `Catch::capture_by_value`, but that is only a some-effort - * heuristic. But as with 2), users can specialize `capture_by_value` - * for their own types as needed. + * the common cases by using `std::is_arithmetic` and `std::is_enum` + * as the default for `Catch::capture_by_value`, but that is only a + * some-effort heuristic. These combine to capture all possible bitfield + * bases, and also some trait-like types. As with 2), users can + * specialize `capture_by_value` for their own types as needed. * * 4) To support C++20 and make the SFINAE on our decomposing operators * work, the SFINAE has to happen in return type, rather than in @@ -133,13 +134,22 @@ namespace Catch { using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<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 - // keep this as it used to be and it can be changed later. + // Note: This is about as much as we can currently reasonably support. + // In an ideal world, we could capture by value small trivially + // copyable types, but the actual `std::is_trivially_copyable` + // trait is a huge mess with standard-violating results on + // GCC and Clang, which are unlikely to be fixed soon due to ABI + // concerns. + // `std::is_scalar` also causes issues due to the `is_pointer` + // component, which causes ambiguity issues with (references-to) + // function pointer. If those are resolved, we still need to + // disambiguate the overload set for arrays, through explicit + // overload for references to sized arrays. template <typename T> struct capture_by_value - : std::integral_constant<bool, std::is_arithmetic<T>{}> {}; + : std::integral_constant<bool, + std::is_arithmetic<T>::value || + std::is_enum<T>::value> {}; #if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS ) template <> |