fmt icon indicating copy to clipboard operation
fmt copied to clipboard

Check range_begin is dereferenceable

Open Arghnews opened this issue 1 year ago • 0 comments

Fixes issue #3839

An Eigen 3.4 2x2 matrix has a begin member function that returns void and a static_assert that evaluates to false (as you're not meant to call begin on a non-1d matrix). However this doesn't play nicely with the SFINAE checks at the moment in fmt as they simply perform a SFINAE check that the expression is valid, which evaluating to void is (even though it's of course not a valid type for an iterator):

https://github.com/fmtlib/fmt/blob/75e892420ed84a058f0a494d693a6baf5212eac4/include/fmt/ranges.h#L100-L104


To model a range more strictly to eliminate this case:

If we look at the c++20 concept for a range, it requires ranges::begin on the type, and that requires the type satisfy input_or_output_iterator, which specifically notes that begin returns: The exposition-only concept /*can-reference*/ is satisfied if and only if the type is referenceable (in particular, not void).

So just check we can deref the result of that type to fix this case, and not incorrectly identify a type with void begin/end functions as a range. Note we don't want to do this for the type returned by end, as (in c++ >= 20) it may be a different sentinel type that is not dereferenceable)

Arghnews avatar May 19 '24 03:05 Arghnews