|  | 
| 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