Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2
diff options
context:
space:
mode:
authorMartin Hořeňovský2025-07-29 23:51:13 +0200
committerMartin Hořeňovský2025-07-30 20:20:38 +0200
commitccabd4de891e749f472121497941bb9437b83c2e (patch)
treebed41bf34331cae112e53dba4104796324a92e7f /src/catch2
parenta1c7ee115f17c1e83b382f33ef2614070974626f (diff)
downloadcatch3-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.hpp28
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 <>