diff options
| author | Martin Hořeňovský | 2026-09-04 20:54:35 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2026-09-04 20:54:43 +0200 |
| commit | 897d8043eb192d0fc361c6339ce13e1cabe481c4 (patch) | |
| tree | 5f413a5429e7ffe953b4b30fc2e2affcc4c73bb7 /src | |
| parent | de1330d036168492a04b649a1fa0593faece6f74 (diff) | |
| download | catch3-897d8043eb192d0fc361c6339ce13e1cabe481c4.tar.gz | |
Reduce number of instantiations of is_foo_comparable trait
This provides minor compile-time optimization.
Diffstat (limited to 'src')
| -rw-r--r-- | src/catch2/internal/catch_compare_traits.hpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/catch2/internal/catch_compare_traits.hpp b/src/catch2/internal/catch_compare_traits.hpp index 6304b1ff..b0b501d9 100644 --- a/src/catch2/internal/catch_compare_traits.hpp +++ b/src/catch2/internal/catch_compare_traits.hpp @@ -35,21 +35,40 @@ namespace Catch { # pragma clang diagnostic ignored "-Wfloat-equal" #endif + // To avoid instantiating all of `is_foo_comparable<T, T&>`, + // `is_foo_comparable<T&, T&>`, `is_foo_comparable<T, T>`, ... + // we force the type into simple T ref. This does not cause behaviour + // change, because the decomposer already only uses lvalues. + // + // Note that we do not strip away constness, as that would make + // the comparability of `const T` dependent on comparability of `T`, + // which could lead to behavior change from the current implementation. + template <typename T> + using IsComparableNormalized_t = std::remove_reference_t<T>&; + #define CATCH_DEFINE_COMPARABLE_TRAIT( id, op ) \ template <typename, typename, typename = void> \ - struct is_##id##_comparable : std::false_type {}; \ + struct is_##id##_comparable_impl : std::false_type {}; \ template <typename T, typename U> \ - struct is_##id##_comparable< \ + struct is_##id##_comparable_impl< \ T, \ U, \ void_t<decltype( std::declval<T>() op std::declval<U>() )>> \ : std::true_type {}; \ + template <typename T, typename U> \ + using is_##id##_comparable = \ + is_##id##_comparable_impl<IsComparableNormalized_t<T>, \ + IsComparableNormalized_t<U>>; \ template <typename, typename = void> \ - struct is_##id##_0_comparable : std::false_type {}; \ + struct is_##id##_0_comparable_impl : std::false_type {}; \ + template <typename T> \ + struct is_##id##_0_comparable_impl< \ + T, \ + void_t<decltype( std::declval<T>() op 0 )>> \ + : std::true_type {}; \ template <typename T> \ - struct is_##id##_0_comparable<T, \ - void_t<decltype( std::declval<T>() op 0 )>> \ - : std::true_type {}; + using is_##id##_0_comparable = \ + is_##id##_0_comparable_impl<IsComparableNormalized_t<T>>; // We need all 6 pre-spaceship comparison ops: <, <=, >, >=, ==, != CATCH_DEFINE_COMPARABLE_TRAIT( lt, < ) |