mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-25 06:46:10 +01:00
dc51386b9f
This was originally motivated by `REQUIRE((a <=> b) == 0)` no longer compiling using MSVC. After some investigation, I found that they changed their implementation of the zero literal detector from the previous pointer-constructor with deleted other constructors, into one that uses `consteval` constructor from int. This breaks the previous detection logic, because now `is_foo_comparable<std::strong_ordering, int>` is true, but actually trying to compare them is a compile-time error... The solution was to make the decomposition `constexpr` and rely on a late C++20 DR that makes it so that `consteval` propagates up through the callstack of `constexpr` functions, until it either runs out of `constexpr` functions, or succeeds. However, the default handling of types in decomposition is to take a reference to them. This reference never becomes dangling, but because the constexpr evaluation engine cannot prove this, decomposition paths taking references to objects cannot be actually evaluated at compilation time. Thankfully we already did have a value-oriented decomposition path for arithmetic types (as these are common linkage-less types), so we could just explicitly spell out the `std::foo_ordering` types as also being supposed to be decomposed by-value. Two more fun facts about these changes 1) The original motivation of the MSVC change was to avoid trigering a `Wzero-as-null-pointer-constant` warning. I still do not believe this was a good decision. 2) Current latest version of MSVC does not actually implement the aforementioned C++20 DR, so even with this commit, MSVC cannot compile `REQUIRE((a <=> b) == 0)`. |
||
---|---|---|
.. | ||
parse_test_spec.cpp | ||
parse_test_spec.hpp | ||
range_test_helpers.hpp | ||
type_with_lit_0_comparisons.hpp |