|
78 | 78 | * |
79 | 79 | * 3) If a type has no linkage, we also cannot capture it by reference. |
80 | 80 | * The solution is once again to capture them by value. We handle |
81 | | - * the common cases by using `std::is_arithmetic` as the default |
82 | | - * for `Catch::capture_by_value`, but that is only a some-effort |
83 | | - * heuristic. But as with 2), users can specialize `capture_by_value` |
84 | | - * for their own types as needed. |
| 81 | + * the common cases by using `std::is_arithmetic` and `std::is_enum` |
| 82 | + * as the default for `Catch::capture_by_value`, but that is only a |
| 83 | + * some-effort heuristic. These combine to capture all possible bitfield |
| 84 | + * bases, and also some trait-like types. As with 2), users can |
| 85 | + * specialize `capture_by_value` for their own types as needed. |
85 | 86 | * |
86 | 87 | * 4) To support C++20 and make the SFINAE on our decomposing operators |
87 | 88 | * work, the SFINAE has to happen in return type, rather than in |
@@ -133,13 +134,22 @@ namespace Catch { |
133 | 134 | using RemoveCVRef_t = std::remove_cv_t<std::remove_reference_t<T>>; |
134 | 135 | } |
135 | 136 |
|
136 | | - // Note: There is nothing that stops us from extending this, |
137 | | - // e.g. to `std::is_scalar`, but the more encompassing |
138 | | - // traits are usually also more expensive. For now we |
139 | | - // keep this as it used to be and it can be changed later. |
| 137 | + // Note: This is about as much as we can currently reasonably support. |
| 138 | + // In an ideal world, we could capture by value small trivially |
| 139 | + // copyable types, but the actual `std::is_trivially_copyable` |
| 140 | + // trait is a huge mess with standard-violating results on |
| 141 | + // GCC and Clang, which are unlikely to be fixed soon due to ABI |
| 142 | + // concerns. |
| 143 | + // `std::is_scalar` also causes issues due to the `is_pointer` |
| 144 | + // component, which causes ambiguity issues with (references-to) |
| 145 | + // function pointer. If those are resolved, we still need to |
| 146 | + // disambiguate the overload set for arrays, through explicit |
| 147 | + // overload for references to sized arrays. |
140 | 148 | template <typename T> |
141 | 149 | struct capture_by_value |
142 | | - : std::integral_constant<bool, std::is_arithmetic<T>{}> {}; |
| 150 | + : std::integral_constant<bool, |
| 151 | + std::is_arithmetic<T>::value || |
| 152 | + std::is_enum<T>::value> {}; |
143 | 153 |
|
144 | 154 | #if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS ) |
145 | 155 | template <> |
|
0 commit comments